diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index 2d565795d9f..fa42481f5f6 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -248,9 +248,11 @@ jobs: include: - image: ubuntu2204 std: 20 - - image: ubuntu2204_clang + cxx: g++ + - image: ubuntu2204 std: 20 - container: ghcr.io/acts-project/${{ matrix.image }}:63 + cxx: clang++ + container: ghcr.io/acts-project/${{ matrix.image }}:71 env: INSTALL_DIR: ${{ github.workspace }}/install ACTS_LOG_FAILURE_THRESHOLD: WARNING @@ -285,6 +287,7 @@ jobs: ccache -z && cmake -B build -S . --preset=github-ci + -DCMAKE_CXX_COMPILER=${{ matrix.cxx }} -DCMAKE_CXX_STANDARD=${{ matrix.std }} -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" -DPython_EXECUTABLE=$(which python3) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 25aff340111..185b3a4fb23 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,9 +6,19 @@ variables: DEPENDENCY_TAG: v5 +.ccache_base: + cache: + - key: ccache-${CI_JOB_NAME}-${CCACHE_KEY_SUFFIX}-${CLONE_URL}_${HEAD_REF} + fallback_keys: + - ccache-${CI_JOB_NAME}-${CCACHE_KEY_SUFFIX}-https://github.com/acts-project/acts.git-main + when: always + paths: + - ${CCACHE_DIR} + + clang_tidy: stage: build - image: ghcr.io/acts-project/ubuntu2404:63 + image: registry.cern.ch/ghcr.io/acts-project/ubuntu2404:63 tags: - large artifacts: @@ -61,19 +71,14 @@ clang_tidy: build_exatrkx_cpu: stage: build - image: ghcr.io/acts-project/ubuntu2204_exatrkx:63 + image: registry.cern.ch/ghcr.io/acts-project/ubuntu2204_exatrkx:63 variables: DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/ubuntu-22.04/deps.$DEPENDENCY_TAG.tar.zst tags: - large cache: - key: ccache-${CI_JOB_NAME}-${CI_COMMIT_REF_SLUG}-${CCACHE_KEY_SUFFIX} - fallback_keys: - - ccache-${CI_JOB_NAME}-${CI_DEFAULT_BRANCH}-${CCACHE_KEY_SUFFIX} - when: always - paths: - - ${CCACHE_DIR} + - !reference [.ccache_base, cache] script: - export PATH=/usr/local/sbin:/usr/sbin:/sbin:$PATH @@ -99,19 +104,14 @@ build_exatrkx_cpu: build_exatrkx: stage: build - image: ghcr.io/acts-project/ubuntu2204_exatrkx:63 + image: registry.cern.ch/ghcr.io/acts-project/ubuntu2204_exatrkx:63 variables: DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/ubuntu-22.04/deps.$DEPENDENCY_TAG.tar.zst tags: - large cache: - key: ccache-${CI_JOB_NAME}-${CI_COMMIT_REF_SLUG}-${CCACHE_KEY_SUFFIX} - fallback_keys: - - ccache-${CI_JOB_NAME}-${CI_DEFAULT_BRANCH}-${CCACHE_KEY_SUFFIX} - when: always - paths: - - ${CCACHE_DIR} + - !reference [.ccache_base, cache] artifacts: paths: @@ -146,7 +146,7 @@ test_exatrkx_unittests: stage: test needs: - build_exatrkx - image: ghcr.io/acts-project/ubuntu2204_exatrkx:63 + image: registry.cern.ch/ghcr.io/acts-project/ubuntu2204_exatrkx:63 variables: DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/ubuntu-22.04/deps.$DEPENDENCY_TAG.tar.zst tags: @@ -159,13 +159,13 @@ test_exatrkx_unittests: - git checkout $HEAD_SHA - source CI/dependencies.sh - cd .. - - ctest --test-dir build -R ExaTrkX + - ctest --test-dir build -R "(ExaTrkX|ConnectedComponentsCuda)" test_exatrkx_python: stage: test needs: - build_exatrkx - image: ghcr.io/acts-project/ubuntu2204_exatrkx:63 + image: registry.cern.ch/ghcr.io/acts-project/ubuntu2204_exatrkx:63 variables: DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/ubuntu-22.04/deps.$DEPENDENCY_TAG.tar.zst tags: @@ -188,17 +188,12 @@ test_exatrkx_python: build_linux_ubuntu: stage: build - image: ghcr.io/acts-project/ubuntu2404:63 + image: registry.cern.ch/ghcr.io/acts-project/ubuntu2404:63 variables: DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/ubuntu-24.04/deps.$DEPENDENCY_TAG.tar.zst cache: - key: ccache-${CI_JOB_NAME}-${CI_COMMIT_REF_SLUG}-${CCACHE_KEY_SUFFIX} - fallback_keys: - - ccache-${CI_JOB_NAME}-${CI_DEFAULT_BRANCH}-${CCACHE_KEY_SUFFIX} - when: always - paths: - - ${CCACHE_DIR} + - !reference [.ccache_base, cache] artifacts: paths: @@ -231,9 +226,29 @@ build_linux_ubuntu: - cmake --build build -- -j6 - ccache -s + - ctest --test-dir build -j$(nproc) + - cmake --build build --target integrationtests + + # Install main project + - cmake --install build + + # Downstream configure + - > + cmake -B build-downstream -S src/Tests/DownstreamProject + -GNinja + -DCMAKE_BUILD_TYPE=Release + -DCMAKE_CXX_FLAGS=-Werror + -DCMAKE_PREFIX_PATH="${INSTALL_DIR}" + + # Downstream build + - cmake --build build-downstream + + # Downstream run + - ./build-downstream/bin/ShowActsVersion + linux_test_examples: stage: test - image: ghcr.io/acts-project/ubuntu2404:63 + image: registry.cern.ch/ghcr.io/acts-project/ubuntu2404:63 variables: DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/ubuntu-24.04/deps.$DEPENDENCY_TAG.tar.zst needs: [build_linux_ubuntu] @@ -257,7 +272,7 @@ linux_test_examples: linux_physmon: stage: test - image: ghcr.io/acts-project/ubuntu2404:63 + image: registry.cern.ch/ghcr.io/acts-project/ubuntu2404:63 variables: DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/ubuntu-24.04/deps.$DEPENDENCY_TAG.tar.zst needs: [build_linux_ubuntu] @@ -299,16 +314,12 @@ linux_physmon: .linux_ubuntu_extra: variables: INSTALL_DIR: ${CI_PROJECT_DIR}/install + CXX: g++ stage: build cache: - key: ccache-${CI_JOB_NAME}-${CI_COMMIT_REF_SLUG}-${CCACHE_KEY_SUFFIX} - fallback_keys: - - ccache-${CI_JOB_NAME}-${CI_DEFAULT_BRANCH}-${CCACHE_KEY_SUFFIX} - when: always - paths: - - ${CCACHE_DIR} + - !reference [.ccache_base, cache] script: - git clone $CLONE_URL src @@ -326,6 +337,7 @@ linux_physmon: --preset=gitlab-ci -DPython_EXECUTABLE=$(which python3) -DCMAKE_CXX_STANDARD=${CXXSTD} + -DCMAKE_CXX_COMPILER=${CXX} - ccache -z - cmake --build build -- -j6 @@ -357,14 +369,15 @@ linux_ubuntu_2204: variables: CXXSTD: 20 DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/ubuntu-22.04/deps.$DEPENDENCY_TAG.tar.zst - image: ghcr.io/acts-project/ubuntu2204:63 + image: registry.cern.ch/ghcr.io/acts-project/ubuntu2204:71 linux_ubuntu_2204_clang: extends: .linux_ubuntu_extra variables: + CXX: clang++ CXXSTD: 20 DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/ubuntu-22.04/deps.$DEPENDENCY_TAG.tar.zst - image: ghcr.io/acts-project/ubuntu2204_clang:63 + image: registry.cern.ch/ghcr.io/acts-project/ubuntu2204:71 ###################### @@ -372,7 +385,7 @@ linux_ubuntu_2204_clang: ###################### .lcg_base_job: - image: ghcr.io/acts-project/${OS}-base:63 + image: registry.cern.ch/ghcr.io/acts-project/${OS}-base:63 stage: build tags: - cvmfs @@ -384,12 +397,7 @@ linux_ubuntu_2204_clang: SETUP: cache: - key: ccache-${CI_JOB_NAME}-${CI_COMMIT_REF_SLUG}-${CCACHE_KEY_SUFFIX} - fallback_keys: - - ccache-${CI_JOB_NAME}-${CI_DEFAULT_BRANCH}-${CCACHE_KEY_SUFFIX} - when: always - paths: - - ${CCACHE_DIR} + - !reference [.ccache_base, cache] before_script: - 'echo "LCG_VERSION: ${LCG_VERSION}"' diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d4c224bf3c7..87251106806 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,6 +14,7 @@ repos: - id: end-of-file-fixer exclude: \.(diff|patch)$ - id: check-yaml + exclude: \.gitlab-ci.yml$ - id: check-added-large-files diff --git a/CI/physmon/reference/simulation/particles_fatras_hist.root b/CI/physmon/reference/simulation/particles_fatras_hist.root index 9bb02761ed4..1dd189aea0b 100644 Binary files a/CI/physmon/reference/simulation/particles_fatras_hist.root and b/CI/physmon/reference/simulation/particles_fatras_hist.root differ diff --git a/CI/physmon/reference/simulation/particles_geant4_hist.root b/CI/physmon/reference/simulation/particles_geant4_hist.root index bd99cf9b723..dcd1ae90b8a 100644 Binary files a/CI/physmon/reference/simulation/particles_geant4_hist.root and b/CI/physmon/reference/simulation/particles_geant4_hist.root differ diff --git a/CI/physmon/reference/trackfinding_1muon/seeded/performance_fitting_ckf.root b/CI/physmon/reference/trackfinding_1muon/seeded/performance_fitting_ckf.root index 94fcbafbdbf..77c44fa3c2a 100644 Binary files a/CI/physmon/reference/trackfinding_1muon/seeded/performance_fitting_ckf.root and b/CI/physmon/reference/trackfinding_1muon/seeded/performance_fitting_ckf.root differ diff --git a/CI/physmon/reference/trackfinding_ttbar_pu200/performance_finding_ckf.root b/CI/physmon/reference/trackfinding_ttbar_pu200/performance_finding_ckf.root index d4b5a8b9dde..0a36fb36353 100644 Binary files a/CI/physmon/reference/trackfinding_ttbar_pu200/performance_finding_ckf.root and b/CI/physmon/reference/trackfinding_ttbar_pu200/performance_finding_ckf.root differ diff --git a/CI/physmon/reference/trackfinding_ttbar_pu200/performance_finding_ckf_ambi.root b/CI/physmon/reference/trackfinding_ttbar_pu200/performance_finding_ckf_ambi.root index a083efffaff..b560e3868c9 100644 Binary files a/CI/physmon/reference/trackfinding_ttbar_pu200/performance_finding_ckf_ambi.root and b/CI/physmon/reference/trackfinding_ttbar_pu200/performance_finding_ckf_ambi.root differ diff --git a/CI/physmon/reference/trackfinding_ttbar_pu200/performance_finding_ckf_ml_solver.root b/CI/physmon/reference/trackfinding_ttbar_pu200/performance_finding_ckf_ml_solver.root index db22a916d9e..9437ebe5ff2 100644 Binary files a/CI/physmon/reference/trackfinding_ttbar_pu200/performance_finding_ckf_ml_solver.root and b/CI/physmon/reference/trackfinding_ttbar_pu200/performance_finding_ckf_ml_solver.root differ diff --git a/CI/physmon/reference/trackfinding_ttbar_pu200/performance_fitting_ckf.root b/CI/physmon/reference/trackfinding_ttbar_pu200/performance_fitting_ckf.root index 754dd91bb0a..a1e728f876e 100644 Binary files a/CI/physmon/reference/trackfinding_ttbar_pu200/performance_fitting_ckf.root and b/CI/physmon/reference/trackfinding_ttbar_pu200/performance_fitting_ckf.root differ diff --git a/CI/physmon/reference/trackfinding_ttbar_pu200/performance_fitting_ckf_ambi.root b/CI/physmon/reference/trackfinding_ttbar_pu200/performance_fitting_ckf_ambi.root index 949d8cebfc3..02283c04dd6 100644 Binary files a/CI/physmon/reference/trackfinding_ttbar_pu200/performance_fitting_ckf_ambi.root and b/CI/physmon/reference/trackfinding_ttbar_pu200/performance_fitting_ckf_ambi.root differ diff --git a/CI/physmon/reference/trackfinding_ttbar_pu200/performance_fitting_ckf_ml_solver.root b/CI/physmon/reference/trackfinding_ttbar_pu200/performance_fitting_ckf_ml_solver.root index 0a40506d1bb..ec28bba43f0 100644 Binary files a/CI/physmon/reference/trackfinding_ttbar_pu200/performance_fitting_ckf_ml_solver.root and b/CI/physmon/reference/trackfinding_ttbar_pu200/performance_fitting_ckf_ml_solver.root differ diff --git a/CI/physmon/reference/trackfinding_ttbar_pu200/performance_seeding.root b/CI/physmon/reference/trackfinding_ttbar_pu200/performance_seeding.root index 500783b48a4..c372a4ca301 100644 Binary files a/CI/physmon/reference/trackfinding_ttbar_pu200/performance_seeding.root and b/CI/physmon/reference/trackfinding_ttbar_pu200/performance_seeding.root differ diff --git a/CI/physmon/reference/trackfinding_ttbar_pu200/performance_vertexing_amvf_gauss_notime_hist.root b/CI/physmon/reference/trackfinding_ttbar_pu200/performance_vertexing_amvf_gauss_notime_hist.root index 8d1bf337631..36436c9b092 100644 Binary files a/CI/physmon/reference/trackfinding_ttbar_pu200/performance_vertexing_amvf_gauss_notime_hist.root and b/CI/physmon/reference/trackfinding_ttbar_pu200/performance_vertexing_amvf_gauss_notime_hist.root differ diff --git a/CI/physmon/reference/trackfinding_ttbar_pu200/performance_vertexing_amvf_grid_time_hist.root b/CI/physmon/reference/trackfinding_ttbar_pu200/performance_vertexing_amvf_grid_time_hist.root index 25110c369be..65eb53fb02a 100644 Binary files a/CI/physmon/reference/trackfinding_ttbar_pu200/performance_vertexing_amvf_grid_time_hist.root and b/CI/physmon/reference/trackfinding_ttbar_pu200/performance_vertexing_amvf_grid_time_hist.root differ diff --git a/CI/physmon/reference/trackfinding_ttbar_pu200/tracksummary_ckf_hist.root b/CI/physmon/reference/trackfinding_ttbar_pu200/tracksummary_ckf_hist.root index f803f21ee8f..9507d9082dd 100644 Binary files a/CI/physmon/reference/trackfinding_ttbar_pu200/tracksummary_ckf_hist.root and b/CI/physmon/reference/trackfinding_ttbar_pu200/tracksummary_ckf_hist.root differ diff --git a/CI/physmon/reference/trackfitting_gsf/performance_trackfitting.root b/CI/physmon/reference/trackfitting_gsf/performance_trackfitting.root index b3543963d9f..5d20e028d9c 100644 Binary files a/CI/physmon/reference/trackfitting_gsf/performance_trackfitting.root and b/CI/physmon/reference/trackfitting_gsf/performance_trackfitting.root differ diff --git a/CI/physmon/workflows/physmon_simulation.py b/CI/physmon/workflows/physmon_simulation.py index 206890540b8..af56902f306 100755 --- a/CI/physmon/workflows/physmon_simulation.py +++ b/CI/physmon/workflows/physmon_simulation.py @@ -8,7 +8,6 @@ from acts.examples.simulation import ( addFatras, addGeant4, - ParticleSelectorConfig, addPythia8, ) @@ -58,7 +57,7 @@ acts.PdgParticle.eElectron, ] ], - outputParticles="particles_input", + outputParticles="particles_generated", outputVertices="vertices_input", randomNumbers=rnd, ) @@ -67,7 +66,7 @@ s.addWriter( acts.examples.RootParticleWriter( level=acts.logging.INFO, - inputParticles="particles_input", + inputParticles="particles_generated", filePath=tp / "particles.root", ) ) @@ -78,9 +77,7 @@ setup.field, rnd, enableInteractions=True, - preSelectParticles=None, - postSelectParticles=ParticleSelectorConfig(removeSecondaries=True), - inputParticles="particles_input", + inputParticles="particles_generated", outputParticles="particles_fatras", outputSimHits="simhits_fatras", outputDirRoot=tp / "fatras", @@ -92,12 +89,10 @@ setup.trackingGeometry, setup.field, rnd, - preSelectParticles=None, - postSelectParticles=ParticleSelectorConfig(removeSecondaries=True), killVolume=setup.trackingGeometry.highestTrackingVolume, killAfterTime=25 * u.ns, killSecondaries=True, - inputParticles="particles_input", + inputParticles="particles_generated", outputParticles="particles_geant4", outputSimHits="simhits_geant4", outputDirRoot=tp / "geant4", diff --git a/CI/physmon/workflows/physmon_trackfinding_1muon.py b/CI/physmon/workflows/physmon_trackfinding_1muon.py index 028b30ce5e5..2e62cb0b429 100755 --- a/CI/physmon/workflows/physmon_trackfinding_1muon.py +++ b/CI/physmon/workflows/physmon_trackfinding_1muon.py @@ -11,9 +11,10 @@ EtaConfig, PhiConfig, ParticleConfig, - ParticleSelectorConfig, addFatras, addDigitization, + ParticleSelectorConfig, + addDigiParticleSelection, ) from acts.examples.reconstruction import ( @@ -72,11 +73,6 @@ def run_ckf_tracking(label, seeding): setup.field, enableInteractions=True, rnd=rnd, - postSelectParticles=ParticleSelectorConfig( - pt=(0.9 * u.GeV, None), - hits=(9, None), - removeNeutral=True, - ), ) addDigitization( @@ -87,6 +83,15 @@ def run_ckf_tracking(label, seeding): rnd=rnd, ) + addDigiParticleSelection( + s, + ParticleSelectorConfig( + pt=(0.9 * u.GeV, None), + measurements=(9, None), + removeNeutral=True, + ), + ) + addSeeding( s, setup.trackingGeometry, diff --git a/CI/physmon/workflows/physmon_trackfinding_4muon_50vertices.py b/CI/physmon/workflows/physmon_trackfinding_4muon_50vertices.py index 85debced2b4..1677b418986 100755 --- a/CI/physmon/workflows/physmon_trackfinding_4muon_50vertices.py +++ b/CI/physmon/workflows/physmon_trackfinding_4muon_50vertices.py @@ -11,9 +11,10 @@ EtaConfig, PhiConfig, ParticleConfig, - ParticleSelectorConfig, addFatras, addDigitization, + ParticleSelectorConfig, + addDigiParticleSelection, ) from acts.examples.reconstruction import ( addSeeding, @@ -69,11 +70,6 @@ setup.trackingGeometry, setup.field, rnd=rnd, - postSelectParticles=ParticleSelectorConfig( - pt=(0.9 * u.GeV, None), - hits=(9, None), - removeNeutral=True, - ), ) addDigitization( @@ -84,6 +80,15 @@ rnd=rnd, ) + addDigiParticleSelection( + s, + ParticleSelectorConfig( + pt=(0.9 * u.GeV, None), + measurements=(9, None), + removeNeutral=True, + ), + ) + addSeeding( s, setup.trackingGeometry, diff --git a/CI/physmon/workflows/physmon_trackfinding_ttbar_pu200.py b/CI/physmon/workflows/physmon_trackfinding_ttbar_pu200.py index d26e5e78873..95b2fb6448b 100755 --- a/CI/physmon/workflows/physmon_trackfinding_ttbar_pu200.py +++ b/CI/physmon/workflows/physmon_trackfinding_ttbar_pu200.py @@ -7,9 +7,11 @@ import acts from acts.examples.simulation import ( addPythia8, + ParticleSelectorConfig, + addGenParticleSelection, addFatras, addDigitization, - ParticleSelectorConfig, + addDigiParticleSelection, ) from acts.examples.reconstruction import ( addSeeding, @@ -61,20 +63,19 @@ outputDirRoot=tp, ) + addGenParticleSelection( + s, + ParticleSelectorConfig( + rho=(0.0, 24 * u.mm), + absZ=(0.0, 1.0 * u.m), + ), + ) + addFatras( s, setup.trackingGeometry, setup.field, rnd=rnd, - preSelectParticles=ParticleSelectorConfig( - rho=(0.0, 24 * u.mm), - absZ=(0.0, 1.0 * u.m), - ), - postSelectParticles=ParticleSelectorConfig( - pt=(0.5 * u.GeV, None), - hits=(9, None), - removeNeutral=True, - ), ) addDigitization( @@ -85,6 +86,15 @@ rnd=rnd, ) + addDigiParticleSelection( + s, + ParticleSelectorConfig( + pt=(0.5 * u.GeV, None), + measurements=(9, None), + removeNeutral=True, + ), + ) + addSeeding( s, setup.trackingGeometry, diff --git a/CMakeLists.txt b/CMakeLists.txt index 04fb58d6825..5487b731292 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,36 @@ include(ActsRetrieveVersion) project(Acts VERSION ${_acts_version} LANGUAGES CXX) +# policy settings + +# Steers how project() handles the VERSION option +cmake_policy(SET CMP0048 NEW) + +# the `_VERSION` variables set by `setup(... VERSION ...)` have +# only local scope, i.e. they are not accessible her for dependencies added +# via `add_subdirectory`. this overrides the `project(...)` function for +# sub-projects such that the resulting `_VERSION` has +# global scope and is accessible within the main project later on. +macro(project) + _project(${ARGN}) + set(${PROJECT_NAME}_VERSION "${${PROJECT_NAME}_VERSION}" CACHE INTERNAL "") +endmacro() + +# Controls the way python is located +if(POLICY CMP0094) + cmake_policy(SET CMP0094 NEW) +endif() + +# Controls behavior of DOWNLOAD_EXTRACT_TIMESTAMP +if(POLICY CMP0135) + cmake_policy(SET CMP0135 NEW) +endif() + +# Use boost's cmake config files +if(POLICY CMP0167) + cmake_policy(SET CMP0167 NEW) +endif() + # build options # all options and compile-time parameters must be defined here for clear @@ -253,17 +283,8 @@ set(_acts_boost_recommended_version 1.78.0) # Include the sources for the external dependencies. include(ActsExternSources) -# Controls behavior of DOWNLOAD_EXTRACT_TIMESTAMP -if(POLICY CMP0135) - cmake_policy(SET CMP0135 NEW) -endif() - # required packages if(ACTS_SETUP_BOOST) - if(POLICY CMP0167) - cmake_policy(SET CMP0167 NEW) - endif() - # Enable both program_options and unit_test_framework to reduce complexity # Also Cuda tests seem to use program_options if( @@ -311,17 +332,6 @@ endif() find_package(Filesystem REQUIRED) -# the `_VERSION` variables set by `setup(... VERSION ...)` have -# only local scope, i.e. they are not accessible her for dependencies added -# via `add_subdirectory`. this overrides the `project(...)` function for -# sub-projects such that the resulting `_VERSION` has -# global scope and is accessible within the main project later on. -cmake_policy(SET CMP0048 NEW) -macro(project) - _project(${ARGN}) - set(${PROJECT_NAME}_VERSION "${${PROJECT_NAME}_VERSION}" CACHE INTERNAL "") -endmacro() - # CUDA settings are collected here in a macro, so that they can be reused by different plugins macro(enable_cuda) enable_language(CUDA) @@ -432,9 +442,6 @@ if(ACTS_BUILD_PLUGIN_EXATRKX) and ACTS_EXATRKX_ENABLE_TORCHSCRIPT must be enabled." ) endif() - if(ACTS_EXATRKX_ENABLE_ONNX) - find_package(cugraph REQUIRED) - endif() if(ACTS_EXATRKX_ENABLE_TORCH) find_package(TorchScatter REQUIRED) endif() diff --git a/CMakePresets.json b/CMakePresets.json index 2aef0f3fe94..fc7275cbd4e 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -47,6 +47,7 @@ "cacheVariables": { "CMAKE_BUILD_TYPE": "Release", "CMAKE_COMPILE_WARNING_AS_ERROR": "ON", + "CMAKE_FIND_FRAMEWORK": "LAST", "ACTS_FORCE_ASSERTIONS": "ON", "ACTS_ENABLE_LOG_FAILURE_THRESHOLD": "ON", "ACTS_BUILD_BENCHMARKS": "ON", diff --git a/Core/include/Acts/Definitions/Direction.hpp b/Core/include/Acts/Definitions/Direction.hpp index 985caac0e6c..bd9a8d216f3 100644 --- a/Core/include/Acts/Definitions/Direction.hpp +++ b/Core/include/Acts/Definitions/Direction.hpp @@ -27,14 +27,18 @@ class Direction final { }; public: - static constexpr auto Negative = Value::Negative; - static constexpr auto Positive = Value::Positive; + static constexpr Direction Negative() { return Direction{Value::Negative}; } + static constexpr Direction Positive() { return Direction{Value::Positive}; } - static constexpr auto Backward = Value::Negative; - static constexpr auto Forward = Value::Positive; + static constexpr Direction Backward() { return Direction{Value::Negative}; } + static constexpr Direction Forward() { return Direction{Value::Positive}; } - static constexpr auto OppositeNormal = Value::Negative; - static constexpr auto AlongNormal = Value::Positive; + static constexpr Direction OppositeNormal() { + return Direction{Value::Negative}; + } + static constexpr Direction AlongNormal() { + return Direction{Value::Positive}; + } /// This turns a signed value into a direction. Will assert on zero. /// @@ -43,7 +47,7 @@ class Direction final { /// @return a direction enum static constexpr Direction fromScalar(double scalar) { assert(scalar != 0); - return scalar >= 0 ? Value::Positive : Value::Negative; + return scalar >= 0 ? Positive() : Negative(); } /// This turns a signed value into a direction and 0 will be handled as a @@ -54,7 +58,7 @@ class Direction final { /// /// @return a direction enum static constexpr Direction fromScalarZeroAsPositive(double scalar) { - return scalar >= 0 ? Value::Positive : Value::Negative; + return scalar >= 0 ? Positive() : Negative(); } /// Convert and index [0,1] to a direction e.g. for sorting in @@ -62,10 +66,7 @@ class Direction final { /// /// @param index is the direction at input static constexpr Direction fromIndex(std::size_t index) { - if (index == 0u) { - return Value::Negative; - } - return Value::Positive; + return index == 0u ? Negative() : Positive(); } /// Convert dir to index [0,1] which allows to store direction dependent @@ -88,19 +89,18 @@ class Direction final { /// /// @return an opposite direction constexpr Direction invert() const { - return (m_value == Value::Positive) ? Value::Negative : Value::Positive; + return *this == Positive() ? Negative() : Positive(); } std::string toString() const; - constexpr Direction() = default; - constexpr Direction(Value value) : m_value(value) {} - - constexpr bool operator==(Direction other) const { - return m_value == other.m_value; + friend constexpr bool operator==(Direction lhs, Direction rhs) { + return lhs.m_value == rhs.m_value; } private: + explicit constexpr Direction(Value value) : m_value(value) {} + Value m_value = Value::Positive; }; diff --git a/Core/include/Acts/Detector/Blueprint.hpp b/Core/include/Acts/Detector/Blueprint.hpp index 1e3ec527674..b3724f3fec5 100644 --- a/Core/include/Acts/Detector/Blueprint.hpp +++ b/Core/include/Acts/Detector/Blueprint.hpp @@ -13,7 +13,7 @@ #include "Acts/Detector/ProtoBinning.hpp" #include "Acts/Geometry/Extent.hpp" #include "Acts/Geometry/VolumeBounds.hpp" -#include "Acts/Utilities/BinningData.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/StringHelpers.hpp" #include @@ -47,11 +47,11 @@ struct Node final { /// @param t the transform /// @param bt the boundary type /// @param bv the boundary values - /// @param bss the binning values + /// @param bss the axis directions for the binning /// @param cs the children of the node /// @param e the estimated extent of the node (optional) Node(const std::string& n, const Transform3& t, VolumeBounds::BoundsType bt, - const std::vector& bv, const std::vector& bss, + const std::vector& bv, const std::vector& bss, std::vector> cs = {}, const Extent& e = Extent()) : name(n), transform(t), @@ -96,7 +96,7 @@ struct Node final { /// Branch definitions: children std::vector> children = {}; /// Branch definition binning - std::vector binning = {}; + std::vector binning = {}; /// Portal proto material binning std::map portalMaterialBinning = {}; diff --git a/Core/include/Acts/Detector/CuboidalContainerBuilder.hpp b/Core/include/Acts/Detector/CuboidalContainerBuilder.hpp index ea5b98675cf..0a8b87acb85 100644 --- a/Core/include/Acts/Detector/CuboidalContainerBuilder.hpp +++ b/Core/include/Acts/Detector/CuboidalContainerBuilder.hpp @@ -12,7 +12,7 @@ #include "Acts/Detector/DetectorComponents.hpp" #include "Acts/Detector/interface/IDetectorComponentBuilder.hpp" #include "Acts/Geometry/GeometryContext.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Logger.hpp" #include @@ -36,8 +36,8 @@ class IGeometryIdGenerator; /// @note the builder expects a fully consistent set of sub volume builders /// that will be executed in a chain /// -/// @note allowed BinningValue(s) for the cuboid container builder are -/// {binX}, {binY}, {binZ}. +/// @note allowed AxisDirection(s) for the cuboid container builder are +/// {AxisX}, {AxisY}, {AxisZ}. /// /// @note Connecting containers isn't functional yet due to the underlying /// issues in the CuboidDetectorHelper @@ -48,8 +48,8 @@ class CuboidalContainerBuilder : public IDetectorComponentBuilder { struct Config { /// The configured volume builders std::vector> builders = {}; - /// Binning prescription of attachment - BinningValue binning{}; + /// Axis direction for the binning + AxisDirection binning{}; /// The root volume finder std::shared_ptr rootVolumeFinderBuilder = nullptr; diff --git a/Core/include/Acts/Detector/CylindricalContainerBuilder.hpp b/Core/include/Acts/Detector/CylindricalContainerBuilder.hpp index 4520eea5e07..2abc41327fb 100644 --- a/Core/include/Acts/Detector/CylindricalContainerBuilder.hpp +++ b/Core/include/Acts/Detector/CylindricalContainerBuilder.hpp @@ -13,7 +13,7 @@ #include "Acts/Detector/ProtoBinning.hpp" #include "Acts/Detector/interface/IDetectorComponentBuilder.hpp" #include "Acts/Geometry/GeometryContext.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Logger.hpp" #include @@ -39,17 +39,17 @@ class IGeometryIdGenerator; /// @note the builder expects a fully consistent set of sub volume builders /// that will be executed in a chain /// -/// @note allowed BinningValue(s) for the cylindrical container builder are -/// {binZ}, {binR}, {binPhi}, {binZ, binR}, whereas the last option indicates -/// a wrapping setup. +/// @note allowed AxisDirection(s) for the cylindrical container builder are +/// {AxisZ}, {AxisR}, {AxisPhi}, {AxisZ, AxisR}, whereas the last option +/// indicates a wrapping setup. class CylindricalContainerBuilder : public IDetectorComponentBuilder { public: /// Nested configuration object struct Config { /// The configured volume builders std::vector> builders = {}; - /// Binning prescription of attachment - std::vector binning = {}; + /// The axis direction for the binning + std::vector binning = {}; /// The root volume finder std::shared_ptr rootVolumeFinderBuilder = nullptr; diff --git a/Core/include/Acts/Detector/IndexedRootVolumeFinderBuilder.hpp b/Core/include/Acts/Detector/IndexedRootVolumeFinderBuilder.hpp index 64483115c61..ba67d3bd10e 100644 --- a/Core/include/Acts/Detector/IndexedRootVolumeFinderBuilder.hpp +++ b/Core/include/Acts/Detector/IndexedRootVolumeFinderBuilder.hpp @@ -11,7 +11,7 @@ #include "Acts/Detector/interface/IRootVolumeFinderBuilder.hpp" #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Navigation/PortalNavigation.hpp" -#include "Acts/Utilities/BinningData.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include #include @@ -26,7 +26,7 @@ class IndexedRootVolumeFinderBuilder final : public IRootVolumeFinderBuilder { public: /// @brief Constructor with binning casts /// @param binning the cast values for the grid binning - IndexedRootVolumeFinderBuilder(std::vector binning); + IndexedRootVolumeFinderBuilder(std::vector binning); /// The virtual interface definition for root volume finder builders /// @@ -40,7 +40,7 @@ class IndexedRootVolumeFinderBuilder final : public IRootVolumeFinderBuilder { const final; private: - std::vector m_casts; + std::vector m_casts; }; } // namespace Acts::Experimental diff --git a/Core/include/Acts/Detector/KdtSurfacesProvider.hpp b/Core/include/Acts/Detector/KdtSurfacesProvider.hpp index 72bea84737f..74a4a195f1c 100644 --- a/Core/include/Acts/Detector/KdtSurfacesProvider.hpp +++ b/Core/include/Acts/Detector/KdtSurfacesProvider.hpp @@ -12,7 +12,7 @@ #include "Acts/Detector/detail/ReferenceGenerators.hpp" #include "Acts/Detector/interface/ISurfacesProvider.hpp" #include "Acts/Surfaces/Surface.hpp" -#include "Acts/Utilities/BinningData.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/KDTree.hpp" #include @@ -50,7 +50,7 @@ class KdtSurfaces { /// @param rgen the reference point generator KdtSurfaces(const GeometryContext& gctx, const std::vector>& surfaces, - const std::array& casts, + const std::array& casts, const reference_generator& rgen = detail::PolyhedronReferenceGenerator<1u, false>{}) : m_kdt(nullptr), m_casts(casts), m_rGenerator(rgen) { @@ -113,7 +113,7 @@ class KdtSurfaces { std::unique_ptr m_kdt = nullptr; /// Cast values that turn a global position to lookup position - std::array m_casts = {}; + std::array m_casts = {}; /// Helper to generate reference points for filling reference_generator m_rGenerator; diff --git a/Core/include/Acts/Detector/ProtoBinning.hpp b/Core/include/Acts/Detector/ProtoBinning.hpp index 3700dfc4d6f..231405d5991 100644 --- a/Core/include/Acts/Detector/ProtoBinning.hpp +++ b/Core/include/Acts/Detector/ProtoBinning.hpp @@ -10,9 +10,8 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/Common.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/BinUtility.hpp" -#include "Acts/Utilities/BinningType.hpp" #include #include @@ -27,8 +26,8 @@ namespace Acts::Experimental { /// only for convenience that the binning can be defined and then /// translated into concrete axis types struct ProtoBinning { - /// The binning value of this - BinningValue binValue; + /// The axis direction + AxisDirection axisDir; /// The axis type: equidistant or variable Acts::AxisType axisType = Acts::AxisType::Equidistant; /// The axis boundary type: Open, Bound or Closed @@ -42,13 +41,13 @@ struct ProtoBinning { /// Convenience constructors - for variable binning /// - /// @param bValue the value/cast in which this is binned + /// @param aDir the value/cast in which this is binned /// @param bType the axis boundary type /// @param e the bin edges (variable binning) /// @param exp the expansion (in bins) - ProtoBinning(BinningValue bValue, Acts::AxisBoundaryType bType, + ProtoBinning(AxisDirection aDir, Acts::AxisBoundaryType bType, const std::vector& e, std::size_t exp = 0u) - : binValue(bValue), + : axisDir(aDir), axisType(Acts::AxisType::Variable), boundaryType(bType), edges(e), @@ -61,18 +60,18 @@ struct ProtoBinning { /// Convenience constructors - for equidistant binning /// - /// @param bValue the value/cast in which this is binned + /// @param aDir the value/cast in which this is binned /// @param bType the axis boundary type /// @param minE the lowest edge of the binning /// @param maxE the highest edge of the binning /// @param nbins the number of bins /// @param exp the expansion (in bins) - ProtoBinning(BinningValue bValue, Acts::AxisBoundaryType bType, double minE, + ProtoBinning(AxisDirection aDir, Acts::AxisBoundaryType bType, double minE, double maxE, std::size_t nbins, std::size_t exp = 0u) - : binValue(bValue), boundaryType(bType), expansion(exp) { + : axisDir(aDir), boundaryType(bType), expansion(exp) { if (minE >= maxE) { - std::string msg = "ProtoBinning: Invalid binning for value '"; - msg += binningValueName(bValue); + std::string msg = "ProtoBinning: Invalid axis range for direction '"; + msg += axisDirectionName(axisDir); msg += "', min edge (" + std::to_string(minE) + ") "; msg += " needs to be smaller than max edge ("; msg += std::to_string(maxE) + ")."; @@ -96,13 +95,13 @@ struct ProtoBinning { /// when the actual extent is not yet evaluated, only works /// for equidistant binning obviously /// - /// @param bValue the value/cast in which this is binned + /// @param aDir the value/cast in which this is binned /// @param bType the axis boundary type /// @param nbins the number of bins /// @param exp the expansion (in bins) - ProtoBinning(BinningValue bValue, Acts::AxisBoundaryType bType, + ProtoBinning(AxisDirection aDir, Acts::AxisBoundaryType bType, std::size_t nbins, std::size_t exp = 0u) - : binValue(bValue), + : axisDir(aDir), boundaryType(bType), edges(nbins + 1, 0.), expansion(exp), @@ -115,7 +114,7 @@ struct ProtoBinning { std::string toString() const { std::stringstream ss; ss << "ProtoBinning: " << bins() << " bins in " - << binningValueName(binValue); + << axisDirectionName(axisDir); ss << (axisType == Acts::AxisType::Variable ? ", variable " : ", equidistant "); if (!autorange) { @@ -165,12 +164,12 @@ struct BinningDescription { : Acts::closed; if (b.axisType == Acts::AxisType::Equidistant) { binUtility += BinUtility(b.bins(), b.edges.front(), b.edges.back(), - bOption, b.binValue); + bOption, b.axisDir); } else { std::vector edges; std::for_each(b.edges.begin(), b.edges.end(), [&](double edge) { edges.push_back(edge); }); - binUtility += BinUtility(edges, bOption, b.binValue); + binUtility += BinUtility(edges, bOption, b.axisDir); } } return binUtility; diff --git a/Core/include/Acts/Detector/ProtoDetector.hpp b/Core/include/Acts/Detector/ProtoDetector.hpp index 5e4e4d426c2..50a6797d203 100644 --- a/Core/include/Acts/Detector/ProtoDetector.hpp +++ b/Core/include/Acts/Detector/ProtoDetector.hpp @@ -98,12 +98,12 @@ struct ProtoVolume { void extendUp(ProtoVolume& ptVolume); /// Extend the tracking volume with its own constituents - /// @param bValue the binning value that is propagated - void propagateMinDown(BinningValue bValue); + /// @param aDir the axis direction that is propagated + void propagateMinDown(AxisDirection aDir); /// Extend the tracking volume with its own constituents - /// @param bValue the binning value that is propagated - void propagateMaxDown(BinningValue bValue); + /// @param aDir the axis direction that is propagated + void propagateMaxDown(AxisDirection aDir); /// Constrain the daughter volumes with this volume /// diff --git a/Core/include/Acts/Detector/ProtoSupport.hpp b/Core/include/Acts/Detector/ProtoSupport.hpp index abde3a71539..2c02bd2ba22 100644 --- a/Core/include/Acts/Detector/ProtoSupport.hpp +++ b/Core/include/Acts/Detector/ProtoSupport.hpp @@ -12,7 +12,7 @@ #include "Acts/Definitions/Common.hpp" #include "Acts/Detector/ProtoBinning.hpp" #include "Acts/Surfaces/Surface.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/BinningData.hpp" #include @@ -55,7 +55,7 @@ struct ProtoSupport { /// The internal constraint would overwrite the volume one in order to allow /// support surfaces to be fitted from global volume extensions to the /// actually contained internal objects. - std::vector internalConstraints = {}; + std::vector internalConstraints = {}; // Building instructions 2 (surface is provided): @@ -69,7 +69,7 @@ struct ProtoSupport { unsigned int splits = 1u; /// Planar placement (only valid for planar support surfaces) - BinningValue pPlacement = BinningValue::binZ; + AxisDirection pPlacement = AxisDirection::AxisZ; /// Indicate if the support surface(s) should always be addressed in /// navigation diff --git a/Core/include/Acts/Detector/detail/CuboidalDetectorHelper.hpp b/Core/include/Acts/Detector/detail/CuboidalDetectorHelper.hpp index eda1da8452b..2388e7bad06 100644 --- a/Core/include/Acts/Detector/detail/CuboidalDetectorHelper.hpp +++ b/Core/include/Acts/Detector/detail/CuboidalDetectorHelper.hpp @@ -33,7 +33,7 @@ namespace detail::CuboidalDetectorHelper { /// /// @param gctx The geometry context /// @param volumes the volumes -/// @param bValue the binning value (allowed are binX, binY, binZ) +/// @param bValue the binning value (allowed are AxisX, AxisY, AxisZ) /// @param selectedOnly switch only selected boundaries /// @param logLevel is the screen logging level /// @@ -43,7 +43,7 @@ namespace detail::CuboidalDetectorHelper { /// @return a proto container with the outside portals DetectorComponent::PortalContainer connect( const GeometryContext& gctx, - std::vector>& volumes, BinningValue bValue, + std::vector>& volumes, AxisDirection bValue, const std::vector& selectedOnly = {}, Acts::Logging::Level logLevel = Acts::Logging::INFO); @@ -51,7 +51,7 @@ DetectorComponent::PortalContainer connect( /// /// @param gctx The geometry context /// @param containers the containers -/// @param bValue the binning value (allowed are binX, binY, binZ) +/// @param bValue the binning value (allowed are AxisX, AxisY, AxisZ) /// @param selectedOnly switch only selected boundaries /// @param logLevel is the screen logging level /// @@ -62,7 +62,7 @@ DetectorComponent::PortalContainer connect( DetectorComponent::PortalContainer connect( const GeometryContext& gctx, const std::vector& containers, - BinningValue bValue, const std::vector& selectedOnly = {}, + AxisDirection bValue, const std::vector& selectedOnly = {}, Acts::Logging::Level logLevel = Acts::Logging::INFO); /// @brief Helper method to extract r,z,phi boundaries for diff --git a/Core/include/Acts/Detector/detail/DetectorVolumeConsistency.hpp b/Core/include/Acts/Detector/detail/DetectorVolumeConsistency.hpp index f4de79980f3..c02ef00a011 100644 --- a/Core/include/Acts/Detector/detail/DetectorVolumeConsistency.hpp +++ b/Core/include/Acts/Detector/detail/DetectorVolumeConsistency.hpp @@ -48,7 +48,7 @@ void checkRotationAlignment( std::vector checkCenterAlignment( const GeometryContext& gctx, const std::vector>& volumes, - BinningValue axisValue); + AxisDirection axisValue); } // namespace detail::DetectorVolumeConsistency } // namespace Acts::Experimental diff --git a/Core/include/Acts/Detector/detail/IndexedSurfacesGenerator.hpp b/Core/include/Acts/Detector/detail/IndexedSurfacesGenerator.hpp index 83dc9170208..08fc8043d99 100644 --- a/Core/include/Acts/Detector/detail/IndexedSurfacesGenerator.hpp +++ b/Core/include/Acts/Detector/detail/IndexedSurfacesGenerator.hpp @@ -38,7 +38,7 @@ struct IndexedSurfacesGenerator { // Indices of surfaces that are to be assigned to all bins std::vector assignToAll = {}; /// The binning for the indexing - std::vector bValues = {}; + std::vector bValues = {}; // Bin expansion std::vector binExpansion = {}; /// The transform into the local binning schema @@ -68,7 +68,7 @@ struct IndexedSurfacesGenerator { typename axis_generator::template grid_type>; GridType grid(std::move(aGenerator())); - std::array bvArray = {}; + std::array bvArray = {}; for (auto [ibv, bv] : enumerate(bValues)) { bvArray[ibv] = bv; } diff --git a/Core/include/Acts/Detector/detail/PortalHelper.hpp b/Core/include/Acts/Detector/detail/PortalHelper.hpp index ba54513976b..0798432c29a 100644 --- a/Core/include/Acts/Detector/detail/PortalHelper.hpp +++ b/Core/include/Acts/Detector/detail/PortalHelper.hpp @@ -34,7 +34,7 @@ class Portal; /// gathered from the sub volumes, the binning description using PortalReplacement = std::tuple, unsigned int, Direction, - std::vector, BinningValue>; + std::vector, AxisDirection>; namespace detail::PortalHelper { @@ -63,7 +63,7 @@ void attachDetectorVolumesUpdater( const GeometryContext& gctx, Portal& portal, const std::vector>& volumes, const Direction& direction, const std::vector& boundaries, - const BinningValue& binning); + const AxisDirection& binning); /// @brief Create and attach the multi link updator, the portal will get /// a volume updator attached, that points to the different sub volumes diff --git a/Core/include/Acts/Detector/detail/ReferenceGenerators.hpp b/Core/include/Acts/Detector/detail/ReferenceGenerators.hpp index db77685a2bc..27c2dab0cf9 100644 --- a/Core/include/Acts/Detector/detail/ReferenceGenerators.hpp +++ b/Core/include/Acts/Detector/detail/ReferenceGenerators.hpp @@ -41,8 +41,8 @@ struct CenterReferenceGenerator { /// /// This generator will provide only one filling point and hence /// only a single bin in the indexed grid. -template -struct BinningValueReferenceGenerator { +template +struct AxisDirectionReferenceGenerator { /// Helper to access a reference position based on binning value /// /// @param gctx the geometry context of this operation @@ -51,7 +51,7 @@ struct BinningValueReferenceGenerator { /// @return a vector of reference points for filling const std::vector references(const GeometryContext& gctx, const Surface& surface) const { - return {surface.binningPosition(gctx, bVAL)}; + return {surface.referencePosition(gctx, bVAL)}; } }; diff --git a/Core/include/Acts/Detector/detail/SupportSurfacesHelper.hpp b/Core/include/Acts/Detector/detail/SupportSurfacesHelper.hpp index 9c52e961498..3eef98dfd3a 100644 --- a/Core/include/Acts/Detector/detail/SupportSurfacesHelper.hpp +++ b/Core/include/Acts/Detector/detail/SupportSurfacesHelper.hpp @@ -95,7 +95,7 @@ struct DiscSupport { /// @brief Helper method to build planar support structure struct RectangularSupport { /// Placement - the remaining loc0, loc1 are then cyclic - BinningValue pPlacement = BinningValue::binZ; + AxisDirection pPlacement = AxisDirection::AxisZ; /// Offset in position placement double pOffset = 0.; diff --git a/Core/include/Acts/EventData/VectorMultiTrajectory.hpp b/Core/include/Acts/EventData/VectorMultiTrajectory.hpp index 8f416dd6969..4238afd88f6 100644 --- a/Core/include/Acts/EventData/VectorMultiTrajectory.hpp +++ b/Core/include/Acts/EventData/VectorMultiTrajectory.hpp @@ -192,7 +192,7 @@ class VectorMultiTrajectoryBase { TrackStatePropMask allocMask = TrackStatePropMask::None; }; - VectorMultiTrajectoryBase() = default; + VectorMultiTrajectoryBase() noexcept = default; VectorMultiTrajectoryBase(const VectorMultiTrajectoryBase& other) : m_index{other.m_index}, @@ -388,7 +388,7 @@ class VectorMultiTrajectory final VectorMultiTrajectory(const VectorMultiTrajectory& other) : VectorMultiTrajectoryBase{other} {} - VectorMultiTrajectory(VectorMultiTrajectory&& other) + VectorMultiTrajectory(VectorMultiTrajectory&& other) noexcept : VectorMultiTrajectoryBase{std::move(other)} {} Statistics statistics() const { diff --git a/Core/include/Acts/EventData/detail/CorrectedTransformationFreeToBound.hpp b/Core/include/Acts/EventData/detail/CorrectedTransformationFreeToBound.hpp index 72cb0965507..42b480482ec 100644 --- a/Core/include/Acts/EventData/detail/CorrectedTransformationFreeToBound.hpp +++ b/Core/include/Acts/EventData/detail/CorrectedTransformationFreeToBound.hpp @@ -96,7 +96,7 @@ struct CorrectedFreeToBoundTransformer { std::optional> operator()( const FreeVector& freeParams, const FreeSquareMatrix& freeCovariance, const Surface& surface, const GeometryContext& geoContext, - Direction navDir = Direction::Forward, + Direction navDir = Direction::Forward(), const Logger& logger = getDummyLogger()) const; private: diff --git a/Core/include/Acts/Geometry/BlueprintNode.hpp b/Core/include/Acts/Geometry/BlueprintNode.hpp index e159c463067..63a0e8b83e7 100644 --- a/Core/include/Acts/Geometry/BlueprintNode.hpp +++ b/Core/include/Acts/Geometry/BlueprintNode.hpp @@ -12,7 +12,7 @@ #include "Acts/Geometry/BlueprintOptions.hpp" #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/NavigationPolicyFactory.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Logger.hpp" #include "Acts/Utilities/TransformRange.hpp" @@ -192,7 +192,7 @@ class BlueprintNode { /// @ref Acts::CylinderVolumeStack for details. /// @param callback An optional callback that receives the node as an argument CylinderContainerBlueprintNode& addCylinderContainer( - const std::string& name, BinningValue direction, + const std::string& name, AxisDirection direction, const std::function& callback = {}); diff --git a/Core/include/Acts/Geometry/BoundarySurfaceT.hpp b/Core/include/Acts/Geometry/BoundarySurfaceT.hpp index 60fd4be9dc4..eafc84e5fa6 100644 --- a/Core/include/Acts/Geometry/BoundarySurfaceT.hpp +++ b/Core/include/Acts/Geometry/BoundarySurfaceT.hpp @@ -161,7 +161,7 @@ inline const RegularSurface& BoundarySurfaceT::surfaceRepresentation() template void BoundarySurfaceT::attachVolume(const volume_t* volume, Direction dir) { - if (dir == Direction::Backward) { + if (dir == Direction::Backward()) { m_oppositeVolume = volume; } else { m_alongVolume = volume; @@ -171,7 +171,7 @@ void BoundarySurfaceT::attachVolume(const volume_t* volume, template void BoundarySurfaceT::attachVolumeArray( const std::shared_ptr volumes, Direction dir) { - if (dir == Direction::Backward) { + if (dir == Direction::Backward()) { m_oppositeVolumeArray = volumes; } else { m_alongVolumeArray = volumes; diff --git a/Core/include/Acts/Geometry/CompositePortalLink.hpp b/Core/include/Acts/Geometry/CompositePortalLink.hpp index 231af047b6c..f06144e682a 100644 --- a/Core/include/Acts/Geometry/CompositePortalLink.hpp +++ b/Core/include/Acts/Geometry/CompositePortalLink.hpp @@ -51,8 +51,8 @@ class CompositePortalLink final : public PortalLinkBase { /// @param direction The binning direction /// @param flatten If true, the composite will flatten any nested composite CompositePortalLink(std::unique_ptr a, - std::unique_ptr b, BinningValue direction, - bool flatten = true); + std::unique_ptr b, + AxisDirection direction, bool flatten = true); /// Construct a composite portal from any number of arbitrary other portal /// links. The only requirement is that the portal link surfaces are @@ -61,7 +61,7 @@ class CompositePortalLink final : public PortalLinkBase { /// @param direction The binning direction /// @param flatten If true, the composite will flatten any nested composite CompositePortalLink(std::vector> links, - BinningValue direction, bool flatten = true); + AxisDirection direction, bool flatten = true); /// Print the composite portal link /// @param os The output stream @@ -110,7 +110,7 @@ class CompositePortalLink final : public PortalLinkBase { boost::container::small_vector, 4> m_children{}; - BinningValue m_direction; + AxisDirection m_direction; }; } // namespace Acts diff --git a/Core/include/Acts/Geometry/CuboidVolumeBounds.hpp b/Core/include/Acts/Geometry/CuboidVolumeBounds.hpp index bc3c75ac70d..db2656daeb6 100644 --- a/Core/include/Acts/Geometry/CuboidVolumeBounds.hpp +++ b/Core/include/Acts/Geometry/CuboidVolumeBounds.hpp @@ -11,10 +11,12 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Geometry/Volume.hpp" #include "Acts/Geometry/VolumeBounds.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/BoundingBox.hpp" #include #include +#include #include #include #include @@ -70,6 +72,9 @@ class CuboidVolumeBounds : public VolumeBounds { /// @param values iw the bound values CuboidVolumeBounds(const std::array& values); + CuboidVolumeBounds( + std::initializer_list> keyValues); + /// Copy Constructor /// /// @param bobo is the source volume bounds to be copied @@ -118,21 +123,22 @@ class CuboidVolumeBounds : public VolumeBounds { const Vector3& envelope = {0, 0, 0}, const Volume* entity = nullptr) const final; - /// Get the canonical binning values, i.e. the binning values + /// Get the canonical binning direction, i.e. the binning directions /// for that fully describe the shape's extent /// /// @return vector of canonical binning values - std::vector canonicalBinning() const override { - return {Acts::BinningValue::binX, Acts::BinningValue::binY, - Acts::BinningValue::binZ}; + std::vector canonicalAxes() const override { + using enum AxisDirection; + return {AxisX, AxisY, AxisZ}; }; /// Binning borders in double /// - /// @param bValue is the binning schema used + /// @param aDir is the axis direction for which the + /// reference border is requested /// /// @return float offset to be used for the binning - double binningBorder(BinningValue bValue) const final; + double referenceBorder(AxisDirection aDir) const final; /// Access to the bound values /// @param bValue the class nested enum for the array access @@ -147,6 +153,11 @@ class CuboidVolumeBounds : public VolumeBounds { /// @param keyValues the initializer list of key value pairs void set(std::initializer_list> keyValues); + /// Convert axis direction to a corresponding bound value + /// in local coordinate convention + /// @param direction the axis direction to convert + static BoundValues fromAxisDirection(AxisDirection direction); + /// Output Method for std::ostream /// /// @param os is ostream operator to be dumped into diff --git a/Core/include/Acts/Geometry/CuboidVolumeBuilder.hpp b/Core/include/Acts/Geometry/CuboidVolumeBuilder.hpp index 185d55f229d..c0eb1695302 100644 --- a/Core/include/Acts/Geometry/CuboidVolumeBuilder.hpp +++ b/Core/include/Acts/Geometry/CuboidVolumeBuilder.hpp @@ -11,7 +11,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/ITrackingVolumeBuilder.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include #include @@ -82,7 +82,7 @@ class CuboidVolumeBuilder : public ITrackingVolumeBuilder { // An optional rotation for this std::optional rotation{std::nullopt}; // Dimension for the binning - Acts::BinningValue binningDimension = Acts::BinningValue::binX; + Acts::AxisDirection binningDimension = Acts::AxisDirection::AxisX; }; /// @brief This struct stores the data for the construction of a cuboid @@ -105,7 +105,7 @@ class CuboidVolumeBuilder : public ITrackingVolumeBuilder { // Material std::shared_ptr volumeMaterial = nullptr; // Dimension for the binning - Acts::BinningValue binningDimension = Acts::BinningValue::binX; + Acts::AxisDirection binningDimension = Acts::AxisDirection::AxisX; }; /// @brief This struct stores the configuration of the tracking geometry @@ -176,7 +176,7 @@ class CuboidVolumeBuilder : public ITrackingVolumeBuilder { const VolumeConfig& cfg) const; void sortVolumes(std::vector>& tapVec, - BinningValue bValue) const; + AxisDirection bValue) const; /// @brief This function builds a world TrackingVolume based on a given /// configuration diff --git a/Core/include/Acts/Geometry/CuboidVolumeStack.hpp b/Core/include/Acts/Geometry/CuboidVolumeStack.hpp new file mode 100644 index 00000000000..4485ce170c5 --- /dev/null +++ b/Core/include/Acts/Geometry/CuboidVolumeStack.hpp @@ -0,0 +1,187 @@ +// 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/Geometry/Volume.hpp" +#include "Acts/Geometry/VolumeAttachmentStrategy.hpp" +#include "Acts/Geometry/VolumeResizeStrategy.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" +#include "Acts/Utilities/Logger.hpp" + +#include +#include + +namespace Acts { + +/// @class CuboidVolumeStack +/// This class implements a x-. y-. z-aligned stack +/// of cuboid volumes with synchronized bounds. +/// Externally, it presents as a single volume. +/// On construction, the input volumes are modified so that +/// they are connected in x, y, z and have synchronized bounds. +/// The way this is done can be configured using an *attachment* +/// and a *resize* strategy. Depending on the configuration, +/// the input volumes are either extended or gap volumes are created. +/// +/// @note The size adjustment convention is that volumes are never shrunk +class CuboidVolumeStack : public Volume { + public: + /// Constructor from a vector of volumes and direction + /// @param volumes is the vector of volumes + /// @param direction is the axis direction + /// @param strategy is the attachment strategy + /// @param resizeStrategy is the resize strategy + /// @note @p resizeStrategy only affects resizing along + /// @p direction. Resizing in the other direction + /// is always delegated to the child volumes, + /// which might in turn be @c CuboidVolumeStack + /// @param logger is the logger + /// @pre The volumes need to have a common coordinate + /// system relative to @p direction. I.e. they need + /// to be aligned in @c z and cannot have a rotation + /// in @c x or @c y. + /// @pre The volumes all need to have @c CuboidVolumeBounds + /// @note Preconditions are checked on construction + CuboidVolumeStack( + std::vector& volumes, AxisDirection direction, + VolumeAttachmentStrategy strategy = VolumeAttachmentStrategy::Midpoint, + VolumeResizeStrategy resizeStrategy = VolumeResizeStrategy::Expand, + const Logger& logger = Acts::getDummyLogger()); + + /// Constructor from a vector of volumes and direction + /// @param volumes is the vector of volumes + /// @param direction is the vector specifying the global direction + /// @param strategy is the attachment strategy + /// @param resizeStrategy is the resize strategy + /// @note @p resizeStrategy only affects resizing along + /// @p direction. Resizing in the other direction + /// is always delegated to the child volumes, + /// which might in turn be @c CuboidVolumeStack + /// @param logger is the logger + /// @pre The volumes need to have a common coordinate + /// system relative to @p direction. I.e. they need + /// to be aligned in @c z and cannot have a rotation + /// in @c x or @c y. + /// @pre The volumes all need to have @c CuboidVolumeBounds + /// @note Preconditions are checked on construction + CuboidVolumeStack( + std::vector& volumes, const Vector3& direction, + VolumeAttachmentStrategy strategy = VolumeAttachmentStrategy::Midpoint, + VolumeResizeStrategy resizeStrategy = VolumeResizeStrategy::Expand, + const Logger& logger = Acts::getDummyLogger()); + + /// Update the volume bounds and transform. This + /// will update the bounds of all volumes in the stack + /// to accommodate the new bounds and optionally create + /// gap volumes according to the resize strategy set during + /// construction. + /// @param volbounds is the new bounds + /// @param transform is the new transform + /// @param logger is the logger + /// @pre The volume bounds need to be of type + /// @c CuboidVolumeBounds. + void update(std::shared_ptr volbounds, + std::optional transform = std::nullopt, + const Logger& logger = getDummyLogger()) override; + + /// Access the gap volume that were created during attachment or resizing. + /// @return the vector of gap volumes + const std::vector>& gaps() const; + + /// Convert axis direction to an array index according to + /// stack convention. For example, AxisX --> 0 + /// @param direction is the axis direction to convert + static std::size_t axisToIndex(AxisDirection direction); + + /// Get axis directions orthogonal to the given one according + /// to stack convention. For example AxisX --> + /// @param direction is the axis direction to find the orthogonal for + static std::pair getOrthogonalAxes( + AxisDirection direction); + + private: + /// Helper to get the first volume in the input, and throw an exception if + /// there is not one. + /// @param volumes is the vector of volumes + /// @return the first volume + static Volume& initialVolume(const std::vector& volumes); + + /// Helper function called during construction that performs the + /// internal attachment and produces the overall outer volume bounds. + /// @param strategy is the attachment strategy + /// @param logger is the logger + void initializeOuterVolume(VolumeAttachmentStrategy strategy, + const Logger& logger); + + struct VolumeTuple; + + /// Helper function to pretty print the internal volume representation + /// @param volumes is the vector of volumes + /// @param logger is the logger + /// @param lvl is the logging level + static void printVolumeSequence(const std::vector& volumes, + const Logger& logger, + Acts::Logging::Level lvl); + + /// Helper function that prints output helping in debugging overlaps + /// @param a is the first volume + /// @param b is the second volume + /// @param logger is the logger + void overlapPrint(const VolumeTuple& a, const VolumeTuple& b, + const Logger& logger); + + /// Helper function that checks if volumes are properly aligned + /// for attachment. + /// @param volumes is the vector of volumes + /// @param logger is the logger + void checkVolumeAlignment(const std::vector& volumes, + const Logger& logger) const; + + /// Helper function that checks overlaps and attaches along the stacking + /// direction + /// @param volumes is the vector of volumes + /// @param strategy is the attachment strategy + /// @param logger is the logger + /// @return vector of gap volumes. Can be empty if none were created. + std::vector checkOverlapAndAttach( + std::vector& volumes, VolumeAttachmentStrategy strategy, + const Logger& logger); + + /// Helper function to synchronize the bounds of the volumes + /// @param volumes is the vector of volumes + /// @param logger is the logger + /// @return tuple of the minimum and maximum radii + std::pair synchronizeBounds(std::vector& volumes, + const Logger& logger); + + /// Helper function to create a gap volume with given bounds and register it. + /// @param transform is the transform of the gap volume + /// @param bounds is the bounds of the gap volume + /// @return the shared pointer to the gap volume + std::shared_ptr addGapVolume( + const Transform3& transform, const std::shared_ptr& bounds); + + /// Merging direction of the stack + /// in local group coordinates + AxisDirection m_dir{}; + + /// Directions orthogonal to the + /// merging direction of the stack + /// in local group coordinates + AxisDirection m_dirOrth1{}; + AxisDirection m_dirOrth2{}; + + VolumeResizeStrategy m_resizeStrategy{}; + Transform3 m_groupTransform{}; + std::vector> m_gaps{}; + std::vector& m_volumes; +}; + +} // namespace Acts diff --git a/Core/include/Acts/Geometry/CutoutCylinderVolumeBounds.hpp b/Core/include/Acts/Geometry/CutoutCylinderVolumeBounds.hpp index 5d7278219da..c90791e376a 100644 --- a/Core/include/Acts/Geometry/CutoutCylinderVolumeBounds.hpp +++ b/Core/include/Acts/Geometry/CutoutCylinderVolumeBounds.hpp @@ -11,6 +11,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Geometry/Volume.hpp" #include "Acts/Geometry/VolumeBounds.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include #include @@ -109,13 +110,13 @@ class CutoutCylinderVolumeBounds : public VolumeBounds { const Vector3& envelope = {0, 0, 0}, const Volume* entity = nullptr) const final; - /// Get the canonical binning values, i.e. the binning values - /// for that fully describe the shape's extent + /// Get the canonical binning direction, i.e. the axis values + /// that fully describe the shape's extent /// /// @return vector of canonical binning values - std::vector canonicalBinning() const override { - return {Acts::BinningValue::binR, Acts::BinningValue::binPhi, - Acts::BinningValue::binZ}; + std::vector canonicalAxes() const override { + using enum AxisDirection; + return {AxisR, AxisPhi, AxisZ}; }; /// Write information about this instance to an outstream diff --git a/Core/include/Acts/Geometry/CylinderContainerBlueprintNode.hpp b/Core/include/Acts/Geometry/CylinderContainerBlueprintNode.hpp index 637f1594c0c..9731715de1e 100644 --- a/Core/include/Acts/Geometry/CylinderContainerBlueprintNode.hpp +++ b/Core/include/Acts/Geometry/CylinderContainerBlueprintNode.hpp @@ -11,7 +11,9 @@ #include "Acts/Geometry/BlueprintNode.hpp" #include "Acts/Geometry/CylinderVolumeStack.hpp" #include "Acts/Geometry/PortalShell.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Geometry/VolumeAttachmentStrategy.hpp" +#include "Acts/Geometry/VolumeResizeStrategy.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Logger.hpp" #include @@ -36,11 +38,10 @@ class CylinderContainerBlueprintNode final : public BlueprintNode { /// @note The parameters are passed through to @ref CylinderVolumeStack, /// see documentation of that class for more information CylinderContainerBlueprintNode( - const std::string& name, BinningValue direction, - CylinderVolumeStack::AttachmentStrategy attachmentStrategy = - CylinderVolumeStack::AttachmentStrategy::Midpoint, - CylinderVolumeStack::ResizeStrategy resizeStrategy = - CylinderVolumeStack::ResizeStrategy::Expand); + const std::string& name, AxisDirection direction, + VolumeAttachmentStrategy attachmentStrategy = + VolumeAttachmentStrategy::Midpoint, + VolumeResizeStrategy resizeStrategy = VolumeResizeStrategy::Expand); /// @copydoc BlueprintNode::name const std::string& name() const override; @@ -95,31 +96,31 @@ class CylinderContainerBlueprintNode final : public BlueprintNode { /// Setter for the stacking direction /// @param direction The stacking direction /// @return This node for chaining - CylinderContainerBlueprintNode& setDirection(BinningValue direction); + CylinderContainerBlueprintNode& setDirection(AxisDirection direction); /// Setter for the attachment strategy /// @param attachmentStrategy The attachment strategy /// @return This node for chaining CylinderContainerBlueprintNode& setAttachmentStrategy( - CylinderVolumeStack::AttachmentStrategy attachmentStrategy); + VolumeAttachmentStrategy attachmentStrategy); /// Setter for the resize strategy /// @param resizeStrategy The resize strategy /// @return This node for chaining CylinderContainerBlueprintNode& setResizeStrategy( - CylinderVolumeStack::ResizeStrategy resizeStrategy); + VolumeResizeStrategy resizeStrategy); /// Accessor to the stacking direction /// @return The stacking direction - BinningValue direction() const; + AxisDirection direction() const; /// Accessor to the attachment strategy /// @return The attachment strategy - CylinderVolumeStack::AttachmentStrategy attachmentStrategy() const; + VolumeAttachmentStrategy attachmentStrategy() const; /// Accessor to the resize strategy /// @return The resize strategy - CylinderVolumeStack::ResizeStrategy resizeStrategy() const; + VolumeResizeStrategy resizeStrategy() const; private: /// @copydoc BlueprintNode::addToGraphviz @@ -136,13 +137,12 @@ class CylinderContainerBlueprintNode final : public BlueprintNode { std::string m_name; - BinningValue m_direction = BinningValue::binZ; + AxisDirection m_direction = AxisDirection::AxisZ; - CylinderVolumeStack::AttachmentStrategy m_attachmentStrategy{ - CylinderVolumeStack::AttachmentStrategy::Midpoint}; + VolumeAttachmentStrategy m_attachmentStrategy{ + VolumeAttachmentStrategy::Midpoint}; - CylinderVolumeStack::ResizeStrategy m_resizeStrategy{ - CylinderVolumeStack::ResizeStrategy::Expand}; + VolumeResizeStrategy m_resizeStrategy{VolumeResizeStrategy::Expand}; // Is only initialized during `build` std::vector m_childVolumes; diff --git a/Core/include/Acts/Geometry/CylinderVolumeBounds.hpp b/Core/include/Acts/Geometry/CylinderVolumeBounds.hpp index 3e5d8862cd8..79916c84083 100644 --- a/Core/include/Acts/Geometry/CylinderVolumeBounds.hpp +++ b/Core/include/Acts/Geometry/CylinderVolumeBounds.hpp @@ -12,7 +12,7 @@ #include "Acts/Geometry/BoundarySurfaceFace.hpp" #include "Acts/Geometry/Volume.hpp" #include "Acts/Geometry/VolumeBounds.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include #include @@ -172,24 +172,24 @@ class CylinderVolumeBounds : public VolumeBounds { const Vector3& envelope = {0, 0, 0}, const Volume* entity = nullptr) const final; - /// Get the canonical binning values, i.e. the binning values - /// for that fully describe the shape's extent + /// Get the canonical binning directions, i.e. the axis directions + /// that fully describe the shape's extent /// /// @return vector of canonical binning values - std::vector canonicalBinning() const override { - return {Acts::BinningValue::binR, Acts::BinningValue::binPhi, - Acts::BinningValue::binZ}; + std::vector canonicalAxes() const override { + using enum AxisDirection; + return {AxisR, AxisPhi, AxisZ}; }; /// Binning offset - overloaded for some R-binning types /// - /// @param bValue is the type used for the binning - Vector3 binningOffset(BinningValue bValue) const override; + /// @param aDir is the axis direction used for the binning + Vector3 referenceOffset(AxisDirection aDir) const override; /// Binning borders in double /// - /// @param bValue is the type used for the binning - double binningBorder(BinningValue bValue) const override; + /// @param aDir is the axis direction used for the binning + double referenceBorder(AxisDirection aDir) const override; /// Output Method for std::ostream /// @param os is the output stream diff --git a/Core/include/Acts/Geometry/CylinderVolumeHelper.hpp b/Core/include/Acts/Geometry/CylinderVolumeHelper.hpp index 6156230817d..85f20ee8ea9 100644 --- a/Core/include/Acts/Geometry/CylinderVolumeHelper.hpp +++ b/Core/include/Acts/Geometry/CylinderVolumeHelper.hpp @@ -12,7 +12,7 @@ #include "Acts/Geometry/BoundarySurfaceFace.hpp" #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/ITrackingVolumeHelper.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Logger.hpp" #include @@ -205,7 +205,7 @@ class CylinderVolumeHelper : public ITrackingVolumeHelper { const GeometryContext& gctx, const LayerVector& layers, std::shared_ptr& cylinderVolumeBounds, const Transform3& transform, double& rMinClean, double& rMaxClean, - double& zMinClean, double& zMaxClean, BinningValue& bValue, + double& zMinClean, double& zMaxClean, AxisDirection& bValue, BinningType bType = arbitrary) const; /// Private method - interglue all volumes contained by a TrackingVolume diff --git a/Core/include/Acts/Geometry/CylinderVolumeStack.hpp b/Core/include/Acts/Geometry/CylinderVolumeStack.hpp index 06e1e75dd58..44fa11b5ecf 100644 --- a/Core/include/Acts/Geometry/CylinderVolumeStack.hpp +++ b/Core/include/Acts/Geometry/CylinderVolumeStack.hpp @@ -11,7 +11,9 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Geometry/CylinderVolumeBounds.hpp" #include "Acts/Geometry/Volume.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Geometry/VolumeAttachmentStrategy.hpp" +#include "Acts/Geometry/VolumeResizeStrategy.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Logger.hpp" #include @@ -32,29 +34,6 @@ namespace Acts { /// result in overlaps of the resulting volumes bounds. class CylinderVolumeStack : public Volume { public: - /// The attachment strategy defines how the volumes are attached - /// Attachment always happens pair-wise - enum class AttachmentStrategy { - /// Given two volumes, the *left* one, i.e. the one with the lower **local** - /// z or r value is extended - First, - /// Given two volumes, the *right* one, i.e. the one with the higher - /// **local** z or r value is extended - Second, - /// Given two volumes, the *midpoint* between the two volumes is found - Midpoint, - /// A gap volume is created to fit between the two volumes - Gap, - }; - - /// The resize strategy defines how the volumes are resized - enum class ResizeStrategy { - /// Extend the volume connected to the respective edge to fit the new bounds - Expand, - /// Create a gap volume at the respective edge to fit the new bounds - Gap, - }; - /// Constructor from a vector of volumes and direction /// @param volumes is the vector of volumes /// @param direction is the binning direction @@ -73,9 +52,9 @@ class CylinderVolumeStack : public Volume { /// and cannot have a @f$\phi@f$ sector or bevels. /// @note Preconditions are checked on construction CylinderVolumeStack( - std::vector& volumes, BinningValue direction, - AttachmentStrategy strategy = AttachmentStrategy::Midpoint, - ResizeStrategy resizeStrategy = ResizeStrategy::Expand, + std::vector& volumes, AxisDirection direction, + VolumeAttachmentStrategy strategy = VolumeAttachmentStrategy::Midpoint, + VolumeResizeStrategy resizeStrategy = VolumeResizeStrategy::Expand, const Logger& logger = Acts::getDummyLogger()); /// Update the volume bounds and transform. This @@ -108,8 +87,9 @@ class CylinderVolumeStack : public Volume { /// @param direction is the binning direction /// @param strategy is the attachment strategy /// @param logger is the logger - void initializeOuterVolume(BinningValue direction, - AttachmentStrategy strategy, const Logger& logger); + void initializeOuterVolume(AxisDirection direction, + VolumeAttachmentStrategy strategy, + const Logger& logger); struct VolumeTuple; @@ -126,7 +106,7 @@ class CylinderVolumeStack : public Volume { /// @param a is the first volume /// @param b is the second volume /// @param logger is the logger - static void overlapPrint(BinningValue direction, const VolumeTuple& a, + static void overlapPrint(AxisDirection direction, const VolumeTuple& a, const VolumeTuple& b, const Logger& logger); /// Helper function that checks if volumes are properly aligned @@ -142,7 +122,7 @@ class CylinderVolumeStack : public Volume { /// @param logger is the logger /// @return vector of gap volumes. Can be empty if none were created. std::vector checkOverlapAndAttachInZ( - std::vector& volumes, AttachmentStrategy strategy, + std::vector& volumes, VolumeAttachmentStrategy strategy, const Logger& logger); /// Helper function to synchronize the r bounds of the volumes @@ -158,7 +138,7 @@ class CylinderVolumeStack : public Volume { /// @param logger is the logger /// @return vector of gap volumes. Can be empty if none were created. std::vector checkOverlapAndAttachInR( - std::vector& volumes, AttachmentStrategy strategy, + std::vector& volumes, VolumeAttachmentStrategy strategy, const Logger& logger); /// Helper function to synchronize the z bounds of the volumes @@ -182,25 +162,11 @@ class CylinderVolumeStack : public Volume { std::shared_ptr addGapVolume( const Transform3& transform, const std::shared_ptr& bounds); - BinningValue m_direction{}; - ResizeStrategy m_resizeStrategy{}; + AxisDirection m_direction{}; + VolumeResizeStrategy m_resizeStrategy{}; Transform3 m_groupTransform{}; std::vector> m_gaps{}; std::vector& m_volumes; }; -/// Output operator for the attachment strategy -/// @param os is the output stream -/// @param strategy is the attachment strategy -/// @return the output stream -std::ostream& operator<<(std::ostream& os, - CylinderVolumeStack::AttachmentStrategy strategy); - -/// Output operator for the resize strategy -/// @param os is the output stream -/// @param strategy is the resize strategy -/// @return the output stream -std::ostream& operator<<(std::ostream& os, - CylinderVolumeStack::ResizeStrategy strategy); - } // namespace Acts diff --git a/Core/include/Acts/Geometry/Extent.hpp b/Core/include/Acts/Geometry/Extent.hpp index 840a4ef582c..f34d1de8b05 100644 --- a/Core/include/Acts/Geometry/Extent.hpp +++ b/Core/include/Acts/Geometry/Extent.hpp @@ -11,7 +11,7 @@ /// @note This file is foreseen for the `Geometry` module to replace `Extent` #include "Acts/Definitions/Algebra.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Enumerate.hpp" #include "Acts/Utilities/Helpers.hpp" #include "Acts/Utilities/RangeXD.hpp" @@ -29,20 +29,20 @@ using Envelope = std::array; constexpr Envelope zeroEnvelope = {0, 0}; -/// This struct models a multi-dimensional enveloper along the binning values +/// This struct models a multi-dimensional enveloper along the axis directions struct ExtentEnvelope { /// Access a single envelope configuration - /// @param bValue the binning value + /// @param aDir the axis definition /// @return the envelope - Envelope& operator[](BinningValue bValue) { - return m_values.at(toUnderlying(bValue)); + Envelope& operator[](AxisDirection aDir) { + return m_values.at(toUnderlying(aDir)); } /// Access a single envelope configuration - /// @param bValue the binning value + /// @param aDir the axis direction /// @return the envelope - const Envelope& operator[](BinningValue bValue) const { - return m_values.at(toUnderlying(bValue)); + const Envelope& operator[](AxisDirection aDir) const { + return m_values.at(toUnderlying(aDir)); } /// Constructor from a single envelope that is assigned to all values @@ -77,7 +77,7 @@ struct ExtentEnvelope { Envelope r = zeroEnvelope; Envelope phi = zeroEnvelope; Envelope rPhi = zeroEnvelope; - Envelope h = zeroEnvelope; + Envelope theta = zeroEnvelope; Envelope eta = zeroEnvelope; Envelope mag = zeroEnvelope; }; @@ -85,15 +85,15 @@ struct ExtentEnvelope { /// Constructor using a helper struct for designated initializaion /// @param args the arguments constexpr explicit ExtentEnvelope(Arguments&& args) { - using enum BinningValue; - m_values[toUnderlying(binX)] = args.x; - m_values[toUnderlying(binY)] = args.y; - m_values[toUnderlying(binZ)] = args.z; - m_values[toUnderlying(binR)] = args.r; - m_values[toUnderlying(binPhi)] = args.phi; - m_values[toUnderlying(binH)] = args.h; - m_values[toUnderlying(binEta)] = args.eta; - m_values[toUnderlying(binMag)] = args.mag; + using enum AxisDirection; + m_values[toUnderlying(AxisX)] = args.x; + m_values[toUnderlying(AxisY)] = args.y; + m_values[toUnderlying(AxisZ)] = args.z; + m_values[toUnderlying(AxisR)] = args.r; + m_values[toUnderlying(AxisPhi)] = args.phi; + m_values[toUnderlying(AxisTheta)] = args.theta; + m_values[toUnderlying(AxisEta)] = args.eta; + m_values[toUnderlying(AxisMag)] = args.mag; } /// Comparison operator between envelope sets @@ -105,11 +105,11 @@ struct ExtentEnvelope { } private: - std::array m_values{}; + std::array m_values{}; }; /// A class representing the geometric extent of an object in its possible -/// dimensions, these can be all dimensions that are described as BinningValues +/// dimensions, these can be all dimensions that are described as AxisDirections /// /// The extent object can have an optional envelope in all of those values /// @note that the consistency of the different envelopes is not checked @@ -125,28 +125,28 @@ class Extent { /// Extend with a position vertex /// /// @param vtx the vertex to be used for extending - /// @param bValues the binning values + /// @param aDirs the axis directions /// @param applyEnv boolean to steer if envelope should be applied /// @param fillHistograms is a boolean flag to steer whether the values /// to fill this extent should be stored void extend(const Vector3& vtx, - const std::vector& bValues = allBinningValues(), + const std::vector& aDirs = allAxisDirections(), bool applyEnv = true, bool fillHistograms = false); /// Extend with a set of vectors by iterators /// /// @param start the start iterator of the loop /// @param end the end iterator of the loop - /// @param bValues the binning values + /// @param aDirs the axis directions /// @param applyEnv boolean to steer if envelope should be applied /// @param fillHistograms is a boolean flag to steer whether the values /// to fill this extent should be stored template void extend(const vector_iterator_t& start, const vector_iterator_t& end, - const std::vector& bValues = allBinningValues(), + const std::vector& aDirs = allAxisDirections(), bool applyEnv = true, bool fillHistograms = false) { for (vector_iterator_t vIt = start; vIt < end; ++vIt) { - extend(*vIt, bValues, applyEnv, fillHistograms); + extend(*vIt, aDirs, applyEnv, fillHistograms); } } @@ -158,14 +158,14 @@ class Extent { /// which then is applied to the current one /// /// @param rhs is the other source Extent - /// @param bValues the binning values + /// @param aDirs the axis directions /// @param applyEnv boolean to steer if envelope should be applied /// on the constraint values, if only an envelope is given /// but the value not constraint, then it is always applied /// /// @note that the histogram values can not be filled in this call void extend(const Extent& rhs, - const std::vector& bValues = allBinningValues(), + const std::vector& aDirs = allAxisDirections(), bool applyEnv = true); /// Constrain an extent by another one, this is @@ -180,22 +180,22 @@ class Extent { /// Set a range for a dedicated binning value /// - /// @param bValue the binning identification + /// @param aDir the axis direction /// @param min the minimum parameter /// @param max the maximum parameter - void set(BinningValue bValue, double min, double max); + void set(AxisDirection aDir, double min, double max); /// Set a min value for a dedicated binning value /// - /// @param bValue the binning identification + /// @param aDir the axis direction /// @param min the minimum parameter - void setMin(BinningValue bValue, double min); + void setMin(AxisDirection aDir, double min); /// Set a max value for a dedicated binning value /// - /// @param bValue the binning identification + /// @param aDir the axis direction /// @param max the maximum parameter - void setMax(BinningValue bValue, double max); + void setMax(AxisDirection aDir, double max); /// (re-)Set the envelope /// @@ -204,31 +204,31 @@ class Extent { /// Return the individual 1-dimensional range /// - /// @param bValue is the binning value to be returned + /// @param aDir is the axis direction to be returned /// /// @return a one dimensional arrange - auto range(BinningValue bValue) { return m_range[toUnderlying(bValue)]; } + auto range(AxisDirection aDir) { return m_range[toUnderlying(aDir)]; } /// Return the individual 1-dimensional range /// - /// @param bValue is the binning value to be returned + /// @param aDir is the axis direction to be returned /// /// @return a one dimensional arrange - Range1D range(BinningValue bValue) const; + Range1D range(AxisDirection aDir) const; /// Return the N-dimension range - const RangeXD& range() const; + const RangeXD& range() const; /// Return an D-dimensional sub range according to the /// the given binvalues /// @tparam kSUBDIM the number of sub dimensions - /// @param binValues the binning values + /// @param axisDirections the axis directions /// @return the sub range template RangeXD range( - const std::array& binValues) const { + const std::array& axisDirections) const { RangeXD rRange; - for (auto [i, v] : enumerate(binValues)) { + for (auto [i, v] : enumerate(axisDirections)) { rRange[i] = range(v); } return rRange; @@ -243,47 +243,47 @@ class Extent { /// Return the histogram store /// /// The histogram store can be used for automated binning detection - const std::array, numBinningValues()>& valueHistograms() + const std::array, numAxisDirections()>& valueHistograms() const; /// Access the minimum parameter /// - /// @param bValue the binning identification - double min(BinningValue bValue) const { - return m_range[toUnderlying(bValue)].min(); + /// @param aDir the axis direction + double min(AxisDirection aDir) const { + return m_range[toUnderlying(aDir)].min(); } /// Access the maximum parameter /// - /// @param bValue the binning identification - double max(BinningValue bValue) const { - return m_range[toUnderlying(bValue)].max(); + /// @param aDir the axis direction + double max(AxisDirection aDir) const { + return m_range[toUnderlying(aDir)].max(); } /// Access the midpoint /// - /// @param bValue the binning identification - double medium(BinningValue bValue) const { - return 0.5 * (m_range[toUnderlying(bValue)].min() + - m_range[toUnderlying(bValue)].max()); + /// @param aDir the axis direction + double medium(AxisDirection aDir) const { + return 0.5 * (m_range[toUnderlying(aDir)].min() + + m_range[toUnderlying(aDir)].max()); } /// Access the parameter interval (i.e. the range span) /// - /// @param bValue the binning identification - double interval(BinningValue bValue) const { - return m_range[toUnderlying(bValue)].size(); + /// @param aDir the axis direction + double interval(AxisDirection aDir) const { + return m_range[toUnderlying(aDir)].size(); } /// Contains check /// /// @param rhs the extent that is check if it is contained - /// @param bValue is the binning value, if set to nullopt + /// @param aDir is the axis direction, if set to nullopt /// the check on all is done /// /// @return true if the rhs is contained bool contains(const Extent& rhs, - std::optional bValue = std::nullopt) const; + std::optional aDir = std::nullopt) const; /// Contains check for a single point /// @@ -295,17 +295,17 @@ class Extent { /// Intersection checks /// /// @param rhs the extent that is check for intersection - /// @param bValue is the binning value, if set to nulloptr + /// @param aDir is the axis direction, if set to nulloptr /// the check on all is done /// /// @return true if the rhs intersects bool intersects(const Extent& rhs, - std::optional bValue = std::nullopt) const; + std::optional aDir = std::nullopt) const; /// Check if this object constrains a given direction /// - /// @param bValue is the binning value - bool constrains(BinningValue bValue) const; + /// @param aDir is the axis direction + bool constrains(AxisDirection aDir) const; /// Check if this object constrains any direction bool constrains() const; @@ -317,20 +317,20 @@ class Extent { private: /// A bitset that remembers the constraint values - std::bitset m_constrains{0}; + std::bitset m_constrains{0}; /// The actual range store - RangeXD m_range; + RangeXD m_range; /// A potential envelope ExtentEnvelope m_envelope = ExtentEnvelope::Zero(); /// (Optional) Value histograms for bin detection - std::array, numBinningValues()> m_valueHistograms; + std::array, numAxisDirections()> m_valueHistograms; }; -inline Range1D Acts::Extent::range(BinningValue bValue) const { - return m_range[toUnderlying(bValue)]; +inline Range1D Acts::Extent::range(AxisDirection aDir) const { + return m_range[toUnderlying(aDir)]; } -inline const RangeXD& Extent::range() const { +inline const RangeXD& Extent::range() const { return m_range; } @@ -342,7 +342,7 @@ inline const ExtentEnvelope& Extent::envelope() const { return m_envelope; } -inline const std::array, numBinningValues()>& +inline const std::array, numAxisDirections()>& Extent::valueHistograms() const { return m_valueHistograms; } diff --git a/Core/include/Acts/Geometry/GenericCuboidVolumeBounds.hpp b/Core/include/Acts/Geometry/GenericCuboidVolumeBounds.hpp index 5f063a62842..93ebeaa828b 100644 --- a/Core/include/Acts/Geometry/GenericCuboidVolumeBounds.hpp +++ b/Core/include/Acts/Geometry/GenericCuboidVolumeBounds.hpp @@ -89,13 +89,13 @@ class GenericCuboidVolumeBounds : public VolumeBounds { const Vector3& envelope = {0, 0, 0}, const Volume* entity = nullptr) const final; - /// Get the canonical binning values, i.e. the binning values - /// for that fully describe the shape's extent + /// Get the canonical direction values, i.e. the axis directions + /// that fully describe the shape's extent /// /// @return vector of canonical binning values - std::vector canonicalBinning() const override { - return {Acts::BinningValue::binX, Acts::BinningValue::binY, - Acts::BinningValue::binZ}; + std::vector canonicalAxes() const override { + using enum AxisDirection; + return {AxisX, AxisY, AxisZ}; }; /// @param sl is the output stream to be written into diff --git a/Core/include/Acts/Geometry/GeometryHierarchyMap.hpp b/Core/include/Acts/Geometry/GeometryHierarchyMap.hpp index 3bdfc63425b..61cdcdb5e6d 100644 --- a/Core/include/Acts/Geometry/GeometryHierarchyMap.hpp +++ b/Core/include/Acts/Geometry/GeometryHierarchyMap.hpp @@ -79,10 +79,10 @@ class GeometryHierarchyMap { // defaulted constructors and assignment operators GeometryHierarchyMap() = default; GeometryHierarchyMap(const GeometryHierarchyMap&) = default; - GeometryHierarchyMap(GeometryHierarchyMap&&) = default; + GeometryHierarchyMap(GeometryHierarchyMap&&) noexcept = default; ~GeometryHierarchyMap() = default; GeometryHierarchyMap& operator=(const GeometryHierarchyMap&) = default; - GeometryHierarchyMap& operator=(GeometryHierarchyMap&&) = default; + GeometryHierarchyMap& operator=(GeometryHierarchyMap&&) noexcept = default; /// Return an iterator pointing to the beginning of the stored values. Iterator begin() const { return m_values.begin(); } diff --git a/Core/include/Acts/Geometry/GeometryObject.hpp b/Core/include/Acts/Geometry/GeometryObject.hpp index a3754996a1e..191d2234cd5 100644 --- a/Core/include/Acts/Geometry/GeometryObject.hpp +++ b/Core/include/Acts/Geometry/GeometryObject.hpp @@ -12,7 +12,7 @@ #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/GeometryIdentifier.hpp" #include "Acts/Geometry/Polyhedron.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/VectorHelpers.hpp" namespace Acts { @@ -20,7 +20,7 @@ namespace Acts { /// Base class to provide GeometryIdentifier interface: /// - simple set and get /// -/// It also provides the binningPosition method for +/// It also provides the referencePosition method for /// Geometry geometrical object to be binned in BinnedArrays /// class GeometryObject { @@ -53,20 +53,20 @@ class GeometryObject { /// Force a binning position method /// /// @param gctx The current geometry context object, e.g. alignment - /// @param bValue is the value in which you want to bin + /// @param aDir is the value for which the reference position is requesed /// /// @return vector 3D used for the binning schema - virtual Vector3 binningPosition(const GeometryContext& gctx, - BinningValue bValue) const = 0; + virtual Vector3 referencePosition(const GeometryContext& gctx, + AxisDirection aDir) const = 0; /// Implement the binningValue /// /// @param gctx The current geometry context object, e.g. alignment - /// @param bValue is the dobule in which you want to bin + /// @param aDir is the dobule in which you want to bin /// /// @return float to be used for the binning schema - virtual double binningPositionValue(const GeometryContext& gctx, - BinningValue bValue) const; + virtual double referencePositionValue(const GeometryContext& gctx, + AxisDirection aDir) const; /// Set the value /// @@ -86,9 +86,9 @@ inline void GeometryObject::assignGeometryId( m_geometryId = geometryId; } -inline double GeometryObject::binningPositionValue(const GeometryContext& gctx, - BinningValue bValue) const { - return VectorHelpers::cast(binningPosition(gctx, bValue), bValue); +inline double GeometryObject::referencePositionValue( + const GeometryContext& gctx, AxisDirection aDir) const { + return VectorHelpers::cast(referencePosition(gctx, aDir), aDir); } } // namespace Acts diff --git a/Core/include/Acts/Geometry/GeometryObjectSorter.hpp b/Core/include/Acts/Geometry/GeometryObjectSorter.hpp index 5783103d6af..6de46fbb86a 100644 --- a/Core/include/Acts/Geometry/GeometryObjectSorter.hpp +++ b/Core/include/Acts/Geometry/GeometryObjectSorter.hpp @@ -15,6 +15,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Geometry/GeometryContext.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/VectorHelpers.hpp" #include @@ -27,8 +28,8 @@ class ObjectSorterT { public: /// Constructor from a binning value /// - /// @param bValue is the value in which the binning is done - ObjectSorterT(BinningValue bValue) : m_binningValue(bValue) {} + /// @param aDir is the direction in which the sorting is done + explicit ObjectSorterT(AxisDirection aDir) : m_sortingDirection(aDir) {} /// Comparison operator /// @@ -37,32 +38,33 @@ class ObjectSorterT { /// /// @return boolean indicator bool operator()(T one, T two) const { - using Acts::VectorHelpers::eta; - using Acts::VectorHelpers::perp; - using Acts::VectorHelpers::phi; - switch (m_binningValue) { + using VectorHelpers::eta; + using VectorHelpers::perp; + using VectorHelpers::phi; + using enum AxisDirection; + switch (m_sortingDirection) { // compare on x - case BinningValue::binX: { + case AxisX: { return one.x() < two.x(); } // compare on y - case BinningValue::binY: { + case AxisY: { return one.y() < two.y(); } // compare on z - case BinningValue::binZ: { + case AxisZ: { return one.z() < two.z(); } // compare on r - case BinningValue::binR: { + case AxisR: { return perp(one) < perp(two); } // compare on phi - case BinningValue::binPhi: { + case AxisPhi: { return phi(one) < phi(two); } // compare on eta - case BinningValue::binEta: { + case AxisEta: { return eta(one) < eta(two); } // default for the moment @@ -72,10 +74,10 @@ class ObjectSorterT { } } - BinningValue binningValue() const { return m_binningValue; } + AxisDirection sortingDirection() const { return m_sortingDirection; } private: - BinningValue m_binningValue; ///< the binning value + AxisDirection m_sortingDirection; ///< the binning value }; /// This will check on absolute distance @@ -84,10 +86,10 @@ class DistanceSorterT { public: /// Constructor from a binning value /// - /// @param bValue is the value in which the binning is done + /// @param aDir is the value in which the sorting is done /// @param reference is the reference point - DistanceSorterT(BinningValue bValue, Vector3 reference) - : m_binningValue(bValue), + DistanceSorterT(AxisDirection aDir, Vector3 reference) + : m_sortingDirection(aDir), m_reference(reference), m_refR(VectorHelpers::perp(reference)), m_refPhi(VectorHelpers::phi(reference)), @@ -103,41 +105,41 @@ class DistanceSorterT { using Acts::VectorHelpers::eta; using Acts::VectorHelpers::perp; using Acts::VectorHelpers::phi; - // switch the binning value - // - binX, binY, binZ, binR, binPhi, binRPhi, binH, binEta - switch (m_binningValue) { + // switch the sorting value + // - AxisX, AxisY, AxisZ, AxisR, AxisPhi, AxisRPhi, AxisTheta, AxisEta + switch (m_sortingDirection) { // compare on diff x - case BinningValue::binX: { + case AxisDirection::AxisX: { double diffOneX = one.x() - m_reference.x(); double diffTwoX = two.x() - m_reference.x(); return std::abs(diffOneX) < std::abs(diffTwoX); } // compare on diff y - case BinningValue::binY: { + case AxisDirection::AxisY: { double diffOneY = one.y() - m_reference.y(); double diffTwoY = two.y() - m_reference.y(); return std::abs(diffOneY) < std::abs(diffTwoY); } // compare on diff z - case BinningValue::binZ: { + case AxisDirection::AxisZ: { double diffOneZ = one.z() - m_reference.z(); double diffTwoZ = two.z() - m_reference.z(); return std::abs(diffOneZ) < std::abs(diffTwoZ); } // compare on r - case BinningValue::binR: { + case AxisDirection::AxisR: { double diffOneR = perp(one) - m_refR; double diffTwoR = perp(two) - m_refR; return std::abs(diffOneR) < std::abs(diffTwoR); } // compare on phi /// @todo add cyclic value - case BinningValue::binPhi: { + case AxisDirection::AxisPhi: { double diffOnePhi = phi(one) - m_refPhi; double diffTwoPhi = phi(two) - m_refPhi; return std::abs(diffOnePhi) < std::abs(diffTwoPhi); } // compare on eta - case BinningValue::binEta: { + case AxisDirection::AxisEta: { double diffOneEta = eta(one) - m_refEta; double diffTwoEta = eta(two) - m_refEta; return std::abs(diffOneEta) < std::abs(diffTwoEta); @@ -152,7 +154,7 @@ class DistanceSorterT { } private: - BinningValue m_binningValue; ///< the binning value + AxisDirection m_sortingDirection; ///< the sorting direction T m_reference; double m_refR; double m_refPhi; @@ -162,35 +164,37 @@ class DistanceSorterT { template class GeometryObjectSorterT { public: - /// Constructor from a binning value + /// Constructor from a sorting direction /// /// @param gctx The geometry context to use - /// @param bValue is the value in which the binning is done + /// @param aDir is the direction in which the sorting is done /// @param transform is an optional transform to be performed - GeometryObjectSorterT(const GeometryContext& gctx, BinningValue bValue, + GeometryObjectSorterT(const GeometryContext& gctx, AxisDirection aDir, std::shared_ptr transform = nullptr) : m_context(gctx), - m_objectSorter(bValue), + m_objectSorter(aDir), m_transform(std::move(transform)) {} /// Comparison operator /// - /// @tparam one first object - /// @tparam two second object + /// @tparam one is the first object + /// @tparam two is the second object /// /// @return boolean indicator bool operator()(T one, T two) const { // get the pos one / pos two - Vector3 posOne = - m_transform - ? m_transform->inverse() * - one->binningPosition(m_context, m_objectSorter.binningValue()) - : one->binningPosition(m_context, m_objectSorter.binningValue()); - Vector3 posTwo = - m_transform - ? m_transform->inverse() * - two->binningPosition(m_context, m_objectSorter.binningValue()) - : two->binningPosition(m_context, m_objectSorter.binningValue()); + Vector3 posOne = m_transform + ? m_transform->inverse() * + one->referencePosition( + m_context, m_objectSorter.sortingDirection()) + : one->referencePosition( + m_context, m_objectSorter.sortingDirection()); + Vector3 posTwo = m_transform + ? m_transform->inverse() * + two->referencePosition( + m_context, m_objectSorter.sortingDirection()) + : two->referencePosition( + m_context, m_objectSorter.sortingDirection()); // now call the distance sorter return m_objectSorter.operator()(posOne, posTwo); } diff --git a/Core/include/Acts/Geometry/GridPortalLink.hpp b/Core/include/Acts/Geometry/GridPortalLink.hpp index 94e98867905..d94ba5fc749 100644 --- a/Core/include/Acts/Geometry/GridPortalLink.hpp +++ b/Core/include/Acts/Geometry/GridPortalLink.hpp @@ -11,12 +11,13 @@ #include "Acts/Definitions/Tolerance.hpp" #include "Acts/Geometry/PortalLinkBase.hpp" #include "Acts/Geometry/TrackingVolume.hpp" -#include "Acts/Surfaces/BoundaryTolerance.hpp" #include "Acts/Surfaces/CylinderSurface.hpp" #include "Acts/Surfaces/DiscSurface.hpp" #include "Acts/Surfaces/PlaneSurface.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Grid.hpp" #include "Acts/Utilities/Logger.hpp" +#include "Acts/Utilities/ThrowAssert.hpp" #include @@ -42,7 +43,7 @@ class GridPortalLink : public PortalLinkBase { /// @param surface The surface /// @param direction The binning direction GridPortalLink(std::shared_ptr surface, - BinningValue direction) + AxisDirection direction) : PortalLinkBase(std::move(surface)), m_direction(direction) {} public: @@ -56,15 +57,18 @@ class GridPortalLink : public PortalLinkBase { /// @return A unique pointer to the grid portal link template static std::unique_ptr> make( - std::shared_ptr surface, BinningValue direction, + std::shared_ptr surface, AxisDirection direction, axis_t&& axis) { - using enum BinningValue; + using enum AxisDirection; if (dynamic_cast(surface.get()) != nullptr) { - if (direction != binZ && direction != binRPhi) { + if (direction != AxisZ && direction != AxisRPhi) { throw std::invalid_argument{"Invalid binning direction"}; } } else if (dynamic_cast(surface.get()) != nullptr && - direction != binR && direction != binPhi) { + direction != AxisR && direction != AxisPhi) { + throw std::invalid_argument{"Invalid binning direction"}; + } else if (dynamic_cast(surface.get()) != nullptr && + direction != AxisX && direction != AxisY) { throw std::invalid_argument{"Invalid binning direction"}; } @@ -84,11 +88,13 @@ class GridPortalLink : public PortalLinkBase { template static std::unique_ptr> make( std::shared_ptr surface, axis_1_t axis1, axis_2_t axis2) { - std::optional direction; + std::optional direction; if (dynamic_cast(surface.get()) != nullptr) { - direction = BinningValue::binRPhi; + direction = AxisDirection::AxisRPhi; } else if (dynamic_cast(surface.get()) != nullptr) { - direction = BinningValue::binR; + direction = AxisDirection::AxisR; + } else if (dynamic_cast(surface.get()) != nullptr) { + direction = AxisDirection::AxisX; } return std::make_unique>( @@ -102,7 +108,7 @@ class GridPortalLink : public PortalLinkBase { /// @return A unique pointer to the grid portal link static std::unique_ptr make( const std::shared_ptr& surface, TrackingVolume& volume, - BinningValue direction); + AxisDirection direction); /// Merge two grid portal links into a single one. The routine can merge /// one-dimenaional, tow-dimensional and mixed links. The merge will try to @@ -297,7 +303,7 @@ class GridPortalLink : public PortalLinkBase { /// to be handled by th caller! Invalid input is handled /// via exceptions. static std::unique_ptr merge( - const GridPortalLink& a, const GridPortalLink& b, BinningValue direction, + const GridPortalLink& a, const GridPortalLink& b, AxisDirection direction, const Logger& logger = getDummyLogger()); /// Return the associated grid in a type-erased form @@ -324,7 +330,7 @@ class GridPortalLink : public PortalLinkBase { /// @note For 2D grids, this will always be the loc0 /// direction, depending on the surface type. /// @return The binning direction - BinningValue direction() const { return m_direction; } + AxisDirection direction() const { return m_direction; } /// Helper function to fill the bin contents after merging. /// This called by the merging routine, and requires access to the internal @@ -335,7 +341,7 @@ class GridPortalLink : public PortalLinkBase { /// @param direction The merging direction /// @param logger The logger to use for messages static void fillMergedGrid(const GridPortalLink& a, const GridPortalLink& b, - GridPortalLink& merged, BinningValue direction, + GridPortalLink& merged, AxisDirection direction, const Logger& logger); /// Helper function that prints a textual representation of the grid with the @@ -352,6 +358,10 @@ class GridPortalLink : public PortalLinkBase { /// @param disc The disc surface void checkConsistency(const DiscSurface& disc) const; + /// Helper function to check consistency for grid on a plane surface + /// @param plane The plane surface + void checkConsistency(const PlaneSurface& plane) const; + /// Expand a 1D grid to a 2D one for a cylinder surface /// @param surface The cylinder surface /// @param other The axis to use for the missing direction, @@ -369,6 +379,14 @@ class GridPortalLink : public PortalLinkBase { std::unique_ptr extendTo2dImpl( const std::shared_ptr& surface, const IAxis* other) const; + /// Expand a 1D grid to a 2D one for a plane surface + /// @param surface The plane surface + /// @param other The axis to use for the missing direction, + /// can be null for auto determination + /// @return A unique pointer to the 2D grid portal link + std::unique_ptr extendTo2dImpl( + const std::shared_ptr& surface, const IAxis* other) const; + /// Helper enum to declare which local direction to fill enum class FillDirection { loc0, @@ -401,7 +419,7 @@ class GridPortalLink : public PortalLinkBase { virtual const TrackingVolume* atLocalBins(IndexType indices) const = 0; private: - BinningValue m_direction; + AxisDirection m_direction; }; /// Concrete class deriving from @c GridPortalLink that boxes a concrete grid for lookup. @@ -422,19 +440,19 @@ class GridPortalLinkT : public GridPortalLink { /// @param axes The axes for the grid /// @note The axes are checked for consistency with the bounds of @p surface. GridPortalLinkT(std::shared_ptr surface, - BinningValue direction, Axes&&... axes) + AxisDirection direction, Axes&&... axes) : GridPortalLink(std::move(surface), direction), m_grid(std::tuple{std::move(axes)...}) { - using enum BinningValue; + using enum AxisDirection; if (const auto* cylinder = dynamic_cast(m_surface.get())) { checkConsistency(*cylinder); - if (direction == binRPhi) { - m_projection = &projection; - } else if (direction == binZ) { - m_projection = &projection; + if (direction == AxisRPhi) { + m_projection = &projection; + } else if (direction == AxisZ) { + m_projection = &projection; } else { throw std::invalid_argument{"Invalid binning direction"}; } @@ -443,10 +461,21 @@ class GridPortalLinkT : public GridPortalLink { dynamic_cast(m_surface.get())) { checkConsistency(*disc); - if (direction == binR) { - m_projection = &projection; - } else if (direction == BinningValue::binPhi) { - m_projection = &projection; + if (direction == AxisR) { + m_projection = &projection; + } else if (direction == AxisDirection::AxisPhi) { + m_projection = &projection; + } else { + throw std::invalid_argument{"Invalid binning direction"}; + } + } else if (const auto* plane = + dynamic_cast(m_surface.get())) { + checkConsistency(*plane); + + if (direction == AxisX) { + m_projection = &projection; + } else if (direction == AxisDirection::AxisY) { + m_projection = &projection; } else { throw std::invalid_argument{"Invalid binning direction"}; } @@ -489,6 +518,9 @@ class GridPortalLinkT : public GridPortalLink { } else if (auto disc = std::dynamic_pointer_cast(m_surface)) { return extendTo2dImpl(disc, other); + } else if (auto plane = + std::dynamic_pointer_cast(m_surface)) { + return extendTo2dImpl(plane, other); } else { throw std::logic_error{ "Surface type is not supported (this should not happen)"}; @@ -538,7 +570,8 @@ class GridPortalLinkT : public GridPortalLink { Result resolveVolume( const GeometryContext& /*gctx*/, const Vector2& position, double /*tolerance*/ = s_onSurfaceTolerance) const override { - assert(surface().insideBounds(position, BoundaryTolerance::None())); + throw_assert(surface().insideBounds(position, BoundaryTolerance::None()), + "Checking volume outside of bounds"); return m_grid.atPosition(m_projection(position)); } @@ -580,37 +613,37 @@ class GridPortalLinkT : public GridPortalLink { private: /// Helper function that's assigned to project from the 2D local position to a /// possible 1D grid. - template + template static ActsVector projection(const Vector2& position) { - using enum BinningValue; + using enum AxisDirection; if constexpr (DIM == 2) { return position; } else { if constexpr (std::is_same_v) { - static_assert(direction == binRPhi || direction == binZ, + static_assert(direction == AxisRPhi || direction == AxisZ, "Invalid binning direction"); - if constexpr (direction == binRPhi) { + if constexpr (direction == AxisRPhi) { return ActsVector<1>{position[0]}; - } else if constexpr (direction == binZ) { + } else if constexpr (direction == AxisZ) { return ActsVector<1>{position[1]}; } } else if constexpr (std::is_same_v) { - static_assert(direction == binR || direction == binPhi, + static_assert(direction == AxisR || direction == AxisPhi, "Invalid binning direction"); - if constexpr (direction == binR) { + if constexpr (direction == AxisR) { return ActsVector<1>{position[0]}; - } else if constexpr (direction == binPhi) { + } else if constexpr (direction == AxisPhi) { return ActsVector<1>{position[1]}; } } else if constexpr (std::is_same_v) { - static_assert(direction == binX || direction == binY, + static_assert(direction == AxisX || direction == AxisY, "Invalid binning direction"); - if constexpr (direction == binX) { + if constexpr (direction == AxisX) { return ActsVector<1>{position[0]}; - } else if constexpr (direction == binY) { + } else if constexpr (direction == AxisY) { return ActsVector<1>{position[1]}; } } diff --git a/Core/include/Acts/Geometry/ILayerArrayCreator.hpp b/Core/include/Acts/Geometry/ILayerArrayCreator.hpp index d2011c89a21..b36291438cc 100644 --- a/Core/include/Acts/Geometry/ILayerArrayCreator.hpp +++ b/Core/include/Acts/Geometry/ILayerArrayCreator.hpp @@ -50,6 +50,6 @@ class ILayerArrayCreator { virtual std::unique_ptr layerArray( const GeometryContext& gctx, const LayerVector& layers, double min, double max, BinningType btype = arbitrary, - BinningValue bvalue = BinningValue::binX) const = 0; + AxisDirection bvalue = AxisDirection::AxisX) const = 0; }; } // namespace Acts diff --git a/Core/include/Acts/Geometry/ITrackingVolumeArrayCreator.hpp b/Core/include/Acts/Geometry/ITrackingVolumeArrayCreator.hpp index 01a8efd850a..615ac487577 100644 --- a/Core/include/Acts/Geometry/ITrackingVolumeArrayCreator.hpp +++ b/Core/include/Acts/Geometry/ITrackingVolumeArrayCreator.hpp @@ -9,8 +9,8 @@ #pragma once #include "Acts/Geometry/GeometryContext.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/BinnedArray.hpp" -#include "Acts/Utilities/BinningType.hpp" #include #include @@ -50,11 +50,11 @@ class ITrackingVolumeArrayCreator { /// /// @param [in] gctx the geometry context for this building /// @param vols are the TrackingVolumes ordered in a tracker - /// @param bVal is the binning value for the volume binning + /// @param aDir is the axis direction for the volume binning /// /// @return shared pointer to a new TrackingVolumeArray virtual std::shared_ptr trackingVolumeArray( const GeometryContext& gctx, const TrackingVolumeVector& vols, - BinningValue bVal) const = 0; + AxisDirection aDir) const = 0; }; } // namespace Acts diff --git a/Core/include/Acts/Geometry/LayerArrayCreator.hpp b/Core/include/Acts/Geometry/LayerArrayCreator.hpp index 5358483cdde..dfccc615f3d 100644 --- a/Core/include/Acts/Geometry/LayerArrayCreator.hpp +++ b/Core/include/Acts/Geometry/LayerArrayCreator.hpp @@ -10,7 +10,7 @@ #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/ILayerArrayCreator.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Logger.hpp" #include @@ -54,13 +54,13 @@ class LayerArrayCreator : public ILayerArrayCreator { /// @param min is the minimum value for binning /// @param max is the maximum value for binning /// @param bType is the binning type - /// @param bValue is the value in which the binning should be done + /// @param aDir is the axis direction for the layer binning /// /// @return unique pointer to a newly created LayerArray std::unique_ptr layerArray( const GeometryContext& gctx, const LayerVector& layersInput, double min, double max, BinningType bType = arbitrary, - BinningValue bValue = BinningValue::binX) const override; + AxisDirection aDir = AxisDirection::AxisX) const override; /// set logging instance void setLogger(std::unique_ptr logger) { @@ -79,11 +79,11 @@ class LayerArrayCreator : public ILayerArrayCreator { /// @param layer object and thus needs the /// @param gctx geometry context. /// - /// @param bValue is the Binning value for the layer array + /// @param aDir is the axis direction for the binning /// @param offset is the sift for the navigation layer std::shared_ptr createNavigationSurface(const GeometryContext& gctx, const Layer& layer, - BinningValue bValue, + AxisDirection aDir, double offset) const; }; diff --git a/Core/include/Acts/Geometry/LayerCreator.hpp b/Core/include/Acts/Geometry/LayerCreator.hpp index b7996f68912..04a864f8055 100644 --- a/Core/include/Acts/Geometry/LayerCreator.hpp +++ b/Core/include/Acts/Geometry/LayerCreator.hpp @@ -13,6 +13,7 @@ #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/ProtoLayer.hpp" #include "Acts/Surfaces/SurfaceArray.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/BinningType.hpp" #include "Acts/Utilities/Logger.hpp" @@ -174,7 +175,7 @@ class LayerCreator { /// bValue /// @param [in] bins2 is the number of bins in the orthogonal direction to @p /// bValue - /// @param [in] bValue Direction of the aligned surfaces + /// @param [in] aDir Direction of the aligned surfaces /// @param [in] transform is the (optional) transform of the layer /// @param [in] _protoLayer (optional) proto layer specifying the dimensions /// and @@ -187,7 +188,7 @@ class LayerCreator { MutableLayerPtr planeLayer( const GeometryContext& gctx, std::vector> surfaces, std::size_t bins1, - std::size_t bins2, BinningValue bValue, + std::size_t bins2, AxisDirection aDir, std::optional _protoLayer = std::nullopt, const Transform3& transform = Transform3::Identity(), std::unique_ptr ad = nullptr) const; diff --git a/Core/include/Acts/Geometry/NavigationLayer.hpp b/Core/include/Acts/Geometry/NavigationLayer.hpp index 6c80477d98a..63536280a5a 100644 --- a/Core/include/Acts/Geometry/NavigationLayer.hpp +++ b/Core/include/Acts/Geometry/NavigationLayer.hpp @@ -13,7 +13,7 @@ #include "Acts/Geometry/Layer.hpp" #include "Acts/Surfaces/BoundaryTolerance.hpp" #include "Acts/Surfaces/Surface.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include #include @@ -44,12 +44,12 @@ class NavigationLayer : public Layer { /// The binning position method /// /// @param gctx The current geometry context object, e.g. alignment - /// @param bValue is the value for which the binning position is requested + /// @param aDir is the axis direction for which the reference position is requested /// - as default the center is given, but may be overloaded /// /// @return The return vector can be used for binning in a TrackingVolume - Vector3 binningPosition(const GeometryContext& gctx, - BinningValue bValue) const final; + Vector3 referencePosition(const GeometryContext& gctx, + AxisDirection aDir) const final; /// Default Constructor - deleted NavigationLayer() = delete; @@ -117,9 +117,9 @@ inline Surface& NavigationLayer::surfaceRepresentation() { return *(const_cast(m_surfaceRepresentation.get())); } -inline Vector3 NavigationLayer::binningPosition(const GeometryContext& gctx, - BinningValue bValue) const { - return m_surfaceRepresentation->binningPosition(gctx, bValue); +inline Vector3 NavigationLayer::referencePosition(const GeometryContext& gctx, + AxisDirection aDir) const { + return m_surfaceRepresentation->referencePosition(gctx, aDir); } inline bool NavigationLayer::isOnLayer( diff --git a/Core/include/Acts/Geometry/Portal.hpp b/Core/include/Acts/Geometry/Portal.hpp index 3d1a065026f..de2018a79d4 100644 --- a/Core/include/Acts/Geometry/Portal.hpp +++ b/Core/include/Acts/Geometry/Portal.hpp @@ -10,7 +10,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/Direction.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Logger.hpp" #include "Acts/Utilities/Result.hpp" @@ -163,7 +163,7 @@ class Portal { /// @param direction The direction of the merge (e.g. along z) /// @param logger The logger to push output to static Portal merge(const GeometryContext& gctx, Portal& aPortal, - Portal& bPortal, BinningValue direction, + Portal& bPortal, AxisDirection direction, const Logger& logger = getDummyLogger()); /// Resolve the volume for a 3D position and a direction diff --git a/Core/include/Acts/Geometry/PortalLinkBase.hpp b/Core/include/Acts/Geometry/PortalLinkBase.hpp index 2f8273f10b5..1d872f38562 100644 --- a/Core/include/Acts/Geometry/PortalLinkBase.hpp +++ b/Core/include/Acts/Geometry/PortalLinkBase.hpp @@ -10,7 +10,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/Tolerance.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Logger.hpp" #include "Acts/Utilities/Result.hpp" @@ -75,7 +75,7 @@ class PortalLinkBase { /// @return The merged portal link static std::unique_ptr merge( std::unique_ptr a, std::unique_ptr b, - BinningValue direction, const Logger& logger = getDummyLogger()); + AxisDirection direction, const Logger& logger = getDummyLogger()); /// Stream output function /// @param os The output stream @@ -111,7 +111,7 @@ class PortalLinkBase { /// executed. static void checkMergePreconditions(const PortalLinkBase& a, const PortalLinkBase& b, - BinningValue direction); + AxisDirection direction); std::shared_ptr m_surface; }; diff --git a/Core/include/Acts/Geometry/PortalShell.hpp b/Core/include/Acts/Geometry/PortalShell.hpp index fe9f606c576..b587af89cce 100644 --- a/Core/include/Acts/Geometry/PortalShell.hpp +++ b/Core/include/Acts/Geometry/PortalShell.hpp @@ -9,7 +9,7 @@ #pragma once #include "Acts/Geometry/CylinderVolumeBounds.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Logger.hpp" #include @@ -179,7 +179,7 @@ class CylinderStackPortalShell : public CylinderPortalShell { /// @param logger A logging instance for debugging CylinderStackPortalShell(const GeometryContext& gctx, std::vector shells, - BinningValue direction, + AxisDirection direction, const Logger& logger = getDummyLogger()); /// @copydoc PortalShellBase::size @@ -205,7 +205,7 @@ class CylinderStackPortalShell : public CylinderPortalShell { std::string label() const override; private: - BinningValue m_direction; + AxisDirection m_direction; std::vector m_shells; bool m_hasInnerCylinder{true}; }; diff --git a/Core/include/Acts/Geometry/ProtoLayer.hpp b/Core/include/Acts/Geometry/ProtoLayer.hpp index cf33f255e15..93ea871eb55 100644 --- a/Core/include/Acts/Geometry/ProtoLayer.hpp +++ b/Core/include/Acts/Geometry/ProtoLayer.hpp @@ -11,7 +11,7 @@ #include "Acts/Geometry/Extent.hpp" #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Surfaces/Surface.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include #include @@ -79,24 +79,24 @@ struct ProtoLayer { ProtoLayer() = default; /// Get the parameters : min - /// @param bval The accessed binning value + /// @param aDir The accessed axis direction /// @param addenv The steering if enevlope is added or not - double min(BinningValue bval, bool addenv = true) const; + double min(AxisDirection aDir, bool addenv = true) const; // Get the parameters : max - /// @param bval The accessed binning value + /// @param aDir The accessed axis direction /// @param addenv The steering if enevlope is added or not - double max(BinningValue bval, bool addenv = true) const; + double max(AxisDirection aDir, bool addenv = true) const; // Get the parameters : max - /// @param bval The accessed binning value + /// @param aDir The accessed axis direction /// @param addenv The steering if enevlope is added or not - double medium(BinningValue bval, bool addenv = true) const; + double medium(AxisDirection aDir, bool addenv = true) const; // Get the parameters : max - /// @param bval The accessed binning value + /// @param aDir The accessed axis direction /// @param addenv The steering if enevlope is added or not - double range(BinningValue bval, bool addenv = true) const; + double range(AxisDirection aDir, bool addenv = true) const; /// Output to ostream /// @param sl the input ostream diff --git a/Core/include/Acts/Geometry/ProtoLayerHelper.hpp b/Core/include/Acts/Geometry/ProtoLayerHelper.hpp index 33ca14718b4..fe187954903 100644 --- a/Core/include/Acts/Geometry/ProtoLayerHelper.hpp +++ b/Core/include/Acts/Geometry/ProtoLayerHelper.hpp @@ -10,7 +10,7 @@ #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/ProtoLayer.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Logger.hpp" #include @@ -30,7 +30,7 @@ struct ProtoLayer; /// @todo write more documentation on how this is done class ProtoLayerHelper { public: - using SortingConfig = std::pair; + using SortingConfig = std::pair; struct Config {}; diff --git a/Core/include/Acts/Geometry/SurfaceArrayCreator.hpp b/Core/include/Acts/Geometry/SurfaceArrayCreator.hpp index 9906fda7939..a1076f8c6ba 100644 --- a/Core/include/Acts/Geometry/SurfaceArrayCreator.hpp +++ b/Core/include/Acts/Geometry/SurfaceArrayCreator.hpp @@ -14,7 +14,7 @@ #include "Acts/Geometry/ProtoLayer.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Surfaces/SurfaceArray.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/BinningType.hpp" #include "Acts/Utilities/Logger.hpp" @@ -36,8 +36,9 @@ namespace Test { struct SurfaceArrayCreatorFixture; } -using SurfaceMatcher = std::function; +using SurfaceMatcher = + std::function; using SurfaceVector = std::vector; using SurfaceMatrix = std::vector; @@ -59,7 +60,7 @@ class SurfaceArrayCreator { struct ProtoAxis { BinningType bType = BinningType::equidistant; - BinningValue bValue = BinningValue::binX; + AxisDirection axisDir = AxisDirection::AxisX; std::size_t nBins = 0; AxisScalar min = 0; AxisScalar max = 0; @@ -216,10 +217,10 @@ class SurfaceArrayCreator { /// @warning This function requires the plane aligned with either the x-, y- /// or z-axis /// @param [in] bins1 is the number of bins in the orthogonal direction to @p - /// bValue + /// aDir /// @param [in] bins2 is the number of bins in the orthogonal direction to @p - /// bValue - /// @param [in] bValue Direction of the aligned surfaces + /// aDir + /// @param [in] aDir Direction of the aligned surfaces /// @param [in] protoLayerOpt Optional @c ProtoLayer instance /// @param [in] transform is the (optional) additional transform applied /// @@ -227,26 +228,26 @@ class SurfaceArrayCreator { std::unique_ptr surfaceArrayOnPlane( const GeometryContext& gctx, std::vector> surfaces, std::size_t bins1, - std::size_t bins2, BinningValue bValue, + std::size_t bins2, AxisDirection aDir, std::optional protoLayerOpt = std::nullopt, const Transform3& transform = Transform3::Identity()) const; /// Static check function for surface equivalent /// /// @param [in] gctx the geometry context for this check - /// @param bValue the binning value for the binning + /// @param aDir the axis direction for the binning /// @param a first surface for checking /// @param b second surface for checking static bool isSurfaceEquivalent(const GeometryContext& gctx, - BinningValue bValue, const Surface* a, + AxisDirection aDir, const Surface* a, const Surface* b) { using namespace UnitLiterals; using VectorHelpers::perp; - if (bValue == Acts::BinningValue::binPhi) { + if (aDir == Acts::AxisDirection::AxisPhi) { // Take the two binning positions - auto pos1 = a->binningPosition(gctx, BinningValue::binR), - pos2 = b->binningPosition(gctx, BinningValue::binR); + Vector3 pos1 = a->referencePosition(gctx, AxisDirection::AxisR); + Vector3 pos2 = b->referencePosition(gctx, AxisDirection::AxisR); // Project them on the (x, y) plane, where Phi angles are calculated auto proj1 = pos1.head<2>(), proj2 = pos2.head<2>(); @@ -261,15 +262,15 @@ class SurfaceArrayCreator { return std::abs(dPhi) < std::numbers::pi / 180.; } - if (bValue == Acts::BinningValue::binZ) { - return (std::abs(a->binningPosition(gctx, BinningValue::binR).z() - - b->binningPosition(gctx, BinningValue::binR).z()) < + if (aDir == Acts::AxisDirection::AxisZ) { + return (std::abs(a->referencePosition(gctx, AxisDirection::AxisR).z() - + b->referencePosition(gctx, AxisDirection::AxisR).z()) < 1_um); } - if (bValue == Acts::BinningValue::binR) { - return (std::abs(perp(a->binningPosition(gctx, BinningValue::binR)) - - perp(b->binningPosition(gctx, BinningValue::binR))) < + if (aDir == Acts::AxisDirection::AxisR) { + return (std::abs(perp(a->referencePosition(gctx, AxisDirection::AxisR)) - + perp(b->referencePosition(gctx, AxisDirection::AxisR))) < 1_um); } @@ -295,7 +296,7 @@ class SurfaceArrayCreator { std::size_t determineBinCount(const GeometryContext& gctx, const std::vector& surfaces, - BinningValue bValue) const; + AxisDirection aDir) const; /// SurfaceArrayCreator internal method /// Creates a variable @c ProtoAxis from a vector of (unsorted) surfaces with @@ -311,8 +312,8 @@ class SurfaceArrayCreator { /// @todo implement for x,y binning /// @param [in] gctx the geometry context for this call /// @param surfaces are the sensitive surfaces to be - /// @param bValue the BinningValue in which direction should be binned - /// (currently possible: binPhi, binR, binZ) + /// @param aDir the AxisDirection in which direction should be binned + /// (currently possible: AxisPhi, AxisR, AxisZ) /// @param protoLayer Instance of @c ProtoLayer holding generic layer info /// @param transform is the (optional) additional transform applied /// @return Instance of @c ProtoAxis containing determined properties @@ -320,8 +321,7 @@ class SurfaceArrayCreator { /// into an actual @c Axis object to be used ProtoAxis createVariableAxis(const GeometryContext& gctx, const std::vector& surfaces, - BinningValue bValue, - const ProtoLayer& protoLayer, + AxisDirection aDir, const ProtoLayer& protoLayer, Transform3& transform) const; /// SurfaceArrayCreator internal method @@ -338,8 +338,8 @@ class SurfaceArrayCreator { /// @todo implement for x,y binning /// @param [in] gctx the geometry context for this call /// @param surfaces are the sensitive surfaces to be - /// @param bValue the BinningValue in which direction should be binned - /// (currently possible: binPhi, binR, binZ) + /// @param aDir the AxisDirection in which direction should be binned + /// (currently possible: AxisPhi, AxisR, AxisZ) /// @param protoLayer Instance of @c ProtoLayer holding generic layer info /// @param transform is the (optional) additional transform applied /// @param nBins Number of bins to use, 0 means determine automatically @@ -348,7 +348,7 @@ class SurfaceArrayCreator { /// into an actual @c Axis object to be used ProtoAxis createEquidistantAxis(const GeometryContext& gctx, const std::vector& surfaces, - BinningValue bValue, + AxisDirection aDir, const ProtoLayer& protoLayer, Transform3& transform, std::size_t nBins = 0) const; @@ -382,7 +382,7 @@ class SurfaceArrayCreator { using SGL = SurfaceArray::SurfaceGridLookup; ptr = std::make_unique( - globalToLocal, localToGlobal, std::pair{axisA, axisB}, std::vector{pAxisA.bValue, pAxisB.bValue}); + globalToLocal, localToGlobal, std::pair{axisA, axisB}, std::vector{pAxisA.axisDir, pAxisB.axisDir}); } else if (pAxisA.bType == equidistant && pAxisB.bType == arbitrary) { @@ -391,7 +391,7 @@ class SurfaceArrayCreator { using SGL = SurfaceArray::SurfaceGridLookup; ptr = std::make_unique( - globalToLocal, localToGlobal, std::pair{axisA, axisB}, std::vector{pAxisA.bValue, pAxisB.bValue}); + globalToLocal, localToGlobal, std::pair{axisA, axisB}, std::vector{pAxisA.axisDir, pAxisB.axisDir}); } else if (pAxisA.bType == arbitrary && pAxisB.bType == equidistant) { @@ -400,7 +400,7 @@ class SurfaceArrayCreator { using SGL = SurfaceArray::SurfaceGridLookup; ptr = std::make_unique( - globalToLocal, localToGlobal, std::pair{axisA, axisB}, std::vector{pAxisA.bValue, pAxisB.bValue}); + globalToLocal, localToGlobal, std::pair{axisA, axisB}, std::vector{pAxisA.axisDir, pAxisB.axisDir}); } else /*if (pAxisA.bType == arbitrary && pAxisB.bType == arbitrary)*/ { @@ -409,7 +409,7 @@ class SurfaceArrayCreator { using SGL = SurfaceArray::SurfaceGridLookup; ptr = std::make_unique( - globalToLocal, localToGlobal, std::pair{axisA, axisB}, std::vector{pAxisA.bValue, pAxisB.bValue}); + globalToLocal, localToGlobal, std::pair{axisA, axisB}, std::vector{pAxisA.axisDir, pAxisB.axisDir}); } // clang-format on diff --git a/Core/include/Acts/Geometry/SurfaceBinningMatcher.hpp b/Core/include/Acts/Geometry/SurfaceBinningMatcher.hpp index c15928ee1dc..3dae7b47932 100644 --- a/Core/include/Acts/Geometry/SurfaceBinningMatcher.hpp +++ b/Core/include/Acts/Geometry/SurfaceBinningMatcher.hpp @@ -20,7 +20,8 @@ namespace Acts { struct SurfaceBinningMatcher { /// The binning tolerance parameters using Range = std::pair; - std::vector tolerances{static_cast(numBinningValues()), {0., 0.}}; + std::vector tolerances{static_cast(numAxisDirections()), + {0., 0.}}; SurfaceBinningMatcher() = default; @@ -30,10 +31,10 @@ struct SurfaceBinningMatcher { /// Check function for surface equivalent /// /// @param gctx [in] gctx the geometry context for this check - /// @param bValue the binning value for the binning + /// @param aDir the axis direction value for the binning /// @param one first surface for checking /// @param other second surface for checking - bool operator()(const Acts::GeometryContext& gctx, Acts::BinningValue bValue, + bool operator()(const Acts::GeometryContext& gctx, Acts::AxisDirection aDir, const Acts::Surface* one, const Acts::Surface* other) const { // Fast exit if (one == other) { @@ -43,15 +44,15 @@ struct SurfaceBinningMatcher { auto oneExt = one->polyhedronRepresentation(gctx, 1).extent(); auto otherExt = other->polyhedronRepresentation(gctx, 1).extent(); - double oneMin = oneExt.min(bValue); - double oneMax = oneExt.max(bValue); + double oneMin = oneExt.min(aDir); + double oneMax = oneExt.max(aDir); - double otherMin = otherExt.min(bValue); - double otherMax = otherExt.max(bValue); + double otherMin = otherExt.min(aDir); + double otherMax = otherExt.max(aDir); return ( - std::abs(oneMin - otherMin) <= tolerances[toUnderlying(bValue)].first && - std::abs(oneMax - otherMax) <= tolerances[toUnderlying(bValue)].second); + std::abs(oneMin - otherMin) <= tolerances[toUnderlying(aDir)].first && + std::abs(oneMax - otherMax) <= tolerances[toUnderlying(aDir)].second); } }; diff --git a/Core/include/Acts/Geometry/TrackingVolumeArrayCreator.hpp b/Core/include/Acts/Geometry/TrackingVolumeArrayCreator.hpp index fe951f61dc0..be59b61e3ec 100644 --- a/Core/include/Acts/Geometry/TrackingVolumeArrayCreator.hpp +++ b/Core/include/Acts/Geometry/TrackingVolumeArrayCreator.hpp @@ -11,7 +11,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/ITrackingVolumeArrayCreator.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Logger.hpp" #include @@ -45,12 +45,12 @@ class TrackingVolumeArrayCreator : public ITrackingVolumeArrayCreator { /// /// @param [in] gctx the geometry context for this building /// @param [in] tVolumes is the vector of TrackingVolumes to be - /// @param [in] bValue is the binning value + /// @param [in] aDir is the axis direction /// /// @return new created volume array std::shared_ptr trackingVolumeArray( const GeometryContext& gctx, const TrackingVolumeVector& tVolumes, - BinningValue bValue) const override; + AxisDirection aDir) const override; /// Set logging instance /// diff --git a/Core/include/Acts/Geometry/TrivialPortalLink.hpp b/Core/include/Acts/Geometry/TrivialPortalLink.hpp index f68a7e326c6..8876696f5db 100644 --- a/Core/include/Acts/Geometry/TrivialPortalLink.hpp +++ b/Core/include/Acts/Geometry/TrivialPortalLink.hpp @@ -10,6 +10,7 @@ #include "Acts/Definitions/Tolerance.hpp" #include "Acts/Geometry/PortalLinkBase.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" namespace Acts { @@ -29,9 +30,9 @@ class TrivialPortalLink final : public PortalLinkBase { /// Make a 1D grid portal link from this trivial portal link /// The grid size is automatically determined from the surface bounds. - /// @param direction The binning direction + /// @param direction The axis direction of the grid /// @return A grid - std::unique_ptr makeGrid(BinningValue direction) const; + std::unique_ptr makeGrid(AxisDirection direction) const; /// Print the portal link to a stream /// @param os output stream diff --git a/Core/include/Acts/Geometry/Volume.hpp b/Core/include/Acts/Geometry/Volume.hpp index 92085819676..0d10cfa977b 100644 --- a/Core/include/Acts/Geometry/Volume.hpp +++ b/Core/include/Acts/Geometry/Volume.hpp @@ -11,7 +11,6 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/GeometryObject.hpp" -#include "Acts/Utilities/BinningType.hpp" #include "Acts/Utilities/BoundingBox.hpp" #include "Acts/Utilities/Logger.hpp" @@ -112,11 +111,10 @@ class Volume : public GeometryObject { /// - as default the center is given, but may be overloaded /// /// @param gctx The current geometry context object, e.g. alignment - /// @param bValue is the binning value schema - /// + /// @param aDir is the axis direction for the reference position /// @return vector 3D that can be used for the binning - Vector3 binningPosition(const GeometryContext& gctx, - BinningValue bValue) const override; + Vector3 referencePosition(const GeometryContext& gctx, + AxisDirection aDir) const override; bool operator==(const Volume& other) const; diff --git a/Core/include/Acts/Geometry/VolumeAttachmentStrategy.hpp b/Core/include/Acts/Geometry/VolumeAttachmentStrategy.hpp new file mode 100644 index 00000000000..68af1b14026 --- /dev/null +++ b/Core/include/Acts/Geometry/VolumeAttachmentStrategy.hpp @@ -0,0 +1,32 @@ +// 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 + +namespace Acts { + +/// The attachment strategy defines how the volumes are attached +/// Attachment always happens pair-wise +enum class VolumeAttachmentStrategy { + /// Given two volumes, the *left* one, i.e. the one with the lower **local** + /// x, y, or z value is extended + First, + /// Given two volumes, the *right* one, i.e. the one with the higher + /// **local** x, y, or z value is extended + Second, + /// Given two volumes, the *midpoint* between the two volumes is found + Midpoint, + /// A gap volume is created to fit between the two volumes + Gap, +}; + +std::ostream& operator<<(std::ostream& os, VolumeAttachmentStrategy strategy); + +} // namespace Acts diff --git a/Core/include/Acts/Geometry/VolumeBounds.hpp b/Core/include/Acts/Geometry/VolumeBounds.hpp index 28bcc029166..8611a120541 100644 --- a/Core/include/Acts/Geometry/VolumeBounds.hpp +++ b/Core/include/Acts/Geometry/VolumeBounds.hpp @@ -12,7 +12,7 @@ #include "Acts/Definitions/Direction.hpp" #include "Acts/Geometry/Volume.hpp" #include "Acts/Surfaces/RegularSurface.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include #include @@ -29,7 +29,7 @@ class Direction; struct OrientedSurface { std::shared_ptr surface; - Direction direction; + Direction direction = Direction::AlongNormal(); }; // Planar definitions to help construct the boundary surfaces @@ -121,32 +121,32 @@ class VolumeBounds { const Transform3* trf = nullptr, const Vector3& envelope = {0, 0, 0}, const Volume* entity = nullptr) const = 0; - /// Get the canonical binning values, i.e. the binning values - /// for that fully describe the shape's extent + /// Get the canonical axis direction + /// that fully describe the shape's extent /// - /// @return vector of canonical binning values + /// @return vector of canonical axis directions /// /// @note This is the default implementation that /// returns the bounding box binning. Individual shapes /// should override this method - virtual std::vector canonicalBinning() const { - return {Acts::BinningValue::binX, Acts::BinningValue::binY, - Acts::BinningValue::binZ}; + virtual std::vector canonicalAxes() const { + using enum AxisDirection; + return {AxisX, AxisY, AxisZ}; }; /// Binning offset - overloaded for some R-binning types /// - /// @param bValue is the binning schema used + /// @param aDir is the binning schema used /// /// @return vector 3D to be used for the binning - virtual Vector3 binningOffset(BinningValue bValue) const; + virtual Vector3 referenceOffset(AxisDirection aDir) const; /// Binning borders in double /// - /// @param bValue is the binning schema used + /// @param aDir is the binning schema used /// /// @return float offset to be used for the binning - virtual double binningBorder(BinningValue bValue) const; + virtual double referenceBorder(AxisDirection aDir) const; /// Output Method for std::ostream, to be overloaded by child classes /// @@ -155,12 +155,12 @@ class VolumeBounds { }; /// Binning offset - overloaded for some R-binning types -inline Vector3 VolumeBounds::binningOffset( - BinningValue /*bValue*/) const { // standard offset is 0.,0.,0. +inline Vector3 VolumeBounds::referenceOffset( + AxisDirection /*aDir*/) const { // standard offset is 0.,0.,0. return Vector3(0., 0., 0.); } -inline double VolumeBounds::binningBorder(BinningValue /*bValue*/) const { +inline double VolumeBounds::referenceBorder(AxisDirection /*aDir*/) const { return 0.; } diff --git a/Core/include/Acts/Geometry/VolumeResizeStrategy.hpp b/Core/include/Acts/Geometry/VolumeResizeStrategy.hpp new file mode 100644 index 00000000000..3124de68b6c --- /dev/null +++ b/Core/include/Acts/Geometry/VolumeResizeStrategy.hpp @@ -0,0 +1,25 @@ +// 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 + +namespace Acts { + +/// The resize strategy defines how the volumes are resized +enum class VolumeResizeStrategy { + /// Extend the volume connected to the respective edge to fit the new bounds + Expand, + /// Create a gap volume at the respective edge to fit the new bounds + Gap, +}; + +std::ostream& operator<<(std::ostream& os, VolumeResizeStrategy strategy); + +} // namespace Acts diff --git a/Core/include/Acts/MagneticField/BFieldMapUtils.hpp b/Core/include/Acts/MagneticField/BFieldMapUtils.hpp index ff46acfa78e..ec3d7f0e701 100644 --- a/Core/include/Acts/MagneticField/BFieldMapUtils.hpp +++ b/Core/include/Acts/MagneticField/BFieldMapUtils.hpp @@ -11,7 +11,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/Units.hpp" #include "Acts/MagneticField/InterpolatedBFieldMap.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Grid.hpp" #include diff --git a/Core/include/Acts/Material/ISurfaceMaterial.hpp b/Core/include/Acts/Material/ISurfaceMaterial.hpp index cad6832441a..734930cca40 100644 --- a/Core/include/Acts/Material/ISurfaceMaterial.hpp +++ b/Core/include/Acts/Material/ISurfaceMaterial.hpp @@ -137,9 +137,9 @@ inline double ISurfaceMaterial::factor(Direction pDir, if (mStage == Acts::MaterialUpdateStage::FullUpdate) { return 1.; } else if (mStage == Acts::MaterialUpdateStage::PreUpdate) { - return pDir == Direction::Negative ? m_splitFactor : 1 - m_splitFactor; + return pDir == Direction::Negative() ? m_splitFactor : 1 - m_splitFactor; } else /*if (mStage == Acts::MaterialUpdateStage::PostUpdate)*/ { - return pDir == Direction::Positive ? m_splitFactor : 1 - m_splitFactor; + return pDir == Direction::Positive() ? m_splitFactor : 1 - m_splitFactor; } } diff --git a/Core/include/Acts/Material/MaterialGridHelper.hpp b/Core/include/Acts/Material/MaterialGridHelper.hpp index 0f68a86c3b3..955a9245e73 100644 --- a/Core/include/Acts/Material/MaterialGridHelper.hpp +++ b/Core/include/Acts/Material/MaterialGridHelper.hpp @@ -12,7 +12,7 @@ #include "Acts/Material/AccumulatedVolumeMaterial.hpp" #include "Acts/Material/Material.hpp" #include "Acts/Utilities/Axis.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/BinUtility.hpp" #include "Acts/Utilities/BinningType.hpp" #include "Acts/Utilities/Grid.hpp" @@ -71,7 +71,7 @@ Grid3D createGrid(MaterialGridAxisData gridAxis1, /// /// @return a coordinate transform function std::function globalToLocalFromBin( - Acts::BinningValue& type); + Acts::AxisDirection& type); /// @brief Create a 2DGrid using a BinUtility. /// Also determine the corresponding global to local transform and grid mapping diff --git a/Core/include/Acts/Material/MaterialMapUtils.hpp b/Core/include/Acts/Material/MaterialMapUtils.hpp index 8cacb23eb20..16523c03f70 100644 --- a/Core/include/Acts/Material/MaterialMapUtils.hpp +++ b/Core/include/Acts/Material/MaterialMapUtils.hpp @@ -12,7 +12,7 @@ #include "Acts/Definitions/Units.hpp" #include "Acts/Material/InterpolatedMaterialMap.hpp" #include "Acts/Material/Material.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Grid.hpp" #include diff --git a/Core/include/Acts/Navigation/DetectorNavigator.hpp b/Core/include/Acts/Navigation/DetectorNavigator.hpp index 56f588dfb47..8ba5a1b4000 100644 --- a/Core/include/Acts/Navigation/DetectorNavigator.hpp +++ b/Core/include/Acts/Navigation/DetectorNavigator.hpp @@ -14,6 +14,7 @@ #include "Acts/Geometry/GeometryIdentifier.hpp" #include "Acts/Geometry/Layer.hpp" #include "Acts/Navigation/NavigationState.hpp" +#include "Acts/Propagator/NavigationTarget.hpp" #include "Acts/Propagator/NavigatorOptions.hpp" #include "Acts/Propagator/NavigatorStatistics.hpp" #include "Acts/Surfaces/BoundaryTolerance.hpp" @@ -45,6 +46,9 @@ class DetectorNavigator { }; struct Options : public NavigatorPlainOptions { + explicit Options(const GeometryContext& gctx) + : NavigatorPlainOptions(gctx) {} + void setPlainOptions(const NavigatorPlainOptions& options) { static_cast(*this) = options; } @@ -56,12 +60,12 @@ class DetectorNavigator { /// created for every propagation/extrapolation step /// and keep thread-local navigation information struct State : public NavigationState { + explicit State(const Options& options_) : options(options_) {} + Options options; /// Navigation state - external state: the current surface const Surface* currentSurface = nullptr; - /// Indicator if the target is reached - bool targetReached = false; /// Navigation state : a break has been detected bool navigationBreak = false; @@ -80,8 +84,7 @@ class DetectorNavigator { : m_cfg{cfg}, m_logger{std::move(_logger)} {} State makeState(const Options& options) const { - State state; - state.options = options; + State state(options); return state; } @@ -105,8 +108,6 @@ class DetectorNavigator { return state.options.targetSurface; } - bool targetReached(const State& state) const { return state.targetReached; } - bool endOfWorldReached(State& state) const { return state.currentVolume == nullptr; } @@ -115,147 +116,109 @@ class DetectorNavigator { return state.navigationBreak; } - void currentSurface(State& state, const Surface* surface) const { - state.currentSurface = surface; - } - - void targetReached(State& state, bool targetReached) const { - state.targetReached = targetReached; - } - - void navigationBreak(State& state, bool navigationBreak) const { - state.navigationBreak = navigationBreak; - } + void initialize(State& state, const Vector3& position, + const Vector3& direction, + Direction propagationDirection) const { + (void)propagationDirection; - /// Initialize call - start of propagation - /// - /// @tparam propagator_state_t The state type of the propagator - /// @tparam stepper_t The type of stepper used for the propagation - /// - /// @param [in,out] state is the propagation state object - /// @param [in] stepper Stepper in use - /// - /// @return boolean return triggers exit to stepper - template - void initialize(propagator_state_t& state, const stepper_t& stepper) const { - ACTS_VERBOSE(volInfo(state) << posInfo(state, stepper) << "initialize"); + ACTS_VERBOSE(volInfo(state) << posInfo(state, position) << "initialize"); - auto& nState = state.navigation; - - if (nState.currentDetector == nullptr) { + if (state.currentDetector == nullptr) { ACTS_VERBOSE("Assigning detector from the config."); - nState.currentDetector = m_cfg.detector; + state.currentDetector = m_cfg.detector; } - if (nState.currentDetector == nullptr) { + if (state.currentDetector == nullptr) { throw std::invalid_argument("DetectorNavigator: no detector assigned"); } - fillNavigationState(state, stepper, nState); - if (nState.currentVolume == nullptr) { - nState.currentVolume = nState.currentDetector->findDetectorVolume( - state.geoContext, nState.position); + fillNavigationState(position, direction, state); + if (state.currentVolume == nullptr) { + state.currentVolume = state.currentDetector->findDetectorVolume( + state.options.geoContext, state.position); } - if (nState.currentVolume == nullptr) { + if (state.currentVolume == nullptr) { throw std::invalid_argument("DetectorNavigator: no current volume found"); } - updateCandidateSurfaces(state, stepper); + updateCandidateSurfaces(state, position); } - /// @brief Navigator pre step call - /// - /// This will invalid the current surface and current portal in order - /// to navigate to the next ones. - /// - /// @tparam propagator_state_t is the type of Propagatgor state - /// @tparam stepper_t is the used type of the Stepper by the Propagator - /// - /// @param [in,out] state is the mutable propagator state object - /// @param [in] stepper Stepper in use - template - void preStep(propagator_state_t& state, const stepper_t& stepper) const { + NavigationTarget nextTarget(State& state, const Vector3& position, + const Vector3& direction) const { ACTS_VERBOSE(volInfo(state) - << posInfo(state, stepper) << "Entering navigator::preStep."); + << posInfo(state, position) << "Entering navigator::preStep."); if (inactive()) { ACTS_VERBOSE(volInfo(state) - << posInfo(state, stepper) << "navigator inactive"); - return; + << posInfo(state, position) << "navigator inactive"); + return NavigationTarget::None(); } - auto& nState = state.navigation; - fillNavigationState(state, stepper, nState); + fillNavigationState(position, direction, state); - if (nState.currentSurface != nullptr) { + if (state.currentSurface != nullptr) { ACTS_VERBOSE(volInfo(state) - << posInfo(state, stepper) << "stepping through surface"); + << posInfo(state, position) << "stepping through surface"); } - for (; nState.surfaceCandidateIndex != nState.surfaceCandidates.size(); - ++nState.surfaceCandidateIndex) { - // Screen output how much is left to try - ACTS_VERBOSE(volInfo(state) - << posInfo(state, stepper) - << (nState.surfaceCandidates.size() - - nState.surfaceCandidateIndex) - << " out of " << nState.surfaceCandidates.size() - << " surfaces remain to try."); - // Take the surface - const auto& c = nState.surfaceCandidate(); - const auto& surface = - (c.surface != nullptr) ? (*c.surface) : (c.portal->surface()); - // Screen output which surface you are on + if (state.surfaceCandidateIndex == state.surfaceCandidates.size()) { ACTS_VERBOSE(volInfo(state) - << posInfo(state, stepper) - << "next surface candidate will be " << surface.geometryId() - << " (" << surface.center(state.geoContext).transpose() - << ")"); - // Estimate the surface status - auto surfaceStatus = stepper.updateSurfaceStatus( - state.stepping, surface, c.objectIntersection.index(), - state.options.direction, c.boundaryTolerance, - state.options.surfaceTolerance, logger()); - - ACTS_VERBOSE(volInfo(state) << posInfo(state, stepper) - << "surface status is " << surfaceStatus); - - if (surfaceStatus == IntersectionStatus::reachable) { - ACTS_VERBOSE(volInfo(state) - << posInfo(state, stepper) << "surface " - << surface.center(state.geoContext).transpose() - << " is reachable, step size updated to " - << stepper.outputStepSize(state.stepping)); - break; - } + << posInfo(state, position) << "no surface candidates"); + return NavigationTarget::None(); } - nState.currentSurface = nullptr; - nState.currentPortal = nullptr; + // Screen output how much is left to try + ACTS_VERBOSE(volInfo(state) << posInfo(state, position) + << (state.surfaceCandidates.size() - + state.surfaceCandidateIndex) + << " out of " << state.surfaceCandidates.size() + << " surfaces remain to try."); + // Take the surface + const auto& candidate = state.surfaceCandidate(); + const auto& surface = (candidate.surface != nullptr) + ? (*candidate.surface) + : (candidate.portal->surface()); + // Screen output which surface you are on + ACTS_VERBOSE(volInfo(state) + << posInfo(state, position) + << "next surface candidate will be " << surface.geometryId() + << " (" << surface.center(state.options.geoContext).transpose() + << ")"); + + state.currentSurface = nullptr; + state.currentPortal = nullptr; + + return NavigationTarget(surface, candidate.objectIntersection.index(), + candidate.boundaryTolerance); } - /// @brief Navigator post step call - /// - /// @tparam propagator_state_t is the type of Propagatgor state - /// @tparam stepper_t is the used type of the Stepper by the Propagator - /// - /// @param [in,out] state is the mutable propagator state object - /// @param [in] stepper Stepper in use - template - void postStep(propagator_state_t& state, const stepper_t& stepper) const { - ACTS_VERBOSE(volInfo(state) - << posInfo(state, stepper) << "Entering navigator::postStep."); + bool checkTargetValid(const State& state, const Vector3& position, + const Vector3& direction) const { + (void)state; + (void)position; + (void)direction; + + return true; + } + + void handleSurfaceReached(State& state, const Vector3& position, + const Vector3& direction, + const Surface& surface) const { + (void)surface; - auto& nState = state.navigation; - fillNavigationState(state, stepper, nState); + ACTS_VERBOSE(volInfo(state) << posInfo(state, position) + << "Entering navigator::handleSurfaceReached."); + + fillNavigationState(position, direction, state); if (inactive()) { ACTS_VERBOSE(volInfo(state) - << posInfo(state, stepper) << "navigator inactive"); + << posInfo(state, position) << "navigator inactive"); return; } - if (nState.surfaceCandidateIndex == nState.surfaceCandidates.size()) { + if (state.surfaceCandidateIndex == state.surfaceCandidates.size()) { ACTS_VERBOSE(volInfo(state) - << posInfo(state, stepper) + << posInfo(state, position) << "no surface candidates - waiting for target call"); return; } @@ -263,74 +226,62 @@ class DetectorNavigator { const Portal* nextPortal = nullptr; const Surface* nextSurface = nullptr; bool isPortal = false; - BoundaryTolerance boundaryTolerance = - nState.surfaceCandidate().boundaryTolerance; - if (nState.surfaceCandidate().surface != nullptr) { - nextSurface = nState.surfaceCandidate().surface; - } else if (nState.surfaceCandidate().portal != nullptr) { - nextPortal = nState.surfaceCandidate().portal; + if (state.surfaceCandidate().surface != nullptr) { + nextSurface = state.surfaceCandidate().surface; + } else if (state.surfaceCandidate().portal != nullptr) { + nextPortal = state.surfaceCandidate().portal; nextSurface = &nextPortal->surface(); isPortal = true; } else { std::string msg = "DetectorNavigator: " + volInfo(state) + - posInfo(state, stepper) + + posInfo(state, position) + "panic: not a surface not a portal - what is it?"; throw std::runtime_error(msg); } - // TODO not sure about the boundary check - auto surfaceStatus = stepper.updateSurfaceStatus( - state.stepping, *nextSurface, - nState.surfaceCandidate().objectIntersection.index(), - state.options.direction, boundaryTolerance, - state.options.surfaceTolerance, logger()); + ACTS_VERBOSE(volInfo(state) + << posInfo(state, position) << "landed on surface"); - // Check if we are at a surface - if (surfaceStatus == IntersectionStatus::onSurface) { + if (isPortal) { ACTS_VERBOSE(volInfo(state) - << posInfo(state, stepper) << "landed on surface"); - - if (isPortal) { + << posInfo(state, position) + << "this is a portal, updating to new volume."); + state.currentPortal = nextPortal; + state.currentSurface = &nextPortal->surface(); + state.surfaceCandidates.clear(); + state.surfaceCandidateIndex = 0; + + state.currentPortal->updateDetectorVolume(state.options.geoContext, + state); + + // If no Volume is found, we are at the end of the world + if (state.currentVolume == nullptr) { ACTS_VERBOSE(volInfo(state) - << posInfo(state, stepper) - << "this is a portal, updating to new volume."); - nState.currentPortal = nextPortal; - nState.currentSurface = &nextPortal->surface(); - nState.surfaceCandidates.clear(); - nState.surfaceCandidateIndex = 0; - - nState.currentPortal->updateDetectorVolume(state.geoContext, nState); - - // If no Volume is found, we are at the end of the world - if (nState.currentVolume == nullptr) { - ACTS_VERBOSE(volInfo(state) - << posInfo(state, stepper) - << "no volume after Portal update, end of world."); - nState.navigationBreak = true; - return; - } - - // Switched to a new volume - // Update candidate surfaces - updateCandidateSurfaces(state, stepper); + << posInfo(state, position) + << "no volume after Portal update, end of world."); + state.navigationBreak = true; + return; + } - ACTS_VERBOSE(volInfo(state) - << posInfo(state, stepper) << "current portal set to " - << nState.currentPortal->surface().geometryId()); + // Switched to a new volume + // Update candidate surfaces + updateCandidateSurfaces(state, position); - } else { - ACTS_VERBOSE(volInfo(state) << posInfo(state, stepper) - << "this is a surface, storing it."); + ACTS_VERBOSE(volInfo(state) + << posInfo(state, position) << "current portal set to " + << state.currentPortal->surface().geometryId()); + } else { + ACTS_VERBOSE(volInfo(state) << posInfo(state, position) + << "this is a surface, storing it."); - // If we are on the surface pointed at by the iterator, we can make - // it the current one to pass it to the other actors - nState.currentSurface = nextSurface; - ACTS_VERBOSE(volInfo(state) - << posInfo(state, stepper) << "current surface set to " - << nState.currentSurface->geometryId()); - ++nState.surfaceCandidateIndex; - } + // If we are on the surface pointed at by the iterator, we can make + // it the current one to pass it to the other actors + state.currentSurface = nextSurface; + ACTS_VERBOSE(volInfo(state) + << posInfo(state, position) << "current surface set to " + << state.currentSurface->geometryId()); + ++state.surfaceCandidateIndex; } } @@ -339,19 +290,15 @@ class DetectorNavigator { std::shared_ptr m_logger; - template - std::string volInfo(const propagator_state_t& state) const { - auto& nState = state.navigation; - - return (nState.currentVolume ? nState.currentVolume->name() : "No Volume") + + std::string volInfo(const State& state) const { + return (state.currentVolume != nullptr ? state.currentVolume->name() + : "No Volume") + " | "; } - template - std::string posInfo(const propagator_state_t& state, - const stepper_t& stepper) const { + std::string posInfo(const State& /*state*/, const Vector3& position) const { std::stringstream ss; - ss << stepper.position(state.stepping).transpose(); + ss << position.transpose(); ss << " | "; return ss.str(); } @@ -361,7 +308,7 @@ class DetectorNavigator { /// This checks if a navigation break had been triggered or navigator /// is misconfigured /// - /// boolean return triggers exit to stepper + /// @return true if the navigator is inactive bool inactive() const { if (m_cfg.detector == nullptr) { return true; @@ -385,48 +332,28 @@ class DetectorNavigator { /// - attempted volume switch /// Target finding by association will not be done again /// - /// @tparam propagator_state_t The state type of the propagator - /// @tparam stepper_t The type of stepper used for the propagation - /// /// @param [in,out] state is the propagation state object - /// @param [in] stepper Stepper in use - /// - /// boolean return triggers exit to stepper - template - void updateCandidateSurfaces(propagator_state_t& state, - const stepper_t& stepper) const { + /// @param [in] position is the current position + void updateCandidateSurfaces(State& state, const Vector3& position) const { ACTS_VERBOSE(volInfo(state) - << posInfo(state, stepper) << "initialize target"); - - auto& nState = state.navigation; + << posInfo(state, position) << "initialize target"); // Here we get the candidate surfaces - nState.currentVolume->updateNavigationState(state.geoContext, nState); + state.currentVolume->updateNavigationState(state.options.geoContext, state); // Sort properly the surface candidates - auto& nCandidates = nState.surfaceCandidates; + auto& nCandidates = state.surfaceCandidates; std::ranges::sort(nCandidates, {}, [](const auto& c) { return c.objectIntersection.pathLength(); }); // Set the surface candidate - nState.surfaceCandidateIndex = 0; + state.surfaceCandidateIndex = 0; } - template - void fillNavigationState(propagator_state_t& state, const stepper_t& stepper, - NavigationState& nState) const { - nState.position = stepper.position(state.stepping); - nState.direction = - state.options.direction * stepper.direction(state.stepping); - nState.absMomentum = stepper.absoluteMomentum(state.stepping); - auto fieldResult = stepper.getField(state.stepping, nState.position); - if (!fieldResult.ok()) { - std::string msg = "DetectorNavigator: " + volInfo(state) + - posInfo(state, stepper) + - "could not read from the magnetic field"; - throw std::runtime_error(msg); - } - nState.magneticField = *fieldResult; + void fillNavigationState(const Vector3& position, const Vector3& direction, + State& state) const { + state.position = position; + state.direction = direction; } }; diff --git a/Core/include/Acts/Navigation/MultiLayerNavigation.hpp b/Core/include/Acts/Navigation/MultiLayerNavigation.hpp index 7a56086971a..82dc94f7eb3 100644 --- a/Core/include/Acts/Navigation/MultiLayerNavigation.hpp +++ b/Core/include/Acts/Navigation/MultiLayerNavigation.hpp @@ -12,6 +12,7 @@ #include "Acts/Navigation/NavigationDelegates.hpp" #include "Acts/Navigation/NavigationStateFillers.hpp" #include "Acts/Navigation/NavigationStateUpdaters.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/VectorHelpers.hpp" #include @@ -34,7 +35,7 @@ class MultiLayerNavigation : public IInternalNavigation { path_generator pgenerator; /// These are the cast parameters - copied from constructor - std::array casts{}; + std::array casts{}; /// An inverse transform to be applied to the position Transform3 transform = Transform3::Identity(); @@ -44,7 +45,7 @@ class MultiLayerNavigation : public IInternalNavigation { /// @param icasts is the cast values array /// @param itr a transform applied to the global position MultiLayerNavigation(grid_type igrid, - const std::array& icasts, + const std::array& icasts, const Transform3& itr = Transform3::Identity()) : grid(std::move(igrid)), casts(icasts), transform(itr) {} diff --git a/Core/include/Acts/Navigation/NavigationState.hpp b/Core/include/Acts/Navigation/NavigationState.hpp index 0e0d8e5af9c..e2a7cb96bae 100644 --- a/Core/include/Acts/Navigation/NavigationState.hpp +++ b/Core/include/Acts/Navigation/NavigationState.hpp @@ -10,9 +10,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/Units.hpp" -#include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Surfaces/BoundaryTolerance.hpp" -#include "Acts/Utilities/Delegate.hpp" #include "Acts/Utilities/Intersection.hpp" #include @@ -59,15 +57,6 @@ struct NavigationState { /// The current direction Vector3 direction = Vector3(0., 0., 0.); - /// The current absolute momentum - double absMomentum = 0.; - - /// The current absolute charge - double absCharge = 0.; - - /// The current magnetic field - Vector3 magneticField = Vector3(0., 0., 0.); - /// The current detector in processing const Detector* currentDetector = nullptr; diff --git a/Core/include/Acts/Navigation/NavigationStateUpdaters.hpp b/Core/include/Acts/Navigation/NavigationStateUpdaters.hpp index 83b7bfd5016..664c9c99166 100644 --- a/Core/include/Acts/Navigation/NavigationStateUpdaters.hpp +++ b/Core/include/Acts/Navigation/NavigationStateUpdaters.hpp @@ -14,7 +14,7 @@ #include "Acts/Navigation/NavigationDelegates.hpp" #include "Acts/Navigation/NavigationState.hpp" #include "Acts/Surfaces/Surface.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Enumerate.hpp" #include "Acts/Utilities/GridAccessHelpers.hpp" #include "Acts/Utilities/IAxis.hpp" @@ -195,7 +195,7 @@ class IndexedGridNavigation : public navigation_type { grid_type grid; /// These are the cast parameters - copied from constructor - std::array casts{}; + std::array casts{}; /// A transform to be applied to the position Transform3 transform = Transform3::Identity(); @@ -205,7 +205,7 @@ class IndexedGridNavigation : public navigation_type { /// @param icasts is the cast values array /// @param itr a transform applied to the global position IndexedGridNavigation(grid_type&& igrid, - const std::array& icasts, + const std::array& icasts, const Transform3& itr = Transform3::Identity()) : grid(std::move(igrid)), casts(icasts), transform(itr) {} diff --git a/Core/include/Acts/Navigation/PortalNavigation.hpp b/Core/include/Acts/Navigation/PortalNavigation.hpp index b810e179c69..b5ed5ca8a50 100644 --- a/Core/include/Acts/Navigation/PortalNavigation.hpp +++ b/Core/include/Acts/Navigation/PortalNavigation.hpp @@ -14,6 +14,7 @@ #include "Acts/Navigation/NavigationStateFillers.hpp" #include "Acts/Navigation/NavigationStateUpdaters.hpp" #include "Acts/Utilities/Axis.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Grid.hpp" #include @@ -86,7 +87,7 @@ struct BoundVolumesGrid1Navigation : public IExternalNavigation { /// @param cVolumes the contained volumes /// @param bTransform is the optional transform BoundVolumesGrid1Navigation( - const std::vector& gBoundaries, BinningValue bValue, + const std::vector& gBoundaries, AxisDirection bValue, const std::vector& cVolumes, const Transform3& bTransform = Transform3::Identity()) noexcept(false) : indexedUpdater(IndexedUpdater(VariableBoundIndexGrid1(std::make_tuple( diff --git a/Core/include/Acts/Propagator/AtlasStepper.hpp b/Core/include/Acts/Propagator/AtlasStepper.hpp index 0dd90197ef5..4a103bcaae5 100644 --- a/Core/include/Acts/Propagator/AtlasStepper.hpp +++ b/Core/include/Acts/Propagator/AtlasStepper.hpp @@ -28,10 +28,11 @@ #include -// This is based original stepper code from the ATLAS RungeKuttaPropagator namespace Acts { /// @brief the AtlasStepper implementation for the +/// +/// This is based original stepper code from the ATLAS RungeKuttaPropagator class AtlasStepper { public: using Jacobian = BoundMatrix; @@ -78,7 +79,7 @@ class AtlasStepper { bool needgradient = false; bool newfield = true; // internal parameters to be used - Vector3 field; + Vector3 field = Vector3::Zero(); std::array pVector{}; /// Storage pattern of pVector @@ -115,9 +116,6 @@ class AtlasStepper { // Previous step size for overstep estimation double previousStepSize = 0.; - /// The tolerance for the stepping - double tolerance = s_onSurfaceTolerance; - /// It caches the current magnetic field cell and stays (and interpolates) /// within as long as this is valid. See step() code for details. MagneticFieldProvider::Cache fieldCache; @@ -143,11 +141,13 @@ class AtlasStepper { const BoundTrackParameters& par) const { State state{options, m_bField->makeCache(options.magFieldContext)}; + state.particleHypothesis = par.particleHypothesis(); + // The rest of this constructor is copy&paste of AtlasStepper::update() - // this is a nasty but working solution for the stepper state without // functions - const auto pos = par.position(state.options.geoContext); + const auto pos = par.position(options.geoContext); const auto Vp = par.parameters(); double Sf = std::sin(Vp[eBoundPhi]); @@ -179,7 +179,7 @@ class AtlasStepper { state.covTransport = true; state.useJacobian = true; const auto transform = par.referenceSurface().referenceFrame( - state.options.geoContext, pos, par.direction()); + options.geoContext, pos, par.direction()); pVector[8] = transform(0, eBoundLoc0); pVector[16] = transform(0, eBoundLoc1); @@ -407,15 +407,16 @@ class AtlasStepper { /// @param [in] navDir The navigation direction /// @param [in] boundaryTolerance The boundary check for this status update /// @param [in] surfaceTolerance Surface tolerance used for intersection + /// @param [in] stype The step size type to be set /// @param [in] logger Logger instance to use IntersectionStatus updateSurfaceStatus( State& state, const Surface& surface, std::uint8_t index, Direction navDir, const BoundaryTolerance& boundaryTolerance, - double surfaceTolerance = s_onSurfaceTolerance, + double surfaceTolerance, ConstrainedStep::Type stype, const Logger& logger = getDummyLogger()) const { return detail::updateSingleSurfaceStatus( *this, state, surface, index, navDir, boundaryTolerance, - surfaceTolerance, logger); + surfaceTolerance, stype, logger); } /// Update step size @@ -425,11 +426,14 @@ class AtlasStepper { /// /// @param state [in,out] The stepping state (thread-local cache) /// @param oIntersection [in] The ObjectIntersection to layer, boundary, etc - /// @param release [in] boolean to trigger step size release + /// @param direction [in] The propagation direction + /// @param stype [in] The step size type to be set template void updateStepSize(State& state, const object_intersection_t& oIntersection, - Direction /*direction*/, bool release = true) const { - detail::updateSingleStepSize(state, oIntersection, release); + Direction direction, ConstrainedStep::Type stype) const { + (void)direction; + double stepSize = oIntersection.pathLength(); + updateStepSize(state, stepSize, stype); } /// Update step size - explicitly with a double @@ -437,19 +441,10 @@ class AtlasStepper { /// @param [in,out] state The stepping state (thread-local cache) /// @param [in] stepSize The step size value /// @param [in] stype The step size type to be set - /// @param release [in] Do we release the step size? void updateStepSize(State& state, double stepSize, - ConstrainedStep::Type stype, bool release = true) const { + ConstrainedStep::Type stype) const { state.previousStepSize = state.stepSize.value(); - state.stepSize.update(stepSize, stype, release); - } - - /// Get the step size - /// - /// @param state [in] The stepping state (thread-local cache) - /// @param stype [in] The step size type to be returned - double getStepSize(const State& state, ConstrainedStep::Type stype) const { - return state.stepSize.value(stype); + state.stepSize.update(stepSize, stype); } /// Release the Step size @@ -460,6 +455,14 @@ class AtlasStepper { state.stepSize.release(stype); } + /// Get the step size + /// + /// @param state [in] The stepping state (thread-local cache) + /// @param stype [in] The step size type to be returned + double getStepSize(const State& state, ConstrainedStep::Type stype) const { + return state.stepSize.value(stype); + } + /// Output the Step Size - single component /// /// @param [in,out] state The stepping state (thread-local cache) diff --git a/Core/include/Acts/Propagator/ConstrainedStep.hpp b/Core/include/Acts/Propagator/ConstrainedStep.hpp index 412f308bac9..bb2e0779115 100644 --- a/Core/include/Acts/Propagator/ConstrainedStep.hpp +++ b/Core/include/Acts/Propagator/ConstrainedStep.hpp @@ -8,7 +8,7 @@ #pragma once -#include "Acts/Definitions/Algebra.hpp" +#include "Acts/Utilities/Helpers.hpp" #include #include @@ -44,37 +44,37 @@ namespace Acts { class ConstrainedStep { public: /// the types of constraints - /// from actor - this would be a typical navigation step - /// from aborter - this would be a target condition - /// from user - this is user given for what reason ever - enum Type : int { actor = 0, aborter = 1, user = 2 }; + /// from navigator - this would be a navigation step + /// from actor - this would be an actor condition + /// from user - this is user given for what reason ever + enum class Type : int { Navigator = 0, Actor = 1, User = 2 }; constexpr ConstrainedStep() = default; /// constructor - /// @param value is the user given initial value - constexpr explicit ConstrainedStep(double value) { setUser(value); } + /// @param v is the user given initial value + constexpr explicit ConstrainedStep(double v) { setUser(v); } /// set accuracy /// /// this will set only the accuracy, as this is the most /// exposed to the Propagator /// - /// @param value is the new accuracy value - constexpr void setAccuracy(double value) { - assert(value > 0 && "ConstrainedStep accuracy must be > 0."); + /// @param v is the new accuracy value + constexpr void setAccuracy(double v) { + assert(v > 0 && "ConstrainedStep accuracy must be > 0."); // set the accuracy value - m_accuracy = value; + m_accuracy = v; } /// set user /// - /// @param value is the new user value - constexpr void setUser(double value) { + /// @param v is the new user value + constexpr void setUser(double v) { // TODO enable assert; see https://github.com/acts-project/acts/issues/2543 - // assert(value != 0 && "ConstrainedStep user must be != 0."); + // assert(v != 0 && "ConstrainedStep user must be != 0."); // set the user value - m_values[user] = value; + setValue(Type::User, v); } /// returns the min step size @@ -88,7 +88,9 @@ class ConstrainedStep { /// Access a specific value /// /// @param type is the requested parameter type - constexpr double value(Type type) const { return m_values[type]; } + constexpr double value(Type type) const { + return m_values[toUnderlying(type)]; + } /// Access the accuracy value constexpr double accuracy() const { return m_accuracy; } @@ -96,7 +98,7 @@ class ConstrainedStep { /// release a certain constraint value /// /// @param type is the constraint type to be released - constexpr void release(Type type) { m_values[type] = kNotSet; } + constexpr void release(Type type) { setValue(type, kNotSet); } /// release accuracy constexpr void releaseAccuracy() { m_accuracy = kNotSet; } @@ -106,42 +108,38 @@ class ConstrainedStep { /// Only navigation and target abortion step size /// updates may change the sign due to overstepping /// - /// @param value is the new value to be updated + /// @param v is the new value to be updated /// @param type is the constraint type - /// @param releaseStep Allow step size to increase again - constexpr void update(double value, Type type, bool releaseStep = false) { - if (releaseStep) { - release(type); - } + constexpr void update(double v, Type type) { // check the current value and set it if appropriate // this will also allow signed values due to overstepping - if (std::abs(value) < std::abs(m_values[type])) { + if (std::abs(v) < std::abs(value(type))) { // TODO enable assert; see // https://github.com/acts-project/acts/issues/2543 // assert(value != 0 && "ConstrainedStep user must be != 0."); - m_values[type] = value; + setValue(type, v); } } std::ostream& toStream(std::ostream& os) const { // Helper method to avoid unreadable screen output - auto streamValue = [&](double val) { + auto streamValue = [&](double v) { os << std::setw(5); - if (std::abs(val) == kNotSet) { - os << (val > 0 ? "+∞" : "-∞"); + if (std::abs(v) == kNotSet) { + os << (v > 0 ? "+∞" : "-∞"); } else { - os << val; + os << v; } }; os << "("; streamValue(m_accuracy); os << ", "; - streamValue(value(actor)); + streamValue(value(Type::Navigator)); os << ", "; - streamValue(value(aborter)); + streamValue(value(Type::Actor)); os << ", "; - streamValue(value(user)); + streamValue(value(Type::User)); os << ")"; return os; @@ -160,6 +158,10 @@ class ConstrainedStep { std::array m_values = {kNotSet, kNotSet, kNotSet}; /// the accuracy value - this can vary up and down given a good step estimator double m_accuracy = kNotSet; + + constexpr void setValue(Type type, double v) { + m_values[toUnderlying(type)] = v; + } }; inline std::ostream& operator<<(std::ostream& os, const ConstrainedStep& step) { diff --git a/Core/include/Acts/Propagator/EigenStepper.hpp b/Core/include/Acts/Propagator/EigenStepper.hpp index 1200636c5ad..5dd61626f3c 100644 --- a/Core/include/Acts/Propagator/EigenStepper.hpp +++ b/Core/include/Acts/Propagator/EigenStepper.hpp @@ -12,7 +12,6 @@ #include "Acts/Utilities/detail/ReferenceWrapperAnyCompat.hpp" #include "Acts/Definitions/Algebra.hpp" -#include "Acts/Definitions/Tolerance.hpp" #include "Acts/EventData/TrackParameters.hpp" #include "Acts/EventData/detail/CorrectedTransformationFreeToBound.hpp" #include "Acts/MagneticField/MagneticFieldProvider.hpp" @@ -22,6 +21,7 @@ #include "Acts/Propagator/StepperOptions.hpp" #include "Acts/Propagator/StepperStatistics.hpp" #include "Acts/Propagator/detail/SteppingHelper.hpp" +#include "Acts/Surfaces/Surface.hpp" #include "Acts/Utilities/Intersection.hpp" #include "Acts/Utilities/Result.hpp" @@ -72,7 +72,7 @@ class EigenStepper { struct State { /// Constructor from the initial bound track parameters /// - /// @param [in] optionsIn The stepper options + /// @param [in] optionsIn is the options object for the stepper /// @param [in] fieldCacheIn is the cache object for the magnetic field /// /// @note the covariance matrix is copied when needed @@ -239,15 +239,16 @@ class EigenStepper { /// @param [in] navDir The navigation direction /// @param [in] boundaryTolerance The boundary check for this status update /// @param [in] surfaceTolerance Surface tolerance used for intersection + /// @param [in] stype The step size type to be set /// @param [in] logger A @c Logger instance IntersectionStatus updateSurfaceStatus( State& state, const Surface& surface, std::uint8_t index, Direction navDir, const BoundaryTolerance& boundaryTolerance, - double surfaceTolerance = s_onSurfaceTolerance, + double surfaceTolerance, ConstrainedStep::Type stype, const Logger& logger = getDummyLogger()) const { return detail::updateSingleSurfaceStatus( *this, state, surface, index, navDir, boundaryTolerance, - surfaceTolerance, logger); + surfaceTolerance, stype, logger); } /// Update step size @@ -259,11 +260,14 @@ class EigenStepper { /// /// @param state [in,out] The stepping state (thread-local cache) /// @param oIntersection [in] The ObjectIntersection to layer, boundary, etc - /// @param release [in] boolean to trigger step size release + /// @param direction [in] The propagation direction + /// @param stype [in] The step size type to be set template void updateStepSize(State& state, const object_intersection_t& oIntersection, - Direction /*direction*/, bool release = true) const { - detail::updateSingleStepSize(state, oIntersection, release); + Direction direction, ConstrainedStep::Type stype) const { + (void)direction; + double stepSize = oIntersection.pathLength(); + updateStepSize(state, stepSize, stype); } /// Update step size - explicitly with a double @@ -271,11 +275,10 @@ class EigenStepper { /// @param state [in,out] The stepping state (thread-local cache) /// @param stepSize [in] The step size value /// @param stype [in] The step size type to be set - /// @param release [in] Do we release the step size? void updateStepSize(State& state, double stepSize, - ConstrainedStep::Type stype, bool release = true) const { + ConstrainedStep::Type stype) const { state.previousStepSize = state.stepSize.value(); - state.stepSize.update(stepSize, stype, release); + state.stepSize.update(stepSize, stype); } /// Get the step size diff --git a/Core/include/Acts/Propagator/MultiEigenStepperLoop.hpp b/Core/include/Acts/Propagator/MultiEigenStepperLoop.hpp index 4e481ea5d2d..6e1364a16e4 100644 --- a/Core/include/Acts/Propagator/MultiEigenStepperLoop.hpp +++ b/Core/include/Acts/Propagator/MultiEigenStepperLoop.hpp @@ -221,7 +221,7 @@ class MultiEigenStepperLoop : public EigenStepper { /// Constructor from the initial bound track parameters /// - /// @param [in] optionsIn The options for the stepper + /// @param [in] optionsIn is the options object for the stepper /// /// @note the covariance matrix is copied when needed explicit State(const Options& optionsIn) : options(optionsIn) {} @@ -499,11 +499,12 @@ class MultiEigenStepperLoop : public EigenStepper { /// @param [in] navDir The navigation direction /// @param [in] boundaryTolerance The boundary check for this status update /// @param [in] surfaceTolerance Surface tolerance used for intersection + /// @param [in] stype The step size type to be set /// @param [in] logger A @c Logger instance IntersectionStatus updateSurfaceStatus( State& state, const Surface& surface, std::uint8_t index, Direction navDir, const BoundaryTolerance& boundaryTolerance, - double surfaceTolerance = s_onSurfaceTolerance, + double surfaceTolerance, ConstrainedStep::Type stype, const Logger& logger = getDummyLogger()) const { using Status = IntersectionStatus; @@ -512,7 +513,7 @@ class MultiEigenStepperLoop : public EigenStepper { for (auto& component : state.components) { component.status = detail::updateSingleSurfaceStatus( *this, component.state, surface, index, navDir, boundaryTolerance, - surfaceTolerance, logger); + surfaceTolerance, stype, logger); ++counts[static_cast(component.status)]; } @@ -576,10 +577,10 @@ class MultiEigenStepperLoop : public EigenStepper { /// @param state [in,out] The stepping state (thread-local cache) /// @param oIntersection [in] The ObjectIntersection to layer, boundary, etc /// @param direction [in] The propagation direction - /// @param release [in] boolean to trigger step size release + /// @param stype [in] The step size type to be set template void updateStepSize(State& state, const object_intersection_t& oIntersection, - Direction direction, bool release = true) const { + Direction direction, ConstrainedStep::Type stype) const { const Surface& surface = *oIntersection.object(); for (auto& component : state.components) { @@ -590,7 +591,7 @@ class MultiEigenStepperLoop : public EigenStepper { BoundaryTolerance::None())[oIntersection.index()]; SingleStepper::updateStepSize(component.state, intersection, direction, - release); + stype); } } @@ -599,11 +600,10 @@ class MultiEigenStepperLoop : public EigenStepper { /// @param state [in,out] The stepping state (thread-local cache) /// @param stepSize [in] The step size value /// @param stype [in] The step size type to be set - /// @param release [in] Do we release the step size? void updateStepSize(State& state, double stepSize, - ConstrainedStep::Type stype, bool release = true) const { + ConstrainedStep::Type stype) const { for (auto& component : state.components) { - SingleStepper::updateStepSize(component.state, stepSize, stype, release); + SingleStepper::updateStepSize(component.state, stepSize, stype); } } diff --git a/Core/include/Acts/Propagator/MultiEigenStepperLoop.ipp b/Core/include/Acts/Propagator/MultiEigenStepperLoop.ipp index a09e35b9a18..01b392dbf2a 100644 --- a/Core/include/Acts/Propagator/MultiEigenStepperLoop.ipp +++ b/Core/include/Acts/Propagator/MultiEigenStepperLoop.ipp @@ -116,15 +116,18 @@ Result MultiEigenStepperLoop::step( } } - removeMissedComponents(stepping); - reweightComponents(stepping); - ACTS_VERBOSE("Stepper performed " << m_stepLimitAfterFirstComponentOnSurface - << " after the first component hit a surface."); + << " steps after the first component hit a surface."); ACTS_VERBOSE( "-> remove all components not on a surface, perform no step"); + removeMissedComponents(stepping); + reweightComponents(stepping); + + ACTS_VERBOSE(components.size() + << " components left after removing missed components"); + stepping.stepCounterAfterFirstComponentOnSurface.reset(); return 0.0; @@ -184,7 +187,7 @@ Result MultiEigenStepperLoop::step( }; // Loop over components and remove errorous components - stepping.components.erase( + components.erase( std::remove_if(components.begin(), components.end(), errorInStep), components.end()); @@ -218,10 +221,15 @@ Result MultiEigenStepperLoop::step( } // Return error if there is no ok result - if (stepping.components.empty()) { + if (components.empty()) { return MultiStepperError::AllComponentsSteppingError; } + // Invalidate the component status after each step + for (auto& cmp : components) { + cmp.status = Status::unreachable; + } + // Return the weighted accumulated path length of all successful steps stepping.pathAccumulated += accumulatedPathLength; return accumulatedPathLength; diff --git a/Core/include/Acts/Propagator/MultiStepperAborters.hpp b/Core/include/Acts/Propagator/MultiStepperAborters.hpp index e42d3387e2f..577c9c7e43f 100644 --- a/Core/include/Acts/Propagator/MultiStepperAborters.hpp +++ b/Core/include/Acts/Propagator/MultiStepperAborters.hpp @@ -13,7 +13,7 @@ namespace Acts { -struct MultiStepperSurfaceReached : public SurfaceReached { +struct MultiStepperSurfaceReached : public ForcedSurfaceReached { /// If this is set, we are also happy if the mean of the components is on the /// surface. How the averaging is performed depends on the stepper /// implementation @@ -25,7 +25,6 @@ struct MultiStepperSurfaceReached : public SurfaceReached { double averageOnSurfaceTolerance = 0.2; MultiStepperSurfaceReached() = default; - explicit MultiStepperSurfaceReached(double oLimit) : SurfaceReached(oLimit) {} /// boolean operator for abort condition without using the result /// @@ -82,9 +81,8 @@ struct MultiStepperSurfaceReached : public SurfaceReached { auto singleState = cmp.singleState(state); const auto& singleStepper = cmp.singleStepper(stepper); - if (!SurfaceReached::checkAbort(singleState, singleStepper, navigator, - logger)) { - cmp.status() = Acts::IntersectionStatus::reachable; + if (!ForcedSurfaceReached::checkAbort(singleState, singleStepper, + navigator, logger)) { reached = false; } else { cmp.status() = Acts::IntersectionStatus::onSurface; diff --git a/Core/include/Acts/Propagator/NavigationTarget.hpp b/Core/include/Acts/Propagator/NavigationTarget.hpp new file mode 100644 index 00000000000..ce23132195b --- /dev/null +++ b/Core/include/Acts/Propagator/NavigationTarget.hpp @@ -0,0 +1,46 @@ +// 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/Surfaces/BoundaryTolerance.hpp" + +#include + +namespace Acts { + +class Surface; + +/// @brief The navigation target +/// +/// This struct represents a navigation target which is communicated from the +/// navigator to the stepper through the propagator. +/// +/// @note This incorporates `std::optional` semantics as the next target might +/// not exist. +struct NavigationTarget { + const Surface* surface = nullptr; + std::uint8_t surfaceIntersectionIndex = 0; + BoundaryTolerance boundaryTolerance = BoundaryTolerance::None(); + + static NavigationTarget None() { return NavigationTarget(); } + + NavigationTarget(const Surface& surface_, + std::uint8_t surfaceIntersectionIndex_, + BoundaryTolerance boundaryTolerance_) + : surface(&surface_), + surfaceIntersectionIndex(surfaceIntersectionIndex_), + boundaryTolerance(std::move(boundaryTolerance_)) {} + + bool isNone() const { return surface == nullptr; } + + private: + NavigationTarget() = default; +}; + +} // namespace Acts diff --git a/Core/include/Acts/Propagator/Navigator.hpp b/Core/include/Acts/Propagator/Navigator.hpp index 504912b507f..221963d0020 100644 --- a/Core/include/Acts/Propagator/Navigator.hpp +++ b/Core/include/Acts/Propagator/Navigator.hpp @@ -12,15 +12,17 @@ #include "Acts/Geometry/Layer.hpp" #include "Acts/Geometry/TrackingGeometry.hpp" #include "Acts/Geometry/TrackingVolume.hpp" -#include "Acts/Propagator/ConstrainedStep.hpp" +#include "Acts/Propagator/NavigationTarget.hpp" #include "Acts/Propagator/NavigatorOptions.hpp" #include "Acts/Propagator/NavigatorStatistics.hpp" #include "Acts/Surfaces/BoundaryTolerance.hpp" #include "Acts/Surfaces/Surface.hpp" +#include "Acts/Utilities/Intersection.hpp" #include "Acts/Utilities/Logger.hpp" #include "Acts/Utilities/StringHelpers.hpp" #include +#include #include #include @@ -28,8 +30,7 @@ namespace Acts { -/// @brief struct for the Navigation options that are forwarded to -/// the geometry +/// @brief The navigation options for the tracking geometry /// /// @tparam object_t Type of the object for navigation to check against template @@ -59,11 +60,11 @@ struct NavigationOptions { double farLimit = std::numeric_limits::max(); }; -/// @brief Steers the propagation through the geometry by adjusting the step -/// size and providing the next surface to be targeted. +/// @brief Steers the propagation through the geometry by providing the next +/// surface to be targeted. /// /// The Navigator is part of the propagation and responsible for steering -/// the step size in order to encounter all the relevant surfaces which are +/// the surface sequence to encounter all the relevant surfaces which are /// intersected by the trajectory. /// /// The current navigation stage is cached in the state struct and updated @@ -73,13 +74,11 @@ struct NavigationOptions { /// The current target surface is referenced by an index which points into /// the navigation candidates. The navigation candidates are ordered by the /// path length to the surface. If a surface is hit, the -/// `state.navigation.currentSurface` pointer is set. This actors to observe +/// `state.currentSurface` pointer is set. This actors to observe /// that we are on a surface. /// class Navigator { public: - using Surfaces = std::vector; - using NavigationSurfaces = boost::container::small_vector; @@ -93,12 +92,13 @@ class Navigator { /// The navigation stage enum struct Stage : int { - undefined = 0, + initial = 0, surfaceTarget = 1, layerTarget = 2, - boundaryTarget = 3 + boundaryTarget = 3, }; + /// The navigator configuration struct Config { /// Tracking Geometry for this Navigator std::shared_ptr trackingGeometry{nullptr}; @@ -111,7 +111,20 @@ class Navigator { bool resolvePassive = false; }; + /// The navigator options struct Options : public NavigatorPlainOptions { + explicit Options(const GeometryContext& gctx) + : NavigatorPlainOptions(gctx) {} + + /// The surface tolerance + double surfaceTolerance = s_onSurfaceTolerance; + + /// The near limit to resolve surfaces + double nearLimit = s_onSurfaceTolerance; + + /// The far limit to resolve surfaces + double farLimit = std::numeric_limits::max(); + /// Externally provided surfaces - these are tried to be hit ExternalSurfaces externalSurfaces = {}; @@ -130,71 +143,75 @@ class Navigator { /// It acts as an internal state which is created for every propagation and /// meant to keep thread-local navigation information. struct State { + explicit State(const Options& options_) : options(options_) {} + Options options; // Navigation on surface level /// the vector of navigation surfaces to work through NavigationSurfaces navSurfaces = {}; /// the current surface index of the navigation state - std::size_t navSurfaceIndex = navSurfaces.size(); + std::optional navSurfaceIndex; // Navigation on layer level /// the vector of navigation layers to work through NavigationLayers navLayers = {}; /// the current layer index of the navigation state - std::size_t navLayerIndex = navLayers.size(); + std::optional navLayerIndex; // Navigation on volume level /// the vector of boundary surfaces to work through NavigationBoundaries navBoundaries = {}; /// the current boundary index of the navigation state - std::size_t navBoundaryIndex = navBoundaries.size(); - - auto navSurface() const { return navSurfaces.at(navSurfaceIndex); } - auto navLayer() const { return navLayers.at(navLayerIndex); } - auto navBoundary() const { return navBoundaries.at(navBoundaryIndex); } + std::optional navBoundaryIndex; - /// Navigation state: the world volume - const TrackingVolume* worldVolume = nullptr; + SurfaceIntersection& navSurface() { + return navSurfaces.at(navSurfaceIndex.value()); + } + LayerIntersection& navLayer() { + return navLayers.at(navLayerIndex.value()); + } + BoundaryIntersection& navBoundary() { + return navBoundaries.at(navBoundaryIndex.value()); + } - /// Navigation state: the start volume const TrackingVolume* startVolume = nullptr; - /// Navigation state: the start layer const Layer* startLayer = nullptr; - /// Navigation state: the start surface const Surface* startSurface = nullptr; - /// Navigation state: the current volume const TrackingVolume* currentVolume = nullptr; - /// Navigation state: the current layer const Layer* currentLayer = nullptr; - /// Navigation state - external state: the current surface const Surface* currentSurface = nullptr; - /// Navigation state: the target surface const Surface* targetSurface = nullptr; - /// Indicator if the target is reached - bool targetReached = false; - /// Navigation state : a break has been detected bool navigationBreak = false; - /// The navigation stage (@todo: integrate break, target) - Stage navigationStage = Stage::undefined; + Stage navigationStage = Stage::initial; - /// Navigation statistics NavigatorStatistics statistics; - void reset() { + void resetAfterLayerSwitch() { navSurfaces.clear(); - navSurfaceIndex = navSurfaces.size(); + navSurfaceIndex.reset(); + } + + void resetAfterVolumeSwitch() { + resetAfterLayerSwitch(); + navLayers.clear(); - navLayerIndex = navLayers.size(); + navLayerIndex.reset(); navBoundaries.clear(); - navBoundaryIndex = navBoundaries.size(); + navBoundaryIndex.reset(); - currentVolume = nullptr; currentLayer = nullptr; + } + + void reset() { + resetAfterVolumeSwitch(); + + currentVolume = nullptr; currentSurface = nullptr; - navigationStage = Stage::undefined; + navigationBreak = false; + navigationStage = Stage::initial; } }; @@ -208,8 +225,7 @@ class Navigator { : m_cfg{std::move(cfg)}, m_logger{std::move(_logger)} {} State makeState(const Options& options) const { - State state; - state.options = options; + State state(options); state.startSurface = options.startSurface; state.targetSurface = options.targetSurface; return state; @@ -238,8 +254,6 @@ class Navigator { return state.targetSurface; } - bool targetReached(const State& state) const { return state.targetReached; } - bool endOfWorldReached(const State& state) const { return state.currentVolume == nullptr; } @@ -248,937 +262,482 @@ class Navigator { return state.navigationBreak; } - void currentSurface(State& state, const Surface* surface) const { - state.currentSurface = surface; - } - - void targetReached(State& state, bool targetReached) const { - state.targetReached = targetReached; - } - - void navigationBreak(State& state, bool navigationBreak) const { - state.navigationBreak = navigationBreak; - } - - /// @brief Initialize call - start of navigation + /// @brief Initialize the navigator /// - /// @tparam propagator_state_t The state type of the propagator - /// @tparam stepper_t The type of stepper used for the propagation + /// This function initializes the navigator for a new propagation. /// - /// @param [in,out] state is the propagation state object - /// @param [in] stepper Stepper in use - template - void initialize(propagator_state_t& state, const stepper_t& stepper) const { - // Call the navigation helper prior to actual navigation + /// @param state The navigation state + /// @param position The start position + /// @param direction The start direction + /// @param propagationDirection The propagation direction + void initialize(State& state, const Vector3& position, + const Vector3& direction, + Direction propagationDirection) const { + (void)propagationDirection; + ACTS_VERBOSE(volInfo(state) << "Initialization."); - // Set the world volume if it is not set - if (state.navigation.worldVolume == nullptr) { - state.navigation.worldVolume = - m_cfg.trackingGeometry->highestTrackingVolume(); - } + state.reset(); // Fast Navigation initialization for start condition: // - short-cut through object association, saves navigation in the // - geometry and volume tree search for the lowest volume - if (state.navigation.startSurface != nullptr && - state.navigation.startSurface->associatedLayer() != nullptr) { + if (state.startSurface != nullptr && + state.startSurface->associatedLayer() != nullptr) { ACTS_VERBOSE( volInfo(state) << "Fast start initialization through association from Surface."); - // assign the current layer and volume by association - state.navigation.startLayer = - state.navigation.startSurface->associatedLayer(); - state.navigation.currentLayer = state.navigation.startLayer; - - state.navigation.startVolume = - state.navigation.startLayer->trackingVolume(); - state.navigation.currentVolume = state.navigation.startVolume; - } else if (state.navigation.startVolume != nullptr) { + state.startLayer = state.startSurface->associatedLayer(); + state.startVolume = state.startLayer->trackingVolume(); + } else if (state.startVolume != nullptr) { ACTS_VERBOSE( volInfo(state) << "Fast start initialization through association from Volume."); - state.navigation.currentVolume = state.navigation.startVolume; - - state.navigation.startLayer = - state.navigation.startVolume->associatedLayer( - state.geoContext, stepper.position(state.stepping)); - state.navigation.currentLayer = state.navigation.startLayer; + state.startLayer = state.startVolume->associatedLayer( + state.options.geoContext, position); } else { ACTS_VERBOSE(volInfo(state) << "Slow start initialization through search."); - // current volume and layer search through global search ACTS_VERBOSE(volInfo(state) - << "Starting from position " - << toString(stepper.position(state.stepping)) - << " and direction " - << toString(stepper.direction(state.stepping))); - - state.navigation.startVolume = - m_cfg.trackingGeometry->lowestTrackingVolume( - state.geoContext, stepper.position(state.stepping)); - state.navigation.currentVolume = state.navigation.startVolume; - - if (state.navigation.startVolume != nullptr) { - state.navigation.startLayer = - state.navigation.startVolume->associatedLayer( - state.geoContext, stepper.position(state.stepping)); - state.navigation.currentLayer = state.navigation.startLayer; - ACTS_VERBOSE(volInfo(state) << "Start volume resolved."); + << "Starting from position " << toString(position) + << " and direction " << toString(direction)); + + // current volume and layer search through global search + state.startVolume = m_cfg.trackingGeometry->lowestTrackingVolume( + state.options.geoContext, position); + + if (state.startVolume != nullptr) { + state.startLayer = state.startVolume->associatedLayer( + state.options.geoContext, position); } else { - ACTS_VERBOSE(volInfo(state) - << "No start volume resolved. Nothing left to do."); - // set the navigation break - state.navigation.navigationBreak = true; + ACTS_ERROR(volInfo(state) + << "No start volume resolved. Nothing left to do."); + state.navigationBreak = true; } } - if (state.navigation.startVolume != nullptr) { - ACTS_VERBOSE(volInfo(state) << "Start volume resolved."); - assert(state.navigation.startVolume->inside( - stepper.position(state.stepping), - state.options.surfaceTolerance) && + state.currentVolume = state.startVolume; + state.currentLayer = state.startLayer; + state.currentSurface = state.startSurface; + + if (state.currentVolume != nullptr) { + ACTS_VERBOSE(volInfo(state) << "Start volume resolved " + << state.currentVolume->geometryId()); + assert(state.currentVolume->inside(position, + state.options.surfaceTolerance) && "We did not end up inside the volume."); } - - if (state.navigation.startLayer != nullptr) { + if (state.currentLayer != nullptr) { ACTS_VERBOSE(volInfo(state) << "Start layer resolved " - << state.navigation.startLayer->geometryId()); - // We provide the layer to the resolve surface method in this case - resolveSurfaces(state, stepper); + << state.currentLayer->geometryId()); } - - // Set the start volume as current volume - state.navigation.currentVolume = state.navigation.startVolume; - // Set the start layer as current layer - state.navigation.currentLayer = state.navigation.startLayer; - - // We set the current surface to the start surface for eventual post-update - // action, e.g. material integration or collection when leaving a surface at - // the start of an extrapolation process - state.navigation.currentSurface = state.navigation.startSurface; - if (state.navigation.currentSurface != nullptr) { - ACTS_VERBOSE(volInfo(state) - << "Current surface set to start surface " - << state.navigation.currentSurface->geometryId()); - - assert(state.navigation.currentSurface->isOnSurface( - state.geoContext, stepper.position(state.stepping), - stepper.direction(state.stepping), + if (state.currentSurface != nullptr) { + ACTS_VERBOSE(volInfo(state) << "Start surface resolved " + << state.currentSurface->geometryId()); + assert(state.currentSurface->isOnSurface( + state.options.geoContext, position, direction, BoundaryTolerance::Infinite(), state.options.surfaceTolerance) && "Stepper not on surface"); } } - /// @brief Navigator pre step call + /// @brief Get the next target surface /// - /// Call options - /// (a) there are still surfaces to be resolved: handle those - /// (b) there no surfaces but still layers to be resolved, handle those - /// (c) there are no surfaces nor layers to be resolved, handle boundary + /// This function gets the next target surface for the propagation. /// - /// @tparam propagator_state_t is the type of Propagatgor state - /// @tparam stepper_t is the used type of the Stepper by the Propagator + /// @param state The navigation state + /// @param position The current position + /// @param direction The current direction /// - /// @param [in,out] state is the mutable propagator state object - /// @param [in] stepper Stepper in use - template - void preStep(propagator_state_t& state, const stepper_t& stepper) const { - // Check if the navigator is inactive - if (inactive(state, stepper)) { - return; + /// @return The next target surface + NavigationTarget nextTarget(State& state, const Vector3& position, + const Vector3& direction) const { + if (inactive(state)) { + return NavigationTarget::None(); } - // Call the navigation helper prior to actual navigation - ACTS_VERBOSE(volInfo(state) << "Entering navigator::preStep."); + ACTS_VERBOSE(volInfo(state) << "Entering Navigator::nextTarget."); - // Navigator pre step always resets the current surface - state.navigation.currentSurface = nullptr; + // Reset the current surface + state.currentSurface = nullptr; - auto tryTargetNextSurface = [&]() { + auto tryGetNextTarget = [&]() -> NavigationTarget { // Try targeting the surfaces - then layers - then boundaries - if (state.navigation.navigationStage <= Stage::surfaceTarget && - targetSurfaces(state, stepper)) { - ACTS_VERBOSE(volInfo(state) << "Target set to next surface."); - return true; + if (state.navigationStage == Stage::initial) { + ACTS_VERBOSE(volInfo(state) << "Target surfaces."); + state.navigationStage = Stage::surfaceTarget; + } + + if (state.navigationStage == Stage::surfaceTarget) { + if (!state.navSurfaceIndex.has_value()) { + // First time, resolve the surfaces + resolveSurfaces(state, position, direction); + state.navSurfaceIndex = 0; + } else { + ++state.navSurfaceIndex.value(); + } + if (state.navSurfaceIndex.value() < state.navSurfaces.size()) { + ACTS_VERBOSE(volInfo(state) << "Target set to next surface."); + return NavigationTarget(*state.navSurface().object(), + state.navSurface().index(), + BoundaryTolerance::None()); + } else { + // This was the last surface, switch to layers + ACTS_VERBOSE(volInfo(state) << "Target layers."); + state.navigationStage = Stage::layerTarget; + } } - if (state.navigation.navigationStage <= Stage::layerTarget && - targetLayers(state, stepper)) { - ACTS_VERBOSE(volInfo(state) << "Target set to next layer."); - return true; + if (state.navigationStage == Stage::layerTarget) { + if (!state.navLayerIndex.has_value()) { + // First time, resolve the layers + resolveLayers(state, position, direction); + state.navLayerIndex = 0; + } else { + ++state.navLayerIndex.value(); + } + if (state.navLayerIndex.value() < state.navLayers.size()) { + ACTS_VERBOSE(volInfo(state) << "Target set to next layer."); + return NavigationTarget(*state.navLayer().first.object(), + state.navLayer().first.index(), + BoundaryTolerance::None()); + } else { + // This was the last layer, switch to boundaries + ACTS_VERBOSE(volInfo(state) << "Target boundaries."); + state.navigationStage = Stage::boundaryTarget; + } } - if (targetBoundaries(state, stepper)) { - ACTS_VERBOSE(volInfo(state) << "Target set to next boundary."); - return true; + if (state.navigationStage == Stage::boundaryTarget) { + if (!state.navBoundaryIndex.has_value()) { + // First time, resolve the boundaries + resolveBoundaries(state, position, direction); + state.navBoundaryIndex = 0; + } else { + ++state.navBoundaryIndex.value(); + } + if (state.navBoundaryIndex.value() < state.navBoundaries.size()) { + ACTS_VERBOSE(volInfo(state) << "Target set to next boundary."); + return NavigationTarget(*state.navBoundary().first.object(), + state.navBoundary().first.index(), + BoundaryTolerance::None()); + } else { + // This was the last boundary, we have to leave the volume somehow, + // renavigate + ACTS_VERBOSE(volInfo(state) + << "Boundary targets exhausted. Renavigate."); + } } - return false; + ACTS_VERBOSE(volInfo(state) + << "Unknown state. No target found. Renavigate."); + return NavigationTarget::None(); }; - if (tryTargetNextSurface()) { - // Proceed to the next surface - return; + NavigationTarget nextTarget = tryGetNextTarget(); + if (!nextTarget.isNone()) { + return nextTarget; } - ACTS_VERBOSE(volInfo(state) - << "No targets found, we got lost! Attempt renavigation."); - - state.navigation.reset(); - ++state.navigation.statistics.nRenavigations; + state.reset(); + ++state.statistics.nRenavigations; // We might have punched through a boundary and entered another volume // so we have to reinitialize - state.navigation.currentVolume = - m_cfg.trackingGeometry->lowestTrackingVolume( - state.geoContext, stepper.position(state.stepping)); + state.currentVolume = m_cfg.trackingGeometry->lowestTrackingVolume( + state.options.geoContext, position); - if (state.navigation.currentVolume == nullptr) { + if (state.currentVolume == nullptr) { ACTS_VERBOSE(volInfo(state) << "No volume found, stop navigation."); - // Set navigation break and release the navigation step size - state.navigation.navigationBreak = true; - stepper.releaseStepSize(state.stepping, ConstrainedStep::actor); - return; + state.navigationBreak = true; + return NavigationTarget::None(); } - state.navigation.currentLayer = - state.navigation.currentVolume->associatedLayer( - state.geoContext, stepper.position(state.stepping)); + state.currentLayer = state.currentVolume->associatedLayer( + state.options.geoContext, position); ACTS_VERBOSE(volInfo(state) << "Resolved volume and layer."); // Rerun the targeting - if (tryTargetNextSurface()) { - return; + nextTarget = tryGetNextTarget(); + if (!nextTarget.isNone()) { + return nextTarget; } - ACTS_VERBOSE(volInfo(state) << "No targets found again, we got " - "really lost! Stop navigation."); - // Set navigation break and release the navigation step size - state.navigation.navigationBreak = true; - stepper.releaseStepSize(state.stepping, ConstrainedStep::actor); + ACTS_VERBOSE( + volInfo(state) + << "No targets found again, we got really lost! Stop navigation."); + state.navigationBreak = true; + return NavigationTarget::None(); } - /// @brief Navigator post step call - /// - /// (a) It initializes the Navigation stream if start volume is - /// not yet defined: - /// - initialize the volume - /// - establish the start layer and start volume - /// - set the current surface to the start surface + /// @brief Check if the current target is still valid /// - /// (b) It establishes the currentSurface status during - /// the propagation flow, currentSurface can be - /// - surfaces still to be handled within a layer - /// - layers still to be handled within a volume - /// - boundaries still to be handled to exit a volume + /// This function checks if the target is valid. /// - /// @tparam propagator_state_t is the type of Propagatgor state - /// @tparam stepper_t is the used type of the Stepper by the Propagator + /// @param state The navigation state + /// @param position The current position + /// @param direction The current direction /// - /// @param [in,out] state is the mutable propagator state object - /// @param [in] stepper Stepper in use - template - void postStep(propagator_state_t& state, const stepper_t& stepper) const { - // Check if the navigator is inactive - if (inactive(state, stepper)) { - return; - } - - // Set the navigation stage - state.navigation.navigationStage = Stage::undefined; - - // Call the navigation helper prior to actual navigation - ACTS_VERBOSE(volInfo(state) << "Entering navigator::postStep."); - - // Navigator post step always starts without current surface - state.navigation.currentSurface = nullptr; - - // (b) Status call within propagation loop - // Try finding status of surfaces - if (surfaceStatus(state, stepper, state.navigation.navSurfaces, - state.navigation.navSurfaceIndex)) { - ACTS_VERBOSE(volInfo(state) << "Post step: in surface handling."); - if (state.navigation.currentSurface != nullptr) { - ACTS_VERBOSE(volInfo(state) - << "On surface: switch forward or release."); - if (++state.navigation.navSurfaceIndex == - state.navigation.navSurfaces.size()) { - // this was the last surface, check if we have layers - if (!state.navigation.navLayers.empty()) { - ++state.navigation.navLayerIndex; - } else { - state.navigation.navigationStage = Stage::layerTarget; - ACTS_VERBOSE(volInfo(state) << "Target layers."); - return; - } - } - } - // Set the navigation stage to surface target - state.navigation.navigationStage = Stage::surfaceTarget; - ACTS_VERBOSE(volInfo(state) << "Staying focussed on surface."); - // Try finding status of layer - } else if (surfaceStatus(state, stepper, state.navigation.navLayers, - state.navigation.navLayerIndex)) { - ACTS_VERBOSE(volInfo(state) << "Post step: in layer handling."); - if (state.navigation.currentSurface != nullptr) { - ACTS_VERBOSE(volInfo(state) << "On layer: update layer information."); - state.navigation.currentLayer = state.navigation.navLayer().second; - if (resolveSurfaces(state, stepper)) { - // Set the navigation stage back to surface handling - state.navigation.navigationStage = Stage::surfaceTarget; - return; - } - } else { - // Set the navigation stage to layer target - state.navigation.navigationStage = Stage::layerTarget; - ACTS_VERBOSE(volInfo(state) << "Staying focussed on layer."); - } - // Try finding status of boundaries - } else if (surfaceStatus(state, stepper, state.navigation.navBoundaries, - state.navigation.navBoundaryIndex)) { - ACTS_VERBOSE(volInfo(state) << "Post step: in boundary handling."); - - // Are we on the boundary - then overwrite the stage - if (state.navigation.currentSurface != nullptr) { - // Set the navigation stage back to surface handling - ACTS_VERBOSE(volInfo(state) - << "On boundary: update volume information."); - // We are on a boundary, reset all information - state.navigation.navSurfaces.clear(); - state.navigation.navSurfaceIndex = state.navigation.navSurfaces.size(); - state.navigation.navLayers.clear(); - state.navigation.navLayerIndex = state.navigation.navLayers.size(); - // Update volume information - // get the attached volume information - const BoundarySurface* boundary = state.navigation.navBoundary().second; - state.navigation.currentVolume = boundary->attachedVolume( - state.geoContext, stepper.position(state.stepping), - state.options.direction * stepper.direction(state.stepping)); - state.navigation.currentLayer = nullptr; - // No volume anymore : end of known world - if (state.navigation.currentVolume == nullptr) { - ACTS_VERBOSE( - volInfo(state) - << "No more volume to progress to, stopping navigation."); - // Navigation break & release navigation stepping - state.navigation.navigationBreak = true; - stepper.releaseStepSize(state.stepping, ConstrainedStep::actor); - return; - } else { - ACTS_VERBOSE(volInfo(state) << "Volume updated."); - assert(state.navigation.currentVolume->inside( - stepper.position(state.stepping), - state.options.surfaceTolerance) && - "We did not end up inside the volume."); - // Forget the boundary information - state.navigation.navBoundaries.clear(); - state.navigation.navBoundaryIndex = - state.navigation.navBoundaries.size(); - ++state.navigation.statistics.nVolumeSwitches; - } - } else { - // Set the navigation stage back to boundary target - state.navigation.navigationStage = Stage::boundaryTarget; - ACTS_VERBOSE(volInfo(state) << "Staying focussed on boundary."); - } - } else { - ACTS_VERBOSE(volInfo(state) - << "Status could not be determined - good luck."); - } + /// @return True if the target is valid + bool checkTargetValid(const State& state, const Vector3& position, + const Vector3& direction) const { + (void)position; + (void)direction; - if (state.navigation.currentSurface != nullptr) { - assert(state.navigation.currentSurface->isOnSurface( - state.geoContext, stepper.position(state.stepping), - stepper.direction(state.stepping), - BoundaryTolerance::Infinite(), - state.options.surfaceTolerance) && - "Stepper not on surface"); - } - } - - private: - const SurfaceIntersection& candidateIntersection( - const NavigationSurfaces& surfaces, std::size_t index) const { - return surfaces.at(index); - } - const SurfaceIntersection& candidateIntersection( - const NavigationLayers& surfaces, std::size_t index) const { - return surfaces.at(index).first; - } - const SurfaceIntersection& candidateIntersection( - const NavigationBoundaries& surfaces, std::size_t index) const { - return surfaces.at(index).first; - } - - /// @brief Status call for test surfaces (surfaces, layers, boundaries) - /// - /// If there are surfaces to be handled, check if the current - /// state is on the surface - /// - /// @tparam propagator_state_t The state type of the propagator - /// @tparam stepper_t The type of stepper used for the propagation - /// @tparam navigation_surfaces_t Type of the propagator - /// - /// @param [in,out] state is the propagation state object - /// @param [in] stepper Stepper in use - /// @param [in] navSurfaces is the navigation status objects - /// @param [in] navIndex test surface fore the status test - /// - /// @return boolean return triggers exit to stepper - template - bool surfaceStatus(propagator_state_t& state, const stepper_t& stepper, - const navigation_surfaces_t& navSurfaces, - std::size_t navIndex) const { - // No surfaces, status check will be done on layer - if (navSurfaces.empty() || navIndex == navSurfaces.size()) { - return false; - } - const auto& intersection = candidateIntersection(navSurfaces, navIndex); - // Take the current surface - const auto* surface = intersection.object(); - // Check if we are at a surface - // If we are on the surface pointed at by the index, we can make - // it the current one to pass it to the other actors - auto surfaceStatus = stepper.updateSurfaceStatus( - state.stepping, *surface, intersection.index(), state.options.direction, - BoundaryTolerance::None(), state.options.surfaceTolerance, logger()); - if (surfaceStatus == IntersectionStatus::onSurface) { - ACTS_VERBOSE(volInfo(state) - << "Status Surface successfully hit, storing it."); - // Set in navigation state, so actors and aborters can access it - state.navigation.currentSurface = surface; - if (state.navigation.currentSurface != nullptr) { - ACTS_VERBOSE(volInfo(state) - << "Current surface set to surface " - << state.navigation.currentSurface->geometryId()); - } - } - // Return a positive status: either on it, or on the way - return true; + return state.navigationStage != Stage::initial; } - /// Loop over surface candidates here: - /// - if an intersect is valid but not yet reached - /// then return with updated step size - /// - if an intersect is not valid, switch to next - /// - /// @tparam propagator_state_t The state type of the propagator - /// @tparam stepper_t The type of stepper used for the propagation + /// @brief Handle the surface reached /// - /// @param [in,out] state is the propagation state object - /// @param [in] stepper Stepper in use + /// This function handles the surface reached. /// - /// boolean return triggers exit to stepper - template - bool targetSurfaces(propagator_state_t& state, - const stepper_t& stepper) const { - if (state.navigation.navigationBreak) { - return false; - } - - // The call that we are on a layer and have not yet resolved the surfaces - // No surfaces, do not return to stepper - if (state.navigation.navSurfaces.empty() || - state.navigation.navSurfaceIndex == - state.navigation.navSurfaces.size()) { - ACTS_VERBOSE(volInfo(state) - << "No surfaces present, target at layer first."); - return false; - } - - auto layerID = state.navigation.navSurface().object()->geometryId().layer(); - std::pair - externalSurfaceRange = - state.navigation.options.externalSurfaces.equal_range(layerID); - // Loop over the remaining navigation surfaces - while (state.navigation.navSurfaceIndex != - state.navigation.navSurfaces.size()) { - // Screen output how much is left to try - ACTS_VERBOSE(volInfo(state) - << (state.navigation.navSurfaces.size() - - state.navigation.navSurfaceIndex) - << " out of " << state.navigation.navSurfaces.size() - << " surfaces remain to try."); - const auto& intersection = state.navigation.navSurface(); - // Take the surface - const auto* surface = intersection.object(); - // Screen output which surface you are on - ACTS_VERBOSE(volInfo(state) << "Next surface candidate will be " - << surface->geometryId()); - // Estimate the surface status - BoundaryTolerance boundaryTolerance = BoundaryTolerance::None(); - for (auto it = externalSurfaceRange.first; - it != externalSurfaceRange.second; it++) { - if (surface->geometryId() == it->second) { - boundaryTolerance = BoundaryTolerance::Infinite(); - break; - } - } - auto surfaceStatus = stepper.updateSurfaceStatus( - state.stepping, *surface, intersection.index(), - state.options.direction, boundaryTolerance, - state.options.surfaceTolerance, logger()); - if (surfaceStatus == IntersectionStatus::reachable) { - ACTS_VERBOSE(volInfo(state) - << "Surface reachable, step size updated to " - << stepper.outputStepSize(state.stepping)); - return true; - } - ++state.navigation.navSurfaceIndex; - continue; - } - - // Reached the end of the surface iteration - if (state.navigation.navSurfaceIndex == - state.navigation.navSurfaces.size()) { - // first clear the surface cache - state.navigation.navSurfaces.clear(); - state.navigation.navSurfaceIndex = state.navigation.navSurfaces.size(); - - if (state.navigation.navLayerIndex != state.navigation.navLayers.size()) { - ACTS_VERBOSE(volInfo(state) - << "Last surface on layer reached, switching layer."); - // now switch to the next layer - ++state.navigation.navLayerIndex; - } else { - ACTS_VERBOSE(volInfo(state) - << "Last surface on layer reached, and no layer."); - } + /// @param state The navigation state + /// @param position The current position + /// @param direction The current direction + /// @param surface The surface reached + void handleSurfaceReached(State& state, const Vector3& position, + const Vector3& direction, + const Surface& surface) const { + if (inactive(state)) { + return; } - // Do not return to the propagator - return false; - } + ACTS_VERBOSE(volInfo(state) << "Entering Navigator::handleSurfaceReached."); - /// @brief Target layer candidates. - /// - /// We are now trying to advance to the next layer (with surfaces) - /// Check if we are on the representing surface of the layer pointed - /// at by navLayerIndex. If so, we unpack the compatible surfaces - /// (determined by straight line intersect), and set up the index - /// so that the next postStep() call will enter the surface - /// check mode above. If no surfaces are found, we skip the layer. - /// If we unpack a surface, the step size is set to the path length - /// to the first surface, as determined by straight line intersect. - /// - /// @tparam propagator_state_t The state type of the propagator - /// @tparam stepper_t The type of stepper used for the propagation - /// - /// @param [in,out] state is the propagation state object - /// @param [in] stepper Stepper in use - /// - /// @return boolean return triggers exit to stepper - template - bool targetLayers(propagator_state_t& state, const stepper_t& stepper) const { - if (state.navigation.navigationBreak) { - return false; - } + state.currentSurface = &surface; - // if there are no layers, go back to the navigator (not stepper yet) - if (state.navigation.navLayers.empty()) { - ACTS_VERBOSE(volInfo(state) - << "No layers present, resolve volume first."); - - if (resolveLayers(state, stepper)) { - // The layer resolving worked - return true; - } - } + if (state.navigationStage == Stage::surfaceTarget && + state.navSurface().object() == &surface) { + ACTS_VERBOSE(volInfo(state) << "Handling surface status."); - // loop over the available navigation layer candidates - while (state.navigation.navLayerIndex != - state.navigation.navLayers.size()) { - const auto& intersection = state.navigation.navLayer().first; - // The layer surface - const auto* layerSurface = intersection.object(); - // We are on the layer - if (state.navigation.currentSurface == layerSurface) { - ACTS_VERBOSE(volInfo(state) << "We are on a layer, resolve Surfaces."); - // If you found surfaces return to the propagator - if (resolveSurfaces(state, stepper)) { - return true; - } else { - // Try the next one - ++state.navigation.navLayerIndex; - continue; - } - } - // Try to step towards it - auto layerStatus = stepper.updateSurfaceStatus( - state.stepping, *layerSurface, intersection.index(), - state.options.direction, BoundaryTolerance::None(), - state.options.surfaceTolerance, logger()); - if (layerStatus == IntersectionStatus::reachable) { - ACTS_VERBOSE(volInfo(state) << "Layer reachable, step size updated to " - << stepper.outputStepSize(state.stepping)); - return true; - } - ACTS_VERBOSE(volInfo(state) - << "Layer intersection not valid, skipping it."); - ++state.navigation.navLayerIndex; + return; } - ACTS_VERBOSE(volInfo(state) << "Last layer done, target volume boundary."); + if (state.navigationStage == Stage::layerTarget && + state.navLayer().first.object() == &surface) { + ACTS_VERBOSE(volInfo(state) << "Handling layer status."); - return false; - } + // Switch to the next layer + state.currentLayer = state.navLayer().second; + state.navigationStage = Stage::surfaceTarget; - /// @brief Navigation through volumes - /// - /// This is the boundary check routine. If the code above set up the - /// boundary surface index, we advance through them here. If we are on - /// the boundary surface, we set the current surface to the boundary - /// surface, and get the volume pointed at by the boundary surface. Next - /// we unpack the layers from that volume. If the volume contains layers - /// we set the step size to the straight line path length to the first - /// layer. If we don't find a next volume, the navigationBreak - /// indicator is set. This ends the navigation. Finally, the boundary - /// index is cleared, so that the subsequent call goes back to - /// the layer iteration logic. - /// - /// If we are not on the current boundary surface, we try the next one. - /// The index is advanced and the step size is set. If no straight - /// line intersect is found, the boundary surface is skipped. - /// If we are out of boundary surfaces, the navigation is terminated. - /// - /// @tparam propagator_state_t The state type of the propagator - /// @tparam stepper_t The type of stepper used for the propagation - /// - /// @param [in,out] state is the propagation state object - /// @param [in] stepper Stepper in use - /// - /// boolean return triggers exit to stepper - template - bool targetBoundaries(propagator_state_t& state, - const stepper_t& stepper) const { - if (state.navigation.navigationBreak) { - return false; - } + // partial reset + state.resetAfterLayerSwitch(); - if (state.navigation.currentVolume == nullptr) { - ACTS_VERBOSE(volInfo(state) - << "No sufficient information to resolve boundary, " - "stopping navigation."); - stepper.releaseStepSize(state.stepping, ConstrainedStep::actor); - return false; + return; } - // Helper function to find boundaries - auto findBoundaries = [&]() -> bool { - // The navigation options - NavigationOptions navOpts; - // Exclude the current surface in case it's a boundary - navOpts.startObject = state.navigation.currentSurface; - navOpts.nearLimit = state.options.surfaceTolerance; - navOpts.farLimit = - stepper.getStepSize(state.stepping, ConstrainedStep::aborter); + if (state.navigationStage == Stage::boundaryTarget && + state.navBoundary().first.object() == &surface) { + ACTS_VERBOSE(volInfo(state) << "Handling boundary status."); - ACTS_VERBOSE(volInfo(state) - << "Try to find boundaries, we are at: " - << stepper.position(state.stepping).transpose() << ", dir: " - << stepper.direction(state.stepping).transpose()); - - // Evaluate the boundary surfaces - state.navigation.navBoundaries = - state.navigation.currentVolume->compatibleBoundaries( - state.geoContext, stepper.position(state.stepping), - state.options.direction * stepper.direction(state.stepping), - navOpts, logger()); - std::ranges::sort( - state.navigation.navBoundaries, [](const auto& a, const auto& b) { - return SurfaceIntersection::pathLengthOrder(a.first, b.first); - }); - - // Print boundary information - if (logger().doPrint(Logging::VERBOSE)) { - std::ostringstream os; - os << state.navigation.navBoundaries.size(); - os << " boundary candidates found at path(s): "; - for (auto& bc : state.navigation.navBoundaries) { - os << bc.first.pathLength() << " "; - } - logger().log(Logging::VERBOSE, os.str()); - } + // Switch to the next volume using the boundary + const BoundarySurface* boundary = state.navBoundary().second; + state.currentVolume = boundary->attachedVolume(state.options.geoContext, + position, direction); - // Set the begin index - state.navigation.navBoundaryIndex = 0; - if (!state.navigation.navBoundaries.empty()) { - // Set to the first and return to the stepper - stepper.updateStepSize(state.stepping, - state.navigation.navBoundary().first, - state.options.direction, true); - ACTS_VERBOSE(volInfo(state) << "Navigation stepSize updated to " - << stepper.outputStepSize(state.stepping)); - return true; - } - return false; - }; + // partial reset + state.resetAfterVolumeSwitch(); - // No boundaries are assigned yet, find them - if (state.navigation.navBoundaries.empty() && findBoundaries()) { - return true; - } - - // Loop over the boundary surface - while (state.navigation.navBoundaryIndex != - state.navigation.navBoundaries.size()) { - const auto& intersection = state.navigation.navBoundary().first; - // That is the current boundary surface - const auto* boundarySurface = intersection.object(); - // Step towards the boundary surfrace - auto boundaryStatus = stepper.updateSurfaceStatus( - state.stepping, *boundarySurface, intersection.index(), - state.options.direction, BoundaryTolerance::None(), - state.options.surfaceTolerance, logger()); - if (boundaryStatus == IntersectionStatus::reachable) { - ACTS_VERBOSE(volInfo(state) - << "Boundary reachable, step size updated to " - << stepper.outputStepSize(state.stepping)); - return true; + if (state.currentVolume != nullptr) { + ACTS_VERBOSE(volInfo(state) << "Volume updated."); + state.navigationStage = Stage::layerTarget; } else { - ACTS_VERBOSE("Boundary " - << (state.navigation.navBoundaries.size() - - state.navigation.navBoundaryIndex) - << " out of " << state.navigation.navBoundaries.size() - << " not reachable anymore, switching to next."); - ACTS_VERBOSE("Targeted boundary surface was: \n" - << boundarySurface->toStream(state.geoContext)); + ACTS_VERBOSE(volInfo(state) + << "No more volume to progress to, stopping navigation."); + state.navigationBreak = true; } - // Increase the index to the next one - ++state.navigation.navBoundaryIndex; + + return; } - // Tried our best, but couldn't do anything - state.navigation.navBoundaries.clear(); - state.navigation.navBoundaryIndex = state.navigation.navBoundaries.size(); - return false; + ACTS_ERROR(volInfo(state) << "Surface reached but unknown state."); } - /// @brief Resolve the surfaces of this layer - /// - /// @tparam propagator_state_t The state type of the propagator - /// @tparam stepper_t The type of stepper used for the propagation + private: + /// @brief Resolve compatible surfaces /// - /// @param [in,out] state is the propagation state object - /// @param [in] stepper Stepper in use + /// This function resolves the compatible surfaces for the navigation. /// - /// boolean return triggers exit to stepper - template - bool resolveSurfaces(propagator_state_t& state, - const stepper_t& stepper) const { - // get the layer and layer surface - const Layer* currentLayer = state.navigation.currentLayer; + /// @param state The navigation state + /// @param position The current position + /// @param direction The current direction + void resolveSurfaces(State& state, const Vector3& position, + const Vector3& direction) const { + ACTS_VERBOSE(volInfo(state) << "Searching for compatible surfaces."); + + const Layer* currentLayer = state.currentLayer; if (currentLayer == nullptr) { ACTS_VERBOSE(volInfo(state) << "No layer to resolve surfaces."); - return false; + return; } const Surface* layerSurface = ¤tLayer->surfaceRepresentation(); - // Use navigation parameters and NavigationOptions NavigationOptions navOpts; navOpts.resolveSensitive = m_cfg.resolveSensitive; navOpts.resolveMaterial = m_cfg.resolveMaterial; navOpts.resolvePassive = m_cfg.resolvePassive; - navOpts.startObject = state.navigation.currentSurface; - navOpts.endObject = state.navigation.targetSurface; + navOpts.startObject = state.currentSurface; + navOpts.endObject = state.targetSurface; + navOpts.nearLimit = state.options.nearLimit; + navOpts.farLimit = state.options.farLimit; - std::vector externalSurfaces; - if (!state.navigation.options.externalSurfaces.empty()) { - auto layerID = layerSurface->geometryId().layer(); + if (!state.options.externalSurfaces.empty()) { + auto layerId = layerSurface->geometryId().layer(); auto externalSurfaceRange = - state.navigation.options.externalSurfaces.equal_range(layerID); + state.options.externalSurfaces.equal_range(layerId); navOpts.externalSurfaces.reserve( - state.navigation.options.externalSurfaces.count(layerID)); + state.options.externalSurfaces.count(layerId)); for (auto itSurface = externalSurfaceRange.first; itSurface != externalSurfaceRange.second; itSurface++) { navOpts.externalSurfaces.push_back(itSurface->second); } } - navOpts.nearLimit = state.options.surfaceTolerance; - navOpts.farLimit = - stepper.getStepSize(state.stepping, ConstrainedStep::aborter); - - // get the surfaces - state.navigation.navSurfaces = currentLayer->compatibleSurfaces( - state.geoContext, stepper.position(state.stepping), - state.options.direction * stepper.direction(state.stepping), navOpts); - std::ranges::sort(state.navigation.navSurfaces, - SurfaceIntersection::pathLengthOrder); + // Request the compatible surfaces + state.navSurfaces = currentLayer->compatibleSurfaces( + state.options.geoContext, position, direction, navOpts); + std::ranges::sort(state.navSurfaces, SurfaceIntersection::pathLengthOrder); // Print surface information if (logger().doPrint(Logging::VERBOSE)) { std::ostringstream os; - os << state.navigation.navSurfaces.size(); + os << state.navSurfaces.size(); os << " surface candidates found at path(s): "; - for (auto& sfc : state.navigation.navSurfaces) { + for (auto& sfc : state.navSurfaces) { os << sfc.pathLength() << " "; } logger().log(Logging::VERBOSE, os.str()); } - // Surface candidates have been found - if (!state.navigation.navSurfaces.empty()) { - // set the index - state.navigation.navSurfaceIndex = 0; - // The stepper updates the step size ( single / multi component) - stepper.updateStepSize(state.stepping, state.navigation.navSurface(), - state.options.direction, true); - ACTS_VERBOSE(volInfo(state) << "Navigation stepSize updated to " - << stepper.outputStepSize(state.stepping)); - return true; + if (state.navSurfaces.empty()) { + ACTS_VERBOSE(volInfo(state) << "No surface candidates found."); } - - state.navigation.navSurfaceIndex = state.navigation.navSurfaces.size(); - ACTS_VERBOSE(volInfo(state) << "No surface candidates found."); - return false; } - /// @brief Navigation through layers - /// - /// Resolve layers. - /// - /// This initializes the layer candidates when starting - /// or when entering a new volume + /// @brief Resolve compatible layers /// - /// @tparam propagator_state_t The state type of the propagator - /// @tparam stepper_t The type of stepper used for the propagation + /// This function resolves the compatible layers for the navigation. /// - /// @param [in,out] state is the propagation state object - /// @param [in] stepper Stepper in use - /// - /// @return boolean return triggers exit to stepper - template - bool resolveLayers(propagator_state_t& state, - const stepper_t& stepper) const { + /// @param state The navigation state + /// @param position The current position + /// @param direction The current direction + void resolveLayers(State& state, const Vector3& position, + const Vector3& direction) const { ACTS_VERBOSE(volInfo(state) << "Searching for compatible layers."); - // Create the navigation options - // - and get the compatible layers, start layer will be excluded NavigationOptions navOpts; navOpts.resolveSensitive = m_cfg.resolveSensitive; navOpts.resolveMaterial = m_cfg.resolveMaterial; navOpts.resolvePassive = m_cfg.resolvePassive; - navOpts.startObject = state.navigation.currentLayer; - navOpts.nearLimit = state.options.surfaceTolerance; - navOpts.farLimit = - stepper.getStepSize(state.stepping, ConstrainedStep::aborter); + navOpts.startObject = state.currentLayer; + navOpts.nearLimit = state.options.nearLimit; + navOpts.farLimit = state.options.farLimit; // Request the compatible layers - state.navigation.navLayers = - state.navigation.currentVolume->compatibleLayers( - state.geoContext, stepper.position(state.stepping), - state.options.direction * stepper.direction(state.stepping), - navOpts); - std::ranges::sort( - state.navigation.navLayers, [](const auto& a, const auto& b) { - return SurfaceIntersection::pathLengthOrder(a.first, b.first); - }); + state.navLayers = state.currentVolume->compatibleLayers( + state.options.geoContext, position, direction, navOpts); + std::ranges::sort(state.navLayers, [](const auto& a, const auto& b) { + return SurfaceIntersection::pathLengthOrder(a.first, b.first); + }); // Print layer information if (logger().doPrint(Logging::VERBOSE)) { std::ostringstream os; - os << state.navigation.navLayers.size(); + os << state.navLayers.size(); os << " layer candidates found at path(s): "; - for (auto& lc : state.navigation.navLayers) { + for (auto& lc : state.navLayers) { os << lc.first.pathLength() << " "; } logger().log(Logging::VERBOSE, os.str()); } - // Layer candidates have been found - if (!state.navigation.navLayers.empty()) { - // Set the index to the first - state.navigation.navLayerIndex = 0; - // Setting the step size towards first - ACTS_VERBOSE(volInfo(state) << "Target at layer."); - // The stepper updates the step size ( single / multi component) - stepper.updateStepSize(state.stepping, state.navigation.navLayer().first, - state.options.direction, true); - ACTS_VERBOSE(volInfo(state) << "Navigation stepSize updated to " - << stepper.outputStepSize(state.stepping)); - return true; + if (state.navLayers.empty()) { + ACTS_VERBOSE(volInfo(state) << "No layer candidates found."); } + } - // Set the index to the end of the list - state.navigation.navLayerIndex = state.navigation.navLayers.size(); + /// @brief Resolve compatible boundaries + /// + /// This function resolves the compatible boundaries for the navigation. + /// + /// @param state The navigation state + /// @param position The current position + /// @param direction The current direction + void resolveBoundaries(State& state, const Vector3& position, + const Vector3& direction) const { + ACTS_VERBOSE(volInfo(state) << "Searching for compatible boundaries."); - // Screen output - no layer candidates found - ACTS_VERBOSE(volInfo(state) << "No compatible layer candidates found."); - // Release the step size - stepper.releaseStepSize(state.stepping, ConstrainedStep::actor); - return false; + NavigationOptions navOpts; + navOpts.startObject = state.currentSurface; + navOpts.nearLimit = state.options.nearLimit; + navOpts.farLimit = state.options.farLimit; + + ACTS_VERBOSE(volInfo(state) + << "Try to find boundaries, we are at: " << toString(position) + << ", dir: " << toString(direction)); + + // Request the compatible boundaries + state.navBoundaries = state.currentVolume->compatibleBoundaries( + state.options.geoContext, position, direction, navOpts, logger()); + std::ranges::sort(state.navBoundaries, [](const auto& a, const auto& b) { + return SurfaceIntersection::pathLengthOrder(a.first, b.first); + }); + + // Print boundary information + if (logger().doPrint(Logging::VERBOSE)) { + std::ostringstream os; + os << state.navBoundaries.size(); + os << " boundary candidates found at path(s): "; + for (auto& bc : state.navBoundaries) { + os << bc.first.pathLength() << " "; + } + logger().log(Logging::VERBOSE, os.str()); + } + + if (state.navBoundaries.empty()) { + ACTS_VERBOSE(volInfo(state) << "No boundary candidates found."); + } } - /// Inactive - /// - /// This checks if a navigation break had been triggered or navigator - /// is misconfigured + /// @brief Check if the navigator is inactive /// - /// @tparam propagator_state_t The state type of the propagator - /// @tparam stepper_t The type of stepper used for the propagation + /// This function checks if the navigator is inactive. /// - /// @param [in,out] state is the propagation state object - /// @param [in] stepper Stepper in use + /// @param state The navigation state /// - /// boolean return triggers exit to stepper - template - bool inactive(propagator_state_t& state, const stepper_t& stepper) const { + /// @return True if the navigator is inactive + bool inactive(const State& state) const { // Void behavior in case no tracking geometry is present if (m_cfg.trackingGeometry == nullptr) { return true; } - // turn the navigator into void when you are instructed to do nothing + + // Turn the navigator into void when you are instructed to do nothing if (!m_cfg.resolveSensitive && !m_cfg.resolveMaterial && !m_cfg.resolvePassive) { return true; } - // Navigation break handling - // This checks if a navigation break had been triggered: - // - If so & the target exists or was hit - it simply returns - // - If a target exists and was not yet hit, it checks for it - // -> return is always to the stepper - if (state.navigation.navigationBreak) { - // target exists and reached, or no target exists - if (state.navigation.targetReached || - state.navigation.targetSurface == nullptr) { - return true; - } - // TODO we do not know the intersection index - passing 0 - auto targetStatus = stepper.updateSurfaceStatus( - state.stepping, *state.navigation.targetSurface, 0, - state.options.direction, BoundaryTolerance::None(), - state.options.surfaceTolerance, logger()); - // the only advance could have been to the target - if (targetStatus == IntersectionStatus::onSurface) { - // set the target surface - state.navigation.currentSurface = state.navigation.targetSurface; - ACTS_VERBOSE(volInfo(state) - << volInfo(state) - << "Current surface set to target surface " - << state.navigation.currentSurface->geometryId()); - return true; - } + if (state.navigationBreak) { + return true; } + return false; } private: template std::string volInfo(const propagator_state_t& state) const { - return (state.navigation.currentVolume != nullptr - ? state.navigation.currentVolume->volumeName() - : "No Volume") + + return (state.currentVolume != nullptr ? state.currentVolume->volumeName() + : "No Volume") + " | "; } diff --git a/Core/include/Acts/Propagator/NavigatorOptions.hpp b/Core/include/Acts/Propagator/NavigatorOptions.hpp index 27f017d47b2..ca2472a9dc8 100644 --- a/Core/include/Acts/Propagator/NavigatorOptions.hpp +++ b/Core/include/Acts/Propagator/NavigatorOptions.hpp @@ -8,11 +8,21 @@ #pragma once +#include + namespace Acts { +class GeometryContext; class Surface; struct NavigatorPlainOptions { + /// NavigatorPlainOptions with context + explicit NavigatorPlainOptions(const GeometryContext &gctx) + : geoContext(gctx) {} + + /// Context object for the geometry + std::reference_wrapper geoContext; + const Surface *startSurface{}; const Surface *targetSurface{}; }; diff --git a/Core/include/Acts/Propagator/Propagator.ipp b/Core/include/Acts/Propagator/Propagator.ipp index 3475bc7175f..0790a5d906b 100644 --- a/Core/include/Acts/Propagator/Propagator.ipp +++ b/Core/include/Acts/Propagator/Propagator.ipp @@ -9,9 +9,12 @@ #include "Acts/EventData/TrackParametersConcept.hpp" #include "Acts/Propagator/ActorList.hpp" #include "Acts/Propagator/ConstrainedStep.hpp" +#include "Acts/Propagator/NavigationTarget.hpp" #include "Acts/Propagator/PropagatorError.hpp" #include "Acts/Propagator/StandardAborters.hpp" #include "Acts/Propagator/detail/LoopProtection.hpp" +#include "Acts/Surfaces/BoundaryTolerance.hpp" +#include "Acts/Utilities/Intersection.hpp" #include @@ -19,7 +22,7 @@ namespace Acts::detail { template concept propagator_stepper_compatible_with = requires(const Stepper& s, StateType& st, const N& n) { - { s.step(st, n) } -> std::same_as>; + { s.step(st, n) } -> std::same_as>; }; } // namespace Acts::detail @@ -27,80 +30,157 @@ template template auto Acts::Propagator::propagate(propagator_state_t& state) const -> Result { - // Pre-stepping call to the navigator and actor list ACTS_VERBOSE("Entering propagation."); state.stage = PropagatorStage::prePropagation; - // Pre-Stepping call to the actor list + // Pre-Propagation: call to the actor list, abort condition check state.options.actorList.act(state, m_stepper, m_navigator, logger()); - // assume negative outcome, only set to true later if we actually have - // a positive outcome. - - // start at true, if we don't begin the stepping loop we're fine. - bool terminatedNormally = true; - - // Pre-Stepping: abort condition check - if (!state.options.actorList.checkAbort(state, m_stepper, m_navigator, - logger())) { - // Stepping loop - ACTS_VERBOSE("Starting stepping loop."); - - terminatedNormally = false; // priming error condition - - // Propagation loop : stepping - for (; state.steps < state.options.maxSteps; ++state.steps) { - // Pre-Stepping: target setting - state.stage = PropagatorStage::preStep; - m_navigator.preStep(state, m_stepper); - // Perform a propagation step - it takes the propagation state - Result res = m_stepper.step(state, m_navigator); - if (res.ok()) { - // Accumulate the path length - double s = *res; - state.pathLength += s; - ACTS_VERBOSE("Step with size = " << s << " performed"); - } else { - ACTS_ERROR("Step failed with " << res.error() << ": " - << res.error().message()); - // pass error to caller - return res.error(); + + if (state.options.actorList.checkAbort(state, m_stepper, m_navigator, + logger())) { + ACTS_VERBOSE("Propagation terminated without going into stepping loop."); + + state.stage = PropagatorStage::postPropagation; + + state.options.actorList.act(state, m_stepper, m_navigator, logger()); + + return Result::success(); + } + + auto getNextTarget = [&]() -> Result { + for (unsigned int i = 0; i < state.options.maxTargetSkipping; ++i) { + NavigationTarget nextTarget = m_navigator.nextTarget( + state.navigation, state.position, state.direction); + if (nextTarget.isNone()) { + return NavigationTarget::None(); } - // release actor and aborter constrains after step was performed - m_stepper.releaseStepSize(state.stepping, ConstrainedStep::actor); - m_stepper.releaseStepSize(state.stepping, ConstrainedStep::aborter); - // Post-stepping: - // navigator post step call - actor list act - actor list check - state.stage = PropagatorStage::postStep; - m_navigator.postStep(state, m_stepper); - state.options.actorList.act(state, m_stepper, m_navigator, logger()); - if (state.options.actorList.checkAbort(state, m_stepper, m_navigator, - logger())) { - terminatedNormally = true; - break; + IntersectionStatus preStepSurfaceStatus = m_stepper.updateSurfaceStatus( + state.stepping, *nextTarget.surface, + nextTarget.surfaceIntersectionIndex, state.options.direction, + nextTarget.boundaryTolerance, state.options.surfaceTolerance, + ConstrainedStep::Type::Navigator, logger()); + if (preStepSurfaceStatus == IntersectionStatus::reachable || + preStepSurfaceStatus == IntersectionStatus::onSurface) { + return nextTarget; } } - } else { - ACTS_VERBOSE("Propagation terminated without going into stepping loop."); + + ACTS_ERROR("getNextTarget failed to find a valid target surface after " + << state.options.maxTargetSkipping << " attempts."); + return Result::failure( + PropagatorError::NextTargetLimitReached); + }; + + // priming error condition + bool terminatedNormally = false; + + // Pre-Stepping: target setting + state.stage = PropagatorStage::preStep; + + Result nextTargetResult = getNextTarget(); + if (!nextTargetResult.ok()) { + return nextTargetResult.error(); } + NavigationTarget nextTarget = *nextTargetResult; + + ACTS_VERBOSE("Starting stepping loop."); + + // Stepping loop + for (; state.steps < state.options.maxSteps; ++state.steps) { + // Perform a step + Result res = m_stepper.step(state, m_navigator); + if (!res.ok()) { + ACTS_ERROR("Step failed with " << res.error() << ": " + << res.error().message()); + // pass error to caller + return res.error(); + } + // Accumulate the path length + state.pathLength += *res; + // Update the position and direction + state.position = m_stepper.position(state.stepping); + state.direction = + state.options.direction * m_stepper.direction(state.stepping); + + ACTS_VERBOSE("Step with size " << *res << " performed. We are now at " + << state.position.transpose() + << " with direction " + << state.direction.transpose()); + + // release actor and aborter constrains after step was performed + m_stepper.releaseStepSize(state.stepping, ConstrainedStep::Type::Navigator); + m_stepper.releaseStepSize(state.stepping, ConstrainedStep::Type::Actor); + + // Post-stepping: check target status, call actors, check abort conditions + state.stage = PropagatorStage::postStep; + + if (!nextTarget.isNone()) { + IntersectionStatus postStepSurfaceStatus = m_stepper.updateSurfaceStatus( + state.stepping, *nextTarget.surface, + nextTarget.surfaceIntersectionIndex, state.options.direction, + nextTarget.boundaryTolerance, state.options.surfaceTolerance, + ConstrainedStep::Type::Navigator, logger()); + if (postStepSurfaceStatus == IntersectionStatus::onSurface) { + m_navigator.handleSurfaceReached(state.navigation, state.position, + state.direction, *nextTarget.surface); + } + if (postStepSurfaceStatus != IntersectionStatus::reachable) { + nextTarget = NavigationTarget::None(); + } + } - state.stage = PropagatorStage::postPropagation; + state.options.actorList.act(state, m_stepper, m_navigator, logger()); + + if (state.options.actorList.checkAbort(state, m_stepper, m_navigator, + logger())) { + terminatedNormally = true; + break; + } + + // Update the position and direction because actors might have changed it + state.position = m_stepper.position(state.stepping); + state.direction = + state.options.direction * m_stepper.direction(state.stepping); + + // Pre-Stepping: target setting + state.stage = PropagatorStage::preStep; - // if we didn't terminate normally (via aborters) set navigation break. - // this will trigger error output in the lines below + if (!nextTarget.isNone() && + !m_navigator.checkTargetValid(state.navigation, state.position, + state.direction)) { + ACTS_VERBOSE("Target is not valid anymore."); + nextTarget = NavigationTarget::None(); + } + + if (nextTarget.isNone()) { + // navigator step constraint is not valid anymore + m_stepper.releaseStepSize(state.stepping, + ConstrainedStep::Type::Navigator); + + nextTargetResult = getNextTarget(); + if (!nextTargetResult.ok()) { + return nextTargetResult.error(); + } + nextTarget = *nextTargetResult; + } + } // end of stepping loop + + // check if we didn't terminate normally via aborters if (!terminatedNormally) { - m_navigator.navigationBreak(state.navigation, true); ACTS_ERROR("Propagation reached the step count limit of " << state.options.maxSteps << " (did " << state.steps << " steps)"); return PropagatorError::StepCountLimitReached; } - // Post-stepping call to the actor list ACTS_VERBOSE("Stepping loop done."); + + state.stage = PropagatorStage::postPropagation; + + // Post-stepping call to the actor list state.options.actorList.act(state, m_stepper, m_navigator, logger()); - // return progress flag here, decide on SUCCESS later return Result::success(); } @@ -318,8 +398,13 @@ auto Acts::Propagator::makeResult( template template void Acts::Propagator::initialize(propagator_state_t& state) const { + state.position = m_stepper.position(state.stepping); + state.direction = + state.options.direction * m_stepper.direction(state.stepping); + // Navigator initialize state call - m_navigator.initialize(state, m_stepper); + m_navigator.initialize(state.navigation, state.position, state.direction, + state.options.direction); // Apply the loop protection - it resets the internal path limit detail::setupLoopProtection( diff --git a/Core/include/Acts/Propagator/PropagatorError.hpp b/Core/include/Acts/Propagator/PropagatorError.hpp index 34bd9df0f90..ba92240821e 100644 --- a/Core/include/Acts/Propagator/PropagatorError.hpp +++ b/Core/include/Acts/Propagator/PropagatorError.hpp @@ -16,8 +16,8 @@ namespace Acts { enum class PropagatorError { // ensure all values are non-zero Failure = 1, - WrongDirection, StepCountLimitReached, + NextTargetLimitReached, }; std::error_code make_error_code(Acts::PropagatorError e); diff --git a/Core/include/Acts/Propagator/PropagatorOptions.hpp b/Core/include/Acts/Propagator/PropagatorOptions.hpp index c6d77550661..234283a4ce9 100644 --- a/Core/include/Acts/Propagator/PropagatorOptions.hpp +++ b/Core/include/Acts/Propagator/PropagatorOptions.hpp @@ -25,11 +25,20 @@ namespace detail { /// @brief Holds the generic pure propagator options struct PurePropagatorPlainOptions { /// Propagation direction - Direction direction = Direction::Forward; + Direction direction = Direction::Forward(); /// Maximum number of steps for one propagate call + /// + /// This ensures that the propagation does not hang in the stepping loop in + /// case of misconfiguration or bugs. unsigned int maxSteps = 1000; + /// Maximum number of next target calls for one step + /// + /// This ensures that the propagation does not hang in the target resolution + /// loop in case of misconfiguration or bugs. + unsigned int maxTargetSkipping = 100; + /// Absolute maximum path length double pathLimit = std::numeric_limits::max(); @@ -61,7 +70,7 @@ struct PropagatorPlainOptions : public detail::PurePropagatorPlainOptions { : geoContext(gctx), magFieldContext(mctx), stepping(gctx, mctx), - navigation() {} + navigation(gctx) {} /// The context object for the geometry std::reference_wrapper geoContext; @@ -94,14 +103,14 @@ struct PropagatorOptions : public detail::PurePropagatorPlainOptions { : geoContext(gctx), magFieldContext(mctx), stepping(gctx, mctx), - navigation() {} + navigation(gctx) {} /// PropagatorOptions with context and plain options PropagatorOptions(const PropagatorPlainOptions& pOptions) : geoContext(pOptions.geoContext), magFieldContext(pOptions.magFieldContext), stepping(pOptions.geoContext, pOptions.magFieldContext), - navigation() { + navigation(pOptions.geoContext) { setPlainOptions(pOptions); } diff --git a/Core/include/Acts/Propagator/PropagatorState.hpp b/Core/include/Acts/Propagator/PropagatorState.hpp index 03346cfd57d..f8b639d1faa 100644 --- a/Core/include/Acts/Propagator/PropagatorState.hpp +++ b/Core/include/Acts/Propagator/PropagatorState.hpp @@ -8,6 +8,7 @@ #pragma once +#include "Acts/Definitions/Algebra.hpp" #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Propagator/PropagatorStatistics.hpp" #include "Acts/Utilities/detail/Extendable.hpp" @@ -45,29 +46,35 @@ struct PropagatorState : private detail::Extendable { /// @param navigationIn Navigator state instance to begin with PropagatorState(const propagator_options_t& topts, stepper_state_t steppingIn, navigator_state_t navigationIn) - : options(topts), + : geoContext(topts.geoContext), + options(topts), stepping{std::move(steppingIn)}, - navigation{std::move(navigationIn)}, - geoContext(topts.geoContext) {} + navigation{std::move(navigationIn)} {} using detail::Extendable::get; using detail::Extendable::tuple; - /// Propagation stage - PropagatorStage stage = PropagatorStage::invalid; + /// Context object for the geometry + std::reference_wrapper geoContext; /// These are the options - provided for each propagation step propagator_options_t options; + /// Propagation stage + PropagatorStage stage = PropagatorStage::invalid; + + /// The position of the propagation + Vector3 position = Vector3::Zero(); + + /// The direction of the propagation + Vector3 direction = Vector3::Zero(); + /// Stepper state - internal state of the Stepper stepper_state_t stepping; /// Navigation state - internal state of the Navigator navigator_state_t navigation; - /// Context object for the geometry - std::reference_wrapper geoContext; - /// Number of propagation steps that were carried out std::size_t steps = 0; diff --git a/Core/include/Acts/Propagator/StandardAborters.hpp b/Core/include/Acts/Propagator/StandardAborters.hpp index 271ebd85239..c6b7ce3f8ea 100644 --- a/Core/include/Acts/Propagator/StandardAborters.hpp +++ b/Core/include/Acts/Propagator/StandardAborters.hpp @@ -8,8 +8,6 @@ #pragma once -#include "Acts/Definitions/Algebra.hpp" -#include "Acts/Definitions/Direction.hpp" #include "Acts/Definitions/Units.hpp" #include "Acts/Propagator/ConstrainedStep.hpp" #include "Acts/Surfaces/BoundaryTolerance.hpp" @@ -18,9 +16,6 @@ #include "Acts/Utilities/Logger.hpp" #include -#include -#include -#include namespace Acts { @@ -55,8 +50,8 @@ struct PathLimitReached { << distance); return true; } - stepper.updateStepSize(state.stepping, distance, ConstrainedStep::aborter, - false); + stepper.updateStepSize(state.stepping, distance, + ConstrainedStep::Type::Actor); ACTS_VERBOSE("PathLimit aborter | " << "Target stepSize (path limit) updated to " << stepper.outputStepSize(state.stepping)); @@ -134,7 +129,7 @@ struct SurfaceReached { detail::checkPathLength(intersection.pathLength(), nearLimit, farLimit, logger)) { stepper.updateStepSize(state.stepping, intersection.pathLength(), - ConstrainedStep::aborter, false); + ConstrainedStep::Type::Actor); ACTS_VERBOSE( "SurfaceReached aborter | " "Target stepSize (surface) updated to " diff --git a/Core/include/Acts/Propagator/StepperConcept.hpp b/Core/include/Acts/Propagator/StepperConcept.hpp index fb4ea187bcd..3e45382fa3c 100644 --- a/Core/include/Acts/Propagator/StepperConcept.hpp +++ b/Core/include/Acts/Propagator/StepperConcept.hpp @@ -10,13 +10,11 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/TrackParametrization.hpp" -#include "Acts/EventData/TrackParameters.hpp" #include "Acts/EventData/detail/CorrectedTransformationFreeToBound.hpp" #include "Acts/Propagator/ConstrainedStep.hpp" #include "Acts/Surfaces/BoundaryTolerance.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Utilities/Concepts.hpp" -#include "Acts/Utilities/Intersection.hpp" #include "Acts/Utilities/Logger.hpp" namespace Acts { @@ -54,15 +52,16 @@ concept CommonStepper = requires { }; requires requires(const Surface& sf, std::uint8_t ui, Direction d, - const BoundaryTolerance& bt, double sc, const Logger& l) { - { s.updateSurfaceStatus(t, sf, ui, d, bt, sc, l) }; + const BoundaryTolerance& bt, double sc, + ConstrainedStep::Type st, const Logger& l) { + { s.updateSurfaceStatus(t, sf, ui, d, bt, sc, st, l) }; }; requires requires(const ConstrainedStep::Type st) { { s.releaseStepSize(t, st) } -> std::same_as; - requires requires(double d, bool b) { - { s.updateStepSize(t, d, st, b) } -> std::same_as; + requires requires(double d) { + { s.updateStepSize(t, d, st) } -> std::same_as; }; }; }; diff --git a/Core/include/Acts/Propagator/StepperOptions.hpp b/Core/include/Acts/Propagator/StepperOptions.hpp index b1be1e799f7..8b8a425f736 100644 --- a/Core/include/Acts/Propagator/StepperOptions.hpp +++ b/Core/include/Acts/Propagator/StepperOptions.hpp @@ -8,8 +8,9 @@ #pragma once +#include "Acts/Definitions/Units.hpp" + #include -#include namespace Acts { @@ -35,7 +36,7 @@ struct StepperPlainOptions { double stepSizeCutOff = 0.; /// Absolute maximum step size - double maxStepSize = std::numeric_limits::max(); + double maxStepSize = 10 * Acts::UnitConstants::m; /// Maximum number of Runge-Kutta steps for the stepper step call unsigned int maxRungeKuttaStepTrials = 10000; diff --git a/Core/include/Acts/Propagator/StraightLineStepper.hpp b/Core/include/Acts/Propagator/StraightLineStepper.hpp index 4bbb5a4295a..de472497090 100644 --- a/Core/include/Acts/Propagator/StraightLineStepper.hpp +++ b/Core/include/Acts/Propagator/StraightLineStepper.hpp @@ -13,11 +13,9 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/Direction.hpp" -#include "Acts/Definitions/Tolerance.hpp" #include "Acts/Definitions/TrackParametrization.hpp" #include "Acts/EventData/TrackParameters.hpp" #include "Acts/EventData/detail/CorrectedTransformationFreeToBound.hpp" -#include "Acts/Geometry/GeometryContext.hpp" #include "Acts/MagneticField/NullBField.hpp" #include "Acts/Propagator/ConstrainedStep.hpp" #include "Acts/Propagator/PropagatorTraits.hpp" @@ -112,9 +110,6 @@ class StraightLineStepper { // Previous step size for overstep estimation (ignored for SL stepper) double previousStepSize = 0.; - /// The tolerance for the stepping - double tolerance = s_onSurfaceTolerance; - /// Statistics of the stepper StepperStatistics statistics; }; @@ -233,15 +228,16 @@ class StraightLineStepper { /// @param [in] navDir The navigation direction /// @param [in] boundaryTolerance The boundary check for this status update /// @param [in] surfaceTolerance Surface tolerance used for intersection + /// @param [in] stype The step size type to be set /// @param [in] logger A logger instance IntersectionStatus updateSurfaceStatus( State& state, const Surface& surface, std::uint8_t index, Direction navDir, const BoundaryTolerance& boundaryTolerance, - double surfaceTolerance = s_onSurfaceTolerance, + double surfaceTolerance, ConstrainedStep::Type stype, const Logger& logger = getDummyLogger()) const { return detail::updateSingleSurfaceStatus( *this, state, surface, index, navDir, boundaryTolerance, - surfaceTolerance, logger); + surfaceTolerance, stype, logger); } /// Update step size @@ -251,12 +247,14 @@ class StraightLineStepper { /// /// @param state [in,out] The stepping state (thread-local cache) /// @param oIntersection [in] The ObjectIntersection to layer, boundary, etc - /// @param release [in] boolean to trigger step size release + /// @param direction [in] The propagation direction + /// @param stype [in] The step size type to be set template void updateStepSize(State& state, const object_intersection_t& oIntersection, - Direction /*direction*/, bool release = true) const { - detail::updateSingleStepSize(state, oIntersection, - release); + Direction direction, ConstrainedStep::Type stype) const { + (void)direction; + double stepSize = oIntersection.pathLength(); + updateStepSize(state, stepSize, stype); } /// Update step size - explicitly with a double @@ -264,12 +262,10 @@ class StraightLineStepper { /// @param state [in,out] The stepping state (thread-local cache) /// @param stepSize [in] The step size value /// @param stype [in] The step size type to be set - /// @param release [in] Do we release the step size? void updateStepSize(State& state, double stepSize, - ConstrainedStep::Type stype = ConstrainedStep::actor, - bool release = true) const { + ConstrainedStep::Type stype) const { state.previousStepSize = state.stepSize.value(); - state.stepSize.update(stepSize, stype, release); + state.stepSize.update(stepSize, stype); } /// Get the step size diff --git a/Core/include/Acts/Propagator/SympyStepper.hpp b/Core/include/Acts/Propagator/SympyStepper.hpp index b5f24fb6eaf..53b3474b851 100644 --- a/Core/include/Acts/Propagator/SympyStepper.hpp +++ b/Core/include/Acts/Propagator/SympyStepper.hpp @@ -13,7 +13,6 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/Direction.hpp" -#include "Acts/Definitions/Tolerance.hpp" #include "Acts/EventData/TrackParameters.hpp" #include "Acts/EventData/detail/CorrectedTransformationFreeToBound.hpp" #include "Acts/MagneticField/MagneticFieldProvider.hpp" @@ -54,7 +53,7 @@ class SympyStepper { struct State { /// Constructor from the initial bound track parameters /// - /// @param [in] optionsIn The stepper options + /// @param [in] optionsIn is the configuration of the stepper /// @param [in] fieldCacheIn is the cache object for the magnetic field /// /// @note the covariance matrix is copied when needed @@ -207,15 +206,16 @@ class SympyStepper { /// @param [in] navDir The navigation direction /// @param [in] boundaryTolerance The boundary check for this status update /// @param [in] surfaceTolerance Surface tolerance used for intersection + /// @param [in] stype The step size type to be set /// @param [in] logger A @c Logger instance IntersectionStatus updateSurfaceStatus( State& state, const Surface& surface, std::uint8_t index, Direction navDir, const BoundaryTolerance& boundaryTolerance, - double surfaceTolerance = s_onSurfaceTolerance, + double surfaceTolerance, ConstrainedStep::Type stype, const Logger& logger = getDummyLogger()) const { return detail::updateSingleSurfaceStatus( *this, state, surface, index, navDir, boundaryTolerance, - surfaceTolerance, logger); + surfaceTolerance, stype, logger); } /// Update step size @@ -227,11 +227,14 @@ class SympyStepper { /// /// @param state [in,out] The stepping state (thread-local cache) /// @param oIntersection [in] The ObjectIntersection to layer, boundary, etc - /// @param release [in] boolean to trigger step size release + /// @param direction [in] The propagation direction + /// @param stype [in] The step size type to be set template void updateStepSize(State& state, const object_intersection_t& oIntersection, - Direction /*direction*/, bool release = true) const { - detail::updateSingleStepSize(state, oIntersection, release); + Direction direction, ConstrainedStep::Type stype) const { + (void)direction; + double stepSize = oIntersection.pathLength(); + updateStepSize(state, stepSize, stype); } /// Update step size - explicitly with a double @@ -239,11 +242,10 @@ class SympyStepper { /// @param state [in,out] The stepping state (thread-local cache) /// @param stepSize [in] The step size value /// @param stype [in] The step size type to be set - /// @param release [in] Do we release the step size? void updateStepSize(State& state, double stepSize, - ConstrainedStep::Type stype, bool release = true) const { + ConstrainedStep::Type stype) const { state.previousStepSize = state.stepSize.value(); - state.stepSize.update(stepSize, stype, release); + state.stepSize.update(stepSize, stype); } /// Get the step size diff --git a/Core/include/Acts/Propagator/TryAllNavigator.hpp b/Core/include/Acts/Propagator/TryAllNavigator.hpp index 7470fa0da0c..84686bcee99 100644 --- a/Core/include/Acts/Propagator/TryAllNavigator.hpp +++ b/Core/include/Acts/Propagator/TryAllNavigator.hpp @@ -12,7 +12,7 @@ #include "Acts/Geometry/Layer.hpp" #include "Acts/Geometry/TrackingGeometry.hpp" #include "Acts/Geometry/TrackingVolume.hpp" -#include "Acts/Propagator/ConstrainedStep.hpp" +#include "Acts/Propagator/NavigationTarget.hpp" #include "Acts/Propagator/NavigatorOptions.hpp" #include "Acts/Propagator/NavigatorStatistics.hpp" #include "Acts/Propagator/detail/NavigationHelpers.hpp" @@ -30,7 +30,11 @@ namespace Acts { -/// @brief Captures the common functionality of the `TryAllNavigator`s +/// @brief Captures the common functionality of the try-all navigators +/// +/// This class is not meant to be used directly, but to be inherited by the +/// actual navigator implementations. +/// class TryAllNavigatorBase { public: /// @brief Configuration for this Navigator @@ -50,7 +54,20 @@ class TryAllNavigatorBase { BoundaryTolerance::None(); }; + /// @brief Options for this Navigator struct Options : public NavigatorPlainOptions { + explicit Options(const GeometryContext& gctx) + : NavigatorPlainOptions(gctx) {} + + /// The surface tolerance + double surfaceTolerance = s_onSurfaceTolerance; + + /// The near limit to resolve surfaces + double nearLimit = s_onSurfaceTolerance; + + /// The far limit to resolve surfaces + double farLimit = std::numeric_limits::max(); + void setPlainOptions(const NavigatorPlainOptions& options) { static_cast(*this) = options; } @@ -61,6 +78,8 @@ class TryAllNavigatorBase { /// It acts as an internal state which is created for every propagation and /// meant to keep thread-local navigation information. struct State { + explicit State(const Options& options_) : options(options_) {} + Options options; // Starting geometry information of the navigation which should only be set @@ -80,11 +99,7 @@ class TryAllNavigatorBase { /// The vector of navigation candidates to work through std::vector navigationCandidates; - /// The vector of intersection candidates to work through - std::vector intersectionCandidates; - /// Indicator if the target is reached - bool targetReached = false; /// If a break has been detected bool navigationBreak = false; @@ -95,17 +110,9 @@ class TryAllNavigatorBase { /// Constructor with configuration object /// /// @param cfg The navigator configuration - /// @param _logger a logger instance - TryAllNavigatorBase(Config cfg, std::unique_ptr _logger) - : m_cfg(std::move(cfg)), m_logger{std::move(_logger)} {} - - State makeState(const Options& options) const { - State state; - state.options = options; - state.startSurface = options.startSurface; - state.targetSurface = options.targetSurface; - return state; - } + /// @param logger a logger instance + TryAllNavigatorBase(Config cfg, std::unique_ptr logger) + : m_cfg(std::move(cfg)), m_logger{std::move(logger)} {} const Surface* currentSurface(const State& state) const { return state.currentSurface; @@ -130,8 +137,6 @@ class TryAllNavigatorBase { return state.targetSurface; } - bool targetReached(const State& state) const { return state.targetReached; } - bool endOfWorldReached(State& state) const { return state.currentVolume == nullptr; } @@ -140,61 +145,52 @@ class TryAllNavigatorBase { return state.navigationBreak; } - void currentSurface(State& state, const Surface* surface) const { - state.currentSurface = surface; - } - - void targetReached(State& state, bool targetReached) const { - state.targetReached = targetReached; - } - - void navigationBreak(State& state, bool navigationBreak) const { - state.navigationBreak = navigationBreak; - } - - /// @brief Initialize call - start of navigation + /// @brief Initialize the navigator /// - /// @tparam propagator_state_t The state type of the propagator - /// @tparam stepper_t The type of stepper used for the propagation + /// This method initializes the navigator for a new propagation. It sets the + /// current volume and surface to the start volume and surface, respectively. /// - /// @param [in,out] state is the propagation state object - /// @param [in] stepper Stepper in use - template - void initialize(propagator_state_t& state, const stepper_t& stepper) const { + /// @param state The navigation state + /// @param position The starting position + /// @param direction The starting direction + /// @param propagationDirection The propagation direction + void initialize(State& state, const Vector3& position, + const Vector3& direction, + Direction propagationDirection) const { + (void)propagationDirection; + ACTS_VERBOSE("initialize"); const TrackingVolume* startVolume = nullptr; - if (state.navigation.startSurface != nullptr && - state.navigation.startSurface->associatedLayer() != nullptr) { + if (state.startSurface != nullptr && + state.startSurface->associatedLayer() != nullptr) { ACTS_VERBOSE( "Fast start initialization through association from Surface."); - const auto* startLayer = state.navigation.startSurface->associatedLayer(); + const auto* startLayer = state.startSurface->associatedLayer(); startVolume = startLayer->trackingVolume(); } else { ACTS_VERBOSE("Slow start initialization through search."); - ACTS_VERBOSE("Starting from position " - << toString(stepper.position(state.stepping)) - << " and direction " - << toString(stepper.direction(state.stepping))); + ACTS_VERBOSE("Starting from position " << toString(position) + << " and direction " + << toString(direction)); startVolume = m_cfg.trackingGeometry->lowestTrackingVolume( - state.geoContext, stepper.position(state.stepping)); + state.options.geoContext, position); } // Initialize current volume, layer and surface { - state.navigation.currentVolume = startVolume; - if (state.navigation.currentVolume != nullptr) { + state.currentVolume = startVolume; + if (state.currentVolume != nullptr) { ACTS_VERBOSE(volInfo(state) << "Start volume resolved."); } else { ACTS_ERROR("Start volume not resolved."); } - state.navigation.currentSurface = state.navigation.startSurface; - if (state.navigation.currentSurface != nullptr) { - ACTS_VERBOSE(volInfo(state) - << "Current surface set to start surface " - << state.navigation.currentSurface->geometryId()); + state.currentSurface = state.startSurface; + if (state.currentSurface != nullptr) { + ACTS_VERBOSE(volInfo(state) << "Current surface set to start surface " + << state.currentSurface->geometryId()); } else { ACTS_VERBOSE(volInfo(state) << "No start surface set."); } @@ -203,28 +199,25 @@ class TryAllNavigatorBase { protected: /// Helper method to initialize navigation candidates for the current volume. - template - void initializeVolumeCandidates(propagator_state_t& state) const { - const TrackingVolume* volume = state.navigation.currentVolume; + void initializeVolumeCandidates(State& state) const { + const TrackingVolume* volume = state.currentVolume; ACTS_VERBOSE(volInfo(state) << "Initialize volume"); if (volume == nullptr) { - state.navigation.navigationBreak = true; + state.navigationBreak = true; ACTS_VERBOSE(volInfo(state) << "No volume set. Good luck."); return; } emplaceAllVolumeCandidates( - state.navigation.navigationCandidates, *volume, m_cfg.resolveSensitive, + state.navigationCandidates, *volume, m_cfg.resolveSensitive, m_cfg.resolveMaterial, m_cfg.resolvePassive, m_cfg.boundaryToleranceSurfaceApproach, logger()); } - template - std::string volInfo(const propagator_state_t& state) const { - return (state.navigation.currentVolume != nullptr - ? state.navigation.currentVolume->volumeName() - : "No Volume") + + std::string volInfo(const State& state) const { + return (state.currentVolume != nullptr ? state.currentVolume->volumeName() + : "No Volume") + " | "; } @@ -248,7 +241,14 @@ class TryAllNavigator : public TryAllNavigatorBase { public: using Config = TryAllNavigatorBase::Config; using Options = TryAllNavigatorBase::Options; - using State = TryAllNavigatorBase::State; + + /// @brief Nested State struct + struct State : public TryAllNavigatorBase::State { + explicit State(const Options& options_) + : TryAllNavigatorBase::State(options_) {} + + std::vector currentCandidates; + }; /// Constructor with configuration object /// @@ -259,7 +259,13 @@ class TryAllNavigator : public TryAllNavigatorBase { getDefaultLogger("TryAllNavigator", Logging::INFO)) : TryAllNavigatorBase(std::move(cfg), std::move(logger)) {} - using TryAllNavigatorBase::makeState; + State makeState(const Options& options) const { + State state(options); + state.startSurface = options.startSurface; + state.targetSurface = options.targetSurface; + + return state; + } using TryAllNavigatorBase::currentSurface; using TryAllNavigatorBase::currentVolume; @@ -267,81 +273,83 @@ class TryAllNavigator : public TryAllNavigatorBase { using TryAllNavigatorBase::endOfWorldReached; using TryAllNavigatorBase::navigationBreak; using TryAllNavigatorBase::startSurface; - using TryAllNavigatorBase::targetReached; using TryAllNavigatorBase::targetSurface; - using TryAllNavigatorBase::initialize; - - /// @brief Initialize call - start of navigation + /// @brief Initialize the navigator /// - /// @tparam propagator_state_t The state type of the propagator - /// @tparam stepper_t The type of stepper used for the propagation + /// This method initializes the navigator for a new propagation. It sets the + /// current volume and surface to the start volume and surface, respectively. /// - /// @param [in,out] state is the propagation state object - /// @param [in] stepper Stepper in use - template - void initialize(propagator_state_t& state, const stepper_t& stepper) const { - TryAllNavigatorBase::initialize(state, stepper); + /// @param state The navigation state + /// @param position The starting position + /// @param direction The starting direction + /// @param propagationDirection The propagation direction + void initialize(State& state, const Vector3& position, + const Vector3& direction, + Direction propagationDirection) const { + TryAllNavigatorBase::initialize(state, position, direction, + propagationDirection); // Initialize navigation candidates for the start volume reinitializeCandidates(state); } - /// @brief Navigator pre step call + /// @brief Get the next target surface /// - /// This determines the next surface to be targeted and sets the step length - /// accordingly. + /// This method gets the next target surface based on the current + /// position and direction. It returns a none target if no target can be + /// found. /// - /// @tparam propagator_state_t is the type of Propagatgor state - /// @tparam stepper_t is the used type of the Stepper by the Propagator + /// @param state The navigation state + /// @param position The current position + /// @param direction The current direction /// - /// @param [in,out] state is the mutable propagator state object - /// @param [in] stepper Stepper in use - template - void preStep(propagator_state_t& state, const stepper_t& stepper) const { - ACTS_VERBOSE(volInfo(state) << "pre step"); - - // Navigator preStep always resets the current surface - state.navigation.currentSurface = nullptr; + /// @return The next target surface + NavigationTarget nextTarget(State& state, const Vector3& position, + const Vector3& direction) const { + // Check if the navigator is inactive + if (state.navigationBreak) { + return NavigationTarget::None(); + } - ACTS_VERBOSE(volInfo(state) << "intersect candidates"); + ACTS_VERBOSE(volInfo(state) << "nextTarget"); - Vector3 position = stepper.position(state.stepping); - Vector3 direction = - state.options.direction * stepper.direction(state.stepping); + // Navigator preStep always resets the current surface + state.currentSurface = nullptr; - double nearLimit = state.options.surfaceTolerance; - double farLimit = std::numeric_limits::max(); + double nearLimit = state.options.nearLimit; + double farLimit = state.options.farLimit; // handle overstepping - if (!state.navigation.intersectionCandidates.empty()) { - const detail::IntersectionCandidate& previousIntersection = - state.navigation.intersectionCandidates.front(); + if (!state.currentCandidates.empty()) { + const detail::IntersectedNavigationObject& previousCandidate = + state.currentCandidates.front(); - const Surface& surface = *previousIntersection.intersection.object(); - std::uint8_t index = previousIntersection.intersection.index(); - BoundaryTolerance boundaryTolerance = - previousIntersection.boundaryTolerance; + const Surface& surface = *previousCandidate.intersection.object(); + std::uint8_t index = previousCandidate.intersection.index(); + BoundaryTolerance boundaryTolerance = previousCandidate.boundaryTolerance; auto intersection = surface.intersect( - state.geoContext, position, direction, boundaryTolerance, + state.options.geoContext, position, direction, boundaryTolerance, state.options.surfaceTolerance)[index]; if (intersection.pathLength() < 0) { - ACTS_VERBOSE(volInfo(state) << "handle overstepping"); - nearLimit = std::min(nearLimit, intersection.pathLength() - state.options.surfaceTolerance); farLimit = -state.options.surfaceTolerance; + + ACTS_VERBOSE(volInfo(state) + << "handle overstepping with nearLimit " << nearLimit + << " and farLimit " << farLimit); } } - std::vector intersectionCandidates; + std::vector intersectionCandidates; // Find intersections with all candidates - for (const auto& candidate : state.navigation.navigationCandidates) { + for (const auto& candidate : state.navigationCandidates) { auto intersections = - candidate.intersect(state.geoContext, position, direction, + candidate.intersect(state.options.geoContext, position, direction, state.options.surfaceTolerance); for (const auto& intersection : intersections.first.split()) { // exclude invalid intersections @@ -357,24 +365,20 @@ class TryAllNavigator : public TryAllNavigatorBase { } std::ranges::sort(intersectionCandidates, - detail::IntersectionCandidate::forwardOrder); + detail::IntersectedNavigationObject::forwardOrder); ACTS_VERBOSE(volInfo(state) << "found " << intersectionCandidates.size() << " intersections"); - bool intersectionFound = false; + NavigationTarget nextTarget = NavigationTarget::None(); + state.currentCandidates.clear(); for (const auto& candidate : intersectionCandidates) { const auto& intersection = candidate.intersection; const Surface& surface = *intersection.object(); BoundaryTolerance boundaryTolerance = candidate.boundaryTolerance; - auto surfaceStatus = stepper.updateSurfaceStatus( - state.stepping, surface, intersection.index(), - state.options.direction, boundaryTolerance, - state.options.surfaceTolerance, logger()); - - if (surfaceStatus == IntersectionStatus::onSurface) { + if (intersection.status() == IntersectionStatus::onSurface) { ACTS_ERROR(volInfo(state) << "We are on surface " << surface.geometryId() << " before trying to reach it. This should not happen. " @@ -382,125 +386,114 @@ class TryAllNavigator : public TryAllNavigatorBase { continue; } - if (surfaceStatus == IntersectionStatus::reachable) { - ACTS_VERBOSE(volInfo(state) - << "Surface reachable, step size updated to " - << stepper.outputStepSize(state.stepping)); - intersectionFound = true; + if (intersection.status() == IntersectionStatus::reachable) { + nextTarget = + NavigationTarget(surface, intersection.index(), boundaryTolerance); break; } } - if (!intersectionFound) { - stepper.releaseStepSize(state.stepping, ConstrainedStep::actor); + state.currentCandidates = std::move(intersectionCandidates); - ACTS_VERBOSE(volInfo(state) << "no intersections found. advance without " - "constraints. step size is " - << stepper.outputStepSize(state.stepping)); + if (nextTarget.isNone()) { + ACTS_VERBOSE(volInfo(state) << "no target found"); + } else { + ACTS_VERBOSE(volInfo(state) + << "next target is " << nextTarget.surface->geometryId()); } - state.navigation.intersectionCandidates = std::move(intersectionCandidates); + return nextTarget; } - /// @brief Navigator post step call + /// @brief Check if the target is still valid /// - /// This determines if we hit the next navigation candidate and deals with it - /// accordingly. It sets the current surface, enters layers and changes - /// volumes. + /// This method checks if the target is valid based on the current position + /// and direction. It returns true if the target is still valid. /// - /// @tparam propagator_state_t is the type of Propagatgor state - /// @tparam stepper_t is the used type of the Stepper by the Propagator + /// For the TryAllNavigator, the target is always invalid since we do not want + /// to assume any specific surface sequence over multiple steps. /// - /// @param [in,out] state is the mutable propagator state object - /// @param [in] stepper Stepper in use + /// @param state The navigation state + /// @param position The current position + /// @param direction The current direction /// - /// @return Boolean to indicate if we continue with the actors and - /// aborters or if we should target again. - template - void postStep(propagator_state_t& state, const stepper_t& stepper) const { - ACTS_VERBOSE(volInfo(state) << "post step"); - - assert(state.navigation.currentSurface == nullptr && - "Current surface must be reset."); + /// @return True if the target is still valid + bool checkTargetValid(const State& state, const Vector3& position, + const Vector3& direction) const { + (void)state; + (void)position; + (void)direction; + + return false; + } - if (state.navigation.intersectionCandidates.empty()) { - ACTS_VERBOSE(volInfo(state) << "no intersections."); + /// @brief Handle the surface reached + /// + /// This method is called when a surface is reached. It sets the current + /// surface in the navigation state and updates the navigation candidates. + /// + /// @param state The navigation state + /// @param position The current position + /// @param direction The current direction + void handleSurfaceReached(State& state, const Vector3& position, + const Vector3& direction, + const Surface& /*surface*/) const { + // Check if the navigator is inactive + if (state.navigationBreak) { return; } - std::vector hitCandidates; - - for (const auto& candidate : state.navigation.intersectionCandidates) { - const auto& intersection = candidate.intersection; - const Surface& surface = *intersection.object(); + ACTS_VERBOSE(volInfo(state) << "handleSurfaceReached"); - IntersectionStatus surfaceStatus = stepper.updateSurfaceStatus( - state.stepping, surface, intersection.index(), - state.options.direction, BoundaryTolerance::Infinite(), - state.options.surfaceTolerance, logger()); - - if (surfaceStatus != IntersectionStatus::onSurface) { - break; - } - - hitCandidates.emplace_back(candidate); - } - - if (hitCandidates.empty()) { - ACTS_VERBOSE(volInfo(state) << "Staying focussed on surface."); + if (state.currentCandidates.empty()) { + ACTS_VERBOSE(volInfo(state) << "No current candidate set."); return; } - state.navigation.intersectionCandidates.clear(); + assert(state.currentSurface == nullptr && "Current surface must be reset."); - ACTS_VERBOSE(volInfo(state) - << "Found " << hitCandidates.size() - << " intersections on surface without bounds check."); + // handle multiple surface intersections due to increased bounds - std::vector trueHitCandidates; + std::vector hitCandidates; - for (const auto& candidate : hitCandidates) { - const auto& intersection = candidate.intersection; - const Surface& surface = *intersection.object(); + for (const auto& candidate : state.currentCandidates) { + const Surface& surface = *candidate.intersection.object(); + std::uint8_t index = candidate.intersection.index(); + BoundaryTolerance boundaryTolerance = BoundaryTolerance::None(); - IntersectionStatus surfaceStatus = stepper.updateSurfaceStatus( - state.stepping, surface, intersection.index(), - state.options.direction, BoundaryTolerance::None(), - state.options.surfaceTolerance, logger()); + auto intersection = surface.intersect( + state.options.geoContext, position, direction, boundaryTolerance, + state.options.surfaceTolerance)[index]; - if (surfaceStatus != IntersectionStatus::onSurface) { - continue; + if (intersection.status() == IntersectionStatus::onSurface) { + hitCandidates.emplace_back(candidate); } - - trueHitCandidates.emplace_back(candidate); } + state.currentCandidates.clear(); + ACTS_VERBOSE(volInfo(state) - << "Found " << trueHitCandidates.size() + << "Found " << hitCandidates.size() << " intersections on surface with bounds check."); - if (trueHitCandidates.empty()) { - ACTS_VERBOSE(volInfo(state) - << "Surface successfully hit, but outside bounds."); + if (hitCandidates.empty()) { + ACTS_VERBOSE(volInfo(state) << "No hit candidates found."); return; } - if (trueHitCandidates.size() > 1) { + if (hitCandidates.size() > 1) { ACTS_VERBOSE(volInfo(state) << "Only using first intersection within bounds."); } - const auto& candidate = trueHitCandidates.front(); + // we can only handle a single surface hit so we pick the first one + const auto candidate = hitCandidates.front(); const auto& intersection = candidate.intersection; const Surface& surface = *intersection.object(); - ACTS_VERBOSE(volInfo(state) << "Surface successfully hit, storing it."); - // Set in navigation state, so actors and aborters can access it - state.navigation.currentSurface = &surface; - if (state.navigation.currentSurface) { - ACTS_VERBOSE(volInfo(state) << "Current surface set to surface " - << surface.geometryId()); - } + ACTS_VERBOSE(volInfo(state) << "Surface " << surface.geometryId() + << " successfully hit, storing it."); + state.currentSurface = &surface; if (candidate.template checkType()) { ACTS_VERBOSE(volInfo(state) << "This is a surface"); @@ -512,9 +505,8 @@ class TryAllNavigator : public TryAllNavigatorBase { const auto& boundary = *candidate.template object(); - state.navigation.currentVolume = boundary.attachedVolume( - state.geoContext, stepper.position(state.stepping), - state.options.direction * stepper.direction(state.stepping)); + state.currentVolume = boundary.attachedVolume(state.options.geoContext, + position, direction); ACTS_VERBOSE(volInfo(state) << "Switched volume"); @@ -526,10 +518,9 @@ class TryAllNavigator : public TryAllNavigatorBase { private: /// Helper method to reset and reinitialize the navigation candidates. - template - void reinitializeCandidates(propagator_state_t& state) const { - state.navigation.navigationCandidates.clear(); - state.navigation.intersectionCandidates.clear(); + void reinitializeCandidates(State& state) const { + state.navigationCandidates.clear(); + state.currentCandidates.clear(); initializeVolumeCandidates(state); } @@ -560,22 +551,25 @@ class TryAllOverstepNavigator : public TryAllNavigatorBase { /// It acts as an internal state which is created for every propagation and /// meant to keep thread-local navigation information. struct State : public TryAllNavigatorBase::State { - /// The vector of navigation candidates to work through - std::vector navigationCandidates; + explicit State(const Options& options_) + : TryAllNavigatorBase::State(options_) {} + /// The vector of active intersection candidates to work through - std::vector activeCandidates; + std::vector activeCandidates; /// The current active candidate index of the navigation state - std::size_t activeCandidateIndex = 0; + int activeCandidateIndex = -1; /// The position before the last step std::optional lastPosition; - /// The last intersection used to avoid rehitting the same surface - std::optional lastIntersection; /// Provides easy access to the active intersection candidate - const detail::IntersectionCandidate& activeCandidate() const { + const detail::IntersectedNavigationObject& activeCandidate() const { return activeCandidates.at(activeCandidateIndex); } + + bool endOfCandidates() const { + return activeCandidateIndex >= static_cast(activeCandidates.size()); + } }; /// Constructor with configuration object @@ -589,10 +583,10 @@ class TryAllOverstepNavigator : public TryAllNavigatorBase { : TryAllNavigatorBase(std::move(cfg), std::move(logger)) {} State makeState(const Options& options) const { - State state; - state.options = options; + State state(options); state.startSurface = options.startSurface; state.targetSurface = options.targetSurface; + return state; } @@ -602,149 +596,85 @@ class TryAllOverstepNavigator : public TryAllNavigatorBase { using TryAllNavigatorBase::endOfWorldReached; using TryAllNavigatorBase::navigationBreak; using TryAllNavigatorBase::startSurface; - using TryAllNavigatorBase::targetReached; using TryAllNavigatorBase::targetSurface; - /// @brief Initialize call - start of navigation + /// @brief Initialize the navigator /// - /// @tparam propagator_state_t The state type of the propagator - /// @tparam stepper_t The type of stepper used for the propagation + /// This method initializes the navigator for a new propagation. It sets the + /// current volume and surface to the start volume and surface, respectively. /// - /// @param [in,out] state is the propagation state object - /// @param [in] stepper Stepper in use - template - void initialize(propagator_state_t& state, const stepper_t& stepper) const { - TryAllNavigatorBase::initialize(state, stepper); + /// @param state The navigation state + /// @param position The starting position + /// @param direction The starting direction + /// @param propagationDirection The propagation direction + void initialize(State& state, const Vector3& position, + const Vector3& direction, + Direction propagationDirection) const { + TryAllNavigatorBase::initialize(state, position, direction, + propagationDirection); // Initialize navigation candidates for the start volume reinitializeCandidates(state); - state.navigation.lastPosition.reset(); - state.navigation.lastIntersection.reset(); + state.lastPosition.reset(); } - /// @brief Navigator pre step call + /// @brief Get the next target surface /// - /// This determines the next surface to be targeted and sets the step length - /// accordingly. + /// This method gets the next target surface based on the current + /// position and direction. It returns an invalid target if no target can be + /// found. /// - /// @tparam propagator_state_t is the type of Propagatgor state - /// @tparam stepper_t is the used type of the Stepper by the Propagator + /// @param state The navigation state + /// @param position The current position + /// @param direction The current direction /// - /// @param [in,out] state is the mutable propagator state object - /// @param [in] stepper Stepper in use - template - void preStep(propagator_state_t& state, const stepper_t& stepper) const { - ACTS_VERBOSE(volInfo(state) << "pre step"); - - // Navigator preStep always resets the current surface - state.navigation.currentSurface = nullptr; - - ACTS_VERBOSE(volInfo(state) << "handle active candidates"); - - // Check next navigation candidate - while (state.navigation.activeCandidateIndex != - state.navigation.activeCandidates.size()) { - // Screen output how much is left to try - ACTS_VERBOSE(volInfo(state) - << (state.navigation.activeCandidates.size() - - state.navigation.activeCandidateIndex) - << " out of " << state.navigation.activeCandidates.size() - << " surfaces remain to try."); - - const auto& candidate = state.navigation.activeCandidate(); - const auto& intersection = candidate.intersection; - const Surface& surface = *intersection.object(); - BoundaryTolerance boundaryTolerance = candidate.boundaryTolerance; - - // Screen output which surface you are on - ACTS_VERBOSE(volInfo(state) << "Next surface candidate will be " - << surface.geometryId()); - - // Estimate the surface status - auto surfaceStatus = stepper.updateSurfaceStatus( - state.stepping, surface, intersection.index(), - state.options.direction, boundaryTolerance, - state.options.surfaceTolerance, logger()); - - if (surfaceStatus == IntersectionStatus::onSurface) { - ACTS_ERROR(volInfo(state) - << "We are on surface " << surface.geometryId() - << " before trying to reach it. This should not happen. " - "Good luck."); - ++state.navigation.activeCandidateIndex; - continue; - } + /// @return The next target surface + NavigationTarget nextTarget(State& state, const Vector3& position, + const Vector3& direction) const { + (void)direction; - if (surfaceStatus == IntersectionStatus::reachable) { - ACTS_VERBOSE(volInfo(state) - << "Surface reachable, step size updated to " - << stepper.outputStepSize(state.stepping)); - break; - } - - ACTS_VERBOSE(volInfo(state) << "Surface " << surface.geometryId() - << " unreachable, skip."); - ++state.navigation.activeCandidateIndex; + if (state.navigationBreak) { + return NavigationTarget::None(); } - if (state.navigation.activeCandidateIndex == - state.navigation.activeCandidates.size()) { - state.navigation.lastPosition = stepper.position(state.stepping); - - stepper.releaseStepSize(state.stepping, ConstrainedStep::actor); + ACTS_VERBOSE(volInfo(state) << "nextTarget"); - ACTS_VERBOSE(volInfo(state) - << "blindly step forwards. step size updated to " - << stepper.outputStepSize(state.stepping)); + state.currentSurface = nullptr; - return; + // We cannot do anything without a last position + if (!state.lastPosition.has_value() && state.endOfCandidates()) { + ACTS_VERBOSE( + volInfo(state) + << "Initial position, nothing to do, blindly stepping forward."); + state.lastPosition = position; + return NavigationTarget::None(); } - } - /// @brief Navigator post step call - /// - /// This determines if we hit the next navigation candidate and deals with it - /// accordingly. It sets the current surface, enters layers and changes - /// volumes. - /// - /// @tparam propagator_state_t is the type of Propagatgor state - /// @tparam stepper_t is the used type of the Stepper by the Propagator - /// - /// @param [in,out] state is the mutable propagator state object - /// @param [in] stepper Stepper in use - /// - /// @return Boolean to indicate if we continue with the actors and - /// aborters or if we should target again. - template - void postStep(propagator_state_t& state, const stepper_t& stepper) const { - ACTS_VERBOSE(volInfo(state) << "post step"); - - assert(state.navigation.currentSurface == nullptr && - "Current surface must be reset."); - - if (state.navigation.activeCandidateIndex == - state.navigation.activeCandidates.size()) { + if (state.endOfCandidates()) { ACTS_VERBOSE(volInfo(state) << "evaluate blind step"); - state.navigation.activeCandidates.clear(); - - assert(state.navigation.lastPosition.has_value() && - "last position not set"); + Vector3 stepStart = state.lastPosition.value(); + Vector3 stepEnd = position; + Vector3 step = stepEnd - stepStart; + double stepDistance = step.norm(); + if (stepDistance < std::numeric_limits::epsilon()) { + ACTS_ERROR(volInfo(state) << "Step distance is zero. " << stepDistance); + } + Vector3 stepDirection = step.normalized(); - Vector3 start = state.navigation.lastPosition.value(); - Vector3 end = stepper.position(state.stepping); - Vector3 step = end - start; - double distance = step.norm(); - Vector3 direction = step.normalized(); + double nearLimit = -stepDistance + state.options.surfaceTolerance; + double farLimit = 0; - double nearLimit = -distance + state.options.surfaceTolerance; - double farLimit = state.options.surfaceTolerance; + state.lastPosition.reset(); + state.activeCandidates.clear(); + state.activeCandidateIndex = -1; // Find intersections with all candidates - for (const auto& candidate : state.navigation.navigationCandidates) { - auto intersections = candidate.intersect( - state.geoContext, end, direction, state.options.surfaceTolerance); + for (const auto& candidate : state.navigationCandidates) { + auto intersections = + candidate.intersect(state.options.geoContext, stepEnd, + stepDirection, state.options.surfaceTolerance); for (const auto& intersection : intersections.first.split()) { // exclude invalid intersections if (!intersection.isValid() || @@ -752,140 +682,189 @@ class TryAllOverstepNavigator : public TryAllNavigatorBase { farLimit)) { continue; } - // exclude last candidate - if (state.navigation.lastIntersection.has_value() && - state.navigation.lastIntersection->object() == - intersection.object() && - state.navigation.lastIntersection->index() == - intersection.index()) { - continue; - } // store candidate - state.navigation.activeCandidates.emplace_back( + state.activeCandidates.emplace_back( intersection, intersections.second, candidate.boundaryTolerance); } } - std::ranges::sort(state.navigation.activeCandidates, - detail::IntersectionCandidate::forwardOrder); + std::ranges::sort(state.activeCandidates, + detail::IntersectedNavigationObject::forwardOrder); - state.navigation.activeCandidateIndex = 0; + ACTS_VERBOSE(volInfo(state) << "Found " << state.activeCandidates.size() + << " intersections"); + for (const auto& candidate : state.activeCandidates) { + ACTS_VERBOSE("found candidate " + << candidate.intersection.object()->geometryId()); + } + } + + ++state.activeCandidateIndex; + + if (state.endOfCandidates()) { ACTS_VERBOSE(volInfo(state) - << "Found " << state.navigation.activeCandidates.size() - << " intersections"); + << "No target found, blindly stepping forward."); + state.lastPosition = position; + return NavigationTarget::None(); } - if (state.navigation.activeCandidateIndex != - state.navigation.activeCandidates.size()) { - ACTS_VERBOSE(volInfo(state) << "handle active candidates"); + ACTS_VERBOSE(volInfo(state) << "handle active candidates"); - std::vector hitCandidates; + ACTS_VERBOSE(volInfo(state) + << (state.activeCandidates.size() - state.activeCandidateIndex) + << " out of " << state.activeCandidates.size() + << " surfaces remain to try."); - while (state.navigation.activeCandidateIndex != - state.navigation.activeCandidates.size()) { - const auto& candidate = state.navigation.activeCandidate(); - const auto& intersection = candidate.intersection; - const Surface& surface = *intersection.object(); + const auto& candidate = state.activeCandidate(); + const auto& intersection = candidate.intersection; + const Surface& surface = *intersection.object(); + BoundaryTolerance boundaryTolerance = candidate.boundaryTolerance; - IntersectionStatus surfaceStatus = stepper.updateSurfaceStatus( - state.stepping, surface, intersection.index(), - state.options.direction, BoundaryTolerance::Infinite(), - state.options.surfaceTolerance, logger()); + ACTS_VERBOSE(volInfo(state) + << "Next surface candidate will be " << surface.geometryId()); - if (surfaceStatus != IntersectionStatus::onSurface) { - break; - } + return NavigationTarget(surface, intersection.index(), boundaryTolerance); + } - hitCandidates.emplace_back(candidate); + /// @brief Check if the target is still valid + /// + /// This method checks if the target is valid based on the current position + /// and direction. It returns true if the target is still valid. + /// + /// @param state The navigation state + /// @param position The current position + /// @param direction The current direction + /// + /// @return True if the target is still valid + bool checkTargetValid(const State& state, const Vector3& position, + const Vector3& direction) const { + (void)state; + (void)position; + (void)direction; + + return true; + } - ++state.navigation.activeCandidateIndex; - } + /// @brief Handle the surface reached + /// + /// This method is called when a surface is reached. It sets the current + /// surface in the navigation state and updates the navigation candidates. + /// + /// @param state The navigation state + /// @param position The current position + /// @param direction The current direction + void handleSurfaceReached(State& state, const Vector3& position, + const Vector3& direction, + const Surface& /*surface*/) const { + if (state.navigationBreak) { + return; + } - if (hitCandidates.empty()) { - ACTS_VERBOSE(volInfo(state) << "Staying focussed on surface."); - return; - } + ACTS_VERBOSE(volInfo(state) << "handleSurfaceReached"); - state.navigation.lastIntersection.reset(); + assert(state.currentSurface == nullptr && "Current surface must be reset."); - std::vector trueHitCandidates; + if (state.endOfCandidates()) { + ACTS_VERBOSE(volInfo(state) << "No active candidate set."); + return; + } - for (const auto& candidate : hitCandidates) { - const auto& intersection = candidate.intersection; - const Surface& surface = *intersection.object(); + std::vector hitCandidates; - IntersectionStatus surfaceStatus = stepper.updateSurfaceStatus( - state.stepping, surface, intersection.index(), - state.options.direction, BoundaryTolerance::None(), - state.options.surfaceTolerance, logger()); + while (!state.endOfCandidates()) { + const auto& candidate = state.activeCandidate(); + const auto& intersection = candidate.intersection; + const Surface& surface = *intersection.object(); + BoundaryTolerance boundaryTolerance = candidate.boundaryTolerance; - if (surfaceStatus != IntersectionStatus::onSurface) { - continue; - } + // first with boundary tolerance + IntersectionStatus surfaceStatus = + surface + .intersect(state.options.geoContext, position, direction, + boundaryTolerance, + state.options.surfaceTolerance)[intersection.index()] + .status(); - trueHitCandidates.emplace_back(candidate); + if (surfaceStatus != IntersectionStatus::onSurface) { + break; } - ACTS_VERBOSE(volInfo(state) - << "Found " << trueHitCandidates.size() - << " intersections on surface with bounds check."); + // now without boundary tolerance + boundaryTolerance = BoundaryTolerance::None(); + surfaceStatus = + surface + .intersect(state.options.geoContext, position, direction, + boundaryTolerance, + state.options.surfaceTolerance)[intersection.index()] + .status(); - if (trueHitCandidates.empty()) { - ACTS_VERBOSE(volInfo(state) - << "Surface successfully hit, but outside bounds."); - return; + if (surfaceStatus == IntersectionStatus::onSurface) { + hitCandidates.emplace_back(candidate); } - if (trueHitCandidates.size() > 1) { - ACTS_VERBOSE(volInfo(state) - << "Only using first intersection within bounds."); - } + ++state.activeCandidateIndex; + ACTS_VERBOSE("skip candidate " << surface.geometryId()); + } - const auto& candidate = trueHitCandidates.front(); - const auto& intersection = candidate.intersection; - const Surface& surface = *intersection.object(); + // we increased the candidate index one too many times + --state.activeCandidateIndex; - state.navigation.lastIntersection = intersection; + ACTS_VERBOSE(volInfo(state) + << "Found " << hitCandidates.size() + << " intersections on surface with bounds check."); - ACTS_VERBOSE(volInfo(state) << "Surface successfully hit, storing it."); - // Set in navigation state, so actors and aborters can access it - state.navigation.currentSurface = &surface; - if (state.navigation.currentSurface) { - ACTS_VERBOSE(volInfo(state) << "Current surface set to surface " - << surface.geometryId()); - } + if (hitCandidates.empty()) { + ACTS_VERBOSE(volInfo(state) + << "Surface successfully hit, but outside bounds."); + return; + } - if (candidate.template checkType()) { - ACTS_VERBOSE(volInfo(state) << "This is a surface"); - } else if (candidate.template checkType()) { - ACTS_VERBOSE(volInfo(state) << "This is a layer"); - } else if (candidate.template checkType()) { - ACTS_VERBOSE(volInfo(state) - << "This is a boundary. Reinitialize navigation"); + if (hitCandidates.size() > 1) { + ACTS_VERBOSE(volInfo(state) + << "Only using first intersection within bounds."); + } - const auto& boundary = *candidate.template object(); + // we can only handle a single surface hit so we pick the first one + const auto& candidate = hitCandidates.front(); + const auto& intersection = candidate.intersection; + const Surface& surface = *intersection.object(); - state.navigation.currentVolume = boundary.attachedVolume( - state.geoContext, stepper.position(state.stepping), - state.options.direction * stepper.direction(state.stepping)); + ACTS_VERBOSE(volInfo(state) << "Surface successfully hit, storing it."); + state.currentSurface = &surface; - ACTS_VERBOSE(volInfo(state) << "Switched volume"); + if (state.currentSurface != nullptr) { + ACTS_VERBOSE(volInfo(state) << "Current surface set to surface " + << surface.geometryId()); + } - reinitializeCandidates(state); - } else { - ACTS_ERROR(volInfo(state) << "Unknown intersection type"); - } + if (candidate.template checkType()) { + ACTS_VERBOSE(volInfo(state) << "This is a surface"); + } else if (candidate.template checkType()) { + ACTS_VERBOSE(volInfo(state) << "This is a layer"); + } else if (candidate.template checkType()) { + ACTS_VERBOSE(volInfo(state) + << "This is a boundary. Reinitialize navigation"); + + const auto& boundary = *candidate.template object(); + + state.currentVolume = boundary.attachedVolume(state.options.geoContext, + position, direction); + + ACTS_VERBOSE(volInfo(state) << "Switched volume"); + + reinitializeCandidates(state); + } else { + ACTS_ERROR(volInfo(state) << "Unknown intersection type"); } } private: /// Helper method to reset and reinitialize the navigation candidates. - template - void reinitializeCandidates(propagator_state_t& state) const { - state.navigation.navigationCandidates.clear(); - state.navigation.activeCandidates.clear(); - state.navigation.activeCandidateIndex = 0; + void reinitializeCandidates(State& state) const { + state.navigationCandidates.clear(); + state.activeCandidates.clear(); + state.activeCandidateIndex = -1; initializeVolumeCandidates(state); } diff --git a/Core/include/Acts/Propagator/VoidNavigator.hpp b/Core/include/Acts/Propagator/VoidNavigator.hpp index 6b461f79210..d91b75450ec 100644 --- a/Core/include/Acts/Propagator/VoidNavigator.hpp +++ b/Core/include/Acts/Propagator/VoidNavigator.hpp @@ -8,28 +8,39 @@ #pragma once +#include "Acts/Definitions/Algebra.hpp" +#include "Acts/Definitions/Direction.hpp" +#include "Acts/Propagator/NavigationTarget.hpp" #include "Acts/Propagator/NavigatorOptions.hpp" #include "Acts/Propagator/NavigatorStatistics.hpp" + namespace Acts { class Surface; -/// @brief The void navigator struct as a default navigator +/// @brief A navigator that does nothing /// -/// It does not provide any navigation action, the compiler -/// should eventually optimise that the function call is not done +/// It does not provide any navigation action /// -struct VoidNavigator { +class VoidNavigator { + public: + /// @brief Nested Config struct struct Config {}; + /// @brief Nested Options struct struct Options : public NavigatorPlainOptions { + explicit Options(const GeometryContext& gctx) + : NavigatorPlainOptions(gctx) {} + void setPlainOptions(const NavigatorPlainOptions& options) { static_cast(*this) = options; } }; - /// @brief Nested State struct, minimal requirement + /// @brief Nested State struct struct State { + explicit State(const Options& options_) : options(options_) {} + Options options; /// Navigation statistics @@ -37,8 +48,7 @@ struct VoidNavigator { }; State makeState(const Options& options) const { - State state; - state.options = options; + State state(options); return state; } @@ -50,45 +60,29 @@ struct VoidNavigator { const Surface* targetSurface(const State& /*state*/) const { return nullptr; } - bool targetReached(const State& /*state*/) const { return false; } - - bool navigationBreak(const State& /*state*/) const { return false; } - - void currentSurface(State& /*state*/, const Surface* /*surface*/) const {} - - void targetReached(State& /*state*/, bool /*targetReached*/) const {} - - void navigationBreak(State& /*state*/, bool /*navigationBreak*/) const {} - - /// Navigation call - void - /// - /// @tparam propagator_state_t is the type of Propagatgor state - /// @tparam stepper_t Type of the Stepper - /// - /// Empty call, compiler should optimise that - template - void initialize(propagator_state_t& /*state*/, - const stepper_t& /*stepper*/) const {} - - /// Navigation call - void - /// - /// @tparam propagator_state_t is the type of Propagatgor state - /// @tparam stepper_t Type of the Stepper - /// - /// Empty call, compiler should optimise that - template - void preStep(propagator_state_t& /*state*/, - const stepper_t& /*stepper*/) const {} - - /// Navigation call - void - /// - /// @tparam propagator_state_t is the type of Propagatgor state - /// @tparam stepper_t Type of the Stepper - /// - /// Empty call, compiler should optimise that - template - void postStep(propagator_state_t& /*state*/, - const stepper_t& /*stepper*/) const {} + bool navigationBreak(const State& /*state*/) const { return true; } + + void initialize(State& /*state*/, const Vector3& /*position*/, + const Vector3& /*direction*/, + Direction /*propagationDirection*/) const { + return; + } + + NavigationTarget nextTarget(State& /*state*/, const Vector3& /*position*/, + const Vector3& /*direction*/) const { + return NavigationTarget::None(); + } + + bool checkTargetValid(const State& /*state*/, const Vector3& /*position*/, + const Vector3& /*direction*/) const { + return true; + } + + void handleSurfaceReached(State& /*state*/, const Vector3& /*position*/, + const Vector3& /*direction*/, + const Surface& /*surface*/) const { + return; + } }; } // namespace Acts diff --git a/Core/include/Acts/Propagator/detail/NavigationHelpers.hpp b/Core/include/Acts/Propagator/detail/NavigationHelpers.hpp index 8965dacae45..646606132b9 100644 --- a/Core/include/Acts/Propagator/detail/NavigationHelpers.hpp +++ b/Core/include/Acts/Propagator/detail/NavigationHelpers.hpp @@ -37,22 +37,19 @@ struct NavigationObjectCandidate { std::pair intersect( const GeometryContext& gctx, const Vector3& position, const Vector3& direction, double tolerance) const { + auto intersection = representation->intersect(gctx, position, direction, + boundaryTolerance, tolerance); + if (std::holds_alternative(object)) { const auto& surface = std::get(object); - auto intersection = representation->intersect( - gctx, position, direction, boundaryTolerance, tolerance); return {intersection, surface}; } if (std::holds_alternative(object)) { const auto& layer = std::get(object); - auto intersection = representation->intersect( - gctx, position, direction, boundaryTolerance, tolerance); return {intersection, layer}; } if (std::holds_alternative(object)) { const auto& boundary = std::get(object); - auto intersection = representation->intersect( - gctx, position, direction, boundaryTolerance, tolerance); return {intersection, boundary}; } throw std::runtime_error("unknown type"); @@ -61,14 +58,14 @@ struct NavigationObjectCandidate { /// Composes an intersection and a bounds check into a navigation candidate. /// This is used to consistently update intersections after creation. -struct IntersectionCandidate { +struct IntersectedNavigationObject { SurfaceIntersection intersection; - detail::AnyIntersectionObject anyObject; + AnyIntersectionObject anyObject; BoundaryTolerance boundaryTolerance; - IntersectionCandidate(SurfaceIntersection _intersection, - detail::AnyIntersectionObject _anyObject, - BoundaryTolerance _boundaryTolerance) + IntersectedNavigationObject(SurfaceIntersection _intersection, + AnyIntersectionObject _anyObject, + BoundaryTolerance _boundaryTolerance) : intersection(std::move(_intersection)), anyObject(_anyObject), boundaryTolerance(std::move(_boundaryTolerance)) {} @@ -83,8 +80,8 @@ struct IntersectionCandidate { return std::get(anyObject); } - static bool forwardOrder(const IntersectionCandidate& aCandidate, - const IntersectionCandidate& bCandidate) { + static bool forwardOrder(const IntersectedNavigationObject& aCandidate, + const IntersectedNavigationObject& bCandidate) { return Intersection3D::pathLengthOrder( aCandidate.intersection.intersection(), bCandidate.intersection.intersection()); @@ -93,7 +90,7 @@ struct IntersectionCandidate { /// @brief Emplace all navigation candidates for a given volume inline void emplaceAllVolumeCandidates( - std::vector& candidates, + std::vector& candidates, const TrackingVolume& volume, bool resolveSensitive, bool resolveMaterial, bool resolvePassive, const BoundaryTolerance& boundaryToleranceSurfaceApproach, diff --git a/Core/include/Acts/Propagator/detail/SteppingHelper.hpp b/Core/include/Acts/Propagator/detail/SteppingHelper.hpp index 48eaaffb2cf..9c7c77720c5 100644 --- a/Core/include/Acts/Propagator/detail/SteppingHelper.hpp +++ b/Core/include/Acts/Propagator/detail/SteppingHelper.hpp @@ -26,40 +26,48 @@ namespace Acts::detail { /// returns the status of the intersection to trigger onSurface in case /// the surface is reached. /// +/// @tparam stepper_t The type of stepper used for the propagation +/// +/// @param stepper [in] The stepper in use /// @param state [in,out] The stepping state (thread-local cache) /// @param surface [in] The surface provided +/// @param index [in] The surface intersection index +/// @param direction [in] The propagation direction /// @param boundaryTolerance [in] The boundary check for this status update +/// @param surfaceTolerance [in] Surface tolerance used for intersection +/// @param stype [in] The step size type to be set +/// @param logger [in] A @c Logger instance template -Acts::IntersectionStatus updateSingleSurfaceStatus( +IntersectionStatus updateSingleSurfaceStatus( const stepper_t& stepper, typename stepper_t::State& state, - const Surface& surface, std::uint8_t index, Direction navDir, + const Surface& surface, std::uint8_t index, Direction direction, const BoundaryTolerance& boundaryTolerance, double surfaceTolerance, - const Logger& logger) { + ConstrainedStep::Type stype, const Logger& logger) { ACTS_VERBOSE("Update single surface status for surface: " << surface.geometryId() << " index " << static_cast(index)); auto sIntersection = surface.intersect(state.options.geoContext, stepper.position(state), - navDir * stepper.direction(state), boundaryTolerance, + direction * stepper.direction(state), boundaryTolerance, surfaceTolerance)[index]; // The intersection is on surface already if (sIntersection.status() == IntersectionStatus::onSurface) { - // Release navigation step size - state.stepSize.release(ConstrainedStep::actor); ACTS_VERBOSE("Intersection: state is ON SURFACE"); + state.stepSize.release(stype); + stepper.updateStepSize(state, sIntersection.pathLength(), stype); return IntersectionStatus::onSurface; } const double nearLimit = std::numeric_limits::lowest(); - const double farLimit = state.stepSize.value(ConstrainedStep::aborter); + const double farLimit = std::numeric_limits::max(); if (sIntersection.isValid() && detail::checkPathLength(sIntersection.pathLength(), nearLimit, farLimit, logger)) { ACTS_VERBOSE("Surface is reachable"); - stepper.updateStepSize(state, sIntersection.pathLength(), - ConstrainedStep::actor); + stepper.releaseStepSize(state, stype); + stepper.updateStepSize(state, sIntersection.pathLength(), stype); return IntersectionStatus::reachable; } @@ -67,20 +75,4 @@ Acts::IntersectionStatus updateSingleSurfaceStatus( return IntersectionStatus::unreachable; } -/// Update the Step size - single component -/// -/// It takes a (valid) object intersection from the compatibleX(...) -/// calls in the geometry and updates the step size -/// -/// @param state [in,out] The stepping state (thread-local cache) -/// @param oIntersection [in] The object that yielded this step size -/// @param release [in] A release flag -template -void updateSingleStepSize(typename stepper_t::State& state, - const object_intersection_t& oIntersection, - bool release = true) { - double stepSize = oIntersection.pathLength(); - state.stepSize.update(stepSize, ConstrainedStep::actor, release); -} - } // namespace Acts::detail diff --git a/Core/include/Acts/Propagator/detail/SteppingLogger.hpp b/Core/include/Acts/Propagator/detail/SteppingLogger.hpp index ffdfcb84500..b5b95ff6487 100644 --- a/Core/include/Acts/Propagator/detail/SteppingLogger.hpp +++ b/Core/include/Acts/Propagator/detail/SteppingLogger.hpp @@ -33,7 +33,7 @@ namespace detail { /// later stage, the surface is referenced counted here. struct Step { ConstrainedStep stepSize; - Direction navDir; + Direction navDir = Direction::Forward(); Vector3 position = Vector3(0., 0., 0.); Vector3 momentum = Vector3(0., 0., 0.); std::shared_ptr surface = nullptr; diff --git a/Core/include/Acts/Seeding/BinnedGroupIterator.ipp b/Core/include/Acts/Seeding/BinnedGroupIterator.ipp index 8bcd0ac04b8..13427525f6c 100644 --- a/Core/include/Acts/Seeding/BinnedGroupIterator.ipp +++ b/Core/include/Acts/Seeding/BinnedGroupIterator.ipp @@ -85,7 +85,8 @@ void Acts::BinnedGroupIterator::findNotEmptyBin() { passesMask = m_group->mask().at(m_gridItr.globalBinIndex()); } // loop and only stop when we find a non-empty bin which is not masked - while ((dimCollection == 0ul || !passesMask) && ++m_gridItr != m_gridItrEnd) { + while ((dimCollection == 0ul || !passesMask) && + (++m_gridItr != m_gridItrEnd)) { dimCollection = (*m_gridItr).size(); if (dimCollection == 0ul) { continue; diff --git a/Core/include/Acts/Seeding/GbtsDataStorage.hpp b/Core/include/Acts/Seeding/GbtsDataStorage.hpp index 8c7ba861bcd..5adbff85cfc 100644 --- a/Core/include/Acts/Seeding/GbtsDataStorage.hpp +++ b/Core/include/Acts/Seeding/GbtsDataStorage.hpp @@ -29,20 +29,20 @@ struct GbtsSP { const space_point_t *SP; // want inside to have pointer int gbtsID; int combined_ID; - GbtsSP(const space_point_t *sp, int id, int combined_id) - : SP(sp), gbtsID(id), combined_ID{combined_id} { - if (SP->sourceLinks().size() == 1) { // pixels have 1 SL - m_isPixel = true; - } else { - m_isPixel = false; - } - m_phi = std::atan(SP->x() / SP->y()); + float m_phi; + float m_r; + float m_ClusterWidth; + GbtsSP(const space_point_t *sp, int id, int combined_id, float ClusterWidth) + : SP(sp), + gbtsID(id), + combined_ID{combined_id}, + m_ClusterWidth(ClusterWidth) { + m_phi = std::atan2(SP->y(), SP->x()); + m_r = std::sqrt((SP->x() * SP->x()) + (SP->y() * SP->y())); }; - bool isPixel() const { return m_isPixel; } - bool isSCT() const { return !m_isPixel; } float phi() const { return m_phi; } - bool m_isPixel; - float m_phi; + float r() const { return m_r; } + float ClusterWidth() const { return m_ClusterWidth; } }; template @@ -152,7 +152,7 @@ class GbtsDataStorage { return -1; } - int binIndex = pL->getEtaBin(sp.SP->z(), sp.SP->r()); + int binIndex = pL->getEtaBin(sp.SP->z(), sp.r()); if (binIndex == -1) { return -2; @@ -165,7 +165,7 @@ class GbtsDataStorage { float max_tau = 100.0; // can't do this bit yet as dont have cluster width if (useClusterWidth) { - float cluster_width = 1; // temporary while cluster width not available + float cluster_width = sp.ClusterWidth(); min_tau = 6.7 * (cluster_width - 0.2); max_tau = 1.6 + 0.15 / (cluster_width + 0.2) + 6.1 * (cluster_width - 0.2); @@ -176,7 +176,7 @@ class GbtsDataStorage { sp, min_tau, max_tau)); // adding ftf member to nodes } else { if (useClusterWidth) { - float cluster_width = 1; // temporary while cluster width not available + float cluster_width = sp.ClusterWidth(); if (cluster_width > 0.2) { return -3; } diff --git a/Core/include/Acts/Seeding/GbtsTrackingFilter.hpp b/Core/include/Acts/Seeding/GbtsTrackingFilter.hpp index c2111482947..9aeb444c30f 100644 --- a/Core/include/Acts/Seeding/GbtsTrackingFilter.hpp +++ b/Core/include/Acts/Seeding/GbtsTrackingFilter.hpp @@ -52,7 +52,7 @@ struct GbtsEdgeState { // x' = x*m_c + y*m_s // y' = -x*m_s + y*m_c - m_refY = pS->m_n2->m_spGbts.SP->r(); + m_refY = pS->m_n2->m_spGbts.r(); m_refX = pS->m_n2->m_spGbts.SP->x() * m_c + pS->m_n2->m_spGbts.SP->y() * m_s; @@ -67,7 +67,7 @@ struct GbtsEdgeState { m_Y[0] = pS->m_n2->m_spGbts.SP->z(); m_Y[1] = (pS->m_n1->m_spGbts.SP->z() - pS->m_n2->m_spGbts.SP->z()) / - (pS->m_n1->m_spGbts.SP->r() - pS->m_n2->m_spGbts.SP->r()); + (pS->m_n1->m_spGbts.r() - pS->m_n2->m_spGbts.r()); memset(&m_Cx[0][0], 0, sizeof(m_Cx)); memset(&m_Cy[0][0], 0, sizeof(m_Cy)); @@ -276,7 +276,7 @@ class GbtsTrackingFilter { x = pS->m_n1->m_spGbts.SP->x(); y = pS->m_n1->m_spGbts.SP->y(); z = pS->m_n1->m_spGbts.SP->z(); - r = pS->m_n1->m_spGbts.SP->r(); + r = pS->m_n1->m_spGbts.r(); refX = x * ts.m_c + y * ts.m_s; mx = -x * ts.m_s + y * ts.m_c; // measured X[0] diff --git a/Core/include/Acts/Seeding/SeedFinderGbts.ipp b/Core/include/Acts/Seeding/SeedFinderGbts.ipp index fb2722db616..a4bceca978e 100644 --- a/Core/include/Acts/Seeding/SeedFinderGbts.ipp +++ b/Core/include/Acts/Seeding/SeedFinderGbts.ipp @@ -10,7 +10,6 @@ // TODO: update to C++17 style #include "Acts/Geometry/Extent.hpp" -#include "Acts/Seeding/SeedFilter.hpp" #include "Acts/Seeding/SeedFinder.hpp" #include "Acts/Seeding/SeedFinderGbtsConfig.hpp" #include "Acts/Seeding/SeedFinderUtils.hpp" @@ -47,10 +46,6 @@ void SeedFinderGbts::loadSpacePoints( const std::vector>& gbtsSPvect) { ACTS_VERBOSE("Loading space points"); for (const auto& gbtssp : gbtsSPvect) { - bool is_Pixel = gbtssp.isPixel(); - if (!is_Pixel) { - continue; - } m_storage->addSpacePoint(gbtssp, (m_config.m_useClusterWidth > 0)); } @@ -166,11 +161,11 @@ void SeedFinderGbts::runGbts_TrackFinder( continue; } - float r1 = n1->m_spGbts.SP->r(); + float r1 = n1->m_spGbts.r(); float x1 = n1->m_spGbts.SP->x(); float y1 = n1->m_spGbts.SP->y(); float z1 = n1->m_spGbts.SP->z(); - float phi1 = std::atan(x1 / y1); + float phi1 = n1->m_spGbts.phi(); float minPhi = phi1 - deltaPhi; float maxPhi = phi1 + deltaPhi; @@ -199,7 +194,7 @@ void SeedFinderGbts::runGbts_TrackFinder( continue; } - float r2 = n2->m_spGbts.SP->r(); + float r2 = n2->m_spGbts.r(); float dr = r2 - r1; @@ -545,7 +540,7 @@ void SeedFinderGbts::runGbts_TrackFinder( for (unsigned int idx_m = 1; idx_m < vSP.size() - 1; idx_m++) { const GbtsSP& spM = *vSP.at(idx_m); - const double pS_r = spM.SP->r(); + const double pS_r = spM.r(); const double pS_x = spM.SP->x(); const double pS_y = spM.SP->y(); const double cosA = pS_x / pS_r; @@ -656,31 +651,32 @@ void SeedFinderGbts::createSeeds( return; } - m_triplets.clear(); // member of class , saying not declared, maybe public? + m_triplets.clear(); for (auto& track : vTracks) { for (auto& seed : track.m_seeds) { // access member of GbtsTrigTracklet - - float newQ = seed.Q(); // function of TrigInDetTriplet - if (m_config.m_LRTmode) { - // In LRT mode penalize pixels in Triplets - if (seed.s1().isPixel()) { - newQ += 1000; // functions of TrigSiSpacePointBase - } - if (seed.s2().isPixel()) { - newQ += 1000; - } - if (seed.s3().isPixel()) { - newQ += 1000; - } - } else { - // In normal (non LRT) mode penalise SSS by 1000, PSS (if enabled) and - // PPS by 10000 - if (seed.s3().isSCT()) { - newQ += seed.s1().isSCT() ? 1000.0 : 10000.0; - } - } - seed.Q(newQ); + // Currently not used, but leaving in to use concept in future development + // float newQ = seed.Q(); // function of TrigInDetTriplet + // if (m_config.m_LRTmode) { + // // In LRT mode penalize pixels in Triplets + // if (seed.s1().isPixel()) { + // newQ += 1000; // functions of TrigSiSpacePointBase + // } + // if (seed.s2().isPixel()) { + // newQ += 1000; + // } + // if (seed.s3().isPixel()) { + // newQ += 1000; + // } + // } else { + // // In normal (non LRT) mode penalise SSS by 1000, PSS (if enabled) + // and + // // PPS by 10000 + // if (seed.s3().isSCT()) { + // newQ += seed.s1().isSCT() ? 1000.0 : 10000.0; + // } + // } + // seed.Q(newQ); m_triplets.emplace_back(seed); } } diff --git a/Core/include/Acts/Seeding/SeedFinderGbtsConfig.hpp b/Core/include/Acts/Seeding/SeedFinderGbtsConfig.hpp index c1f0962a3ac..afaa7cadd07 100644 --- a/Core/include/Acts/Seeding/SeedFinderGbtsConfig.hpp +++ b/Core/include/Acts/Seeding/SeedFinderGbtsConfig.hpp @@ -20,9 +20,6 @@ // core algorithm so in acts namespace namespace Acts { -template -class SeedFilter; - template struct SeedFinderGbtsConfig { // // how many sigmas of scattering angle should be considered? @@ -31,16 +28,12 @@ struct SeedFinderGbtsConfig { // Seed cut float minPt = 400. * Acts::UnitConstants::MeV; - ///////////some declared not filled in by reco: ////// - std::shared_ptr> seedFilter; - // //detector ROI // // derived values, set on SeedFinder construction float highland = 0; float maxScatteringAngle2 = 0; // bool isInInternalUnits = false; /// for load space points - unsigned int maxSeedsPerSpM = 5; // Parameter which can loosen the tolerance of the track seed to form a // helix. This is useful for e.g. misaligned seeding. @@ -50,11 +43,11 @@ struct SeedFinderGbtsConfig { float m_nMaxPhiSlice = 53; // used to calculate phi slices bool m_useClusterWidth = false; // bool for use of cluster width in loadSpacePoints function - std::string connector_input_file; // input file for connector object + std::string ConnectorInputFile; // Path to the connector configuration file + // that defines the layer connections std::vector m_layerGeometry; // for runGbts_TrackFinder - bool m_LRTmode = true; // eventually want to set from full chain bool m_useEtaBinning = true; // bool to use eta binning from geometry structure bool m_doubletFilterRZ = true; // bool applies new Z cuts on doublets diff --git a/Core/include/Acts/Seeding/SeedFinderOrthogonal.ipp b/Core/include/Acts/Seeding/SeedFinderOrthogonal.ipp index a725d68e92d..9af243aa01a 100644 --- a/Core/include/Acts/Seeding/SeedFinderOrthogonal.ipp +++ b/Core/include/Acts/Seeding/SeedFinderOrthogonal.ipp @@ -11,7 +11,7 @@ #include "Acts/Seeding/SeedFinder.hpp" #include "Acts/Seeding/SeedFinderOrthogonalConfig.hpp" #include "Acts/Seeding/SeedFinderUtils.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include #include @@ -756,9 +756,9 @@ void SeedFinderOrthogonal::createSeeds( // variable middle SP radial region of interest const Acts::Range1D rMiddleSPRange( - std::floor(rRangeSPExtent.min(Acts::BinningValue::binR) / 2) * 2 + + std::floor(rRangeSPExtent.min(Acts::AxisDirection::AxisR) / 2) * 2 + m_config.deltaRMiddleMinSPRange, - std::floor(rRangeSPExtent.max(Acts::BinningValue::binR) / 2) * 2 - + std::floor(rRangeSPExtent.max(Acts::AxisDirection::AxisR) / 2) * 2 - m_config.deltaRMiddleMaxSPRange); /* diff --git a/Core/include/Acts/Surfaces/BoundaryTolerance.hpp b/Core/include/Acts/Surfaces/BoundaryTolerance.hpp index 5dfc7ad6552..b0fabd8ec64 100644 --- a/Core/include/Acts/Surfaces/BoundaryTolerance.hpp +++ b/Core/include/Acts/Surfaces/BoundaryTolerance.hpp @@ -54,19 +54,16 @@ namespace Acts { /// class BoundaryTolerance { public: - /// Infinite tolerance i.e. no boundary check - struct Infinite {}; + struct InfiniteParams {}; - /// No tolerance i.e. exact boundary check - struct None {}; + struct NoneParams {}; - /// Absolute tolerance in bound coordinates - struct AbsoluteBound { + struct AbsoluteBoundParams { double tolerance0{}; double tolerance1{}; - AbsoluteBound() = default; - AbsoluteBound(double tolerance0_, double tolerance1_) + AbsoluteBoundParams() = default; + AbsoluteBoundParams(double tolerance0_, double tolerance1_) : tolerance0(tolerance0_), tolerance1(tolerance1_) { if (tolerance0 < 0 || tolerance1 < 0) { throw std::invalid_argument( @@ -75,13 +72,12 @@ class BoundaryTolerance { } }; - /// Absolute tolerance in Cartesian coordinates - struct AbsoluteCartesian { + struct AbsoluteCartesianParams { double tolerance0{}; double tolerance1{}; - AbsoluteCartesian() = default; - AbsoluteCartesian(double tolerance0_, double tolerance1_) + AbsoluteCartesianParams() = default; + AbsoluteCartesianParams(double tolerance0_, double tolerance1_) : tolerance0(tolerance0_), tolerance1(tolerance1_) { if (tolerance0 < 0 || tolerance1 < 0) { throw std::invalid_argument( @@ -94,50 +90,65 @@ class BoundaryTolerance { } }; - /// Absolute tolerance in Euclidean distance - struct AbsoluteEuclidean { + struct AbsoluteEuclideanParams { double tolerance{}; - AbsoluteEuclidean() = default; - explicit AbsoluteEuclidean(double tolerance_) : tolerance(tolerance_) {} + AbsoluteEuclideanParams() = default; + explicit AbsoluteEuclideanParams(double tolerance_) + : tolerance(tolerance_) {} }; - /// Chi2 tolerance in bound coordinates - struct Chi2Bound { + struct Chi2BoundParams { double maxChi2{}; SquareMatrix2 weight = SquareMatrix2::Identity(); - Chi2Bound() = default; - Chi2Bound(const SquareMatrix2& weight_, double maxChi2_) + Chi2BoundParams() = default; + Chi2BoundParams(const SquareMatrix2& weight_, double maxChi2_) : maxChi2(maxChi2_), weight(weight_) {} }; + private: + /// Underlying variant type + using Variant = std::variant; + + /// Construct from variant + explicit BoundaryTolerance(Variant variant); + + public: + /// Infinite tolerance i.e. no boundary check + static auto Infinite() { return BoundaryTolerance{InfiniteParams{}}; } + + /// No tolerance i.e. exact boundary check + static auto None() { return BoundaryTolerance{NoneParams{}}; } + + /// Absolute tolerance in bound coordinates + static auto AbsoluteBound(double tolerance0, double tolerance1) { + return BoundaryTolerance{AbsoluteBoundParams{tolerance0, tolerance1}}; + } + + /// Absolute tolerance in Cartesian coordinates + static auto AbsoluteCartesian(double tolerance0, double tolerance1) { + return BoundaryTolerance{AbsoluteCartesianParams{tolerance0, tolerance1}}; + } + + /// Absolute tolerance in Euclidean distance + static auto AbsoluteEuclidean(double tolerance) { + return BoundaryTolerance{AbsoluteEuclideanParams{tolerance}}; + } + + /// Chi2 tolerance in bound coordinates + static auto Chi2Bound(const SquareMatrix2& weight, double maxChi2) { + return BoundaryTolerance{Chi2BoundParams{weight, maxChi2}}; + } + enum class ToleranceMode { Extend, // Extend the boundary None, // No tolerance Shrink // Shrink the boundary }; - /// Underlying variant type - using Variant = std::variant; - - /// Construct with infinite tolerance. - BoundaryTolerance(const Infinite& infinite); - /// Construct with no tolerance. - BoundaryTolerance(const None& none); - /// Construct with absolute tolerance in bound coordinates. - BoundaryTolerance(const AbsoluteBound& AbsoluteBound); - /// Construct with absolute tolerance in Cartesian coordinates. - BoundaryTolerance(const AbsoluteCartesian& absoluteCartesian); - /// Construct with absolute tolerance in Euclidean distance. - BoundaryTolerance(const AbsoluteEuclidean& absoluteEuclidean); - /// Construct with chi2 tolerance in bound coordinates. - BoundaryTolerance(const Chi2Bound& Chi2Bound); - - /// Construct from variant - BoundaryTolerance(Variant variant); - /// Check if the tolerance is infinite. bool isInfinite() const; /// Check if the is no tolerance. @@ -155,16 +166,16 @@ class BoundaryTolerance { ToleranceMode toleranceMode() const; /// Get the tolerance as absolute bound. - AbsoluteBound asAbsoluteBound(bool isCartesian = false) const; + AbsoluteBoundParams asAbsoluteBound(bool isCartesian = false) const; /// Get the tolerance as absolute Cartesian. - const AbsoluteCartesian& asAbsoluteCartesian() const; + const AbsoluteCartesianParams& asAbsoluteCartesian() const; /// Get the tolerance as absolute Euclidean. - const AbsoluteEuclidean& asAbsoluteEuclidean() const; + const AbsoluteEuclideanParams& asAbsoluteEuclidean() const; /// Get the tolerance as chi2 bound. - const Chi2Bound& asChi2Bound() const; + const Chi2BoundParams& asChi2Bound() const; /// Get the tolerance as absolute bound if possible. - std::optional asAbsoluteBoundOpt( + std::optional asAbsoluteBoundOpt( bool isCartesian = false) const; /// Check if the distance is tolerated. diff --git a/Core/include/Acts/Surfaces/ConeSurface.hpp b/Core/include/Acts/Surfaces/ConeSurface.hpp index 34ebaf49694..6f7886e2063 100644 --- a/Core/include/Acts/Surfaces/ConeSurface.hpp +++ b/Core/include/Acts/Surfaces/ConeSurface.hpp @@ -18,7 +18,7 @@ #include "Acts/Surfaces/RegularSurface.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Surfaces/SurfaceConcept.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Result.hpp" #include "Acts/Utilities/detail/RealQuadraticEquation.hpp" @@ -90,11 +90,11 @@ class ConeSurface : public RegularSurface { /// The binning position method - is overloaded for r-type binning /// /// @param gctx The current geometry context object, e.g. alignment - /// @param bValue defines the type of binning applied in the global frame + /// @param aDir defines the direction of binning applied in the global frame /// /// @return The return type is a vector for positioning in the global frame - Vector3 binningPosition(const GeometryContext& gctx, - BinningValue bValue) const final; + Vector3 referencePosition(const GeometryContext& gctx, + AxisDirection aDir) const final; /// Return the surface type SurfaceType type() const override; diff --git a/Core/include/Acts/Surfaces/CylinderSurface.hpp b/Core/include/Acts/Surfaces/CylinderSurface.hpp index 2f64852dbee..aa21bc667ad 100644 --- a/Core/include/Acts/Surfaces/CylinderSurface.hpp +++ b/Core/include/Acts/Surfaces/CylinderSurface.hpp @@ -18,7 +18,7 @@ #include "Acts/Surfaces/RegularSurface.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Surfaces/SurfaceConcept.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Logger.hpp" #include "Acts/Utilities/Result.hpp" #include "Acts/Utilities/detail/RealQuadraticEquation.hpp" @@ -95,11 +95,11 @@ class CylinderSurface : public RegularSurface { /// The binning position method - is overloaded for r-type binning /// /// @param gctx The current geometry context object, e.g. alignment - /// @param bValue is the type of global binning to be done + /// @param aDir is the axis Direction of global binning to be done /// /// @return is the global position to be used for binning - Vector3 binningPosition(const GeometryContext& gctx, - BinningValue bValue) const final; + Vector3 referencePosition(const GeometryContext& gctx, + AxisDirection aDir) const final; /// Return the measurement frame - this is needed for alignment, in particular /// The measurement frame of a cylinder is the tangential plane at a given @@ -254,14 +254,14 @@ class CylinderSurface : public RegularSurface { /// @note The surfaces need to be *compatible*, i.e. have cylinder bounds /// that align, and have the same radius /// @param other The other cylinder surface to merge with - /// @param direction The binning direction: either @c binZ or @c binRPhi + /// @param direction The axis direction: either @c AxisZ or @c AxisRPhi /// @param externalRotation If true, any phi rotation is done in the transform /// @param logger The logger to use /// @return The merged cylinder surface and a boolean indicating if surfaces are reversed /// @note The returned boolean is `false` if `this` is *left* or /// *counter-clockwise* of @p other, and `true` if not. std::pair, bool> mergedWith( - const CylinderSurface& other, BinningValue direction, + const CylinderSurface& other, AxisDirection direction, bool externalRotation, const Logger& logger = getDummyLogger()) const; protected: diff --git a/Core/include/Acts/Surfaces/DiscSurface.hpp b/Core/include/Acts/Surfaces/DiscSurface.hpp index 01e6bbd297c..f9d34b590a7 100644 --- a/Core/include/Acts/Surfaces/DiscSurface.hpp +++ b/Core/include/Acts/Surfaces/DiscSurface.hpp @@ -18,7 +18,7 @@ #include "Acts/Surfaces/RegularSurface.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Surfaces/SurfaceConcept.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Result.hpp" #include @@ -141,15 +141,24 @@ class DiscSurface : public RegularSurface { /// @return The normal vector Vector3 normal(const GeometryContext& gctx) const; - /// The binning position The position calculated - /// for a certain binning type + /// A reference position for a given axis direction /// /// @param gctx The current geometry context object, e.g. alignment - /// @param bValue The binning type to be used - /// + /// @param aDir The axis direction for the reference position request /// @return position that can beused for this binning - Vector3 binningPosition(const GeometryContext& gctx, - BinningValue bValue) const final; + Vector3 referencePosition(const GeometryContext& gctx, + AxisDirection aDir) const final; + + /// A reference position value for a given axis direction + /// + /// @param gctx The current geometry context object, e.g. alignment + /// @param aDir the value generated for the reference position + /// + /// @note This calls the parent method except for AxisR + /// + /// @return float to be used for the binning schema + double referencePositionValue(const GeometryContext& gctx, + AxisDirection aDir) const final; /// This method returns the bounds by reference const SurfaceBounds& bounds() const final; @@ -290,17 +299,6 @@ class DiscSurface : public RegularSurface { BoundaryTolerance::Infinite(), double tolerance = s_onSurfaceTolerance) const final; - /// Implement the binningValue - /// - /// @param gctx The current geometry context object, e.g. alignment - /// @param bValue is the dobule in which you want to bin - /// - /// @note This calls the parent method except for binR - /// - /// @return float to be used for the binning schema - double binningPositionValue(const GeometryContext& gctx, - BinningValue bValue) const final; - /// Return properly formatted class name for screen output std::string name() const override; @@ -330,14 +328,14 @@ class DiscSurface : public RegularSurface { /// @note The surfaces need to be *compatible*, i.e. have disc bounds /// that align /// @param other The other disc surface to merge with - /// @param direction The binning direction: either @c binR or @c binPhi + /// @param direction The binning direction: either @c AxisR or @c AxisPhi /// @param externalRotation If true, any phi rotation is done in the transform /// @param logger The logger to use /// @return The merged disc surface and a boolean indicating if surfaces are reversed /// @note The returned boolean is `false` if `this` is *left* or /// *counter-clockwise* of @p other, and `true` if not. std::pair, bool> mergedWith( - const DiscSurface& other, BinningValue direction, bool externalRotation, + const DiscSurface& other, AxisDirection direction, bool externalRotation, const Logger& logger = getDummyLogger()) const; protected: diff --git a/Core/include/Acts/Surfaces/LineSurface.hpp b/Core/include/Acts/Surfaces/LineSurface.hpp index 79660e17dca..2b1175c25b1 100644 --- a/Core/include/Acts/Surfaces/LineSurface.hpp +++ b/Core/include/Acts/Surfaces/LineSurface.hpp @@ -16,7 +16,7 @@ #include "Acts/Surfaces/BoundaryTolerance.hpp" #include "Acts/Surfaces/LineBounds.hpp" #include "Acts/Surfaces/Surface.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Result.hpp" #include @@ -91,11 +91,11 @@ class LineSurface : public Surface { /// for a certain binning type /// /// @param gctx The current geometry context object, e.g. alignment - /// @param bValue is the binning type to be used + /// @param aDir is the axis direction for the reference position request /// /// @return position that can beused for this binning - Vector3 binningPosition(const GeometryContext& gctx, - BinningValue bValue) const final; + Vector3 referencePosition(const GeometryContext& gctx, + AxisDirection aDir) const final; /// Return the measurement frame - this is needed for alignment, in particular /// diff --git a/Core/include/Acts/Surfaces/PlaneSurface.hpp b/Core/include/Acts/Surfaces/PlaneSurface.hpp index ddf968da2ea..0279443145d 100644 --- a/Core/include/Acts/Surfaces/PlaneSurface.hpp +++ b/Core/include/Acts/Surfaces/PlaneSurface.hpp @@ -17,7 +17,7 @@ #include "Acts/Surfaces/RegularSurface.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Surfaces/SurfaceConcept.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Result.hpp" #include @@ -102,15 +102,15 @@ class PlaneSurface : public RegularSurface { /// @return The normal vector Vector3 normal(const GeometryContext& gctx) const; - /// The binning position is the position calculated - /// for a certain binning type + /// The axis position is the position calculated + /// for a certain axis type /// /// @param gctx The current geometry context object, e.g. alignment - /// @param bValue is the binning type to be used + /// @param aDir is the axis direction of reference position request /// - /// @return position that can beused for this binning - Vector3 binningPosition(const GeometryContext& gctx, - BinningValue bValue) const final; + /// @return position that can be used for this axis + Vector3 referencePosition(const GeometryContext& gctx, + AxisDirection aDir) const final; /// Return the surface type SurfaceType type() const override; @@ -216,6 +216,20 @@ class PlaneSurface : public RegularSurface { ActsMatrix<2, 3> localCartesianToBoundLocalDerivative( const GeometryContext& gctx, const Vector3& position) const final; + /// Merge two plane surfaces into a single one. + /// @note The surfaces need to be *compatible*, i.e. have bounds + /// that align along merging direction, and have the same bound size + /// along the non-merging direction + /// @param other The other plane surface to merge with + /// @param direction The direction: either @c AxisX or @c AxisY + /// @param logger The logger to use + /// @return The merged plane surface and a boolean indicating if surfaces are reversed + /// @note The returned boolean is `false` if `this` is *left* or + /// *counter-clockwise* of @p other, and `true` if not. + std::pair, bool> mergedWith( + const PlaneSurface& other, AxisDirection direction, + const Logger& logger = getDummyLogger()) const; + protected: /// the bounds of this surface std::shared_ptr m_bounds; diff --git a/Core/include/Acts/Surfaces/SurfaceArray.hpp b/Core/include/Acts/Surfaces/SurfaceArray.hpp index ee40434f102..06212a90eec 100644 --- a/Core/include/Acts/Surfaces/SurfaceArray.hpp +++ b/Core/include/Acts/Surfaces/SurfaceArray.hpp @@ -11,7 +11,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Surfaces/Surface.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Grid.hpp" #include "Acts/Utilities/IAxis.hpp" @@ -107,7 +107,7 @@ class SurfaceArray { /// @brief The binning values described by this surface grid lookup /// They are in order of the axes (optional) and empty for eingle lookups - virtual std::vector binningValues() const { return {}; }; + virtual std::vector binningValues() const { return {}; }; /// Pure virtual destructor virtual ~ISurfaceGridLookup() = 0; @@ -139,7 +139,7 @@ class SurfaceArray { SurfaceGridLookup(std::function globalToLocal, std::function localToGlobal, std::tuple axes, - std::vector bValues = {}) + std::vector bValues = {}) : m_globalToLocal(std::move(globalToLocal)), m_localToGlobal(std::move(localToGlobal)), m_grid(std::move(axes)), @@ -149,7 +149,7 @@ class SurfaceArray { /// @brief Fill provided surfaces into the contained @c Grid. /// - /// This is done by iterating, accessing the binningPosition, lookup + /// This is done by iterating, accessing the referencePosition, lookup /// and append. /// Also populates the neighbor map by combining the filled bins of /// all bins around a given one. @@ -159,7 +159,7 @@ class SurfaceArray { void fill(const GeometryContext& gctx, const SurfaceVector& surfaces) override { for (const auto& srf : surfaces) { - Vector3 pos = srf->binningPosition(gctx, BinningValue::binR); + Vector3 pos = srf->referencePosition(gctx, AxisDirection::AxisR); lookup(pos).push_back(srf); } @@ -195,7 +195,8 @@ class SurfaceArray { minPath = std::numeric_limits::max(); for (const auto& srf : surfaces) { curPath = - (binCtr - srf->binningPosition(gctx, BinningValue::binR)).norm(); + (binCtr - srf->referencePosition(gctx, AxisDirection::AxisR)) + .norm(); if (curPath < minPath) { minPath = curPath; @@ -257,7 +258,7 @@ class SurfaceArray { /// @brief The binning values described by this surface grid lookup /// They are in order of the axes - std::vector binningValues() const override { + std::vector binningValues() const override { return m_binValues; } @@ -347,7 +348,7 @@ class SurfaceArray { std::function m_globalToLocal; std::function m_localToGlobal; Grid_t m_grid; - std::vector m_binValues; + std::vector m_binValues; std::vector m_neighborMap; }; @@ -519,7 +520,7 @@ class SurfaceArray { /// @brief The binning values described by this surface grid lookup /// They are in order of the axes - std::vector binningValues() const { + std::vector binningValues() const { return p_gridLookup->binningValues(); }; diff --git a/Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp b/Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp index e2ffcf9bc11..9c1aa02196d 100644 --- a/Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp +++ b/Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp @@ -25,7 +25,8 @@ #include "Acts/Propagator/detail/LoopProtection.hpp" #include "Acts/Propagator/detail/PointwiseMaterialInteraction.hpp" #include "Acts/TrackFinding/CombinatorialKalmanFilterError.hpp" -#include "Acts/TrackFitting/KalmanFitter.hpp" +#include "Acts/TrackFinding/CombinatorialKalmanFilterExtensions.hpp" +#include "Acts/TrackFinding/TrackStateCreator.hpp" #include "Acts/TrackFitting/detail/VoidFitterComponents.hpp" #include "Acts/Utilities/CalibrationContext.hpp" #include "Acts/Utilities/Logger.hpp" @@ -39,97 +40,12 @@ namespace Acts { -/// Return type of the `BranchStopper` delegate for the -/// CombinatorialKalmanFilter -enum class CombinatorialKalmanFilterBranchStopperResult { - Continue, - StopAndDrop, - StopAndKeep, -}; - -/// Extension struct which holds the delegates to customize the CKF behavior -template -struct CombinatorialKalmanFilterExtensions { - using traj_t = typename track_container_t::TrackStateContainerBackend; - using candidate_container_t = - typename std::vector; - using TrackProxy = typename track_container_t::TrackProxy; - using TrackStateProxy = typename track_container_t::TrackStateProxy; - - using BranchStopperResult = CombinatorialKalmanFilterBranchStopperResult; - - using Calibrator = typename KalmanFitterExtensions::Calibrator; - using Updater = typename KalmanFitterExtensions::Updater; - using MeasurementSelector = - Delegate>( - candidate_container_t& trackStates, bool&, const Logger&)>; - using BranchStopper = - Delegate; - - /// The Calibrator is a dedicated calibration algorithm that allows to - /// calibrate measurements using track information, this could be e.g. sagging - /// for wires, module deformations, etc. - Calibrator calibrator{ - DelegateFuncTag>{}}; - - /// The updater incorporates measurement information into the track parameters - Updater updater{DelegateFuncTag>{}}; - - /// The measurement selector is called during the filtering by the Actor. - MeasurementSelector measurementSelector{ - DelegateFuncTag{}}; - - /// The branch stopper is called during the filtering by the Actor. - BranchStopper branchStopper{DelegateFuncTag{}}; - - private: - /// Default measurement selector which will return all measurements - /// @param candidates Measurement track state candidates - static Result::iterator, - typename std::vector::iterator>> - voidMeasurementSelector(typename std::vector& candidates, - bool& /*isOutlier*/, const Logger& /*logger*/) { - return std::pair{candidates.begin(), candidates.end()}; - }; - - /// Default branch stopper which will never stop - /// @return false - static BranchStopperResult voidBranchStopper( - const TrackProxy& /*track*/, const TrackStateProxy& /*trackState*/) { - return BranchStopperResult::Continue; - } -}; - -/// Delegate type that retrieves a range of source links to for a given surface -/// to be processed by the CKF -template -using SourceLinkAccessorDelegate = - Delegate( - const Surface&)>; - -/// expected max number of track states that are expected to be added by -/// stateCandidateCreator -/// @note if the number of states exceeds this number dynamic memory allocation will occur. -/// the number is chosen to yield a container size of 64 bytes. -static constexpr std::size_t s_maxBranchesPerSurface = 10; - -namespace CkfTypes { - -template -using BranchVector = boost::container::small_vector; - -} // namespace CkfTypes - /// Combined options for the combinatorial Kalman filter. /// /// @tparam source_link_iterator_t Type of the source link iterator /// @tparam track_container_t Type of the track container -template +template struct CombinatorialKalmanFilterOptions { - using SourceLinkIterator = source_link_iterator_t; - using SourceLinkAccessor = SourceLinkAccessorDelegate; - using TrackStateContainerBackend = typename track_container_t::TrackStateContainerBackend; using TrackStateProxy = typename track_container_t::TrackStateProxy; @@ -139,7 +55,6 @@ struct CombinatorialKalmanFilterOptions { /// @param gctx The geometry context for this track finding/fitting /// @param mctx The magnetic context for this track finding/fitting /// @param cctx The calibration context for this track finding/fitting - /// @param accessor_ The source link accessor /// @param extensions_ The extension struct /// @param pOptions The plain propagator options /// @param mScattering Whether to include multiple scattering @@ -147,14 +62,12 @@ struct CombinatorialKalmanFilterOptions { CombinatorialKalmanFilterOptions( const GeometryContext& gctx, const MagneticFieldContext& mctx, std::reference_wrapper cctx, - SourceLinkAccessor accessor_, CombinatorialKalmanFilterExtensions extensions_, const PropagatorPlainOptions& pOptions, bool mScattering = true, bool eLoss = true) : geoContext(gctx), magFieldContext(mctx), calibrationContext(cctx), - sourceLinkAccessor(std::move(accessor_)), extensions(extensions_), propagatorPlainOptions(pOptions), multipleScattering(mScattering), @@ -170,9 +83,6 @@ struct CombinatorialKalmanFilterOptions { /// context object for the calibration std::reference_wrapper calibrationContext; - /// The source link accessor - SourceLinkAccessor sourceLinkAccessor; - /// The filter extensions CombinatorialKalmanFilterExtensions extensions; @@ -184,39 +94,6 @@ struct CombinatorialKalmanFilterOptions { /// certain surface const Surface* targetSurface = nullptr; - using BoundState = std::tuple; - - /// Delegate definition to create track states for selected measurements - /// - /// @note expected to iterator over the given sourceLink range, - /// select measurements, and create track states for - /// which new tips are to be created, more over the outlier - /// flag should be set for states that are outlier. - /// - /// @param geoContext The current geometry context - /// @param calibrationContext pointer to the current calibration context - /// @param surface the surface at which new track states are to be created - /// @param boundState the current bound state of the trajectory - /// @param slBegin Begin iterator for sourceLinks - /// @param slEnd End iterator for sourceLinks - /// @param prevTip Index pointing at previous trajectory state (i.e. tip) - /// @param bufferTrajectory a temporary trajectory which can be used to create temporary track states - /// @param trackStateCandidates a temporary buffer that can be used to collect track states - /// @param trajectory the trajectory to which the new states are to be added - /// @param logger a logger for messages - using TrackStateCandidateCreator = - Delegate>( - const GeometryContext& geoContext, - const CalibrationContext& calibrationContext, const Surface& surface, - const BoundState& boundState, source_link_iterator_t slBegin, - source_link_iterator_t slEnd, TrackIndexType prevTip, - TrackStateContainerBackend& bufferTrajectory, - std::vector& trackStateCandidates, - TrackStateContainerBackend& trajectory, const Logger& logger)>; - - /// The delegate to create new track states. - TrackStateCandidateCreator trackStateCandidateCreator; - /// Whether to consider multiple scattering. bool multipleScattering = true; @@ -247,7 +124,7 @@ struct CombinatorialKalmanFilterResult { /// Indices into `tracks` which mark active branches std::vector collectedTracks; - /// Track state candidates buffer + /// Track state candidates buffer which can be used by the track state creator std::vector trackStateCandidates; /// Indicator if track finding has been done @@ -309,190 +186,13 @@ class CombinatorialKalmanFilter { const Logger& logger() const { return *m_logger; } - struct DefaultTrackStateCreator { - typename CombinatorialKalmanFilterExtensions::Calibrator - calibrator; - typename CombinatorialKalmanFilterExtensions< - track_container_t>::MeasurementSelector measurementSelector; - - /// Create track states for selected measurements given by the source links - /// - /// @param gctx The current geometry context - /// @param calibrationContext pointer to the current calibration context - /// @param surface the surface the sourceLinks are associated to - /// @param boundState Bound state from the propagation on this surface - /// @param slBegin Begin iterator for sourceLinks - /// @param slEnd End iterator for sourceLinks - /// @param prevTip Index pointing at previous trajectory state (i.e. tip) - /// @param bufferTrajectory a buffer for temporary candidate track states - /// @param trackStateCandidates a buffer for temporary track state proxies for candidates - /// @param trajectory the trajectory to which new track states for selected measurements will be added - /// @param logger the logger for messages. - template - Result> createSourceLinkTrackStates( - const GeometryContext& gctx, - const CalibrationContext& calibrationContext, - [[maybe_unused]] const Surface& surface, const BoundState& boundState, - source_link_iterator_t slBegin, source_link_iterator_t slEnd, - TrackIndexType prevTip, TrackStateContainerBackend& bufferTrajectory, - std::vector& trackStateCandidates, - TrackStateContainerBackend& trajectory, const Logger& logger) const { - using PM = TrackStatePropMask; - - using ResultTrackStateList = - Acts::Result>; - ResultTrackStateList resultTrackStateList{ - CkfTypes::BranchVector()}; - const auto& [boundParams, jacobian, pathLength] = boundState; - - trackStateCandidates.clear(); - if constexpr (std::ranges::random_access_range) { - trackStateCandidates.reserve(std::distance(slBegin, slEnd)); - } - - // Calibrate all the source links on the surface since the selection has - // to be done based on calibrated measurement - for (auto it = slBegin; it != slEnd; ++it) { - // get the source link - const auto sourceLink = *it; - - // prepare the track state - PM mask = PM::Predicted | PM::Jacobian | PM::Calibrated; - if (it != slBegin) { - // not the first TrackState, only need uncalibrated and calibrated - mask = PM::Calibrated; - } - - ACTS_VERBOSE("Create temp track state with mask: " << mask); - // CAREFUL! This trackstate has a previous index that is not in this - // MultiTrajectory Visiting backwards from this track state will - // fail! - auto ts = bufferTrajectory.makeTrackState(mask, prevTip); - - if (it == slBegin) { - // only set these for first - ts.predicted() = boundParams.parameters(); - if (boundParams.covariance()) { - ts.predictedCovariance() = *boundParams.covariance(); - } - ts.jacobian() = jacobian; - } else { - // subsequent track states can reuse - auto& first = trackStateCandidates.front(); - ts.shareFrom(first, PM::Predicted); - ts.shareFrom(first, PM::Jacobian); - } - - ts.pathLength() = pathLength; - ts.setReferenceSurface(boundParams.referenceSurface().getSharedPtr()); - - // now calibrate the track state - calibrator(gctx, calibrationContext, sourceLink, ts); - - trackStateCandidates.push_back(ts); - } - - bool isOutlier = false; - Result::iterator, - typename std::vector::iterator>> - selectorResult = - measurementSelector(trackStateCandidates, isOutlier, logger); - if (!selectorResult.ok()) { - ACTS_ERROR("Selection of calibrated measurements failed: " - << selectorResult.error().message()); - resultTrackStateList = - ResultTrackStateList::failure(selectorResult.error()); - } else { - auto selectedTrackStateRange = *selectorResult; - resultTrackStateList = processSelectedTrackStates( - selectedTrackStateRange.first, selectedTrackStateRange.second, - trajectory, isOutlier, logger); - } - - return resultTrackStateList; - } - - /// Create track states for the given trajectory from candidate track states - /// - /// @param begin begin iterator of the list of candidate track states - /// @param end end iterator of the list of candidate track states - /// @param trackStates the trajectory to which the new track states are added - /// @param isOutlier true if the candidate(s) is(are) an outlier(s). - /// @param logger the logger for messages - Result> processSelectedTrackStates( - typename std::vector::const_iterator begin, - typename std::vector::const_iterator end, - TrackStateContainerBackend& trackStates, bool isOutlier, - const Logger& logger) const { - using PM = TrackStatePropMask; - - using ResultTrackStateList = - Acts::Result>; - ResultTrackStateList resultTrackStateList{ - CkfTypes::BranchVector()}; - CkfTypes::BranchVector& trackStateList = - *resultTrackStateList; - trackStateList.reserve(end - begin); - - std::optional firstTrackState{std::nullopt}; - for (auto it = begin; it != end; ++it) { - auto& candidateTrackState = *it; - - PM mask = PM::Predicted | PM::Filtered | PM::Jacobian | PM::Calibrated; - if (it != begin) { - // subsequent track states don't need storage for these as they will - // be shared - mask &= ~PM::Predicted & ~PM::Jacobian; - } - if (isOutlier) { - // outlier won't have separate filtered parameters - mask &= ~PM::Filtered; - } - - // copy this trackstate into fitted states MultiTrajectory - auto trackState = - trackStates.makeTrackState(mask, candidateTrackState.previous()); - ACTS_VERBOSE("Create SourceLink output track state #" - << trackState.index() << " with mask: " << mask); - - if (it != begin) { - // assign indices pointing to first track state - trackState.shareFrom(*firstTrackState, PM::Predicted); - trackState.shareFrom(*firstTrackState, PM::Jacobian); - } else { - firstTrackState = trackState; - } - - // either copy ALL or everything except for predicted and jacobian - trackState.copyFrom(candidateTrackState, mask, false); - - auto typeFlags = trackState.typeFlags(); - typeFlags.set(TrackStateFlag::ParameterFlag); - typeFlags.set(TrackStateFlag::MeasurementFlag); - if (trackState.referenceSurface().surfaceMaterial() != nullptr) { - typeFlags.set(TrackStateFlag::MaterialFlag); - } - if (isOutlier) { - // propagate information that this is an outlier state - ACTS_VERBOSE( - "Creating outlier track state with tip = " << trackState.index()); - typeFlags.set(TrackStateFlag::OutlierFlag); - } - - trackStateList.push_back(trackState.index()); - } - return resultTrackStateList; - } - }; - /// @brief Propagator Actor plugin for the CombinatorialKalmanFilter /// - /// @tparam source_link_accessor_t The type of source link accessor /// @tparam parameters_t The type of parameters used for "local" parameters. /// /// The CombinatorialKalmanFilter Actor does not rely on the measurements to /// be sorted along the track. - template + template class Actor { public: using BoundState = std::tuple; @@ -622,7 +322,8 @@ class CombinatorialKalmanFilter { boundParams.referenceSurface().getSharedPtr()); } - stepper.releaseStepSize(state.stepping, ConstrainedStep::actor); + stepper.releaseStepSize(state.stepping, + ConstrainedStep::Type::Navigator); } // Record the active branch and remove it from the list @@ -682,7 +383,9 @@ class CombinatorialKalmanFilter { navigationOptions.startSurface = ¤tState.referenceSurface(); navigationOptions.targetSurface = nullptr; state.navigation = navigator.makeState(navigationOptions); - navigator.initialize(state, stepper); + navigator.initialize(state.navigation, stepper.position(state.stepping), + stepper.direction(state.stepping), + state.options.direction); // No Kalman filtering for the starting surface, but still need // to consider the material effects here @@ -735,20 +438,6 @@ class CombinatorialKalmanFilter { return Result::success(); } - using SourceLinkRange = decltype(m_sourceLinkAccessor(*surface)); - std::optional slRange = std::nullopt; - bool hasMeasurements = false; - if (isSensitive) { - slRange = m_sourceLinkAccessor(*surface); - hasMeasurements = slRange->first != slRange->second; - } - bool isHole = isSensitive && expectMeasurements && !hasMeasurements; - - if (isHole) { - ACTS_VERBOSE("Detected hole before measurement selection on surface " - << surface->geometryId()); - } - // Transport the covariance to the surface if (isMaterialOnly) { stepper.transportCovarianceToCurvilinear(state.stepping); @@ -772,20 +461,20 @@ class CombinatorialKalmanFilter { auto currentBranch = result.activeBranches.back(); TrackIndexType prevTip = currentBranch.tipIndex(); - // Create trackstates for all source links (will be filtered later) using TrackStatesResult = Acts::Result>; TrackStatesResult tsRes = TrackStatesResult::success({}); - if (hasMeasurements) { - auto [slBegin, slEnd] = *slRange; - - tsRes = trackStateCandidateCreator( + if (isSensitive) { + // extend trajectory with measurements associated to the current surface + // which may create extra trajectory branches if more than one + // measurement is selected. + tsRes = m_extensions.createTrackStates( state.geoContext, *calibrationContextPtr, *surface, boundState, - slBegin, slEnd, prevTip, *result.trackStates, - result.trackStateCandidates, *result.trackStates, logger()); + prevTip, result.trackStateCandidates, *result.trackStates, + logger()); if (!tsRes.ok()) { - ACTS_ERROR( - "Processing of selected track states failed: " << tsRes.error()); + ACTS_ERROR("Track state creation failed on surface " + << surface->geometryId() << ": " << tsRes.error()); return tsRes.error(); } } @@ -1101,23 +790,6 @@ class CombinatorialKalmanFilter { CombinatorialKalmanFilterExtensions m_extensions; - /// The source link accessor - source_link_accessor_t m_sourceLinkAccessor; - - using SourceLinkIterator = - decltype(std::declval(nullptr)))>() - .first); - - using TrackStateCandidateCreator = - typename CombinatorialKalmanFilterOptions< - SourceLinkIterator, track_container_t>::TrackStateCandidateCreator; - - /// the stateCandidator to be used - /// @note will be set to a default trackStateCandidateCreator or the one - // provided via the extension - TrackStateCandidateCreator trackStateCandidateCreator; - /// End of world aborter EndOfWorldReached endOfWorldReached; @@ -1149,7 +821,6 @@ class CombinatorialKalmanFilter { public: /// Combinatorial Kalman Filter implementation, calls the Kalman filter /// - /// @tparam source_link_iterator_t Type of the source link iterator /// @tparam start_parameters_t Type of the initial parameters /// @tparam parameters_t Type of parameters used for local parameters /// @@ -1165,21 +836,17 @@ class CombinatorialKalmanFilter { /// /// @return a container of track finding result for all the initial track /// parameters - template - auto findTracks(const start_parameters_t& initialParameters, - const CombinatorialKalmanFilterOptions< - source_link_iterator_t, track_container_t>& tfOptions, - track_container_t& trackContainer, - typename track_container_t::TrackProxy rootBranch) const + auto findTracks( + const start_parameters_t& initialParameters, + const CombinatorialKalmanFilterOptions& tfOptions, + track_container_t& trackContainer, + typename track_container_t::TrackProxy rootBranch) const -> Result::TrackProxy>> { - using SourceLinkAccessor = - SourceLinkAccessorDelegate; - // Create the ActorList - using CombinatorialKalmanFilterActor = - Actor; + using CombinatorialKalmanFilterActor = Actor; using Actors = ActorList; // Create relevant options for the propagation options @@ -1202,22 +869,8 @@ class CombinatorialKalmanFilter { combKalmanActor.updaterLogger = m_updaterLogger.get(); combKalmanActor.calibrationContextPtr = &tfOptions.calibrationContext.get(); - // copy source link accessor, calibrator and measurement selector - combKalmanActor.m_sourceLinkAccessor = tfOptions.sourceLinkAccessor; + // copy delegates to calibrator, updater, branch stopper combKalmanActor.m_extensions = tfOptions.extensions; - combKalmanActor.trackStateCandidateCreator = - tfOptions.trackStateCandidateCreator; - DefaultTrackStateCreator defaultTrackStateCreator; - // connect a default state candidate creator if no state candidate creator - // was provided via the extension - if (!combKalmanActor.trackStateCandidateCreator.connected()) { - defaultTrackStateCreator.calibrator = tfOptions.extensions.calibrator; - defaultTrackStateCreator.measurementSelector = - tfOptions.extensions.measurementSelector; - combKalmanActor.trackStateCandidateCreator.template connect< - &DefaultTrackStateCreator::template createSourceLinkTrackStates< - source_link_iterator_t>>(&defaultTrackStateCreator); - } auto propState = m_propagator.template makeState - auto findTracks(const start_parameters_t& initialParameters, - const CombinatorialKalmanFilterOptions< - source_link_iterator_t, track_container_t>& tfOptions, - track_container_t& trackContainer) const + auto findTracks( + const start_parameters_t& initialParameters, + const CombinatorialKalmanFilterOptions& tfOptions, + track_container_t& trackContainer) const -> Result::TrackProxy>> { auto rootBranch = trackContainer.makeTrack(); diff --git a/Core/include/Acts/TrackFinding/CombinatorialKalmanFilterExtensions.hpp b/Core/include/Acts/TrackFinding/CombinatorialKalmanFilterExtensions.hpp new file mode 100644 index 00000000000..f503d0b5c4a --- /dev/null +++ b/Core/include/Acts/TrackFinding/CombinatorialKalmanFilterExtensions.hpp @@ -0,0 +1,99 @@ +// 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/TrackFitting/KalmanFitter.hpp" +#include "Acts/Utilities/Result.hpp" + +#include + +namespace Acts { + +namespace CkfTypes { + +/// expected max number of track states that are expected to be added by +/// stateCandidateCreator +/// @note if the number of states exceeds this number dynamic memory allocation will occur. +/// the number is chosen to yield a container size of 64 bytes. + +static constexpr std::size_t s_maxBranchesPerSurface = 10; +template +using BranchVector = boost::container::small_vector; + +using BoundState = std::tuple; + +} // namespace CkfTypes + +/// Return type of the `BranchStopper` delegate for the +/// CombinatorialKalmanFilter +enum class CombinatorialKalmanFilterBranchStopperResult { + Continue, + StopAndDrop, + StopAndKeep, +}; + +/// Extension struct which holds the delegates to customize the CKF behavior +template +struct CombinatorialKalmanFilterExtensions { + using traj_t = typename track_container_t::TrackStateContainerBackend; + using TrackProxy = typename track_container_t::TrackProxy; + using TrackStateProxy = typename track_container_t::TrackStateProxy; + + using BranchStopperResult = CombinatorialKalmanFilterBranchStopperResult; + + using Updater = typename KalmanFitterExtensions::Updater; + using BranchStopper = + Delegate; + + /// The updater incorporates measurement information into the track parameters + Updater updater{DelegateFuncTag>{}}; + + /// The branch stopper is called during the filtering by the Actor. + BranchStopper branchStopper{DelegateFuncTag{}}; + + /// @brief Delegate the extension of the trajectory onto the given surface to + /// an external unit. + /// + /// @note Expected to create track states for measurements associated to the + /// given surface which match the given bound state. Moreover the + /// The "filtered" data is not expected to be set, but the outlier + /// flag should be set for states that are considered to be outlier. + /// + /// @param geoContext The current geometry context + /// @param calibrationContext pointer to the current calibration context + /// @param surface the surface at which new track states are to be created + /// @param boundState the current bound state of the trajectory + /// @param prevTip Index pointing at previous trajectory state (i.e. tip) + /// @param trackStateCandidates a temporary buffer that can be used to collect track states + /// @param trajectory the trajectory to which the new states are to be added + /// @param logger a logger for messages + /// @return indices of new track states which extend the trajectory given by prevTip + + using TrackStateCreator = + Delegate>( + const GeometryContext& geoContext, + const CalibrationContext& calibrationContext, const Surface& surface, + const CkfTypes::BoundState& boundState, TrackIndexType prevTip, + std::vector& trackStateCandidates, + traj_t& trajectory, const Logger& logger)>; + + /// The delegate to create new track states. + /// @note a reference implementation can be found in @ref TrackStateCreator + /// which makes uses of @ref MeasurementSelector and SourceLinkAccessor + TrackStateCreator createTrackStates; + + private: + /// Default branch stopper which will never stop + /// @return false + static BranchStopperResult voidBranchStopper( + const TrackProxy& /*track*/, const TrackStateProxy& /*trackState*/) { + return BranchStopperResult::Continue; + } +}; +} // namespace Acts diff --git a/Core/include/Acts/TrackFinding/TrackStateCreator.hpp b/Core/include/Acts/TrackFinding/TrackStateCreator.hpp new file mode 100644 index 00000000000..cecaaf3b719 --- /dev/null +++ b/Core/include/Acts/TrackFinding/TrackStateCreator.hpp @@ -0,0 +1,294 @@ +// 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 + +// for definitions of Calibrator, MeasurementSelector +#include "Acts/TrackFinding/CombinatorialKalmanFilterExtensions.hpp" +#include "Acts/TrackFitting/KalmanFitter.hpp" + +namespace Acts { + +/// @brief Create track states for selected measurements associated to a surface. +/// +/// - First get a source link range covering relevant measurements associated to +/// the given surface. This task is delegated to a SourceLinkAccessor. +/// - Then create temporary track states for all measurements defined +/// by a source link range, calibrate the measurements and fill the +/// the calibrated data of these track states using a dedicated calibrator +/// - The measurement selection is delegated to a dedicated measurement +/// selector. +/// - Finally add branches to the given trajectory for the selected, temporary +/// track states. The track states of these branches still lack the filtered +/// data which is to be filled by the next stage e.g. the +/// CombinatorialKalmanFilter. +/// All track states, the temporary track states and track states for selected +/// measurements, are created in the given trajectory. The resulting container +/// may become big. Thus, it is advisable to copy selected tracks and their +/// track states to a separate container after each track finding step. +/// +template +struct TrackStateCreator { + using TrackStatesResult = + Acts::Result>; + using TrackStateContainerBackend = + typename track_container_t::TrackStateContainerBackend; + using TrackProxy = typename track_container_t::TrackProxy; + using TrackStateProxy = typename track_container_t::TrackStateProxy; + using BoundState = std::tuple; + using candidate_container_t = + typename std::vector; + + // delegate definition to get source link ranges for a surface + using SourceLinkAccessor = + Delegate( + const Surface&)>; + + // delegate to get calibrted measurements from a source link iterator + using Calibrator = + typename KalmanFitterExtensions::Calibrator; + + // delegate to select measurements from a track state range + using MeasurementSelector = + Delegate>( + candidate_container_t& trackStates, bool&, const Logger&)>; + + /// The source link accessor will return an source link range for a surface + /// which link to the associated measurements. + SourceLinkAccessor sourceLinkAccessor; + + /// The Calibrator is a dedicated calibration algorithm that allows to + /// calibrate measurements using track information, this could be e.g. sagging + /// for wires, module deformations, etc. + Calibrator calibrator{DelegateFuncTag< + detail::voidFitterCalibrator>{}}; + + MeasurementSelector measurementSelector{ + DelegateFuncTag{}}; + + public: + /// @brief extend the trajectory onto the given surface. + /// + /// @param gctx The geometry context to be used for this task + /// @param calibrationContext The calibration context used to fill the calibrated data + /// @param surface The surface onto which the trajectory is extended + /// @param boundState the predicted bound state on the given surface + /// @param prevTip the tip of the trajectory which is to be extended + /// @param trackStateCandidates a temporary buffer which can be used to + /// to keep track of newly created temporary track states. + /// @param trajectory the trajectory to be extended. + /// @param logger a logger for messages. + /// + /// @return a list of indices of newly created track states which extend the + /// trajectory onto the given surface and match the bound state, or an + /// error. + /// + /// Extend or branch the trajectory onto the given surface. This may create + /// new track states using measurements which match the predicted bound state. + /// This may create multiple branches. The new track states still miss the + /// "filtered" data. + Result> createTrackStates( + const GeometryContext& gctx, const CalibrationContext& calibrationContext, + [[maybe_unused]] const Surface& surface, const BoundState& boundState, + TrackIndexType prevTip, + std::vector& trackStateCandidates, + TrackStateContainerBackend& trajectory, const Logger& logger) const { + TrackStatesResult tsRes = TrackStatesResult::success({}); + using SourceLinkRange = decltype(sourceLinkAccessor(surface)); + SourceLinkRange slRange = sourceLinkAccessor(surface); + if (slRange.first != slRange.second) { + auto [slBegin, slEnd] = slRange; + tsRes = createSourceLinkTrackStates( + gctx, calibrationContext, surface, boundState, slBegin, slEnd, + prevTip, trackStateCandidates, trajectory, logger); + } + return tsRes; + } + + /// Create track states for selected measurements given by the source links + /// + /// @param gctx The current geometry context + /// @param calibrationContext pointer to the current calibration context + /// @param surface the surface the sourceLinks are associated to + /// @param boundState Bound state from the propagation on this surface + /// @param slBegin Begin iterator for sourceLinks + /// @param slEnd End iterator for sourceLinks + /// @param prevTip Index pointing at previous trajectory state (i.e. tip) + /// @param trackStateCandidates a temporary buffer which can be used to + /// to keep track of newly created temporary track states. + /// @param trajectory the trajectory to which new track states for selected measurements will be added + /// @param logger the logger for messages. + Result> createSourceLinkTrackStates( + const GeometryContext& gctx, const CalibrationContext& calibrationContext, + [[maybe_unused]] const Surface& surface, const BoundState& boundState, + source_link_iterator_t slBegin, source_link_iterator_t slEnd, + TrackIndexType prevTip, + std::vector& trackStateCandidates, + TrackStateContainerBackend& trajectory, const Logger& logger) const { + using PM = TrackStatePropMask; + + using ResultTrackStateList = + Acts::Result>; + ResultTrackStateList resultTrackStateList{ + CkfTypes::BranchVector()}; + const auto& [boundParams, jacobian, pathLength] = boundState; + + trackStateCandidates.clear(); + if constexpr (std::ranges::random_access_range) { + trackStateCandidates.reserve(std::distance(slBegin, slEnd)); + } + + // Calibrate all the source links on the surface since the selection has + // to be done based on calibrated measurement + for (auto it = slBegin; it != slEnd; ++it) { + // get the source link + const auto sourceLink = *it; + + // prepare the track state + PM mask = PM::Predicted | PM::Jacobian | PM::Calibrated; + if (it != slBegin) { + // not the first TrackState, only need uncalibrated and calibrated + mask = PM::Calibrated; + } + + ACTS_VERBOSE("Create temp track state with mask: " << mask); + // Temporary and final track states are created in the same + // trajectory, which could lead to very large containers. + + // CAREFUL! This trackstate has a previous index that is not in this + // MultiTrajectory Visiting backwards from this track state will + // fail! + auto ts = trajectory.makeTrackState(mask, prevTip); + + if (it == slBegin) { + // only set these for first + ts.predicted() = boundParams.parameters(); + if (boundParams.covariance()) { + ts.predictedCovariance() = *boundParams.covariance(); + } + ts.jacobian() = jacobian; + } else { + // subsequent track states can reuse + auto& first = trackStateCandidates.front(); + ts.shareFrom(first, PM::Predicted); + ts.shareFrom(first, PM::Jacobian); + } + + ts.pathLength() = pathLength; + ts.setReferenceSurface(boundParams.referenceSurface().getSharedPtr()); + + // now calibrate the track state + calibrator(gctx, calibrationContext, sourceLink, ts); + + trackStateCandidates.push_back(ts); + } + + bool isOutlier = false; + Result::iterator, + typename std::vector::iterator>> + selectorResult = + measurementSelector(trackStateCandidates, isOutlier, logger); + if (!selectorResult.ok()) { + ACTS_ERROR("Selection of calibrated measurements failed: " + << selectorResult.error().message()); + resultTrackStateList = + ResultTrackStateList::failure(selectorResult.error()); + } else { + auto selectedTrackStateRange = *selectorResult; + resultTrackStateList = processSelectedTrackStates( + selectedTrackStateRange.first, selectedTrackStateRange.second, + trajectory, isOutlier, logger); + } + + return resultTrackStateList; + } + + /// Create track states for the given trajectory from candidate track states + /// + /// @param begin begin iterator of the list of candidate track states + /// @param end end iterator of the list of candidate track states + /// @param trackStates the trajectory to which the new track states are added + /// @param isOutlier true if the candidate(s) is(are) an outlier(s). + /// @param logger the logger for messages + Result> processSelectedTrackStates( + typename std::vector::const_iterator begin, + typename std::vector::const_iterator end, + TrackStateContainerBackend& trackStates, bool isOutlier, + const Logger& logger) const { + using PM = TrackStatePropMask; + + using ResultTrackStateList = + Acts::Result>; + ResultTrackStateList resultTrackStateList{ + CkfTypes::BranchVector()}; + CkfTypes::BranchVector& trackStateList = + *resultTrackStateList; + trackStateList.reserve(end - begin); + + std::optional firstTrackState{std::nullopt}; + for (auto it = begin; it != end; ++it) { + auto& candidateTrackState = *it; + + PM mask = PM::Predicted | PM::Filtered | PM::Jacobian | PM::Calibrated; + if (it != begin) { + // subsequent track states don't need storage for these as they will + // be shared + mask &= ~PM::Predicted & ~PM::Jacobian; + } + if (isOutlier) { + // outlier won't have separate filtered parameters + mask &= ~PM::Filtered; + } + + // copy this trackstate into fitted states MultiTrajectory + auto trackState = + trackStates.makeTrackState(mask, candidateTrackState.previous()); + ACTS_VERBOSE("Create SourceLink output track state #" + << trackState.index() << " with mask: " << mask); + + if (it != begin) { + // assign indices pointing to first track state + trackState.shareFrom(*firstTrackState, PM::Predicted); + trackState.shareFrom(*firstTrackState, PM::Jacobian); + } else { + firstTrackState = trackState; + } + + // either copy ALL or everything except for predicted and jacobian + trackState.copyFrom(candidateTrackState, mask, false); + + auto typeFlags = trackState.typeFlags(); + typeFlags.set(TrackStateFlag::ParameterFlag); + typeFlags.set(TrackStateFlag::MeasurementFlag); + if (trackState.referenceSurface().surfaceMaterial() != nullptr) { + typeFlags.set(TrackStateFlag::MaterialFlag); + } + if (isOutlier) { + // propagate information that this is an outlier state + ACTS_VERBOSE( + "Creating outlier track state with tip = " << trackState.index()); + typeFlags.set(TrackStateFlag::OutlierFlag); + } + + trackStateList.push_back(trackState.index()); + } + return resultTrackStateList; + } + + /// Default measurement selector which will return all measurements + /// @param candidates Measurement track state candidates + static Result::iterator, + typename std::vector::iterator>> + voidMeasurementSelector(typename std::vector& candidates, + bool& /*isOutlier*/, const Logger& /*logger*/) { + return std::pair{candidates.begin(), candidates.end()}; + }; +}; + +} // namespace Acts diff --git a/Core/include/Acts/TrackFitting/KalmanFitter.hpp b/Core/include/Acts/TrackFitting/KalmanFitter.hpp index 12b70c8a562..1bc0858b3df 100644 --- a/Core/include/Acts/TrackFitting/KalmanFitter.hpp +++ b/Core/include/Acts/TrackFitting/KalmanFitter.hpp @@ -562,7 +562,9 @@ class KalmanFitter { navigationOptions.startSurface = &st.referenceSurface(); navigationOptions.targetSurface = nullptr; state.navigation = navigator.makeState(navigationOptions); - navigator.initialize(state, stepper); + navigator.initialize(state.navigation, stepper.position(state.stepping), + stepper.direction(state.stepping), + state.options.direction); // Update material effects for last measurement state in reversed // direction @@ -1044,7 +1046,9 @@ class KalmanFitter { navigationOptions.startSurface = &surface; navigationOptions.targetSurface = nullptr; state.navigation = navigator.makeState(navigationOptions); - navigator.initialize(state, stepper); + navigator.initialize(state.navigation, stepper.position(state.stepping), + stepper.direction(state.stepping), + state.options.direction); return Result::success(); } diff --git a/Core/include/Acts/TrackFitting/detail/GsfActor.hpp b/Core/include/Acts/TrackFitting/detail/GsfActor.hpp index 695198a7dfc..0b3a8053870 100644 --- a/Core/include/Acts/TrackFitting/detail/GsfActor.hpp +++ b/Core/include/Acts/TrackFitting/detail/GsfActor.hpp @@ -416,7 +416,7 @@ struct GsfActor { auto new_pars = old_bound.parameters(); const auto delta_p = [&]() { - if (state.options.direction == Direction::Forward) { + if (state.options.direction == Direction::Forward()) { return p_prev * (gaussian.mean - 1.); } else { return p_prev * (1. / gaussian.mean - 1.); @@ -431,7 +431,7 @@ struct GsfActor { auto new_cov = old_bound.covariance().value(); const auto varInvP = [&]() { - if (state.options.direction == Direction::Forward) { + if (state.options.direction == Direction::Forward()) { const auto f = 1. / (p_prev * gaussian.mean); return f * f * gaussian.var; } else { @@ -492,7 +492,7 @@ struct GsfActor { auto proxy = tmpStates.traj.getTrackState(idx); cmp.pars() = - MultiTrajectoryHelpers::freeFiltered(state.options.geoContext, proxy); + MultiTrajectoryHelpers::freeFiltered(state.geoContext, proxy); cmp.cov() = proxy.filteredCovariance(); cmp.weight() = tmpStates.weights.at(idx); } diff --git a/Core/include/Acts/TrackFitting/detail/GsfUtils.hpp b/Core/include/Acts/TrackFitting/detail/GsfUtils.hpp index 574a69e8f71..103d83935b7 100644 --- a/Core/include/Acts/TrackFitting/detail/GsfUtils.hpp +++ b/Core/include/Acts/TrackFitting/detail/GsfUtils.hpp @@ -192,12 +192,19 @@ void computePosteriorWeights( state.predictedCovariance(), state.projectorSubspaceIndices(), state.calibratedSize()); + if (detR <= 0) { + // If the determinant is not positive, just leave the weight as it is + continue; + } + const auto factor = std::sqrt(1. / detR) * safeExp(-0.5 * chi2); - // If something is not finite here, just leave the weight as it is - if (std::isfinite(factor)) { - weights.at(tip) *= factor; + if (!std::isfinite(factor)) { + // If something is not finite here, just leave the weight as it is + continue; } + + weights.at(tip) *= factor; } } diff --git a/Core/include/Acts/Utilities/Any.hpp b/Core/include/Acts/Utilities/Any.hpp index 337dafb2c24..bf04ec47ca7 100644 --- a/Core/include/Acts/Utilities/Any.hpp +++ b/Core/include/Acts/Utilities/Any.hpp @@ -213,7 +213,7 @@ class AnyBase : public AnyBaseAll { return *this; } - AnyBase(AnyBase&& other) { + AnyBase(AnyBase&& other) noexcept { _ACTS_ANY_VERBOSE("Move construct (this=" << this << ") at: " << static_cast(m_data.data())); if (m_handler == nullptr && other.m_handler == nullptr) { diff --git a/Core/include/Acts/Utilities/Axis.hpp b/Core/include/Acts/Utilities/Axis.hpp index 758a8c2ec3c..c6d5b53a541 100644 --- a/Core/include/Acts/Utilities/Axis.hpp +++ b/Core/include/Acts/Utilities/Axis.hpp @@ -8,7 +8,7 @@ #pragma once -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/IAxis.hpp" #include diff --git a/Core/include/Acts/Utilities/AxisFwd.hpp b/Core/include/Acts/Utilities/AxisDefinitions.hpp similarity index 66% rename from Core/include/Acts/Utilities/AxisFwd.hpp rename to Core/include/Acts/Utilities/AxisDefinitions.hpp index ce31ff3f7b6..a048693c518 100644 --- a/Core/include/Acts/Utilities/AxisFwd.hpp +++ b/Core/include/Acts/Utilities/AxisDefinitions.hpp @@ -13,6 +13,54 @@ #include namespace Acts { + +/// @enum AxisDirection to specify a local axis direction +enum class AxisDirection : int { + /// AxisX, AxisY, AxisZ are the cartesian directions in the local frame + AxisX = 0, + AxisY = 1, + AxisZ = 2, + /// AxisR is a radial direction + AxisR = 3, + /// AxisPhi is the azimuthal direction + AxisPhi = 4, + /// AxisRPhi is the radial-azimuthal direction + AxisRPhi = 5, + /// AxisTheta is the polar angle direction + AxisTheta = 6, + /// AxisEta is the pseudorapidity direction + AxisEta = 7, + /// AxisMag is the magnitude of the vector + AxisMag = 8 +}; + +/// Get all possible axis directions +/// @return a vector of all possible axis directions +const std::vector& allAxisDirections(); + +/// Returns the total number of axis directions +/// @return the number of axis directions +constexpr std::size_t numAxisDirections() { + return 9; +} + +/// Get an axis direction from its string name +/// +/// @param name is the name of the axis direction +/// @return the axis direction +AxisDirection axisDirectionFromName(const std::string& name); + +/// Get the name of a binning value as a string +/// @param aDir is the binning value +/// @return the name of the binning value +const std::string& axisDirectionName(AxisDirection aDir); + +/// Output stream operator for @c AxisDirection +/// @param os is the output stream +/// @param aDir is the axis direction +/// @return the output stream +std::ostream& operator<<(std::ostream& os, AxisDirection aDir); + /// Enum which determines how the axis handle its outer boundaries /// possible values values enum class AxisBoundaryType { @@ -38,14 +86,15 @@ constexpr auto AxisBound = AxisBoundaryTypeTag{}; constexpr auto AxisClosed = AxisBoundaryTypeTag{}; inline std::ostream& operator<<(std::ostream& os, AxisBoundaryType bdt) { + using enum AxisBoundaryType; switch (bdt) { - case AxisBoundaryType::Open: + case Open: os << "Open"; break; - case AxisBoundaryType::Bound: + case Bound: os << "Bound"; break; - case AxisBoundaryType::Closed: + case Closed: os << "Closed"; break; } diff --git a/Core/include/Acts/Utilities/BinAdjustment.hpp b/Core/include/Acts/Utilities/BinAdjustment.hpp index 6424276c5cf..05de674ee42 100644 --- a/Core/include/Acts/Utilities/BinAdjustment.hpp +++ b/Core/include/Acts/Utilities/BinAdjustment.hpp @@ -6,10 +6,6 @@ // 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/. -/////////////////////////////////////////////////////////////////// -// BinAdjustment.hpp, Acts project -/////////////////////////////////////////////////////////////////// - #pragma once #include "Acts/Definitions/Algebra.hpp" @@ -18,6 +14,7 @@ #include "Acts/Surfaces/RectangleBounds.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Surfaces/TrapezoidBounds.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/BinUtility.hpp" #include @@ -49,18 +46,18 @@ static inline BinUtility adjustBinUtility(const BinUtility& bu, // Loop over the binning data and adjust the dimensions for (auto& bd : bData) { // The binning value - BinningValue bval = bd.binvalue; + AxisDirection bval = bd.binvalue; // Throw exceptions is stuff doesn't make sense: // - not the right binning value // - not equidistant if (bd.type == arbitrary) { throw std::invalid_argument("Arbitrary binning can not be adjusted."); - } else if (bval != BinningValue::binR && bval != BinningValue::binPhi) { + } else if (bval != AxisDirection::AxisR && bval != AxisDirection::AxisPhi) { throw std::invalid_argument("Disc binning must be: phi, r"); } float min = 0., max = 0.; // Perform the value adjustment - if (bval == BinningValue::binPhi) { + if (bval == AxisDirection::AxisPhi) { min = minPhi; max = maxPhi; } else { @@ -100,22 +97,22 @@ static inline BinUtility adjustBinUtility(const BinUtility& bu, // Loop over the binning data and adjust the dimensions for (auto& bd : bData) { // The binning value - BinningValue bval = bd.binvalue; + AxisDirection bval = bd.binvalue; // Throw exceptions if stuff doesn't make sense: // - not the right binning value // - not equidistant if (bd.type == arbitrary) { throw std::invalid_argument("Arbitrary binning can not be adjusted."); - } else if (bval != BinningValue::binRPhi && bval != BinningValue::binPhi && - bval != BinningValue::binZ) { + } else if (bval != AxisDirection::AxisRPhi && + bval != AxisDirection::AxisPhi && bval != AxisDirection::AxisZ) { throw std::invalid_argument("Cylinder binning must be: rphi, phi, z"); } float min = 0., max = 0.; // Perform the value adjustment - if (bval == BinningValue::binPhi) { + if (bval == AxisDirection::AxisPhi) { min = minPhi; max = maxPhi; - } else if (bval == BinningValue::binRPhi) { + } else if (bval == AxisDirection::AxisRPhi) { min = cR * minPhi; max = cR * maxPhi; } else { @@ -153,18 +150,18 @@ static inline BinUtility adjustBinUtility(const BinUtility& bu, // Loop over the binning data and adjust the dimensions for (auto& bd : bData) { // The binning value - BinningValue bval = bd.binvalue; + AxisDirection bval = bd.binvalue; // Throw exceptions if stuff doesn't make sense: // - not the right binning value // - not equidistant if (bd.type == arbitrary) { throw std::invalid_argument("Arbitrary binning can not be adjusted."); - } else if (bval != BinningValue::binX && bval != BinningValue::binY) { + } else if (bval != AxisDirection::AxisX && bval != AxisDirection::AxisY) { throw std::invalid_argument("Rectangle binning must be: x, y. "); } float min = 0., max = 0.; // Perform the value adjustment - if (bval == BinningValue::binX) { + if (bval == AxisDirection::AxisX) { min = minX; max = maxX; } else { @@ -203,18 +200,18 @@ static inline BinUtility adjustBinUtility(const BinUtility& bu, // Loop over the binning data and adjust the dimensions for (auto& bd : bData) { // The binning value - BinningValue bval = bd.binvalue; + AxisDirection bval = bd.binvalue; // Throw exceptions if stuff doesn't make sense: // - not the right binning value // - not equidistant if (bd.type == arbitrary) { throw std::invalid_argument("Arbitrary binning can not be adjusted."); - } else if (bval != BinningValue::binX && bval != BinningValue::binY) { + } else if (bval != AxisDirection::AxisX && bval != AxisDirection::AxisY) { throw std::invalid_argument("Rectangle binning must be: x, y. "); } float min = 0., max = 0.; // Perform the value adjustment - if (bval == BinningValue::binX) { + if (bval == AxisDirection::AxisX) { min = -1 * halfX; max = halfX; } else { diff --git a/Core/include/Acts/Utilities/BinAdjustmentVolume.hpp b/Core/include/Acts/Utilities/BinAdjustmentVolume.hpp index bef7bff3e83..e2ce50180fc 100644 --- a/Core/include/Acts/Utilities/BinAdjustmentVolume.hpp +++ b/Core/include/Acts/Utilities/BinAdjustmentVolume.hpp @@ -6,10 +6,6 @@ // 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/. -/////////////////////////////////////////////////////////////////// -// BinAdjustment.hpp, Acts project -/////////////////////////////////////////////////////////////////// - #pragma once #include "Acts/Definitions/Algebra.hpp" @@ -17,6 +13,7 @@ #include "Acts/Geometry/CutoutCylinderVolumeBounds.hpp" #include "Acts/Geometry/CylinderVolumeBounds.hpp" #include "Acts/Geometry/Volume.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/BinUtility.hpp" #include @@ -48,26 +45,26 @@ BinUtility adjustBinUtility(const BinUtility& bu, // Loop over the binning data and adjust the dimensions for (auto& bd : bData) { // The binning value - BinningValue bval = bd.binvalue; + AxisDirection bval = bd.binvalue; // Throw exceptions is stuff doesn't make sense: // - not the right binning value // - not equidistant if (bd.type == arbitrary) { throw std::invalid_argument("Arbitrary binning can not be adjusted."); - } else if (bval != BinningValue::binR && bval != BinningValue::binPhi && - bval != BinningValue::binZ) { + } else if (bval != AxisDirection::AxisR && bval != AxisDirection::AxisPhi && + bval != AxisDirection::AxisZ) { throw std::invalid_argument("Cylinder volume binning must be: phi, r, z"); } float min = 0; float max = 0; // Perform the value adjustment - if (bval == BinningValue::binPhi) { + if (bval == AxisDirection::AxisPhi) { min = minPhi; max = maxPhi; - } else if (bval == BinningValue::binR) { + } else if (bval == AxisDirection::AxisR) { min = minR; max = maxR; - } else if (bval == BinningValue::binZ) { + } else if (bval == AxisDirection::AxisZ) { min = minZ; max = maxZ; } @@ -104,27 +101,27 @@ BinUtility adjustBinUtility(const BinUtility& bu, // Loop over the binning data and adjust the dimensions for (auto& bd : bData) { // The binning value - BinningValue bval = bd.binvalue; + AxisDirection bval = bd.binvalue; // Throw exceptions is stuff doesn't make sense: // - not the right binning value // - not equidistant if (bd.type == arbitrary) { throw std::invalid_argument("Arbitrary binning can not be adjusted."); - } else if (bval != BinningValue::binR && bval != BinningValue::binPhi && - bval != BinningValue::binZ) { + } else if (bval != AxisDirection::AxisR && bval != AxisDirection::AxisPhi && + bval != AxisDirection::AxisZ) { throw std::invalid_argument( "Cutout cylinder volume binning must be: phi, r, z"); } float min = 0; float max = 0; // Perform the value adjustment - if (bval == BinningValue::binPhi) { + if (bval == AxisDirection::AxisPhi) { min = minPhi; max = maxPhi; - } else if (bval == BinningValue::binR) { + } else if (bval == AxisDirection::AxisR) { min = minR; max = maxR; - } else if (bval == BinningValue::binZ) { + } else if (bval == AxisDirection::AxisZ) { min = minZ; max = maxZ; } @@ -160,26 +157,26 @@ BinUtility adjustBinUtility(const BinUtility& bu, // Loop over the binning data and adjust the dimensions for (auto& bd : bData) { // The binning value - BinningValue bval = bd.binvalue; + AxisDirection bval = bd.binvalue; // Throw exceptions is stuff doesn't make sense: // - not the right binning value // - not equidistant if (bd.type == arbitrary) { throw std::invalid_argument("Arbitrary binning can not be adjusted."); - } else if (bval != BinningValue::binX && bval != BinningValue::binY && - bval != BinningValue::binZ) { + } else if (bval != AxisDirection::AxisX && bval != AxisDirection::AxisY && + bval != AxisDirection::AxisZ) { throw std::invalid_argument("Cylinder volume binning must be: x, y, z"); } float min = 0; float max = 0; // Perform the value adjustment - if (bval == BinningValue::binX) { + if (bval == AxisDirection::AxisX) { min = minX; max = maxX; - } else if (bval == BinningValue::binY) { + } else if (bval == AxisDirection::AxisY) { min = minY; max = maxY; - } else if (bval == BinningValue::binZ) { + } else if (bval == AxisDirection::AxisZ) { min = minZ; max = maxZ; } diff --git a/Core/include/Acts/Utilities/BinUtility.hpp b/Core/include/Acts/Utilities/BinUtility.hpp index a1213ddd8ec..79d59ddadfa 100644 --- a/Core/include/Acts/Utilities/BinUtility.hpp +++ b/Core/include/Acts/Utilities/BinUtility.hpp @@ -9,6 +9,7 @@ #pragma once #include "Acts/Definitions/Algebra.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/BinningData.hpp" #include "Acts/Utilities/BinningType.hpp" #include "Acts/Utilities/Enumerate.hpp" @@ -56,8 +57,8 @@ class BinUtility { /// /// @param bData is the provided binning data /// @param tForm is the (optional) transform - BinUtility(const BinningData& bData, - const Transform3& tForm = Transform3::Identity()) + explicit BinUtility(const BinningData& bData, + const Transform3& tForm = Transform3::Identity()) : m_binningData(), m_transform(tForm), m_itransform(tForm.inverse()) { m_binningData.reserve(3); m_binningData.push_back(bData); @@ -69,10 +70,10 @@ class BinUtility { /// @param min in the minimal value /// @param max is the maximal value /// @param opt is the binning option : open, closed - /// @param value is the binninb value : binX, binY, binZ, etc. + /// @param value is the axis direction : AxisX, AxisY, AxisZ, etc. /// @param tForm is the (optional) transform BinUtility(std::size_t bins, float min, float max, BinningOption opt = open, - BinningValue value = BinningValue::binX, + AxisDirection value = AxisDirection::AxisX, const Transform3& tForm = Transform3::Identity()) : m_binningData(), m_transform(tForm), m_itransform(tForm.inverse()) { m_binningData.reserve(3); @@ -83,10 +84,10 @@ class BinUtility { /// /// @param bValues is the boundary values of the binning /// @param opt is the binning option : open, closed - /// @param value is the binninb value : binX, binY, binZ, etc. + /// @param value is the axis direction : AxisX, AxisY, AxisZ, etc. /// @param tForm is the (optional) transform BinUtility(std::vector& bValues, BinningOption opt = open, - BinningValue value = BinningValue::binPhi, + AxisDirection value = AxisDirection::AxisPhi, const Transform3& tForm = Transform3::Identity()) : m_binningData(), m_transform(tForm), m_itransform(tForm.inverse()) { m_binningData.reserve(3); @@ -267,7 +268,7 @@ class BinUtility { /// @param ba is the binaccessor /// /// @return the binning value of the accessor entry - BinningValue binningValue(std::size_t ba = 0) const { + AxisDirection binningValue(std::size_t ba = 0) const { if (ba >= m_binningData.size()) { throw std::runtime_error{"Dimension out of bounds"}; } diff --git a/Core/include/Acts/Utilities/BinnedArray.hpp b/Core/include/Acts/Utilities/BinnedArray.hpp index 7a13c16ae58..7cceb24270d 100644 --- a/Core/include/Acts/Utilities/BinnedArray.hpp +++ b/Core/include/Acts/Utilities/BinnedArray.hpp @@ -6,10 +6,6 @@ // 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/. -/////////////////////////////////////////////////////////////////// -// BinnedArray.h, Acts project -/////////////////////////////////////////////////////////////////// - #pragma once #include "Acts/Definitions/Algebra.hpp" diff --git a/Core/include/Acts/Utilities/BinningData.hpp b/Core/include/Acts/Utilities/BinningData.hpp index 553ab10b2a9..904429f64be 100644 --- a/Core/include/Acts/Utilities/BinningData.hpp +++ b/Core/include/Acts/Utilities/BinningData.hpp @@ -9,6 +9,7 @@ #pragma once #include "Acts/Definitions/Algebra.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/BinningType.hpp" #include "Acts/Utilities/Helpers.hpp" #include "Acts/Utilities/ThrowAssert.hpp" @@ -41,13 +42,13 @@ namespace Acts { /// class BinningData { public: - BinningType type{}; ///< binning type: equidistant, arbitrary - BinningOption option{}; ///< binning option: open, closed - BinningValue binvalue{}; ///< binning value: binX, binY, binZ, binR ... - float min{}; ///< minimum value - float max{}; ///< maximum value - float step{}; ///< binning step - bool zdim{}; ///< zero dimensional binning : direct access + BinningType type{}; ///< binning type: equidistant, arbitrary + BinningOption option{}; ///< binning option: open, closed + AxisDirection binvalue{}; ///< axis direction: AxisX, AxisY, AxisZ, ... + float min{}; ///< minimum value + float max{}; ///< maximum value + float step{}; ///< binning step + bool zdim{}; ///< zero dimensional binning : direct access /// sub structure: describe some sub binning std::unique_ptr subBinningData; @@ -56,10 +57,10 @@ class BinningData { /// Constructor for 0D binning /// - /// @param bValue is the binning value: binX, binY, etc. + /// @param bValue is the axis direction AxisX, AxisY, etc. /// @param bMin is the minimum value /// @param bMax is the maximum value - BinningData(BinningValue bValue, float bMin, float bMax) + BinningData(AxisDirection bValue, float bMin, float bMax) : type(equidistant), option(open), binvalue(bValue), @@ -79,13 +80,13 @@ class BinningData { /// multiplicative or additive /// /// @param bOption is the binning option : open, closed - /// @param bValue is the binning value: binX, binY, etc. + /// @param bValue is the axis direction: Axis, AxisY, etc. /// @param bBins is number of equidistant bins /// @param bMin is the minimum value /// @param bMax is the maximum value /// @param sBinData is (optional) sub structure /// @param sBinAdditive is the prescription for the sub structure - BinningData(BinningOption bOption, BinningValue bValue, std::size_t bBins, + BinningData(BinningOption bOption, AxisDirection bValue, std::size_t bBins, float bMin, float bMax, std::unique_ptr sBinData = nullptr, bool sBinAdditive = false) @@ -116,10 +117,10 @@ class BinningData { /// Constructor for non-equidistant binning /// /// @param bOption is the binning option : open / closed - /// @param bValue is the binning value : binX, binY, etc. + /// @param bValue is the axis direction : AxisX, AxisY, etc. /// @param bBoundaries are the bin boundaries /// @param sBinData is (optional) sub structure - BinningData(BinningOption bOption, BinningValue bValue, + BinningData(BinningOption bOption, AxisDirection bValue, const std::vector& bBoundaries, std::unique_ptr sBinData = nullptr) : type(arbitrary), @@ -241,8 +242,10 @@ class BinningData { /// @return float value according to the binning setup float value(const Vector2& lposition) const { // ordered after occurrence - if (binvalue == BinningValue::binR || binvalue == BinningValue::binRPhi || - binvalue == BinningValue::binX || binvalue == BinningValue::binH) { + if (binvalue == AxisDirection::AxisR || + binvalue == AxisDirection::AxisRPhi || + binvalue == AxisDirection::AxisX || + binvalue == AxisDirection::AxisTheta) { return lposition[0]; } @@ -259,13 +262,14 @@ class BinningData { using VectorHelpers::perp; using VectorHelpers::phi; // ordered after occurrence - if (binvalue == BinningValue::binR || binvalue == BinningValue::binH) { + if (binvalue == AxisDirection::AxisR || + binvalue == AxisDirection::AxisTheta) { return (perp(position)); } - if (binvalue == BinningValue::binRPhi) { + if (binvalue == AxisDirection::AxisRPhi) { return (perp(position) * phi(position)); } - if (binvalue == BinningValue::binEta) { + if (binvalue == AxisDirection::AxisEta) { return (eta(position)); } if (toUnderlying(binvalue) < 3) { diff --git a/Core/include/Acts/Utilities/BinningType.hpp b/Core/include/Acts/Utilities/BinningType.hpp index 90e90b5a2ad..d58730dec85 100644 --- a/Core/include/Acts/Utilities/BinningType.hpp +++ b/Core/include/Acts/Utilities/BinningType.hpp @@ -25,7 +25,7 @@ namespace Acts { /// open: [0,max] /// closed: 0 -> nextbin -> max -> 0 /// -/// - BinningValue +/// - AxisDirection /// necessary access to global positions /// enum BinningType { equidistant, arbitrary }; @@ -33,43 +33,4 @@ enum BinningType { equidistant, arbitrary }; /// @brief flag for open/closed bins enum BinningOption { open, closed }; -/// @enum BinningValue how to take the global / local position -enum class BinningValue : int { - binX = 0, - binY = 1, - binZ = 2, - binR = 3, - binPhi = 4, - binRPhi = 5, - binH = 6, - binEta = 7, - binMag = 8 -}; - -/// Get all possible binning values -/// @return the binning values -const std::vector& allBinningValues(); - -/// Returns the total number of binningvalues -/// @return the number of binning values -constexpr std::size_t numBinningValues() { - return 9; -} - -/// Get the binning value from a name -/// @param name is the name of the binning value -/// @return the binning value -BinningValue binningValueFromName(const std::string& name); - -/// Get the name of a binning value as a string -/// @param bValue is the binning value -/// @return the name of the binning value -const std::string& binningValueName(BinningValue bValue); - -/// Output stream operator for @c BinningValue -/// @param os is the output stream -/// @param bValue is the binning value -/// @return the output stream -std::ostream& operator<<(std::ostream& os, BinningValue bValue); - } // namespace Acts diff --git a/Core/include/Acts/Utilities/GridAccessHelpers.hpp b/Core/include/Acts/Utilities/GridAccessHelpers.hpp index df8f46ed39b..a358c50af8b 100644 --- a/Core/include/Acts/Utilities/GridAccessHelpers.hpp +++ b/Core/include/Acts/Utilities/GridAccessHelpers.hpp @@ -9,7 +9,7 @@ #pragma once #include "Acts/Definitions/Algebra.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Delegate.hpp" #include "Acts/Utilities/VectorHelpers.hpp" @@ -141,7 +141,7 @@ class Affine3Transformed : public IGlobalToGridLocal { /// @brief A global (potentially casted) sub space of a global /// position /// @tparam ...Args -template +template class GlobalSubspace : public IGlobalToGridLocal { public: using grid_local_t = std::array; @@ -157,8 +157,8 @@ class GlobalSubspace : public IGlobalToGridLocal { // Constructor GlobalSubspace() = default; - /// The binning values - static constexpr std::array bValues = { + /// The axis directions of the subspace + static constexpr std::array axisDirs = { Args...}; /// Transform in to the local frame, then the grid local position @@ -170,7 +170,7 @@ class GlobalSubspace : public IGlobalToGridLocal { // Fill the grid point from global grid_local_t glocal{}; GridAccessHelpers::fillCasts( - position, bValues, glocal, + position, axisDirs, glocal, std::make_integer_sequence{}); return glocal; } diff --git a/Core/include/Acts/Utilities/IAxis.hpp b/Core/include/Acts/Utilities/IAxis.hpp index 09c9fbd3a56..8c12ca85e15 100644 --- a/Core/include/Acts/Utilities/IAxis.hpp +++ b/Core/include/Acts/Utilities/IAxis.hpp @@ -9,9 +9,10 @@ #pragma once #include "Acts/Definitions/Algebra.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include +#include #include namespace Acts { @@ -20,6 +21,9 @@ namespace Acts { /// such as for inspection. class IAxis { public: + /// Virtual destructor + virtual ~IAxis() = default; + /// @brief returns whether the axis is equidistant /// /// @return bool is equidistant @@ -58,11 +62,37 @@ class IAxis { /// @return total number of bins (excluding under-/overflow bins) virtual std::size_t getNBins() const = 0; + /// Centralized axis factory for equidistant binning + /// + /// @param aBoundaryType the axis boundary type + /// @param min the minimum edge of the axis + /// @param max the maximum edge of the axis + /// @param nbins the number of bins + /// + /// @throws std::invalid_argument if min >= max or nbins == 0 + /// + /// @return a unique pointer to the axis + static std::unique_ptr createEquidistant( + AxisBoundaryType aBoundaryType, double min, double max, + std::size_t nbins); + + /// Centralized axis factory for variable binning + /// + /// @param aBoundaryType the axis boundary type + /// @param edges are the bin edges + /// + /// @throws std::invalid_argument if edges is empty or not strictly increasing + /// + /// @return a unique pointer to the axis + static std::unique_ptr createVariable( + AxisBoundaryType aBoundaryType, const std::vector& edges); + /// Helper function that dispatches from the @c IAxis base class /// to a concrete axis type. It will call the provided @p callable /// with a const reference to the concrete axis type. /// @tparam callable_t the callable type /// @param callable the callable object + /// @return the value returned by the callable template decltype(auto) visit(const callable_t& callable) const { auto switchOnType = diff --git a/Core/include/Acts/Utilities/MultiIndex.hpp b/Core/include/Acts/Utilities/MultiIndex.hpp index f809771fd60..ca7d330ba6b 100644 --- a/Core/include/Acts/Utilities/MultiIndex.hpp +++ b/Core/include/Acts/Utilities/MultiIndex.hpp @@ -70,7 +70,7 @@ class MultiIndex { MultiIndex(const MultiIndex&) = default; MultiIndex(MultiIndex&) = default; MultiIndex& operator=(const MultiIndex&) = default; - MultiIndex& operator=(MultiIndex&&) = default; + MultiIndex& operator=(MultiIndex&&) noexcept = default; /// Allow setting the MultiIndex from an already encoded value. constexpr MultiIndex& operator=(Value encoded) { m_value = encoded; diff --git a/Core/include/Acts/Utilities/ProtoAxis.hpp b/Core/include/Acts/Utilities/ProtoAxis.hpp new file mode 100644 index 00000000000..48163a016b9 --- /dev/null +++ b/Core/include/Acts/Utilities/ProtoAxis.hpp @@ -0,0 +1,156 @@ +// 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/Axis.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" +#include "Acts/Utilities/Grid.hpp" +#include "Acts/Utilities/IAxis.hpp" + +namespace Acts { +/// @brief Description of a ProtoAxis which holds an IAxis +/// and lets the user to define a certain axis type, boundary type +/// and associated binning. +/// +/// The IAxis allows via the visitor pattern to access the actual axis type +/// which helps to create grid creation code by the compiler as done +/// in the makeGrid helper functions. +/// +/// In addition to a simple axis definitions, it holds also a description +/// of the axis direction. +class ProtoAxis { + public: + /// Convenience constructors - for variable binning + /// + /// @param aDir the value/cast in which this is binned + /// @param abType the axis boundary type + /// @param edges the bin edges (variable binning) + ProtoAxis(AxisDirection aDir, Acts::AxisBoundaryType abType, + const std::vector& edges); + + /// Convenience constructors - for equidistant binning + /// + /// @param aDir the value/cast in which this is binned + /// @param abType the axis boundary type + /// @param minE the lowest edge of the binning + /// @param maxE the highest edge of the binning + /// @param nbins the number of bins + ProtoAxis(AxisDirection aDir, AxisBoundaryType abType, double minE, + double maxE, std::size_t nbins); + + /// Placeholder constructor for auto-range binning + /// + /// @param aDir the value/cast in which this is binned + /// @param abType the axis boundary type + /// @param nbins the number of bins + /// + /// @note that auto-range is only supported for equidistant binning + ProtoAxis(AxisDirection aDir, AxisBoundaryType abType, std::size_t nbins); + + ProtoAxis(const ProtoAxis&) = delete; + ProtoAxis& operator=(const ProtoAxis&) = delete; + ProtoAxis(ProtoAxis&&) = default; + ProtoAxis& operator=(ProtoAxis&&) = default; + + /// @brief returns the axis direction + /// + /// @return @c AxisDirection of this axis + AxisDirection getAxisDirection() const; + + /// @brief Return the IAxis representation + /// + /// @return @c AxisType of this axis + const IAxis& getAxis() const; + + /// Set the range, this will change auto-range to false + /// + /// @throws std::invalid_argument if the axis is not auto-range + /// @throws std::invalid_argument if the axis is not equidistant + /// + /// @param minE the lowest edge of the binning + /// @param maxE the highest edge of the binning + void setRange(double minE, double maxE); + + /// @brief check if this is an auto-range binning + bool isAutorange() const; + + /// Dump into a string + /// @return the string representation + std::string toString() const; + + private: + /// Dispatch to the correct stream operator + /// @param os output stream + void toStream(std::ostream& os) const; + + /// The axis direction + AxisDirection m_axisDir = AxisDirection::AxisX; + + /// The axis representation + std::unique_ptr m_axis = nullptr; + + /// Indicate if this is a place holder auto-range binning + bool m_autorange = false; +}; + +/// @brief Helper method to create a 1D grid from a single proto axis +/// +/// @tparam payload_t the grid payloat type +/// +/// @param a the proto axis +/// +/// @return an IGrid unique ptr and hence transfers ownership +template +std::unique_ptr makeGrid(const ProtoAxis& a) { + if (a.isAutorange()) { + throw std::invalid_argument( + "ProtoAxis::makeGrid: Auto-range of the proto axis is not (yet) " + "resolved, call setRange() first."); + } + + return a.getAxis().visit( + [&](const AxisTypeA& axis) -> std::unique_ptr { + using GridType = Grid; + return std::make_unique(axis); + }); +} + +/// @brief Helper method to create a 2D grid from a two proto axes +/// +/// @tparam payload_t the grid payloat type +/// +/// @param a the first proto axis +/// @param b the second proto axis +/// +/// @return an IGrid unique ptr and hence transfers ownership +template +std::unique_ptr makeGrid(const ProtoAxis& a, const ProtoAxis& b) { + // Validate axis compatibility + if (a.getAxisDirection() == b.getAxisDirection()) { + throw std::invalid_argument( + "ProtoAxis::makeGrid: Axes must have different directions"); + } + + if (a.isAutorange() || b.isAutorange()) { + throw std::invalid_argument( + "ProtoAxis::makeGrid: Auto-range of the proto axis is not (yet) " + "resolved, call setRange() first."); + } + + return a.getAxis().visit([&](const AxisTypeA& axisA) + -> std::unique_ptr { + return b.getAxis().visit([&](const AxisTypeB& axisB) + -> std::unique_ptr { + using GridType = Grid; + return std::make_unique(axisA, axisB); + }); + }); +} + +} // namespace Acts diff --git a/Core/include/Acts/Utilities/Result.hpp b/Core/include/Acts/Utilities/Result.hpp index 475019fc99b..c71836cc788 100644 --- a/Core/include/Acts/Utilities/Result.hpp +++ b/Core/include/Acts/Utilities/Result.hpp @@ -43,12 +43,12 @@ class Result { Result& operator=(const Result& other) = delete; /// Move construction is allowed - Result(Result&& other) : m_var(std::move(other.m_var)) {} + Result(Result&& other) noexcept : m_var(std::move(other.m_var)) {} /// Move assignment is allowed /// @param other The other result instance, rvalue reference /// @return The assigned instance - Result& operator=(Result&& other) { + Result& operator=(Result&& other) noexcept { m_var = std::move(other.m_var); return *this; } @@ -357,7 +357,7 @@ class Result { /// Move constructor /// @param other The other result object, rvalue ref - Result(Result&& other) : m_opt(std::move(other.m_opt)) {} + Result(Result&& other) noexcept : m_opt(std::move(other.m_opt)) {} /// Move assignment operator /// @param other The other result object, rvalue ref diff --git a/Core/include/Acts/Utilities/VectorHelpers.hpp b/Core/include/Acts/Utilities/VectorHelpers.hpp index e2c78619a3f..c48ffa2be71 100644 --- a/Core/include/Acts/Utilities/VectorHelpers.hpp +++ b/Core/include/Acts/Utilities/VectorHelpers.hpp @@ -11,7 +11,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/Common.hpp" #include "Acts/Definitions/TrackParametrization.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include #include @@ -145,29 +145,35 @@ inline std::array evaluateTrigonomics(const Vector3& direction) { /// Helper method to extract the binning value from a 3D vector. /// /// For this method a 3D vector is required to guarantee all potential -/// binning values. -inline double cast(const Vector3& position, BinningValue bval) { - switch (bval) { - case BinningValue::binX: +/// axis directions to be casted from +/// +/// @param position is the position in global +/// @param aDir is the axis direction to be extracted +/// +/// @return the value of the binning direction +inline double cast(const Vector3& position, AxisDirection aDir) { + using enum AxisDirection; + switch (aDir) { + case AxisX: return position[0]; - case BinningValue::binY: + case AxisY: return position[1]; - case BinningValue::binZ: + case AxisZ: return position[2]; - case BinningValue::binR: + case AxisR: return perp(position); - case BinningValue::binPhi: + case AxisPhi: return phi(position); - case BinningValue::binRPhi: + case AxisRPhi: return perp(position) * phi(position); - case BinningValue::binH: + case AxisTheta: return theta(position); - case BinningValue::binEta: + case AxisEta: return eta(position); - case BinningValue::binMag: + case AxisMag: return position.norm(); default: - assert(false && "Invalid BinningValue enum value"); + assert(false && "Invalid AxisDirection enum value"); return std::numeric_limits::quiet_NaN(); } } diff --git a/Core/src/Detector/CuboidalContainerBuilder.cpp b/Core/src/Detector/CuboidalContainerBuilder.cpp index 47533bc4a11..c7390e0c862 100644 --- a/Core/src/Detector/CuboidalContainerBuilder.cpp +++ b/Core/src/Detector/CuboidalContainerBuilder.cpp @@ -35,13 +35,14 @@ Acts::Experimental::CuboidalContainerBuilder::CuboidalContainerBuilder( "CuboidalContainerBuilder: no sub builders provided."); } // Check if binning value is correctly chosen - if (m_cfg.binning != Acts::BinningValue::binX && - m_cfg.binning != Acts::BinningValue::binY && - m_cfg.binning != Acts::BinningValue::binZ) { + if (m_cfg.binning != Acts::AxisDirection::AxisX && + m_cfg.binning != Acts::AxisDirection::AxisY && + m_cfg.binning != Acts::AxisDirection::AxisZ) { throw std::invalid_argument( "CuboidalContainerBuilder: Invalid binning value. Only " - "Acts::BinningValue::binX, " - "Acts::BinningValue::binY, Acts::BinningValue::binZ are supported."); + "Acts::AxisDirection::AxisX, " + "Acts::AxisDirection::AxisY, Acts::AxisDirection::AxisZ are " + "supported."); } } @@ -94,13 +95,14 @@ Acts::Experimental::CuboidalContainerBuilder::CuboidalContainerBuilder( } m_cfg.binning = bpNode.binning.at(0); // Check if binning value is correctly chosen - if (m_cfg.binning != Acts::BinningValue::binX && - m_cfg.binning != Acts::BinningValue::binY && - m_cfg.binning != Acts::BinningValue::binZ) { + if (m_cfg.binning != Acts::AxisDirection::AxisX && + m_cfg.binning != Acts::AxisDirection::AxisY && + m_cfg.binning != Acts::AxisDirection::AxisZ) { throw std::invalid_argument( "CuboidalContainerBuilder: Invalid binning value. Only " - "Acts::BinningValue::binX, " - "Acts::BinningValue::binY, Acts::BinningValue::binZ are supported."); + "Acts::AxisDirection::AxisX, " + "Acts::AxisDirection::AxisY, Acts::AxisDirection::AxisZ are " + "supported."); } m_cfg.auxiliary = "*** acts auto-generated from proxy ***"; diff --git a/Core/src/Detector/CylindricalContainerBuilder.cpp b/Core/src/Detector/CylindricalContainerBuilder.cpp index 8441dc93762..86dcdb08a16 100644 --- a/Core/src/Detector/CylindricalContainerBuilder.cpp +++ b/Core/src/Detector/CylindricalContainerBuilder.cpp @@ -44,25 +44,25 @@ namespace { template Acts::Experimental::DetectorComponent::PortalContainer connect( const Acts::GeometryContext& gctx, object_collection& objects, - const std::vector& binning, + const std::vector& binning, Acts::Logging::Level logLevel) { // Return container object Acts::Experimental::DetectorComponent::PortalContainer portalContainer; if (binning.size() == 1u) { - Acts::BinningValue bv = binning.front(); + Acts::AxisDirection bv = binning.front(); // 1-dimensional binning options switch (bv) { - case Acts::BinningValue::binR: { + case Acts::AxisDirection::AxisR: { portalContainer = Acts::Experimental::detail::CylindricalDetectorHelper::connectInR( gctx, objects, {}, logLevel); } break; - case Acts::BinningValue::binZ: { + case Acts::AxisDirection::AxisZ: { portalContainer = Acts::Experimental::detail::CylindricalDetectorHelper::connectInZ( gctx, objects, {}, logLevel); } break; - case Acts::BinningValue::binPhi: { + case Acts::AxisDirection::AxisPhi: { portalContainer = Acts::Experimental::detail::CylindricalDetectorHelper::connectInPhi( gctx, objects, {}, logLevel); @@ -71,8 +71,8 @@ Acts::Experimental::DetectorComponent::PortalContainer connect( break; } } else if (binning == - std::vector{Acts::BinningValue::binZ, - Acts::BinningValue::binR} && + std::vector{Acts::AxisDirection::AxisZ, + Acts::AxisDirection::AxisR} && objects.size() == 2u) { portalContainer = Acts::Experimental::detail::CylindricalDetectorHelper::wrapInZR( @@ -95,8 +95,8 @@ Acts::Experimental::CylindricalContainerBuilder::CylindricalContainerBuilder( if (m_cfg.binning.size() == 1u) { // 1-dimensional case auto b = m_cfg.binning.front(); - if (b != Acts::BinningValue::binR && b != Acts::BinningValue::binZ && - b != Acts::BinningValue::binPhi) { + if (b != Acts::AxisDirection::AxisR && b != Acts::AxisDirection::AxisZ && + b != Acts::AxisDirection::AxisPhi) { throw std::invalid_argument( "CylindricalContainerBuilder: 1D binning only supported in z, r, or " "phi"); @@ -104,8 +104,8 @@ Acts::Experimental::CylindricalContainerBuilder::CylindricalContainerBuilder( } else if (m_cfg.binning.size() == 2u) { // 2-dimensional case, this is for wrapping if (m_cfg.binning != - std::vector{Acts::BinningValue::binZ, - Acts::BinningValue::binR}) { + std::vector{Acts::AxisDirection::AxisZ, + Acts::AxisDirection::AxisR}) { throw std::invalid_argument( "CylindricalContainerBuilder: 2D binning only supports wrapping in " "z-r."); @@ -168,8 +168,8 @@ Acts::Experimental::CylindricalContainerBuilder::CylindricalContainerBuilder( if (m_cfg.binning.size() == 1u) { // 1-dimensional case auto b = m_cfg.binning.front(); - if (b != Acts::BinningValue::binR && b != Acts::BinningValue::binZ && - b != Acts::BinningValue::binPhi) { + if (b != Acts::AxisDirection::AxisR && b != Acts::AxisDirection::AxisZ && + b != Acts::AxisDirection::AxisPhi) { throw std::invalid_argument( "CylindricalContainerBuilder: 1D binning only supported in z, r, or " "phi"); @@ -177,8 +177,8 @@ Acts::Experimental::CylindricalContainerBuilder::CylindricalContainerBuilder( } else if (m_cfg.binning.size() == 2u) { // 2-dimensional case, this is for wrapping if (m_cfg.binning != - std::vector{Acts::BinningValue::binZ, - Acts::BinningValue::binR}) { + std::vector{Acts::AxisDirection::AxisZ, + Acts::AxisDirection::AxisR}) { throw std::invalid_argument( "CylindricalContainerBuilder: 2D binning only supports wrapping in " "z-r."); diff --git a/Core/src/Detector/DetectorVolume.cpp b/Core/src/Detector/DetectorVolume.cpp index 6cd8d189298..eb74a2b8b57 100644 --- a/Core/src/Detector/DetectorVolume.cpp +++ b/Core/src/Detector/DetectorVolume.cpp @@ -261,7 +261,7 @@ bool Acts::Experimental::DetectorVolume::checkContainment( // We don't have a logging instance here // so can't throw a warning for shapes that are // using the bounding box - auto binningValues = volumeBounds().canonicalBinning(); + auto binningValues = volumeBounds().canonicalAxes(); // Create the volume extent auto volumeExtent = extent(gctx, nseg); diff --git a/Core/src/Detector/IndexedRootVolumeFinderBuilder.cpp b/Core/src/Detector/IndexedRootVolumeFinderBuilder.cpp index ae1bee83e5d..527a81a80a6 100644 --- a/Core/src/Detector/IndexedRootVolumeFinderBuilder.cpp +++ b/Core/src/Detector/IndexedRootVolumeFinderBuilder.cpp @@ -22,7 +22,7 @@ void fillGridIndices2D( const std::vector>& rootVolumes, const std::array, 2u>& boundaries, - const std::array& casts) { + const std::array& casts) { // Brute force loop over all bins & all volumes for (const auto [ic0, c0] : Acts::enumerate(boundaries[0u])) { if (ic0 > 0) { @@ -31,8 +31,8 @@ void fillGridIndices2D( if (ic1 > 0) { double v1 = 0.5 * (c1 + boundaries[1u][ic1 - 1]); if (casts == - std::array{Acts::BinningValue::binZ, - Acts::BinningValue::binR}) { + std::array{Acts::AxisDirection::AxisZ, + Acts::AxisDirection::AxisR}) { Acts::Vector3 zrPosition{v1, 0., v0}; for (const auto [iv, v] : Acts::enumerate(rootVolumes)) { if (v->inside(gctx, zrPosition)) { @@ -49,10 +49,10 @@ void fillGridIndices2D( } // namespace Acts::Experimental::IndexedRootVolumeFinderBuilder:: - IndexedRootVolumeFinderBuilder(std::vector binning) + IndexedRootVolumeFinderBuilder(std::vector binning) : m_casts(std::move(binning)) { - if (m_casts != std::vector{Acts::BinningValue::binZ, - Acts::BinningValue::binR}) { + if (m_casts != std::vector{Acts::AxisDirection::AxisZ, + Acts::AxisDirection::AxisR}) { throw std::invalid_argument("Online (z,r) binning is currently supported."); } } @@ -72,7 +72,7 @@ Acts::Experimental::IndexedRootVolumeFinderBuilder::construct( using GridType = typename AxesGeneratorType::template grid_type; GridType grid(zrAxes()); - auto casts = std::array{m_casts[0u], m_casts[1u]}; + auto casts = std::array{m_casts[0u], m_casts[1u]}; auto boundaries = std::array, 2u>{rzphis[1], rzphis[0]}; fillGridIndices2D(gctx, grid, rootVolumes, boundaries, casts); diff --git a/Core/src/Detector/LayerStructureBuilder.cpp b/Core/src/Detector/LayerStructureBuilder.cpp index 76092582eea..5b63b40ba39 100644 --- a/Core/src/Detector/LayerStructureBuilder.cpp +++ b/Core/src/Detector/LayerStructureBuilder.cpp @@ -18,7 +18,7 @@ #include "Acts/Navigation/DetectorVolumeFinders.hpp" #include "Acts/Navigation/NavigationDelegates.hpp" #include "Acts/Surfaces/Surface.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/BinningData.hpp" #include "Acts/Utilities/Enumerate.hpp" #include "Acts/Utilities/Grid.hpp" @@ -53,8 +53,8 @@ void adaptBinningRange(std::vector& pBinning, // Get the number of bins std::size_t nBins = pb.bins(); // Check if extent overwrites that - if (extent.constrains(pb.binValue)) { - const auto& range = extent.range(pb.binValue); + if (extent.constrains(pb.axisDir)) { + const auto& range = extent.range(pb.axisDir); // Patch the edges values from the range vmin = range.min(); vmax = range.max(); @@ -99,7 +99,7 @@ Acts::Experimental::InternalNavigationDelegate createUpdater( decltype(lSurfaces), Acts::Experimental::IndexedSurfacesNavigation> isg{std::move(lSurfaces), std::move(assignToAll), - {binning.binValue}, + {binning.axisDir}, {binning.expansion}}; if (binning.axisType == Acts::AxisType::Equidistant) { // Equidistant @@ -141,7 +141,7 @@ Acts::Experimental::InternalNavigationDelegate createUpdater( decltype(lSurfaces), Acts::Experimental::IndexedSurfacesNavigation> isg{lSurfaces, assignToAll, - {aBinning.binValue, bBinning.binValue}, + {aBinning.axisDir, bBinning.axisDir}, {aBinning.expansion, bBinning.expansion}}; // Run through the cases if (aBinning.axisType == Acts::AxisType::Equidistant && @@ -242,11 +242,11 @@ Acts::Experimental::LayerStructureBuilder::construct( Extent supportExtent; // Let us start with an eventually existing volume extent, but only pick // the binning value that are not constrained by the internal surfaces - for (const auto& bv : allBinningValues()) { + for (const auto& bv : allAxisDirections()) { if (support.volumeExtent.constrains(bv) && !rangeContainsValue(support.internalConstraints, bv)) { ACTS_VERBOSE(" Support surface is constrained by volume extent in " - << binningValueName(bv)); + << axisDirectionName(bv)); supportExtent.set(bv, support.volumeExtent.min(bv), support.volumeExtent.max(bv)); } @@ -266,27 +266,27 @@ Acts::Experimental::LayerStructureBuilder::construct( // Add cylindrical support if (support.type == Surface::SurfaceType::Cylinder) { detail::SupportSurfacesHelper::CylindricalSupport cSupport{ - support.offset, support.volumeClearance[BinningValue::binZ], - support.volumeClearance[BinningValue::binPhi]}; + support.offset, support.volumeClearance[AxisDirection::AxisZ], + support.volumeClearance[AxisDirection::AxisPhi]}; detail::SupportSurfacesHelper::addSupport(internalSurfaces, assignToAll, supportExtent, cSupport, support.splits); } else if (support.type == Surface::SurfaceType::Disc) { // Add disc support detail::SupportSurfacesHelper::DiscSupport dSupport{ - support.offset, support.volumeClearance[BinningValue::binR], - support.volumeClearance[BinningValue::binPhi]}; + support.offset, support.volumeClearance[AxisDirection::AxisR], + support.volumeClearance[AxisDirection::AxisPhi]}; detail::SupportSurfacesHelper::addSupport(internalSurfaces, assignToAll, supportExtent, dSupport, support.splits); } else if (support.type == Surface::SurfaceType::Plane) { // Set the local coordinates - cyclic permutation - std::array locals = {BinningValue::binX, - BinningValue::binY}; - if (support.pPlacement == BinningValue::binX) { - locals = {BinningValue::binY, BinningValue::binZ}; - } else if (support.pPlacement == BinningValue::binY) { - locals = {BinningValue::binZ, BinningValue::binX}; + std::array locals = {AxisDirection::AxisX, + AxisDirection::AxisY}; + if (support.pPlacement == AxisDirection::AxisX) { + locals = {AxisDirection::AxisY, AxisDirection::AxisZ}; + } else if (support.pPlacement == AxisDirection::AxisY) { + locals = {AxisDirection::AxisZ, AxisDirection::AxisX}; } // Add rectangular support detail::SupportSurfacesHelper::RectangularSupport rSupport{ @@ -340,7 +340,7 @@ Acts::Experimental::LayerStructureBuilder::construct( adaptBinningRange(binnings, m_cfg.extent.value()); } // Sort the binning for conventions - std::ranges::sort(binnings, {}, [](const auto& b) { return b.binValue; }); + std::ranges::sort(binnings, {}, [](const auto& b) { return b.axisDir; }); ACTS_DEBUG("- 2-dimensional surface binning detected."); // Capture the binnings diff --git a/Core/src/Detector/MultiWireStructureBuilder.cpp b/Core/src/Detector/MultiWireStructureBuilder.cpp index 59f87a7e3c8..6ff673f958a 100644 --- a/Core/src/Detector/MultiWireStructureBuilder.cpp +++ b/Core/src/Detector/MultiWireStructureBuilder.cpp @@ -72,7 +72,7 @@ class MultiWireInternalStructureBuilder Acts::Experimental::MultiLayerSurfacesNavigation> isg{internalSurfaces, {}, - {m_cfg.binning[0u].binValue, m_cfg.binning[1u].binValue}, + {m_cfg.binning[0u].axisDir, m_cfg.binning[1u].axisDir}, {m_cfg.binning[0u].expansion, m_cfg.binning[1u].expansion}, m_cfg.transform}; Acts::Experimental::detail::CenterReferenceGenerator rGenerator; diff --git a/Core/src/Detector/ProtoDetector.cpp b/Core/src/Detector/ProtoDetector.cpp index a1ec0009c57..ef8087c46e8 100644 --- a/Core/src/Detector/ProtoDetector.cpp +++ b/Core/src/Detector/ProtoDetector.cpp @@ -24,20 +24,20 @@ void Acts::ProtoVolume::extendUp(Acts::ProtoVolume& ptVolume) { } } -void Acts::ProtoVolume::propagateMinDown(BinningValue bValue) { +void Acts::ProtoVolume::propagateMinDown(AxisDirection aDir) { if (container.has_value()) { for (auto& cv : container.value().constituentVolumes) { - cv.extent.set(bValue, extent.min(bValue), cv.extent.max(bValue)); - cv.propagateMinDown(bValue); + cv.extent.set(aDir, extent.min(aDir), cv.extent.max(aDir)); + cv.propagateMinDown(aDir); } } } -void Acts::ProtoVolume::propagateMaxDown(BinningValue bValue) { +void Acts::ProtoVolume::propagateMaxDown(AxisDirection aDir) { if (container.has_value()) { for (auto& cv : container.value().constituentVolumes) { - cv.extent.set(bValue, cv.extent.min(bValue), extent.max(bValue)); - cv.propagateMaxDown(bValue); + cv.extent.set(aDir, cv.extent.min(aDir), extent.max(aDir)); + cv.propagateMaxDown(aDir); } } } @@ -52,7 +52,7 @@ void Acts::ProtoVolume::constrainDown(const Acts::ProtoVolume& ptVolume) { } void Acts::ProtoVolume::harmonize(bool legacy) { - std::vector otherConstrains; + std::vector otherConstrains; // Deal with the constituents if (container.has_value() && !container.value().constituentVolumes.empty()) { @@ -82,9 +82,9 @@ void Acts::ProtoVolume::harmonize(bool legacy) { std::vector borders = {}; // The volumes should be harmonized in all other constraining values - for (auto obValue : allBinningValues()) { - if (obValue != binValue && extent.constrains(obValue)) { - otherConstrains.push_back(obValue); + for (auto oaDir : allAxisDirections()) { + if (oaDir != binValue && extent.constrains(oaDir)) { + otherConstrains.push_back(oaDir); } } diff --git a/Core/src/Detector/VolumeStructureBuilder.cpp b/Core/src/Detector/VolumeStructureBuilder.cpp index 9103164ad58..7f16cb0d4aa 100644 --- a/Core/src/Detector/VolumeStructureBuilder.cpp +++ b/Core/src/Detector/VolumeStructureBuilder.cpp @@ -74,15 +74,16 @@ Acts::Experimental::VolumeStructureBuilder::construct( if (boundValues.empty() && m_cfg.extent.has_value()) { ACTS_VERBOSE("Cuboid: estimate parameters from Extent."); const auto& vExtent = m_cfg.extent.value(); - if (vExtent.constrains(BinningValue::binX) && - vExtent.constrains(BinningValue::binY) && - vExtent.constrains(BinningValue::binZ)) { - eTransform.pretranslate(Vector3(vExtent.medium(BinningValue::binX), - vExtent.medium(BinningValue::binY), - vExtent.medium(BinningValue::binZ))); - boundValues = {0.5 * vExtent.interval(BinningValue::binX), - 0.5 * vExtent.interval(BinningValue::binY), - 0.5 * vExtent.interval(BinningValue::binZ)}; + if (vExtent.constrains(AxisDirection::AxisX) && + vExtent.constrains(AxisDirection::AxisY) && + vExtent.constrains(AxisDirection::AxisZ)) { + eTransform.pretranslate( + Vector3(vExtent.medium(AxisDirection::AxisX), + vExtent.medium(AxisDirection::AxisY), + vExtent.medium(AxisDirection::AxisZ))); + boundValues = {0.5 * vExtent.interval(AxisDirection::AxisX), + 0.5 * vExtent.interval(AxisDirection::AxisY), + 0.5 * vExtent.interval(AxisDirection::AxisZ)}; } else { throw std::runtime_error( @@ -119,16 +120,17 @@ Acts::Experimental::VolumeStructureBuilder::construct( if (boundValues.empty() && m_cfg.extent.has_value()) { ACTS_VERBOSE("Cylinder: estimate parameters from Extent."); const auto& vExtent = m_cfg.extent.value(); - if (vExtent.constrains(BinningValue::binR) && - vExtent.constrains(BinningValue::binZ)) { + if (vExtent.constrains(AxisDirection::AxisR) && + vExtent.constrains(AxisDirection::AxisZ)) { eTransform.pretranslate( - Vector3(0., 0., vExtent.medium(BinningValue::binZ))); - boundValues = {vExtent.min(BinningValue::binR), - vExtent.max(BinningValue::binR), - 0.5 * vExtent.interval(BinningValue::binZ)}; - if (vExtent.constrains(BinningValue::binPhi)) { - boundValues.push_back(0.5 * vExtent.interval(BinningValue::binPhi)); - boundValues.push_back(vExtent.medium(BinningValue::binPhi)); + Vector3(0., 0., vExtent.medium(AxisDirection::AxisZ))); + boundValues = {vExtent.min(AxisDirection::AxisR), + vExtent.max(AxisDirection::AxisR), + 0.5 * vExtent.interval(AxisDirection::AxisZ)}; + if (vExtent.constrains(AxisDirection::AxisPhi)) { + boundValues.push_back(0.5 * + vExtent.interval(AxisDirection::AxisPhi)); + boundValues.push_back(vExtent.medium(AxisDirection::AxisPhi)); } } else { throw std::runtime_error( diff --git a/Core/src/Detector/detail/BlueprintHelper.cpp b/Core/src/Detector/detail/BlueprintHelper.cpp index b0167188021..c67782ed757 100644 --- a/Core/src/Detector/detail/BlueprintHelper.cpp +++ b/Core/src/Detector/detail/BlueprintHelper.cpp @@ -18,16 +18,16 @@ namespace { std::array endPointsXYZ( - const Acts::Experimental::Blueprint::Node& node, Acts::BinningValue bVal) { + const Acts::Experimental::Blueprint::Node& node, Acts::AxisDirection bVal) { unsigned int bIdx = 0; switch (bVal) { - case Acts::BinningValue::binX: + case Acts::AxisDirection::AxisX: bIdx = 0; break; - case Acts::BinningValue::binY: + case Acts::AxisDirection::AxisY: bIdx = 1; break; - case Acts::BinningValue::binZ: + case Acts::AxisDirection::AxisZ: bIdx = 2; break; default: @@ -52,14 +52,14 @@ void Acts::Experimental::detail::BlueprintHelper::sort(Blueprint::Node& node, if (node.binning.size() == 1) { auto bVal = node.binning.front(); // x,y,z binning along the axis - if (bVal == BinningValue::binX || bVal == BinningValue::binY || - bVal == BinningValue::binZ) { + if (bVal == AxisDirection::AxisX || bVal == AxisDirection::AxisY || + bVal == AxisDirection::AxisZ) { Vector3 nodeCenter = node.transform.translation(); Vector3 nodeSortAxis = node.transform.rotation().col(toUnderlying(bVal)); std::ranges::sort(node.children, {}, [&](const auto& c) { return (c->transform.translation() - nodeCenter).dot(nodeSortAxis); }); - } else if (bVal == BinningValue::binR && + } else if (bVal == AxisDirection::AxisR && node.boundsType == VolumeBounds::eCylinder) { std::ranges::sort(node.children, {}, [](const auto& c) { return c->boundaryValues[0] + c->boundaryValues[1]; @@ -108,7 +108,7 @@ void Acts::Experimental::detail::BlueprintHelper::fillGapsCylindrical( std::vector> gaps; // Only 1D binning implemented for the moment - if (BinningValue bVal = node.binning.front(); bVal == BinningValue::binZ) { + if (AxisDirection bVal = node.binning.front(); bVal == AxisDirection::AxisZ) { // adjust inner/outer radius if (adjustToParent) { std::for_each(node.children.begin(), node.children.end(), @@ -152,7 +152,7 @@ void Acts::Experimental::detail::BlueprintHelper::fillGapsCylindrical( gaps.push_back(std::move(gap)); } - } else if (bVal == BinningValue::binR) { + } else if (bVal == AxisDirection::AxisR) { // We have binning in R present if (adjustToParent) { std::for_each(node.children.begin(), node.children.end(), @@ -208,8 +208,8 @@ void Acts::Experimental::detail::BlueprintHelper::fillGapsCuboidal( sort(node, false); // Cuboidal detector binnings - std::array allowedBinVals = { - BinningValue::binX, BinningValue::binY, BinningValue::binZ}; + std::array allowedBinVals = { + AxisDirection::AxisX, AxisDirection::AxisY, AxisDirection::AxisZ}; std::vector> gaps; auto binVal = node.binning.front(); diff --git a/Core/src/Detector/detail/CuboidalDetectorHelper.cpp b/Core/src/Detector/detail/CuboidalDetectorHelper.cpp index cda12f02de2..db71fa1a7df 100644 --- a/Core/src/Detector/detail/CuboidalDetectorHelper.cpp +++ b/Core/src/Detector/detail/CuboidalDetectorHelper.cpp @@ -28,23 +28,23 @@ Acts::Experimental::DetectorComponent::PortalContainer Acts::Experimental::detail::CuboidalDetectorHelper::connect( const GeometryContext& gctx, std::vector>& volumes, - BinningValue bValue, const std::vector& selectedOnly, + AxisDirection bValue, const std::vector& selectedOnly, Acts::Logging::Level logLevel) { ACTS_LOCAL_LOGGER(getDefaultLogger("CuboidalDetectorHelper", logLevel)); ACTS_DEBUG("Connect " << volumes.size() << " detector volumes in " - << binningValueName(bValue) << "."); + << axisDirectionName(bValue) << "."); // Check transform for consistency auto centerDistances = DetectorVolumeConsistency::checkCenterAlignment(gctx, volumes, bValue); // Assign the portal indices according to the volume bounds definition - std::array possibleValues = { - BinningValue::binX, BinningValue::binY, BinningValue::binZ}; - // 1 -> [ 2,3 ] for binX connection (cylclic one step) - // 2 -> [ 4,5 ] for binY connection (cylclic two steps) - // 0 -> [ 0,1 ] for binZ connection (to be in line with cylinder covnention) + std::array possibleValues = { + AxisDirection::AxisX, AxisDirection::AxisY, AxisDirection::AxisZ}; + // 1 -> [ 2,3 ] for AxisX connection (cylclic one step) + // 2 -> [ 4,5 ] for AxisY connection (cylclic two steps) + // 0 -> [ 0,1 ] for AxisZ connection (to be in line with cylinder covnention) using PortalSet = std::array; std::vector portalSets = { {PortalSet{2, 3}, PortalSet{4, 5}, PortalSet{0, 1}}}; @@ -61,7 +61,7 @@ Acts::Experimental::detail::CuboidalDetectorHelper::connect( }; // Pick the counter part value - auto counterPart = [&](BinningValue mValue) -> BinningValue { + auto counterPart = [&](AxisDirection mValue) -> AxisDirection { for (auto cValue : possibleValues) { if (cValue != mValue && cValue != bValue) { return cValue; @@ -169,14 +169,14 @@ Acts::Experimental::detail::CuboidalDetectorHelper::connect( // - this is an anticyclic swap bool mergedInX = true; switch (bValue) { - case BinningValue::binZ: { - mergedInX = (mergeValue == BinningValue::binY); + case AxisDirection::AxisZ: { + mergedInX = (mergeValue == AxisDirection::AxisY); } break; - case BinningValue::binY: { - mergedInX = (mergeValue == BinningValue::binX); + case AxisDirection::AxisY: { + mergedInX = (mergeValue == AxisDirection::AxisX); } break; - case BinningValue::binX: { - mergedInX = (mergeValue == BinningValue::binZ); + case AxisDirection::AxisX: { + mergedInX = (mergeValue == AxisDirection::AxisZ); } break; default: break; @@ -208,12 +208,12 @@ Acts::Experimental::detail::CuboidalDetectorHelper::connect( // Assign the portal direction // in a consistent way Acts::Direction dir = - (index % 2 == 0) ? Direction::Forward : Direction::Backward; + (index % 2 == 0) ? Direction::Forward() : Direction::Backward(); // Make the stitch boundaries pReplacements.push_back(PortalReplacement( portal, index, dir, stitchBoundaries, - (mergedInX ? BinningValue::binX : BinningValue::binY))); + (mergedInX ? AxisDirection::AxisX : AxisDirection::AxisY))); } } @@ -243,20 +243,20 @@ Acts::Experimental::DetectorComponent::PortalContainer Acts::Experimental::detail::CuboidalDetectorHelper::connect( const GeometryContext& /*gctx*/, const std::vector& containers, - BinningValue bValue, const std::vector& /*unused */, + AxisDirection bValue, const std::vector& /*unused */, Acts::Logging::Level logLevel) noexcept(false) { // The local logger ACTS_LOCAL_LOGGER(getDefaultLogger("CuboidalDetectorHelper", logLevel)); ACTS_DEBUG("Connect " << containers.size() << " containers in " - << binningValueName(bValue) << "."); + << axisDirectionName(bValue) << "."); // Return the new container DetectorComponent::PortalContainer dShell; // The possible bin values - std::array possibleValues = { - BinningValue::binX, BinningValue::binY, BinningValue::binZ}; + std::array possibleValues = { + AxisDirection::AxisX, AxisDirection::AxisY, AxisDirection::AxisZ}; // And their associated portal sets, see above using PortalSet = std::array; std::vector portalSets = { @@ -283,13 +283,11 @@ Acts::Experimental::detail::CuboidalDetectorHelper::connect( std::shared_ptr sPortal = formerContainer.find(startIndex)->second; auto sAttachedVolumes = - sPortal - ->attachedDetectorVolumes()[Direction(Direction::Backward).index()]; + sPortal->attachedDetectorVolumes()[Direction::Backward().index()]; std::shared_ptr ePortal = currentContainer.find(endIndex)->second; auto eAttachedVolumes = - ePortal - ->attachedDetectorVolumes()[Direction(Direction::Forward).index()]; + ePortal->attachedDetectorVolumes()[Direction::Forward().index()]; auto fusedPortal = Portal::fuse(sPortal, ePortal); diff --git a/Core/src/Detector/detail/CylindricalDetectorHelper.cpp b/Core/src/Detector/detail/CylindricalDetectorHelper.cpp index 545e0947797..43c2978f57d 100644 --- a/Core/src/Detector/detail/CylindricalDetectorHelper.cpp +++ b/Core/src/Detector/detail/CylindricalDetectorHelper.cpp @@ -84,9 +84,9 @@ Acts::Experimental::PortalReplacement createDiscReplacement( const std::vector& phiBoundaries, unsigned int index, Acts::Direction dir) { // Autodetector stitch value - Acts::BinningValue stitchValue = phiBoundaries.size() == 2u - ? Acts::BinningValue::binR - : Acts::BinningValue::binPhi; + Acts::AxisDirection stitchValue = phiBoundaries.size() == 2u + ? Acts::AxisDirection::AxisR + : Acts::AxisDirection::AxisPhi; // Estimate ranges auto [minRit, maxRit] = std::ranges::minmax_element(rBoundaries); auto [sectorPhi, avgPhi] = Acts::range_medium(phiBoundaries); @@ -99,7 +99,7 @@ Acts::Experimental::PortalReplacement createDiscReplacement( transform, std::move(bounds)); // Make a portal and indicate the new link direction const auto& stitchBoundaries = - (stitchValue == Acts::BinningValue::binR) ? rBoundaries : phiBoundaries; + (stitchValue == Acts::AxisDirection::AxisR) ? rBoundaries : phiBoundaries; return Acts::Experimental::PortalReplacement( std::make_shared(surface), index, dir, stitchBoundaries, stitchValue); @@ -121,9 +121,9 @@ Acts::Experimental::PortalReplacement createCylinderReplacement( const std::vector& phiBoundaries, unsigned int index, Acts::Direction dir) { // Autodetector stitch value - Acts::BinningValue stitchValue = phiBoundaries.size() == 2u - ? Acts::BinningValue::binZ - : Acts::BinningValue::binPhi; + Acts::AxisDirection stitchValue = phiBoundaries.size() == 2u + ? Acts::AxisDirection::AxisZ + : Acts::AxisDirection::AxisPhi; auto [lengthZ, medZ] = Acts::range_medium(zBoundaries); auto [sectorPhi, avgPhi] = Acts::range_medium(phiBoundaries); @@ -136,7 +136,7 @@ Acts::Experimental::PortalReplacement createCylinderReplacement( // A make a portal and indicate the new link direction const auto& stitchBoundaries = - (stitchValue == Acts::BinningValue::binZ) ? zBoundaries : phiBoundaries; + (stitchValue == Acts::AxisDirection::AxisZ) ? zBoundaries : phiBoundaries; return Acts::Experimental::PortalReplacement( std::make_shared(surface), index, dir, stitchBoundaries, stitchValue); @@ -155,7 +155,7 @@ Acts::Experimental::PortalReplacement createCylinderReplacement( Acts::Experimental::PortalReplacement createSectorReplacement( const Acts::GeometryContext& gctx, const Acts::Vector3& volumeCenter, const Acts::Surface& refSurface, const std::vector& boundaries, - Acts::BinningValue binning, unsigned int index, Acts::Direction dir) { + Acts::AxisDirection binning, unsigned int index, Acts::Direction dir) { // Get a reference transform const auto& refTransform = refSurface.transform(gctx); auto refRotation = refTransform.rotation(); @@ -165,7 +165,7 @@ Acts::Experimental::PortalReplacement createSectorReplacement( // Create a new transform Acts::Transform3 transform = Acts::Transform3::Identity(); - if (binning == Acts::BinningValue::binR) { + if (binning == Acts::AxisDirection::AxisR) { // Range and center-r calculation auto [range, medium] = Acts::range_medium(boundaries); // New joint center: @@ -179,7 +179,7 @@ Acts::Experimental::PortalReplacement createSectorReplacement( boundValues[Acts::RectangleBounds::BoundValues::eMinX]); // New joint bounds bounds = std::make_unique(halfX, 0.5 * range); - } else if (binning == Acts::BinningValue::binZ) { + } else if (binning == Acts::AxisDirection::AxisZ) { // Range and medium z alculation auto [range, medium] = Acts::range_medium(boundaries); // Center R calculation, using projection onto vector @@ -370,8 +370,8 @@ Acts::Experimental::detail::CylindricalDetectorHelper::connectInR( std::vector pReplacements = {}; // Disc assignments are forward for negative disc, backward for positive - std::vector discDirs = {Acts::Direction::Forward, - Acts::Direction::Backward}; + std::vector discDirs = {Acts::Direction::Forward(), + Acts::Direction::Backward()}; for (const auto [iu, idir] : enumerate(discDirs)) { if (selectedOnly.empty() || rangeContainsValue(selectedOnly, iu)) { const Surface& refSurface = volumes[0u]->portals()[iu]->surface(); @@ -386,8 +386,8 @@ Acts::Experimental::detail::CylindricalDetectorHelper::connectInR( if (sectorsPresent) { ACTS_VERBOSE("Sector planes are present, they need replacement."); // Sector assignments are forward backward - std::vector sectorDirs = {Acts::Direction::Forward, - Acts::Direction::Backward}; + std::vector sectorDirs = {Acts::Direction::Forward(), + Acts::Direction::Backward()}; Acts::Vector3 vCenter = volumes[0u]->transform(gctx).translation(); for (const auto [iu, idir] : enumerate(sectorDirs)) { // (iu + 4u) corresponds to the indices of the phi-low and phi-high sector @@ -396,9 +396,9 @@ Acts::Experimental::detail::CylindricalDetectorHelper::connectInR( // As it is r-wrapping, the inner tube is guaranteed const Surface& refSurface = volumes[volumes.size() - 1u]->portals()[iu + 4u]->surface(); - pReplacements.push_back( - createSectorReplacement(gctx, vCenter, refSurface, rBoundaries, - Acts::BinningValue::binR, iu + 4ul, idir)); + pReplacements.push_back(createSectorReplacement( + gctx, vCenter, refSurface, rBoundaries, Acts::AxisDirection::AxisR, + iu + 4ul, idir)); } } } else { @@ -564,12 +564,12 @@ Acts::Experimental::detail::CylindricalDetectorHelper::connectInZ( std::vector pReplacements = {}; // Disc assignments are forward for negative disc, backward for positive - std::vector cylinderDirs = {Acts::Direction::Backward}; + std::vector cylinderDirs = {Acts::Direction::Backward()}; // Cylinder radii std::vector cylinderR = {maxR}; if (innerPresent) { ACTS_VERBOSE("Inner surface present, tube geometry detected."); - cylinderDirs.push_back(Direction::Forward); + cylinderDirs.push_back(Direction::Forward()); cylinderR.push_back(minR); } else { ACTS_VERBOSE("No inner surface present, solid cylinder geometry detected."); @@ -589,8 +589,8 @@ Acts::Experimental::detail::CylindricalDetectorHelper::connectInZ( if (sectorsPresent) { ACTS_VERBOSE("Sector planes are present, they need replacement."); // Sector assignmenta are forward backward - std::vector sectorDirs = {Acts::Direction::Forward, - Acts::Direction::Backward}; + std::vector sectorDirs = {Acts::Direction::Forward(), + Acts::Direction::Backward()}; for (const auto [iu, idir] : enumerate(sectorDirs)) { // Access with 3u or 4u but always write 4u (to be caught later) if (selectedOnly.empty() || rangeContainsValue(selectedOnly, iu + 4u)) { @@ -598,7 +598,7 @@ Acts::Experimental::detail::CylindricalDetectorHelper::connectInZ( volumes[0u]->portals()[iu + iSecOffset]->surface(); pReplacements.push_back(createSectorReplacement( gctx, combinedCenter, refSurface, zBoundaries, - Acts::BinningValue::binZ, iu + 4ul, idir)); + Acts::AxisDirection::AxisZ, iu + 4ul, idir)); } } } else { @@ -710,21 +710,21 @@ Acts::Experimental::detail::CylindricalDetectorHelper::connectInPhi( refTransform, {refValues[CylinderVolumeBounds::BoundValues::eMinR], refValues[CylinderVolumeBounds::BoundValues::eMaxR]}, - phiBoundaries, 0u, Acts::Direction::Forward)); + phiBoundaries, 0u, Acts::Direction::Forward())); // Positive disc pReplacements.push_back(createDiscReplacement( refTransform, {refValues[CylinderVolumeBounds::BoundValues::eMinR], refValues[CylinderVolumeBounds::BoundValues::eMaxR]}, - phiBoundaries, 1u, Acts::Direction::Backward)); + phiBoundaries, 1u, Acts::Direction::Backward())); // Outside cylinder pReplacements.push_back(createCylinderReplacement( refTransform, refValues[CylinderVolumeBounds::BoundValues::eMaxR], {-refValues[CylinderVolumeBounds::BoundValues::eHalfLengthZ], refValues[CylinderVolumeBounds::BoundValues::eHalfLengthZ]}, - phiBoundaries, 2u, Acts::Direction::Backward)); + phiBoundaries, 2u, Acts::Direction::Backward())); // If the volume has a different inner radius than 0, it MUST have // an inner cylinder @@ -734,7 +734,7 @@ Acts::Experimental::detail::CylindricalDetectorHelper::connectInPhi( refTransform, refValues[CylinderVolumeBounds::BoundValues::eMinR], {-refValues[CylinderVolumeBounds::BoundValues::eHalfLengthZ], refValues[CylinderVolumeBounds::BoundValues::eHalfLengthZ]}, - phiBoundaries, 3u, Acts::Direction::Forward)); + phiBoundaries, 3u, Acts::Direction::Forward())); } // Attach the new volume multi links @@ -822,7 +822,7 @@ Acts::Experimental::detail::CylindricalDetectorHelper::wrapInZR( std::vector pReplacements; pReplacements.push_back(createCylinderReplacement( volumes[0u]->transform(gctx), innerR, {-HlZ, -hlZ, hlZ, HlZ}, - {-std::numbers::pi, std::numbers::pi}, 3u, Direction::Forward)); + {-std::numbers::pi, std::numbers::pi}, 3u, Direction::Forward())); std::vector> zVolumes = { volumes[1u], volumes[0u], volumes[1u]}; // Attach the new volume multi links @@ -874,12 +874,10 @@ Acts::Experimental::detail::CylindricalDetectorHelper::connectInR( std::shared_ptr innerCylinder = containers[ic - 1].find(2u)->second; // Direction is explicitly addressed with a direction index auto innerAttachedVolumes = - innerCylinder - ->attachedDetectorVolumes()[Direction(Direction::Backward).index()]; + innerCylinder->attachedDetectorVolumes()[Direction::Backward().index()]; std::shared_ptr outerCylinder = containers[ic].find(3u)->second; auto outerAttachedVolume = - outerCylinder - ->attachedDetectorVolumes()[Direction(Direction::Forward).index()]; + outerCylinder->attachedDetectorVolumes()[Direction::Forward().index()]; auto fusedCylinder = Portal::fuse(innerCylinder, outerCylinder); // Update the attached volumes with the new portal @@ -944,12 +942,11 @@ Acts::Experimental::detail::CylindricalDetectorHelper::connectInZ( // Container attachment positive Disc of lower, negative Disc at higher std::shared_ptr pDisc = formerContainer.find(1u)->second; auto pAttachedVolumes = - pDisc - ->attachedDetectorVolumes()[Direction(Direction::Backward).index()]; + pDisc->attachedDetectorVolumes()[Direction::Backward().index()]; std::shared_ptr nDisc = currentContainer.find(0u)->second; auto nAttachedVolumes = - nDisc->attachedDetectorVolumes()[Direction(Direction::Forward).index()]; + nDisc->attachedDetectorVolumes()[Direction::Forward().index()]; auto fusedDisc = Portal::fuse(pDisc, nDisc); @@ -1058,8 +1055,7 @@ Acts::Experimental::detail::CylindricalDetectorHelper::wrapInZR( // Fuse outer cover of first with inner cylinder of wrapping volume auto& innerCover = innerContainer[2u]; auto innerAttachedVolumes = - innerCover - ->attachedDetectorVolumes()[Direction(Direction::Backward).index()]; + innerCover->attachedDetectorVolumes()[Direction::Backward().index()]; auto& innerTube = wrappingVolume->portalPtrs()[3u]; auto fusedCover = Portal::fuse(innerCover, innerTube); @@ -1074,8 +1070,7 @@ Acts::Experimental::detail::CylindricalDetectorHelper::wrapInZR( auto& firstDiscN = innerContainer[0u]; auto firstNAttachedVolumes = - firstDiscN - ->attachedDetectorVolumes()[Direction(Direction::Forward).index()]; + firstDiscN->attachedDetectorVolumes()[Direction::Forward().index()]; auto& secondDiscN = wrappingVolume->portalPtrs()[4u]; auto fusedDiscN = Portal::fuse(firstDiscN, secondDiscN); @@ -1089,8 +1084,7 @@ Acts::Experimental::detail::CylindricalDetectorHelper::wrapInZR( // Stich sides - positive auto& firstDiscP = innerContainer[1u]; auto firstPAttachedVolumes = - firstDiscP - ->attachedDetectorVolumes()[Direction(Direction::Backward).index()]; + firstDiscP->attachedDetectorVolumes()[Direction::Backward().index()]; auto& secondDiscP = wrappingVolume->portalPtrs()[5u]; auto fusedDiscP = Portal::fuse(firstDiscP, secondDiscP); diff --git a/Core/src/Detector/detail/DetectorVolumeConsistency.cpp b/Core/src/Detector/detail/DetectorVolumeConsistency.cpp index 999fe5fe6a8..ec8778de96b 100644 --- a/Core/src/Detector/detail/DetectorVolumeConsistency.cpp +++ b/Core/src/Detector/detail/DetectorVolumeConsistency.cpp @@ -39,7 +39,7 @@ std::vector Acts::Experimental::detail::DetectorVolumeConsistency::checkCenterAlignment( const GeometryContext& gctx, const std::vector>& volumes, - BinningValue axisValue) { + AxisDirection axisValue) { std::vector distances = {}; // First it needs to surfive the rotation check checkRotationAlignment(gctx, volumes); diff --git a/Core/src/Detector/detail/PortalHelper.cpp b/Core/src/Detector/detail/PortalHelper.cpp index a24b74308cf..40a418f4e4d 100644 --- a/Core/src/Detector/detail/PortalHelper.cpp +++ b/Core/src/Detector/detail/PortalHelper.cpp @@ -36,7 +36,7 @@ void Acts::Experimental::detail::PortalHelper::attachDetectorVolumesUpdater( const GeometryContext& gctx, Portal& portal, const std::vector>& volumes, const Direction& direction, const std::vector& boundaries, - const BinningValue& binning) { + const AxisDirection& binning) { // Check if the boundaries need a transform const auto pTransform = portal.surface().transform(gctx); // Creating a link to the mother diff --git a/Core/src/Detector/detail/ProtoMaterialHelper.cpp b/Core/src/Detector/detail/ProtoMaterialHelper.cpp index af5b96b187e..5cb3ad59c6f 100644 --- a/Core/src/Detector/detail/ProtoMaterialHelper.cpp +++ b/Core/src/Detector/detail/ProtoMaterialHelper.cpp @@ -25,8 +25,8 @@ Acts::Experimental::detail::ProtoMaterialHelper::attachProtoMaterial( ProtoBinning fBinning = b; // Check if the binning needs to be fixed if (fBinning.autorange) { - auto range = sExtent.range(b.binValue); - fBinning = ProtoBinning(b.binValue, b.boundaryType, range.min(), + auto range = sExtent.range(b.axisDir); + fBinning = ProtoBinning(b.axisDir, b.boundaryType, range.min(), range.max(), b.bins(), b.expansion); } fbDescription.binning.push_back(fBinning); diff --git a/Core/src/Detector/detail/SupportSurfacesHelper.cpp b/Core/src/Detector/detail/SupportSurfacesHelper.cpp index 1d06294e6a3..60f55b5ae74 100644 --- a/Core/src/Detector/detail/SupportSurfacesHelper.cpp +++ b/Core/src/Detector/detail/SupportSurfacesHelper.cpp @@ -28,26 +28,26 @@ Acts::Experimental::detail::SupportSurfacesHelper::SupportSurfaceComponents Acts::Experimental::detail::SupportSurfacesHelper::CylindricalSupport:: operator()(const Extent& lExtent) const { // Bail out if you have no measure of R, Z - if (!lExtent.constrains(BinningValue::binZ) || - !lExtent.constrains(BinningValue::binR)) { + if (!lExtent.constrains(AxisDirection::AxisZ) || + !lExtent.constrains(AxisDirection::AxisR)) { throw std::invalid_argument( "SupportSurfacesHelper::CylindricalSupport::operator() - z or " "r are not constrained."); } // Min / Max z with clearances adapted - double minZ = lExtent.min(BinningValue::binZ) + std::abs(zClearance[0u]); - double maxZ = lExtent.max(BinningValue::binZ) - std::abs(zClearance[1u]); + double minZ = lExtent.min(AxisDirection::AxisZ) + std::abs(zClearance[0u]); + double maxZ = lExtent.max(AxisDirection::AxisZ) - std::abs(zClearance[1u]); // Phi sector double hPhiSector = std::numbers::pi; double avgPhi = 0.; - if (lExtent.constrains(BinningValue::binPhi)) { + if (lExtent.constrains(AxisDirection::AxisPhi)) { // Min / Max phi with clearances adapted double minPhi = - lExtent.min(BinningValue::binPhi) + std::abs(phiClearance[0u]); + lExtent.min(AxisDirection::AxisPhi) + std::abs(phiClearance[0u]); double maxPhi = - lExtent.max(BinningValue::binPhi) - std::abs(phiClearance[1u]); + lExtent.max(AxisDirection::AxisPhi) - std::abs(phiClearance[1u]); hPhiSector = 0.5 * (maxPhi - minPhi); avgPhi = 0.5 * (minPhi + maxPhi); } @@ -58,10 +58,10 @@ operator()(const Extent& lExtent) const { } // The Radius estimation - double r = rOffset < 0 ? lExtent.min(BinningValue::binR) + rOffset - : lExtent.max(BinningValue::binR) + rOffset; + double r = rOffset < 0 ? lExtent.min(AxisDirection::AxisR) + rOffset + : lExtent.max(AxisDirection::AxisR) + rOffset; if (rOffset == 0.) { - r = lExtent.medium(BinningValue::binR); + r = lExtent.medium(AxisDirection::AxisR); } // Components are resolved and returned as a tuple return { @@ -72,35 +72,35 @@ Acts::Experimental::detail::SupportSurfacesHelper::SupportSurfaceComponents Acts::Experimental::detail::SupportSurfacesHelper::DiscSupport::operator()( const Extent& lExtent) const { // Bail out if you have no measure of R, Z - if (!lExtent.constrains(BinningValue::binZ) || - !lExtent.constrains(BinningValue::binR)) { + if (!lExtent.constrains(AxisDirection::AxisZ) || + !lExtent.constrains(AxisDirection::AxisR)) { throw std::invalid_argument( "SupportSurfacesHelper::DiscSupport::operator() - z or " "r are not constrained."); } // Min / Max r with clearances adapted - double minR = lExtent.min(BinningValue::binR) + std::abs(rClearance[0u]); - double maxR = lExtent.max(BinningValue::binR) - std::abs(rClearance[1u]); + double minR = lExtent.min(AxisDirection::AxisR) + std::abs(rClearance[0u]); + double maxR = lExtent.max(AxisDirection::AxisR) - std::abs(rClearance[1u]); // Phi sector double hPhiSector = std::numbers::pi; double avgPhi = 0.; - if (lExtent.constrains(BinningValue::binPhi)) { + if (lExtent.constrains(AxisDirection::AxisPhi)) { // Min / Max phi with clearances adapted double minPhi = - lExtent.min(BinningValue::binPhi) + std::abs(phiClearance[0u]); + lExtent.min(AxisDirection::AxisPhi) + std::abs(phiClearance[0u]); double maxPhi = - lExtent.max(BinningValue::binPhi) - std::abs(phiClearance[1u]); + lExtent.max(AxisDirection::AxisPhi) - std::abs(phiClearance[1u]); hPhiSector = 0.5 * (maxPhi - minPhi); avgPhi = 0.5 * (minPhi + maxPhi); } // The z position estimate - double z = zOffset < 0 ? lExtent.min(BinningValue::binZ) + zOffset - : lExtent.max(BinningValue::binZ) + zOffset; + double z = zOffset < 0 ? lExtent.min(AxisDirection::AxisZ) + zOffset + : lExtent.max(AxisDirection::AxisZ) + zOffset; if (zOffset == 0.) { - z = lExtent.medium(BinningValue::binZ); + z = lExtent.medium(AxisDirection::AxisZ); } Transform3 transform = Transform3::Identity(); @@ -114,20 +114,21 @@ Acts::Experimental::detail::SupportSurfacesHelper::SupportSurfaceComponents Acts::Experimental::detail::SupportSurfacesHelper::RectangularSupport:: operator()(const Extent& lExtent) const { // Bail out if you have no measure of X, Y, Z - if (!(lExtent.constrains(BinningValue::binX) && - lExtent.constrains(BinningValue::binY) && - lExtent.constrains(BinningValue::binZ))) { + if (!(lExtent.constrains(AxisDirection::AxisX) && + lExtent.constrains(AxisDirection::AxisY) && + lExtent.constrains(AxisDirection::AxisZ))) { throw std::invalid_argument( "SupportSurfacesHelper::RectangularSupport::operator() - x, y or " "z are not constrained."); } // Set the local coordinates - cyclic permutation - std::array locals = {BinningValue::binX, BinningValue::binY}; - if (pPlacement == BinningValue::binX) { - locals = {BinningValue::binY, BinningValue::binZ}; - } else if (pPlacement == BinningValue::binY) { - locals = {BinningValue::binZ, BinningValue::binX}; + std::array locals = {AxisDirection::AxisX, + AxisDirection::AxisY}; + if (pPlacement == AxisDirection::AxisX) { + locals = {AxisDirection::AxisY, AxisDirection::AxisZ}; + } else if (pPlacement == AxisDirection::AxisY) { + locals = {AxisDirection::AxisZ, AxisDirection::AxisX}; } // Make the rectangular shape diff --git a/Core/src/Geometry/Blueprint.cpp b/Core/src/Geometry/Blueprint.cpp index f4531acaa2f..a35de4a58f0 100644 --- a/Core/src/Geometry/Blueprint.cpp +++ b/Core/src/Geometry/Blueprint.cpp @@ -58,7 +58,7 @@ void Blueprint::addToGraphviz(std::ostream &os) const { std::unique_ptr Blueprint::construct( const BlueprintOptions &options, const GeometryContext &gctx, const Logger &logger) { - using enum BinningValue; + using enum AxisDirection; ACTS_INFO(prefix() << "Building tracking geometry from blueprint tree"); @@ -94,7 +94,7 @@ std::unique_ptr Blueprint::construct( // Make a copy that we'll modify auto newBounds = std::make_shared(*cyl); - const auto &zEnv = m_cfg.envelope[binZ]; + const auto &zEnv = m_cfg.envelope[AxisZ]; if (zEnv[0] != zEnv[1]) { ACTS_ERROR( prefix() << "Root node cylinder envelope for z must be symmetric"); @@ -103,7 +103,7 @@ std::unique_ptr Blueprint::construct( "symmetric"); } - const auto &rEnv = m_cfg.envelope[binR]; + const auto &rEnv = m_cfg.envelope[AxisR]; newBounds->set({ {eHalfLengthZ, newBounds->get(eHalfLengthZ) + zEnv[0]}, diff --git a/Core/src/Geometry/BlueprintNode.cpp b/Core/src/Geometry/BlueprintNode.cpp index 13c03495494..601fc6d2628 100644 --- a/Core/src/Geometry/BlueprintNode.cpp +++ b/Core/src/Geometry/BlueprintNode.cpp @@ -114,7 +114,7 @@ StaticBlueprintNode& BlueprintNode::addStaticVolume( } CylinderContainerBlueprintNode& BlueprintNode::addCylinderContainer( - const std::string& name, BinningValue direction, + const std::string& name, AxisDirection direction, const std::function& callback) { auto cylinder = diff --git a/Core/src/Geometry/CMakeLists.txt b/Core/src/Geometry/CMakeLists.txt index 189c4396112..2ed76752198 100644 --- a/Core/src/Geometry/CMakeLists.txt +++ b/Core/src/Geometry/CMakeLists.txt @@ -35,6 +35,7 @@ target_sources( Volume.cpp VolumeBounds.cpp CylinderVolumeStack.cpp + CuboidVolumeStack.cpp Portal.cpp GridPortalLink.cpp GridPortalLinkMerging.cpp @@ -50,4 +51,6 @@ target_sources( StaticBlueprintNode.cpp LayerBlueprintNode.cpp MaterialDesignatorBlueprintNode.cpp + VolumeAttachmentStrategy.cpp + VolumeResizeStrategy.cpp ) diff --git a/Core/src/Geometry/CompositePortalLink.cpp b/Core/src/Geometry/CompositePortalLink.cpp index 108db95c192..461c0cd72a5 100644 --- a/Core/src/Geometry/CompositePortalLink.cpp +++ b/Core/src/Geometry/CompositePortalLink.cpp @@ -15,10 +15,13 @@ #include "Acts/Surfaces/DiscSurface.hpp" #include "Acts/Surfaces/PlaneSurface.hpp" #include "Acts/Surfaces/RadialBounds.hpp" +#include "Acts/Surfaces/RectangleBounds.hpp" #include "Acts/Surfaces/RegularSurface.hpp" #include "Acts/Utilities/Axis.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include +#include #include #include #include @@ -30,7 +33,7 @@ namespace Acts { namespace { std::shared_ptr mergedSurface(const Surface& a, const Surface& b, - BinningValue direction) { + AxisDirection direction) { if (a.type() != b.type()) { throw std::invalid_argument{"Cannot merge surfaces of different types"}; } @@ -48,7 +51,9 @@ std::shared_ptr mergedSurface(const Surface& a, return merged; } else if (const auto* planeA = dynamic_cast(&a); planeA != nullptr) { - throw std::logic_error{"Plane surfaces not implemented yet"}; + const auto& planeB = dynamic_cast(b); + auto [merged, reversed] = planeA->mergedWith(planeB, direction); + return merged; } else { throw std::invalid_argument{"Unsupported surface type"}; } @@ -56,7 +61,7 @@ std::shared_ptr mergedSurface(const Surface& a, std::shared_ptr mergePortalLinks( const std::vector>& links, - BinningValue direction) { + AxisDirection direction) { assert(std::ranges::all_of(links, [](const auto& link) { return link != nullptr; })); assert(!links.empty()); @@ -73,7 +78,7 @@ std::shared_ptr mergePortalLinks( CompositePortalLink::CompositePortalLink(std::unique_ptr a, std::unique_ptr b, - BinningValue direction, bool flatten) + AxisDirection direction, bool flatten) : PortalLinkBase(mergedSurface(a->surface(), b->surface(), direction)), m_direction{direction} { if (!flatten) { @@ -99,7 +104,7 @@ CompositePortalLink::CompositePortalLink(std::unique_ptr a, } CompositePortalLink::CompositePortalLink( - std::vector> links, BinningValue direction, + std::vector> links, AxisDirection direction, bool flatten) : PortalLinkBase(mergePortalLinks(links, direction)), m_direction(direction) { @@ -207,7 +212,7 @@ std::unique_ptr CompositePortalLink::makeGrid( if (surface().type() == Surface::SurfaceType::Cylinder) { ACTS_VERBOSE("Combining composite into cylinder grid"); - if (m_direction != BinningValue::binZ) { + if (m_direction != AxisDirection::AxisZ) { ACTS_ERROR("Cylinder grid only supports binning in Z direction"); throw std::runtime_error{"Unsupported binning direction"}; } @@ -251,7 +256,7 @@ std::unique_ptr CompositePortalLink::makeGrid( } else if (surface().type() == Surface::SurfaceType::Disc) { ACTS_VERBOSE("Combining composite into disc grid"); - if (m_direction != BinningValue::binR) { + if (m_direction != AxisDirection::AxisR) { ACTS_ERROR("Disc grid only supports binning in R direction"); throw std::runtime_error{"Unsupported binning direction"}; } @@ -289,7 +294,55 @@ std::unique_ptr CompositePortalLink::makeGrid( return grid; } else if (surface().type() == Surface::SurfaceType::Plane) { - throw std::runtime_error{"Plane surfaces not implemented yet"}; + ACTS_VERBOSE("Combining composite into plane grid"); + + if (m_direction != AxisDirection::AxisX && + m_direction != AxisDirection::AxisY) { + ACTS_ERROR("Plane grid only supports binning in x/y direction"); + throw std::runtime_error{"Unsupported binning direction"}; + } + + bool dirX = m_direction == AxisDirection::AxisX; + + std::vector edges; + edges.reserve(m_children.size() + 1); + + const Transform3& groupTransform = m_surface->transform(gctx); + Transform3 itransform = groupTransform.inverse(); + + std::size_t sortingDir = dirX ? eX : eY; + std::ranges::sort(trivialLinks, [&itransform, &gctx, sortingDir]( + const auto& a, const auto& b) { + return (itransform * a->surface().transform(gctx)) + .translation()[sortingDir] < + (itransform * b->surface().transform(gctx)) + .translation()[sortingDir]; + }); + + for (const auto& [i, child] : enumerate(trivialLinks)) { + const auto& bounds = + dynamic_cast(child->surface().bounds()); + Transform3 ltransform = itransform * child->surface().transform(gctx); + double half = dirX ? bounds.halfLengthX() : bounds.halfLengthY(); + double min = ltransform.translation()[sortingDir] - half; + double max = ltransform.translation()[sortingDir] + half; + if (i == 0) { + edges.push_back(min); + } + edges.push_back(max); + } + + ACTS_VERBOSE("~> Determined bin edges to be " << printEdges(edges)); + + Axis axis{AxisBound, edges}; + + auto grid = GridPortalLink::make(m_surface, m_direction, std::move(axis)); + for (const auto& [i, child] : enumerate(trivialLinks)) { + grid->atLocalBins({i + 1}) = &child->volume(); + } + + return grid; + } else { throw std::invalid_argument{"Unsupported surface type"}; } diff --git a/Core/src/Geometry/ConeVolumeBounds.cpp b/Core/src/Geometry/ConeVolumeBounds.cpp index 425166abcd0..45ca5eedf95 100644 --- a/Core/src/Geometry/ConeVolumeBounds.cpp +++ b/Core/src/Geometry/ConeVolumeBounds.cpp @@ -107,13 +107,13 @@ std::vector Acts::ConeVolumeBounds::orientedSurfaces( auto innerCone = Surface::makeShared(innerConeTrans, m_innerConeBounds); oSurfaces.push_back( - OrientedSurface{std::move(innerCone), Direction::AlongNormal}); + OrientedSurface{std::move(innerCone), Direction::AlongNormal()}); } else if (m_innerCylinderBounds != nullptr) { // Or alternatively the inner Cylinder auto innerCylinder = Surface::makeShared(transform, m_innerCylinderBounds); oSurfaces.push_back( - OrientedSurface{std::move(innerCylinder), Direction::AlongNormal}); + OrientedSurface{std::move(innerCylinder), Direction::AlongNormal()}); } // Create an outer Cone @@ -122,13 +122,13 @@ std::vector Acts::ConeVolumeBounds::orientedSurfaces( auto outerCone = Surface::makeShared(outerConeTrans, m_outerConeBounds); oSurfaces.push_back( - OrientedSurface{std::move(outerCone), Direction::OppositeNormal}); + OrientedSurface{std::move(outerCone), Direction::OppositeNormal()}); } else if (m_outerCylinderBounds != nullptr) { // or alternatively an outer Cylinder auto outerCylinder = Surface::makeShared(transform, m_outerCylinderBounds); oSurfaces.push_back( - OrientedSurface{std::move(outerCylinder), Direction::OppositeNormal}); + OrientedSurface{std::move(outerCylinder), Direction::OppositeNormal()}); } // Set a disc at Zmin @@ -138,7 +138,7 @@ std::vector Acts::ConeVolumeBounds::orientedSurfaces( auto negativeDisc = Surface::makeShared(negativeDiscTrans, m_negativeDiscBounds); oSurfaces.push_back( - OrientedSurface{std::move(negativeDisc), Direction::AlongNormal}); + OrientedSurface{std::move(negativeDisc), Direction::AlongNormal()}); } // Set a disc at Zmax @@ -146,7 +146,7 @@ std::vector Acts::ConeVolumeBounds::orientedSurfaces( auto positiveDisc = Surface::makeShared(positiveDiscTrans, m_positiveDiscBounds); oSurfaces.push_back( - OrientedSurface{std::move(positiveDisc), Direction::OppositeNormal}); + OrientedSurface{std::move(positiveDisc), Direction::OppositeNormal()}); if (m_sectorBounds) { RotationMatrix3 sectorRotation; @@ -161,7 +161,7 @@ std::vector Acts::ConeVolumeBounds::orientedSurfaces( auto negSectorPlane = Surface::makeShared(negSectorAbsTrans, m_sectorBounds); oSurfaces.push_back( - OrientedSurface{std::move(negSectorPlane), Direction::AlongNormal}); + OrientedSurface{std::move(negSectorPlane), Direction::AlongNormal()}); Transform3 posSectorRelTrans{sectorRotation}; posSectorRelTrans.prerotate( @@ -170,8 +170,8 @@ std::vector Acts::ConeVolumeBounds::orientedSurfaces( auto posSectorPlane = Surface::makeShared(posSectorAbsTrans, m_sectorBounds); - oSurfaces.push_back( - OrientedSurface{std::move(posSectorPlane), Direction::OppositeNormal}); + oSurfaces.push_back(OrientedSurface{std::move(posSectorPlane), + Direction::OppositeNormal()}); } return oSurfaces; } diff --git a/Core/src/Geometry/CuboidVolumeBounds.cpp b/Core/src/Geometry/CuboidVolumeBounds.cpp index a8b1729c74a..42ca25ebc1a 100644 --- a/Core/src/Geometry/CuboidVolumeBounds.cpp +++ b/Core/src/Geometry/CuboidVolumeBounds.cpp @@ -9,11 +9,15 @@ #include "Acts/Geometry/CuboidVolumeBounds.hpp" #include "Acts/Definitions/Direction.hpp" +#include "Acts/Surfaces/LineSurface.hpp" #include "Acts/Surfaces/PlaneSurface.hpp" #include "Acts/Surfaces/RectangleBounds.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Utilities/BoundingBox.hpp" +#include +#include +#include #include namespace Acts { @@ -30,6 +34,21 @@ CuboidVolumeBounds::CuboidVolumeBounds(const std::array& values) buildSurfaceBounds(); } +CuboidVolumeBounds::CuboidVolumeBounds( + std::initializer_list> keyValues) + : m_values({-1, -1, -1}) { + for (const auto& [key, value] : keyValues) { + m_values[key] = value; + } + // Throw error here instead of consistency check for clarity + if (std::any_of(m_values.begin(), m_values.end(), + [](const auto& val) { return val == -1; })) { + throw std::logic_error("Missing bound values"); + } + checkConsistency(); + buildSurfaceBounds(); +} + std::vector CuboidVolumeBounds::values() const { return {m_values.begin(), m_values.end()}; } @@ -42,36 +61,36 @@ std::vector Acts::CuboidVolumeBounds::orientedSurfaces( // (1) - at negative local z auto sf = Surface::makeShared( transform * Translation3(0., 0., -get(eHalfLengthZ)), m_xyBounds); - oSurfaces.push_back(OrientedSurface{std::move(sf), Direction::AlongNormal}); + oSurfaces.push_back(OrientedSurface{std::move(sf), Direction::AlongNormal()}); // (2) - at positive local z sf = Surface::makeShared( transform * Translation3(0., 0., get(eHalfLengthZ)), m_xyBounds); oSurfaces.push_back( - OrientedSurface{std::move(sf), Direction::OppositeNormal}); + OrientedSurface{std::move(sf), Direction::OppositeNormal()}); // Face surfaces yz ------------------------------------- // (3) - at negative local x sf = Surface::makeShared( transform * Translation3(-get(eHalfLengthX), 0., 0.) * s_planeYZ, m_yzBounds); - oSurfaces.push_back(OrientedSurface{std::move(sf), Direction::AlongNormal}); + oSurfaces.push_back(OrientedSurface{std::move(sf), Direction::AlongNormal()}); // (4) - at positive local x sf = Surface::makeShared( transform * Translation3(get(eHalfLengthX), 0., 0.) * s_planeYZ, m_yzBounds); oSurfaces.push_back( - OrientedSurface{std::move(sf), Direction::OppositeNormal}); + OrientedSurface{std::move(sf), Direction::OppositeNormal()}); // Face surfaces zx ------------------------------------- // (5) - at negative local y sf = Surface::makeShared( transform * Translation3(0., -get(eHalfLengthY), 0.) * s_planeZX, m_zxBounds); - oSurfaces.push_back(OrientedSurface{std::move(sf), Direction::AlongNormal}); + oSurfaces.push_back(OrientedSurface{std::move(sf), Direction::AlongNormal()}); // (6) - at positive local y sf = Surface::makeShared( transform * Translation3(0., get(eHalfLengthY), 0.) * s_planeZX, m_zxBounds); oSurfaces.push_back( - OrientedSurface{std::move(sf), Direction::OppositeNormal}); + OrientedSurface{std::move(sf), Direction::OppositeNormal()}); return oSurfaces; } @@ -104,15 +123,15 @@ void CuboidVolumeBounds::buildSurfaceBounds() { get(eHalfLengthX)); } -double CuboidVolumeBounds::binningBorder(BinningValue bValue) const { - if (bValue <= BinningValue::binZ) { - return m_values[toUnderlying(bValue)]; +double CuboidVolumeBounds::referenceBorder(AxisDirection aDir) const { + if (aDir <= AxisDirection::AxisZ) { + return m_values[toUnderlying(aDir)]; } - if (bValue == BinningValue::binR) { - return std::sqrt(m_values[toUnderlying(BinningValue::binX)] * - m_values[toUnderlying(BinningValue::binX)] + - m_values[toUnderlying(BinningValue::binY)] * - m_values[toUnderlying(BinningValue::binY)]); + if (aDir == AxisDirection::AxisR) { + return std::sqrt(m_values[toUnderlying(AxisDirection::AxisX)] * + m_values[toUnderlying(AxisDirection::AxisX)] + + m_values[toUnderlying(AxisDirection::AxisY)] * + m_values[toUnderlying(AxisDirection::AxisY)]); } return 0.0; } @@ -150,4 +169,19 @@ void CuboidVolumeBounds::set( } } +CuboidVolumeBounds::BoundValues CuboidVolumeBounds::fromAxisDirection( + AxisDirection direction) { + using enum AxisDirection; + switch (direction) { + case AxisX: + return BoundValues::eHalfLengthX; + case AxisY: + return BoundValues::eHalfLengthY; + case AxisZ: + return BoundValues::eHalfLengthZ; + default: + throw std::invalid_argument("Invalid axis direction"); + } +} + } // namespace Acts diff --git a/Core/src/Geometry/CuboidVolumeBuilder.cpp b/Core/src/Geometry/CuboidVolumeBuilder.cpp index 614ce28a67f..90c9df756ae 100644 --- a/Core/src/Geometry/CuboidVolumeBuilder.cpp +++ b/Core/src/Geometry/CuboidVolumeBuilder.cpp @@ -93,9 +93,9 @@ std::shared_ptr Acts::CuboidVolumeBuilder::buildLayer( lCfg.surfaceArrayCreator = std::make_shared(); LayerCreator layerCreator(lCfg); ProtoLayer pl{gctx, cfg.surfaces}; - pl.envelope[BinningValue::binX] = cfg.envelopeX; - pl.envelope[BinningValue::binY] = cfg.envelopeY; - pl.envelope[BinningValue::binZ] = cfg.envelopeZ; + pl.envelope[AxisDirection::AxisX] = cfg.envelopeX; + pl.envelope[AxisDirection::AxisY] = cfg.envelopeY; + pl.envelope[AxisDirection::AxisZ] = cfg.envelopeZ; return layerCreator.planeLayer(gctx, cfg.surfaces, cfg.binsY, cfg.binsZ, cfg.binningDimension, pl, trafo); } @@ -249,7 +249,7 @@ Acts::MutableTrackingVolumePtr Acts::CuboidVolumeBuilder::trackingVolume( } // Build binning - BinningData binData(BinningOption::open, BinningValue::binX, binBoundaries); + BinningData binData(BinningOption::open, AxisDirection::AxisX, binBoundaries); auto bu = std::make_unique(binData); // Build TrackingVolume array diff --git a/Core/src/Geometry/CuboidVolumeStack.cpp b/Core/src/Geometry/CuboidVolumeStack.cpp new file mode 100644 index 00000000000..e9f5f3859bb --- /dev/null +++ b/Core/src/Geometry/CuboidVolumeStack.cpp @@ -0,0 +1,891 @@ +// 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/CuboidVolumeStack.hpp" + +#include "Acts/Definitions/Algebra.hpp" +#include "Acts/Definitions/Tolerance.hpp" +#include "Acts/Geometry/CuboidVolumeBounds.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" +#include "Acts/Utilities/Logger.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Acts { + +struct CuboidVolumeStack::VolumeTuple { + Volume* volume{}; + const CuboidVolumeBounds* bounds{}; + std::shared_ptr updatedBounds{}; + Transform3 localTransform = Transform3::Identity(); + Transform3 globalTransform = Transform3::Identity(); + + bool transformDirty = false; + + VolumeTuple(Volume& volume_, const Transform3& groupTransform) + : volume{&volume_}, + localTransform{groupTransform.inverse() * volume_.transform()}, + globalTransform{volume_.transform()} { + bounds = dynamic_cast(&volume_.volumeBounds()); + assert(bounds != nullptr); + updatedBounds = std::make_shared(*bounds); + } + + double mid(AxisDirection direction) const { + return localTransform.translation()[axisToIndex(direction)]; + } + double halfLength(AxisDirection direction) const { + return updatedBounds->get(CuboidVolumeBounds::fromAxisDirection(direction)); + } + double min(AxisDirection direction) const { + return mid(direction) - halfLength(direction); + } + double max(AxisDirection direction) const { + return mid(direction) + halfLength(direction); + } + + void set( + std::initializer_list> + keyValues) { + updatedBounds->set(keyValues); + } + + void setLocalTransform(const Transform3& transform, + const Transform3& groupTransform) { + localTransform = transform; + globalTransform = groupTransform * localTransform; + transformDirty = true; + } + + void commit(const Logger& logger) { + // make a copy so we can't accidentally modify in-place + auto copy = std::make_shared(*updatedBounds); + + std::optional transform = std::nullopt; + if (transformDirty) { + transform = globalTransform; + } + + volume->update(std::move(updatedBounds), transform, logger); + bounds = copy.get(); + updatedBounds = std::move(copy); + transformDirty = false; + } +}; + +std::size_t CuboidVolumeStack::axisToIndex(AxisDirection direction) { + switch (direction) { + case AxisDirection::AxisX: + return 0; + break; + case AxisDirection::AxisY: + return 1; + break; + case AxisDirection::AxisZ: + return 2; + break; + default: + throw std::invalid_argument("Invalid axis direction"); + } +} + +std::pair CuboidVolumeStack::getOrthogonalAxes( + AxisDirection direction) { + switch (direction) { + case AxisDirection::AxisX: + return {AxisDirection::AxisY, AxisDirection::AxisZ}; + break; + case AxisDirection::AxisY: + return {AxisDirection::AxisZ, AxisDirection::AxisX}; + break; + case AxisDirection::AxisZ: + return {AxisDirection::AxisX, AxisDirection::AxisY}; + break; + default: + throw std::invalid_argument("Invalid axis direction"); + } +} + +CuboidVolumeStack::CuboidVolumeStack(std::vector& volumes, + AxisDirection direction, + VolumeAttachmentStrategy strategy, + VolumeResizeStrategy resizeStrategy, + const Logger& logger) + : Volume(initialVolume(volumes)), + m_dir(direction), + m_resizeStrategy(resizeStrategy), + m_volumes(volumes) { + std::tie(m_dirOrth1, m_dirOrth2) = getOrthogonalAxes(m_dir); + + initializeOuterVolume(strategy, logger); +} + +CuboidVolumeStack::CuboidVolumeStack(std::vector& volumes, + const Vector3& direction, + VolumeAttachmentStrategy strategy, + VolumeResizeStrategy resizeStrategy, + const Logger& logger) + : Volume(initialVolume(volumes)), + m_resizeStrategy(resizeStrategy), + m_volumes(volumes) { + Vector3 localDirVector = + m_volumes.front()->transform().rotation().inverse() * direction; + if ((localDirVector - Vector3::UnitX()).norm() < 1e-4) { + m_dir = AxisDirection::AxisX; + } else if ((localDirVector - Vector3::UnitY()).norm() < 1e-4) { + m_dir = AxisDirection::AxisY; + } else if ((localDirVector - Vector3::UnitZ()).norm() < 1e-4) { + m_dir = AxisDirection::AxisZ; + } else { + throw std::invalid_argument("CuboidVolumeStack: Invalid axis direction"); + } + + std::tie(m_dirOrth1, m_dirOrth2) = getOrthogonalAxes(m_dir); + + initializeOuterVolume(strategy, logger); +} + +Volume& CuboidVolumeStack::initialVolume(const std::vector& volumes) { + if (volumes.empty()) { + throw std::invalid_argument( + "CuboidVolumeStack requires at least one volume"); + } + return *volumes.front(); +} + +void CuboidVolumeStack::initializeOuterVolume(VolumeAttachmentStrategy strategy, + const Logger& logger) { + ACTS_DEBUG("Creating CuboidVolumeStack from " << m_volumes.size() + << " volumes in direction " + << axisDirectionName(m_dir)); + if (m_volumes.empty()) { + throw std::invalid_argument( + "CuboidVolumeStack requires at least one volume"); + } + + if (m_dir != Acts::AxisDirection::AxisX && + m_dir != Acts::AxisDirection::AxisY && + m_dir != Acts::AxisDirection::AxisZ) { + throw std::invalid_argument(axisDirectionName(m_dir) + + " is not supported "); + } + + // For alignment check, we have to pick one of the volumes as the base + m_groupTransform = m_volumes.front()->transform(); + ACTS_VERBOSE("Initial group transform is:\n" << m_groupTransform.matrix()); + + std::vector volumeTuples; + volumeTuples.reserve(m_volumes.size()); + + for (const auto& volume : m_volumes) { + const auto* cuboidBounds = + dynamic_cast(&volume->volumeBounds()); + if (cuboidBounds == nullptr) { + throw std::invalid_argument{ + "CuboidVolumeStack requires all volumes to " + "have CuboidVolumeBounds"}; + } + + volumeTuples.emplace_back(*volume, m_groupTransform); + } + + ACTS_DEBUG("*** Initial volume configuration:"); + printVolumeSequence(volumeTuples, logger, Acts::Logging::DEBUG); + + if (m_volumes.size() == 1) { + ACTS_VERBOSE("Only one volume, returning"); + setTransform(m_volumes.front()->transform()); + const auto* bounds = dynamic_cast( + &m_volumes.front()->volumeBounds()); + assert(bounds != nullptr && "Volume bounds are not cuboid bounds"); + Volume::update(std::make_shared(*bounds), std::nullopt, + logger); + ACTS_VERBOSE("Transform is now: " << m_transform.matrix()); + return; + } + + ACTS_VERBOSE("Checking volume alignment"); + checkVolumeAlignment(volumeTuples, logger); + + auto dirIdx = axisToIndex(m_dir); + ACTS_VERBOSE("Sorting by volume " << axisDirectionName(m_dir) << " position"); + std::ranges::sort(volumeTuples, {}, [dirIdx](const auto& v) { + return v.localTransform.translation()[dirIdx]; + }); + ACTS_VERBOSE("Checking for overlaps and attaching volumes in " + << axisDirectionName(m_dir)); + std::vector gapVolumes = + checkOverlapAndAttach(volumeTuples, strategy, logger); + + ACTS_VERBOSE("Appending " << gapVolumes.size() + << " gap volumes to the end of the volume vector"); + std::copy(gapVolumes.begin(), gapVolumes.end(), + std::back_inserter(volumeTuples)); + + ACTS_VERBOSE("*** Volume configuration after " << axisDirectionName(m_dir) + << " attachment:"); + printVolumeSequence(volumeTuples, logger, Acts::Logging::VERBOSE); + + ACTS_VERBOSE("Synchronizing bounds in " << axisDirectionName(m_dirOrth1) + << "/" + << axisDirectionName(m_dirOrth2)); + const auto [hl1, hl2] = synchronizeBounds(volumeTuples, logger); + + for (auto& vt : volumeTuples) { + ACTS_VERBOSE("Updated bounds for volume at " + << axisDirectionName(m_dir) << ": " + << vt.localTransform.translation()[dirIdx]); + ACTS_VERBOSE(*vt.updatedBounds); + + vt.commit(logger); + } + + ACTS_VERBOSE("*** Volume configuration after " + << axisDirectionName(m_dirOrth1) << "/" + << axisDirectionName(m_dirOrth2) << " synchronization:"); + printVolumeSequence(volumeTuples, logger, Acts::Logging::VERBOSE); + + std::ranges::sort(volumeTuples, {}, + [*this](const auto& v) { return v.mid(m_dir); }); + + m_volumes.clear(); + for (const auto& vt : volumeTuples) { + m_volumes.push_back(vt.volume); + } + + ACTS_DEBUG("*** Volume configuration after final " << axisDirectionName(m_dir) + << " sorting:"); + printVolumeSequence(volumeTuples, logger, Acts::Logging::DEBUG); + + double min = volumeTuples.front().min(m_dir); + double max = volumeTuples.back().max(m_dir); + + double mid = std::midpoint(min, max); + double hl = std::midpoint(max, -min); + + Translation3 translation(Vector3::Unit(dirIdx) * mid); + m_transform = m_groupTransform * translation; + auto bounds = std::make_shared( + std::initializer_list>{ + {CuboidVolumeBounds::fromAxisDirection(m_dir), hl}, + {CuboidVolumeBounds::fromAxisDirection(m_dirOrth1), hl1}, + {CuboidVolumeBounds::fromAxisDirection(m_dirOrth2), hl2}}); + Volume::update(bounds, std::nullopt, logger); + ACTS_DEBUG("Outer bounds are:\n" << volumeBounds()); + ACTS_DEBUG("Outer transform / new group transform is:\n" + << m_transform.matrix()); + + // Update group transform to the new center + // @TODO: We probably can reuse m_transform + m_groupTransform = m_transform; +} + +void CuboidVolumeStack::overlapPrint(const CuboidVolumeStack::VolumeTuple& a, + const CuboidVolumeStack::VolumeTuple& b, + const Logger& logger) { + if (logger().doPrint(Acts::Logging::DEBUG)) { + std::stringstream ss; + ss << std::fixed; + ss << std::setprecision(3); + ss << std::setfill(' '); + + int w = 9; + + ACTS_VERBOSE("Checking overlap between"); + ss << " - " << " " << axisDirectionName(m_dir) << ": [ " << std::setw(w) + << a.min(m_dir) << " <- " << std::setw(w) << a.mid(m_dir) << " -> " + << std::setw(w) << a.max(m_dir) << " ]"; + ACTS_VERBOSE(ss.str()); + + ss.str(""); + ss << " - " << " " << axisDirectionName(m_dir) << ": [ " << std::setw(w) + << b.min(m_dir) << " <- " << std::setw(w) << b.mid(m_dir) << " -> " + << std::setw(w) << b.max(m_dir) << " ]"; + ACTS_VERBOSE(ss.str()); + } +} + +std::vector +CuboidVolumeStack::checkOverlapAndAttach(std::vector& volumes, + VolumeAttachmentStrategy strategy, + const Logger& logger) { + // Preconditions: volumes are sorted along stacking direction + auto dirIdx = axisToIndex(m_dir); + auto dirBoundIdx = CuboidVolumeBounds::fromAxisDirection(m_dir); + + std::vector gapVolumes; + for (std::size_t i = 0; i < volumes.size() - 1; i++) { + std::size_t j = i + 1; + auto& a = volumes.at(i); + auto& b = volumes.at(j); + + overlapPrint(a, b, logger); + + // TODO: What's a good tolerance? + constexpr auto tolerance = s_onSurfaceTolerance; + if (a.max(m_dir) - tolerance > b.min(m_dir)) { + ACTS_ERROR(" -> Overlap in " << axisDirectionName(m_dir)); + throw std::invalid_argument("Volumes overlap in " + + axisDirectionName(m_dir)); + } else { + ACTS_VERBOSE(" -> No overlap"); + } + + if (std::abs(a.max(m_dir) - b.min(m_dir)) < tolerance) { + ACTS_VERBOSE("No gap between volumes, no attachment needed"); + } else { + double gapWidth = b.min(m_dir) - a.max(m_dir); + ACTS_VERBOSE("Gap width: " << gapWidth); + + ACTS_VERBOSE("Synchronizing bounds in " + << axisDirectionName(m_dir) + << " with strategy: " << strategy); + switch (strategy) { + case VolumeAttachmentStrategy::Midpoint: { + ACTS_VERBOSE(" -> Strategy: Expand both volumes to midpoint"); + + double aMidNew = (a.min(m_dir) + a.max(m_dir)) / 2.0 + gapWidth / 4.0; + double aHlNew = a.halfLength(m_dir) + gapWidth / 4.0; + ACTS_VERBOSE(" - New halflength for first volume: " << aHlNew); + ACTS_VERBOSE(" - New bounds for first volume: [" + << (aMidNew - aHlNew) << " <- " << aMidNew << " -> " + << (aMidNew + aHlNew) << "]"); + + assert(std::abs(a.min(m_dir) - (aMidNew - aHlNew)) < 1e-9 && + "Volume shrunk"); + assert(aHlNew >= a.halfLength(m_dir) && "Volume shrunk"); + + double bMidNew = (b.min(m_dir) + b.max(m_dir)) / 2.0 - gapWidth / 4.0; + double bHlNew = b.halfLength(m_dir) + gapWidth / 4.0; + ACTS_VERBOSE(" - New halflength for second volume: " << bHlNew); + ACTS_VERBOSE(" - New bounds for second volume: [" + << (bMidNew - bHlNew) << " <- " << bMidNew << " -> " + << (bMidNew + bHlNew) << "]"); + + assert(bHlNew >= b.halfLength(m_dir) && "Volume shrunk"); + assert(std::abs(b.max(m_dir) - (bMidNew + bHlNew)) < 1e-9 && + "Volume shrunk"); + + Translation3 translationA(Vector3::Unit(dirIdx) * aMidNew); + a.setLocalTransform(Transform3{translationA}, m_groupTransform); + a.updatedBounds->set(dirBoundIdx, aHlNew); + + Translation3 translationB(Vector3::Unit(dirIdx) * bMidNew); + b.setLocalTransform(Transform3{translationB}, m_groupTransform); + b.updatedBounds->set(dirBoundIdx, bHlNew); + + break; + } + case VolumeAttachmentStrategy::First: { + ACTS_VERBOSE(" -> Strategy: Expand first volume"); + double aMidNew = (a.min(m_dir) + b.min(m_dir)) / 2.0; + double aHlNew = (b.min(m_dir) - a.min(m_dir)) / 2.0; + ACTS_VERBOSE(" - Gap width: " << gapWidth); + ACTS_VERBOSE(" - New bounds for first volume: [" + << (aMidNew - aHlNew) << " <- " << aMidNew << " -> " + << (aMidNew + aHlNew) << "]"); + + assert(std::abs(a.min(m_dir) - (aMidNew - aHlNew)) < 1e-9 && + "Volume shrunk"); + assert(aHlNew >= a.halfLength(m_dir) && "Volume shrunk"); + + Translation3 translationA(Vector3::Unit(dirIdx) * aMidNew); + a.setLocalTransform(Transform3{translationA}, m_groupTransform); + a.updatedBounds->set(dirBoundIdx, aHlNew); + + break; + } + case VolumeAttachmentStrategy::Second: { + ACTS_VERBOSE(" -> Strategy: Expand second volume"); + double bMidNew = (a.max(m_dir) + b.max(m_dir)) / 2.0; + double bHlNew = (b.max(m_dir) - a.max(m_dir)) / 2.0; + ACTS_VERBOSE(" - New halflength for second volume: " << bHlNew); + ACTS_VERBOSE(" - New bounds for second volume: [" + << (bMidNew - bHlNew) << " <- " << bMidNew << " -> " + << (bMidNew + bHlNew) << "]"); + + assert(bHlNew >= b.halfLength(m_dir) && "Volume shrunk"); + assert(std::abs(b.max(m_dir) - (bMidNew + bHlNew)) < 1e-9 && + "Volume shrunk"); + + Translation3 translationB(Vector3::Unit(dirIdx) * bMidNew); + b.setLocalTransform(Transform3{translationB}, m_groupTransform); + b.updatedBounds->set(dirBoundIdx, bHlNew); + break; + } + case VolumeAttachmentStrategy::Gap: { + ACTS_VERBOSE(" -> Strategy: Create a gap volume"); + double gapHl = (b.min(m_dir) - a.max(m_dir)) / 2.0; + double gapMid = (b.min(m_dir) + a.max(m_dir)) / 2.0; + + ACTS_VERBOSE(" - Gap half length: " << gapHl << " at " + << axisDirectionName(m_dir) + << ": " << gapMid); + + Translation3 gapTranslation(Vector3::Unit(dirIdx) * gapMid); + + double min1 = std::min(a.min(m_dirOrth1), b.min(m_dirOrth1)); + double max1 = std::max(a.max(m_dirOrth1), b.max(m_dirOrth1)); + + double min2 = std::min(a.min(m_dirOrth2), b.min(m_dirOrth2)); + double max2 = std::max(a.max(m_dirOrth2), b.max(m_dirOrth2)); + + Transform3 gapLocalTransform{gapTranslation}; + Transform3 gapGlobalTransform = m_groupTransform * gapLocalTransform; + + auto gapBounds = std::make_shared( + std::initializer_list< + std::pair>{ + {CuboidVolumeBounds::fromAxisDirection(m_dir), gapHl}, + {CuboidVolumeBounds::fromAxisDirection(m_dirOrth1), + (max1 - min1) / 2}, + {CuboidVolumeBounds::fromAxisDirection(m_dirOrth2), + (max2 - min2) / 2}}); + auto gap = addGapVolume(gapGlobalTransform, gapBounds); + gapVolumes.emplace_back(*gap, m_groupTransform); + + break; + } + default: + ACTS_ERROR("Attachment strategy " << strategy << " not implemented"); + std::stringstream ss; + ss << strategy; + throw std::invalid_argument("Attachment strategy " + ss.str() + + " not implemented"); + } + } + } + + return gapVolumes; +} + +void CuboidVolumeStack::printVolumeSequence( + const std::vector& volumes, const Logger& logger, + Acts::Logging::Level lvl) { + if (!logger().doPrint(lvl)) { + return; + } + for (const auto& vt : volumes) { + std::stringstream ss; + ss << std::fixed; + ss << std::setprecision(3); + ss << std::setfill(' '); + + int w = 9; + + for (const auto& axis : + {AxisDirection::AxisX, AxisDirection::AxisY, AxisDirection::AxisZ}) { + ss << axisDirectionName(axis) << ": [ " << std::setw(w) << vt.min(axis) + << " <- " << std::setw(w) << vt.mid(axis) << " -> " << std::setw(w) + << vt.max(axis) << " ]\n"; + } + logger().log(lvl, ss.str()); + } +} + +void CuboidVolumeStack::checkVolumeAlignment( + const std::vector& volumes, const Logger& logger) const { + std::size_t n = 0; + auto dirIdx = axisToIndex(m_dir); + auto dirOrth1Idx = axisToIndex(m_dirOrth1); + auto dirOrth2Idx = axisToIndex(m_dirOrth2); + + for (auto& vt : volumes) { + ACTS_VERBOSE("Checking volume #" + << n << " at " << axisDirectionName(m_dir) << ": " + << vt.localTransform.translation()[dirIdx]); + ACTS_VERBOSE("- Local transform is:\n" << vt.localTransform.matrix()); + + // @TODO: Rotation precision? + constexpr auto tolerance = s_onSurfaceTolerance; + + // In the group coordinate system: + + // a) the volumes cannot have any relative rotation + if ((vt.localTransform.rotation().matrix() - RotationMatrix3::Identity()) + .norm() > tolerance) { + ACTS_ERROR("Volumes are not aligned: rotation is different"); + throw std::invalid_argument( + "Volumes are not aligned: rotation is different"); + } + + ACTS_VERBOSE(" -> Rotation is ok!"); + + // b) the volumes cannot have translation in orthogonal directions + if (std::abs(vt.localTransform.translation()[dirOrth1Idx]) > tolerance || + std::abs(vt.localTransform.translation()[dirOrth2Idx]) > tolerance) { + ACTS_ERROR("Volumes are not aligned: translation in " + << axisDirectionName(m_dirOrth1) << " or " + << axisDirectionName(m_dirOrth2)); + throw std::invalid_argument("Volumes are not aligned: translation in " + + axisDirectionName(m_dirOrth1) + " or " + + axisDirectionName(m_dirOrth2)); + } + ACTS_VERBOSE(" -> Translation in " << axisDirectionName(m_dirOrth1) << "/" + << axisDirectionName(m_dirOrth2) + << " is ok!"); + + n++; + } +} + +std::pair CuboidVolumeStack::synchronizeBounds( + std::vector& volumes, const Logger& logger) { + auto boundDirOrth1 = CuboidVolumeBounds::fromAxisDirection(m_dirOrth1); + auto boundDirOrth2 = CuboidVolumeBounds::fromAxisDirection(m_dirOrth2); + + const double maxHl1 = + std::max_element(volumes.begin(), volumes.end(), + [boundDirOrth1](const auto& a, const auto& b) { + return a.bounds->get(boundDirOrth1) < + b.bounds->get(boundDirOrth1); + }) + ->bounds->get(boundDirOrth1); + const double maxHl2 = + std::max_element(volumes.begin(), volumes.end(), + [boundDirOrth2](const auto& a, const auto& b) { + return a.bounds->get(boundDirOrth2) < + b.bounds->get(boundDirOrth2); + }) + ->bounds->get(boundDirOrth2); + ACTS_VERBOSE("Found: half length " << axisDirectionName(m_dirOrth1) << ":" + << maxHl1 << ", half length " + << axisDirectionName(m_dirOrth2) << ":" + << maxHl2); + + for (auto& vt : volumes) { + vt.set({ + {boundDirOrth1, maxHl1}, + {boundDirOrth2, maxHl2}, + }); + } + + return {maxHl1, maxHl2}; +} + +void CuboidVolumeStack::update(std::shared_ptr volbounds, + std::optional transform, + const Logger& logger) { + ACTS_DEBUG("Resizing CuboidVolumeStack with strategy: " << m_resizeStrategy); + ACTS_DEBUG("Currently have " << m_volumes.size() << " children"); + ACTS_DEBUG(m_gaps.size() << " gaps"); + for (const auto& v : m_volumes) { + ACTS_DEBUG(" - volume bounds: \n" << v->volumeBounds()); + ACTS_DEBUG(" transform: \n" << v->transform().matrix()); + } + + ACTS_DEBUG("New bounds are: \n" << *volbounds); + + auto bounds = std::dynamic_pointer_cast(volbounds); + if (bounds == nullptr) { + throw std::invalid_argument( + "CuboidVolumeStack requires CuboidVolumeBounds"); + } + + if (*bounds == volumeBounds()) { + ACTS_VERBOSE("Bounds are the same, no resize needed"); + return; + } + + ACTS_VERBOSE("Group transform is:\n" << m_groupTransform.matrix()); + ACTS_VERBOSE("Current transform is:\n" << m_transform.matrix()); + if (transform.has_value()) { + ACTS_VERBOSE("Input transform:\n" << transform.value().matrix()); + } + + VolumeTuple oldVolume{*this, m_transform}; + VolumeTuple newVolume{*this, m_transform}; + newVolume.updatedBounds = std::make_shared(*bounds); + newVolume.globalTransform = transform.value_or(m_transform); + newVolume.localTransform = m_transform.inverse() * newVolume.globalTransform; + + if (!transform.has_value()) { + ACTS_VERBOSE("Local transform does not change"); + } else { + ACTS_VERBOSE("Local transform changes from\n" + << m_groupTransform.matrix() << "\nto\n" + << newVolume.localTransform.matrix()); + ACTS_VERBOSE("Checking transform consistency"); + + std::vector volTemp{newVolume}; + checkVolumeAlignment(volTemp, logger); + } + + constexpr auto tolerance = s_onSurfaceTolerance; + auto same = [](double a, double b) { return std::abs(a - b) < tolerance; }; + + for (const auto& dir : {m_dir, m_dirOrth1, m_dirOrth2}) { + const double newMin = newVolume.min(dir); + const double newMax = newVolume.max(dir); + const double newMid = newVolume.mid(dir); + const double newHl = newVolume.halfLength(dir); + + const double oldMin = oldVolume.min(dir); + const double oldMax = oldVolume.max(dir); + const double oldMid = oldVolume.mid(dir); + const double oldHl = oldVolume.halfLength(dir); + + ACTS_VERBOSE("Previous bounds are: " << axisDirectionName(dir) << ": [ " + << oldMin << " <- " << oldMid << " -> " + << oldMax << " ] (" << oldHl << ")\n"); + ACTS_VERBOSE("New bounds are: " << axisDirectionName(dir) << ": [ " + << newMin << " <- " << newMid << " -> " + << newMax << " ] (" << newHl << ")\n"); + + if (!same(newMin, oldMin) && newMin > oldMin) { + ACTS_ERROR("Shrinking the stack size in " + << axisDirectionName(dir) << " is not supported: " << newMin + << " -> " << oldMin); + throw std::invalid_argument("Shrinking the stack in " + + axisDirectionName(dir) + " is not supported"); + } + + if (!same(newMax, oldMax) && newMax < oldMax) { + ACTS_ERROR("Shrinking the stack size in " + << axisDirectionName(dir) << " is not supported: " << newMax + << " -> " << oldMax); + throw std::invalid_argument("Shrinking the stack in " + + axisDirectionName(dir) + " is not supported"); + } + } + auto isGap = [this](const Volume* vol) { + return std::ranges::any_of( + m_gaps, [&](const auto& gap) { return vol == gap.get(); }); + }; + ACTS_VERBOSE("Stack direction is " << axisDirectionName(m_dir)); + + std::vector volumeTuples; + volumeTuples.reserve(m_volumes.size()); + std::transform(m_volumes.begin(), m_volumes.end(), + std::back_inserter(volumeTuples), [this](const auto& volume) { + return VolumeTuple{*volume, m_groupTransform}; + }); + + ACTS_VERBOSE("*** Initial volume configuration:"); + printVolumeSequence(volumeTuples, logger, Acts::Logging::DEBUG); + for (const auto& dir : {m_dirOrth1, m_dirOrth2}) { + if (!same(newVolume.min(dir), oldVolume.min(dir)) || + !same(newVolume.max(dir), oldVolume.max(dir))) { + ACTS_VERBOSE("Resize all volumes to new " << axisDirectionName(dir) + << " bounds"); + for (auto& volume : volumeTuples) { + volume.set({{CuboidVolumeBounds::fromAxisDirection(dir), + newVolume.halfLength(dir)}}); + } + ACTS_VERBOSE("*** Volume configuration after " << axisDirectionName(dir) + << " resizing:"); + printVolumeSequence(volumeTuples, logger, Acts::Logging::DEBUG); + } else { + ACTS_VERBOSE(axisDirectionName(dir) + << " bounds are the same, no " << axisDirectionName(dir) + << " resize needed"); + } + } + + if (same(newVolume.halfLength(m_dir), oldVolume.halfLength(m_dir))) { + ACTS_VERBOSE("Halflength " << axisDirectionName(m_dir) << "is the same, no " + << axisDirectionName(m_dir) << "resize needed"); + } else { + auto dirIdx = axisToIndex(m_dir); + auto boundDirIdx = CuboidVolumeBounds::fromAxisDirection(m_dir); + if (m_resizeStrategy == VolumeResizeStrategy::Expand) { + if (newVolume.min(m_dir) < oldVolume.min(m_dir)) { + ACTS_VERBOSE("Expanding first volume to new " + << axisDirectionName(m_dir) << "bounds"); + + auto& first = volumeTuples.front(); + double newMinFirst = newVolume.min(m_dir); + double newMidFirst = (newMinFirst + first.max(m_dir)) / 2.0; + double newHlFirst = (first.max(m_dir) - newMinFirst) / 2.0; + + ACTS_VERBOSE(" -> first " << axisDirectionName(m_dir) << ": [ " + << newMinFirst << " <- " << newMidFirst + << " -> " << first.max(m_dir) + << " ] (hl: " << newHlFirst << ")"); + + Translation3 translation(Vector3::Unit(dirIdx) * newMidFirst); + first.set({{boundDirIdx, newHlFirst}}); + first.setLocalTransform(Transform3{translation}, m_groupTransform); + } + + if (newVolume.max(m_dir) > oldVolume.max(m_dir)) { + ACTS_VERBOSE("Expanding last volume to new " << axisDirectionName(m_dir) + << " bounds"); + + auto& last = volumeTuples.back(); + double newMaxLast = newVolume.max(m_dir); + double newMidLast = (last.min(m_dir) + newMaxLast) / 2.0; + double newHlLast = (newMaxLast - last.min(m_dir)) / 2.0; + + ACTS_VERBOSE(" -> last " << axisDirectionName(m_dir) << ": [ " + << last.min(m_dir) << " <- " << newMidLast + << " -> " << newMaxLast + << " ] (hl: " << newHlLast << ")"); + + Translation3 translation(Vector3::Unit(dirIdx) * newMidLast); + last.set({{boundDirIdx, newHlLast}}); + last.setLocalTransform(Transform3{translation}, m_groupTransform); + } + } else if (m_resizeStrategy == VolumeResizeStrategy::Gap) { + ACTS_VERBOSE("Creating gap volumes to fill the new " + << axisDirectionName(m_dir) << " bounds"); + + auto printGapDimensions = [&](const VolumeTuple& gap, + const std::string& prefix = "") { + for (const auto& dir : {m_dir, m_dirOrth1, m_dirOrth2}) { + ACTS_VERBOSE(" -> gap" << prefix << ": " << axisDirectionName(dir) + << ": [ " << gap.min(m_dir) << " <- " + << gap.mid(dir) << " -> " << gap.max(dir) + << " ]"); + } + }; + + if (!same(newVolume.min(m_dir), oldVolume.min(m_dir)) && + newVolume.min(m_dir) < oldVolume.min(m_dir)) { + double gap1Min = newVolume.min(m_dir); + double gap1Max = oldVolume.min(m_dir); + double gap1Hl = (gap1Max - gap1Min) / 2.0; + double gap1P = (gap1Max + gap1Min) / 2.0; + + // check if we need a new gap volume or reuse an existing one + auto& candidate = volumeTuples.front(); + if (isGap(candidate.volume)) { + ACTS_VERBOSE("~> Reusing existing gap volume at negative " + << axisDirectionName(m_dir)); + + gap1Hl = candidate.bounds->get( + CuboidVolumeBounds::fromAxisDirection(m_dir)) + + gap1Hl; + gap1Max = gap1Min + gap1Hl * 2; + gap1P = (gap1Max + gap1Min) / 2.0; + + printGapDimensions(candidate, " before"); + + auto gap1Bounds = std::make_shared( + std::initializer_list< + std::pair>{ + {CuboidVolumeBounds::fromAxisDirection(m_dir), gap1Hl}, + {CuboidVolumeBounds::fromAxisDirection(m_dirOrth1), + newVolume.halfLength(m_dirOrth1)}, + {CuboidVolumeBounds::fromAxisDirection(m_dirOrth2), + newVolume.halfLength(m_dirOrth2)}}); + Translation3 gap1Translation(Vector3::Unit(dirIdx) * gap1P); + Transform3 gap1Transform = m_groupTransform * gap1Translation; + candidate.volume->update(std::move(gap1Bounds), gap1Transform); + candidate = VolumeTuple{*candidate.volume, m_groupTransform}; + ACTS_VERBOSE("After:"); + printGapDimensions(candidate, " after "); + + } else { + ACTS_VERBOSE("~> Creating new gap volume at negative "); + auto gap1Bounds = std::make_shared( + std::initializer_list< + std::pair>{ + {CuboidVolumeBounds::fromAxisDirection(m_dir), gap1Hl}, + {CuboidVolumeBounds::fromAxisDirection(m_dirOrth1), + newVolume.halfLength(m_dirOrth1)}, + {CuboidVolumeBounds::fromAxisDirection(m_dirOrth2), + newVolume.halfLength(m_dirOrth2)}}); + Translation3 gap1Translation(Vector3::Unit(dirIdx) * gap1P); + Transform3 gap1Transform = m_groupTransform * gap1Translation; + auto gap1 = addGapVolume(gap1Transform, std::move(gap1Bounds)); + volumeTuples.insert(volumeTuples.begin(), + VolumeTuple{*gap1, m_groupTransform}); + printGapDimensions(volumeTuples.front()); + } + } + + if (!same(newVolume.max(m_dir), oldVolume.max(m_dir)) && + newVolume.max(m_dir) > oldVolume.max(m_dir)) { + double gap2Min = oldVolume.max(m_dir); + double gap2Max = newVolume.max(m_dir); + double gap2Hl = (gap2Max - gap2Min) / 2.0; + double gap2P = (gap2Max + gap2Min) / 2.0; + + // check if we need a new gap volume or reuse an existing one + auto& candidate = volumeTuples.back(); + if (isGap(candidate.volume)) { + ACTS_VERBOSE("~> Reusing existing gap volume at positive "); + + gap2Hl = candidate.bounds->get( + CuboidVolumeBounds::fromAxisDirection(m_dir)) + + gap2Hl; + gap2Min = newVolume.max(m_dir) - gap2Hl * 2; + gap2P = (gap2Max + gap2Min) / 2.0; + + auto gap2Bounds = std::make_shared( + std::initializer_list< + std::pair>{ + {CuboidVolumeBounds::fromAxisDirection(m_dir), gap2Hl}, + {CuboidVolumeBounds::fromAxisDirection(m_dirOrth1), + newVolume.halfLength(m_dirOrth1)}, + {CuboidVolumeBounds::fromAxisDirection(m_dirOrth2), + newVolume.halfLength(m_dirOrth2)}}); + Translation3 gap2Translation(Vector3::Unit(dirIdx) * gap2P); + Transform3 gap2Transform = m_groupTransform * gap2Translation; + + candidate.volume->update(std::move(gap2Bounds), gap2Transform); + candidate = VolumeTuple{*candidate.volume, m_groupTransform}; + printGapDimensions(candidate, " after "); + } else { + ACTS_VERBOSE("~> Creating new gap volume at positive "); + auto gap2Bounds = std::make_shared( + std::initializer_list< + std::pair>{ + {CuboidVolumeBounds::fromAxisDirection(m_dir), gap2Hl}, + {CuboidVolumeBounds::fromAxisDirection(m_dirOrth1), + newVolume.halfLength(m_dirOrth1)}, + {CuboidVolumeBounds::fromAxisDirection(m_dirOrth2), + newVolume.halfLength(m_dirOrth2)}}); + Translation3 gap2Translation(Vector3::Unit(dirIdx) * gap2P); + Transform3 gap2Transform = m_groupTransform * gap2Translation; + auto gap2 = addGapVolume(gap2Transform, std::move(gap2Bounds)); + volumeTuples.emplace_back(*gap2, m_groupTransform); + printGapDimensions(volumeTuples.back()); + } + } + } + + ACTS_VERBOSE("*** Volume configuration after " << axisDirectionName(m_dir) + << " resizing:"); + printVolumeSequence(volumeTuples, logger, Acts::Logging::DEBUG); + } + + ACTS_VERBOSE("Commit and update outer vector of volumes"); + m_volumes.clear(); + for (auto& vt : volumeTuples) { + vt.commit(logger); + m_volumes.push_back(vt.volume); + } + + m_transform = newVolume.globalTransform; + // @TODO: We probably can reuse m_transform + m_groupTransform = m_transform; + Volume::update(std::move(bounds), std::nullopt, logger); +} + +std::shared_ptr CuboidVolumeStack::addGapVolume( + const Transform3& transform, const std::shared_ptr& bounds) { + auto gapVolume = std::make_shared(transform, bounds); + m_gaps.push_back(gapVolume); + return gapVolume; +} + +const std::vector>& CuboidVolumeStack::gaps() const { + return m_gaps; +} + +} // namespace Acts diff --git a/Core/src/Geometry/CutoutCylinderVolumeBounds.cpp b/Core/src/Geometry/CutoutCylinderVolumeBounds.cpp index 62033200b58..8c30f13c0c4 100644 --- a/Core/src/Geometry/CutoutCylinderVolumeBounds.cpp +++ b/Core/src/Geometry/CutoutCylinderVolumeBounds.cpp @@ -81,13 +81,13 @@ std::vector CutoutCylinderVolumeBounds::orientedSurfaces( auto outer = Surface::makeShared(transform, m_outerCylinderBounds); oSurfaces.at(tubeOuterCover) = - OrientedSurface{std::move(outer), Direction::OppositeNormal}; + OrientedSurface{std::move(outer), Direction::OppositeNormal()}; // Inner (cutout) cylinder envelope auto cutoutInner = Surface::makeShared(transform, m_cutoutCylinderBounds); oSurfaces.at(tubeInnerCover) = - OrientedSurface{std::move(cutoutInner), Direction::AlongNormal}; + OrientedSurface{std::move(cutoutInner), Direction::AlongNormal()}; // z position of the pos and neg choke points double hlChoke = (get(eHalfLengthZ) - get(eHalfLengthZcutout)) * 0.5; @@ -98,13 +98,13 @@ std::vector CutoutCylinderVolumeBounds::orientedSurfaces( auto posInner = Surface::makeShared(posChokeTrf, m_innerCylinderBounds); oSurfaces.at(index7) = - OrientedSurface{std::move(posInner), Direction::AlongNormal}; + OrientedSurface{std::move(posInner), Direction::AlongNormal()}; auto negChokeTrf = transform * Translation3(Vector3(0, 0, -zChoke)); auto negInner = Surface::makeShared(negChokeTrf, m_innerCylinderBounds); oSurfaces.at(index6) = - OrientedSurface{std::move(negInner), Direction::AlongNormal}; + OrientedSurface{std::move(negInner), Direction::AlongNormal()}; } // Two Outer disks @@ -113,14 +113,14 @@ std::vector CutoutCylinderVolumeBounds::orientedSurfaces( auto posOutDisc = Surface::makeShared(posOutDiscTrf, m_outerDiscBounds); oSurfaces.at(positiveFaceXY) = - OrientedSurface{std::move(posOutDisc), Direction::OppositeNormal}; + OrientedSurface{std::move(posOutDisc), Direction::OppositeNormal()}; auto negOutDiscTrf = transform * Translation3(Vector3(0, 0, -get(eHalfLengthZ))); auto negOutDisc = Surface::makeShared(negOutDiscTrf, m_outerDiscBounds); oSurfaces.at(negativeFaceXY) = - OrientedSurface{std::move(negOutDisc), Direction::AlongNormal}; + OrientedSurface{std::move(negOutDisc), Direction::AlongNormal()}; // Two Inner disks auto posInDiscTrf = @@ -128,14 +128,14 @@ std::vector CutoutCylinderVolumeBounds::orientedSurfaces( auto posInDisc = Surface::makeShared(posInDiscTrf, m_innerDiscBounds); oSurfaces.at(index5) = - OrientedSurface{std::move(posInDisc), Direction::AlongNormal}; + OrientedSurface{std::move(posInDisc), Direction::AlongNormal()}; auto negInDiscTrf = transform * Translation3(Vector3(0, 0, -get(eHalfLengthZcutout))); auto negInDisc = Surface::makeShared(negInDiscTrf, m_innerDiscBounds); oSurfaces.at(index4) = - OrientedSurface{std::move(negInDisc), Direction::OppositeNormal}; + OrientedSurface{std::move(negInDisc), Direction::OppositeNormal()}; return oSurfaces; } diff --git a/Core/src/Geometry/CylinderContainerBlueprintNode.cpp b/Core/src/Geometry/CylinderContainerBlueprintNode.cpp index 284b30949ac..1d50558fc14 100644 --- a/Core/src/Geometry/CylinderContainerBlueprintNode.cpp +++ b/Core/src/Geometry/CylinderContainerBlueprintNode.cpp @@ -23,9 +23,9 @@ namespace Acts { CylinderContainerBlueprintNode::CylinderContainerBlueprintNode( - const std::string& name, BinningValue direction, - CylinderVolumeStack::AttachmentStrategy attachmentStrategy, - CylinderVolumeStack::ResizeStrategy resizeStrategy) + const std::string& name, AxisDirection direction, + VolumeAttachmentStrategy attachmentStrategy, + VolumeResizeStrategy resizeStrategy) : m_name(name), m_direction(direction), m_attachmentStrategy(attachmentStrategy), @@ -197,7 +197,7 @@ bool CylinderContainerBlueprintNode::isGapVolume(const Volume& volume) const { } CylinderContainerBlueprintNode& CylinderContainerBlueprintNode::setDirection( - BinningValue direction) { + AxisDirection direction) { if (m_stack != nullptr) { throw std::runtime_error("Cannot change direction after build"); } @@ -207,7 +207,7 @@ CylinderContainerBlueprintNode& CylinderContainerBlueprintNode::setDirection( CylinderContainerBlueprintNode& CylinderContainerBlueprintNode::setAttachmentStrategy( - CylinderVolumeStack::AttachmentStrategy attachmentStrategy) { + VolumeAttachmentStrategy attachmentStrategy) { if (m_stack != nullptr) { throw std::runtime_error("Cannot change direction after build"); } @@ -217,7 +217,7 @@ CylinderContainerBlueprintNode::setAttachmentStrategy( CylinderContainerBlueprintNode& CylinderContainerBlueprintNode::setResizeStrategy( - CylinderVolumeStack::ResizeStrategy resizeStrategy) { + VolumeResizeStrategy resizeStrategy) { if (m_stack != nullptr) { throw std::runtime_error("Cannot change direction after build"); } @@ -240,17 +240,16 @@ void CylinderContainerBlueprintNode::addToGraphviz(std::ostream& os) const { } } -BinningValue CylinderContainerBlueprintNode::direction() const { +AxisDirection CylinderContainerBlueprintNode::direction() const { return m_direction; } -CylinderVolumeStack::AttachmentStrategy -CylinderContainerBlueprintNode::attachmentStrategy() const { +VolumeAttachmentStrategy CylinderContainerBlueprintNode::attachmentStrategy() + const { return m_attachmentStrategy; } -CylinderVolumeStack::ResizeStrategy -CylinderContainerBlueprintNode::resizeStrategy() const { +VolumeResizeStrategy CylinderContainerBlueprintNode::resizeStrategy() const { return m_resizeStrategy; } diff --git a/Core/src/Geometry/CylinderVolumeBounds.cpp b/Core/src/Geometry/CylinderVolumeBounds.cpp index 00a4c71f882..8d1001e22be 100644 --- a/Core/src/Geometry/CylinderVolumeBounds.cpp +++ b/Core/src/Geometry/CylinderVolumeBounds.cpp @@ -115,24 +115,24 @@ std::vector CylinderVolumeBounds::orientedSurfaces( // [0] Bottom Disc (negative z) auto dSurface = Surface::makeShared(transMinZ, m_discBounds); oSurfaces.push_back( - OrientedSurface{std::move(dSurface), Direction::AlongNormal}); + OrientedSurface{std::move(dSurface), Direction::AlongNormal()}); // [1] Top Disc (positive z) dSurface = Surface::makeShared(transMaxZ, m_discBounds); oSurfaces.push_back( - OrientedSurface{std::move(dSurface), Direction::OppositeNormal}); + OrientedSurface{std::move(dSurface), Direction::OppositeNormal()}); // [2] Outer Cylinder auto cSurface = Surface::makeShared(transform, m_outerCylinderBounds); oSurfaces.push_back( - OrientedSurface{std::move(cSurface), Direction::OppositeNormal}); + OrientedSurface{std::move(cSurface), Direction::OppositeNormal()}); // [3] Inner Cylinder (optional) if (m_innerCylinderBounds != nullptr) { cSurface = Surface::makeShared(transform, m_innerCylinderBounds); oSurfaces.push_back( - OrientedSurface{std::move(cSurface), Direction::AlongNormal}); + OrientedSurface{std::move(cSurface), Direction::AlongNormal()}); } // [4] & [5] - Sectoral planes (optional) @@ -147,7 +147,7 @@ std::vector CylinderVolumeBounds::orientedSurfaces( auto pSurface = Surface::makeShared(sp1Transform, m_sectorPlaneBounds); oSurfaces.push_back( - OrientedSurface{std::move(pSurface), Direction::AlongNormal}); + OrientedSurface{std::move(pSurface), Direction::AlongNormal()}); // sectorPlane 2 (positive phi) const Transform3 sp2Transform = Transform3(transform * @@ -158,7 +158,7 @@ std::vector CylinderVolumeBounds::orientedSurfaces( pSurface = Surface::makeShared(sp2Transform, m_sectorPlaneBounds); oSurfaces.push_back( - OrientedSurface{std::move(pSurface), Direction::OppositeNormal}); + OrientedSurface{std::move(pSurface), Direction::OppositeNormal()}); } return oSurfaces; } @@ -232,23 +232,23 @@ bool CylinderVolumeBounds::inside(const Vector3& pos, double tol) const { return (insideZ && insideR && insidePhi); } -Vector3 CylinderVolumeBounds::binningOffset(BinningValue bValue) +Vector3 CylinderVolumeBounds::referenceOffset(AxisDirection aDir) const { // the medium radius is taken for r-type binning - if (bValue == Acts::BinningValue::binR || - bValue == Acts::BinningValue::binRPhi) { + if (aDir == Acts::AxisDirection::AxisR || + aDir == Acts::AxisDirection::AxisRPhi) { return Vector3(0.5 * (get(eMinR) + get(eMaxR)), 0., 0.); } - return VolumeBounds::binningOffset(bValue); + return VolumeBounds::referenceOffset(aDir); } -double CylinderVolumeBounds::binningBorder(BinningValue bValue) const { - if (bValue == Acts::BinningValue::binR) { +double CylinderVolumeBounds::referenceBorder(AxisDirection aDir) const { + if (aDir == Acts::AxisDirection::AxisR) { return 0.5 * (get(eMaxR) - get(eMinR)); } - if (bValue == Acts::BinningValue::binZ) { + if (aDir == Acts::AxisDirection::AxisZ) { return get(eHalfLengthZ); } - return VolumeBounds::binningBorder(bValue); + return VolumeBounds::referenceBorder(aDir); } std::vector CylinderVolumeBounds::values() const { diff --git a/Core/src/Geometry/CylinderVolumeBuilder.cpp b/Core/src/Geometry/CylinderVolumeBuilder.cpp index 4f99a77eabd..0956db85752 100644 --- a/Core/src/Geometry/CylinderVolumeBuilder.cpp +++ b/Core/src/Geometry/CylinderVolumeBuilder.cpp @@ -351,8 +351,8 @@ Acts::CylinderVolumeBuilder::trackingVolume( // Filling loop for (const auto& elay : endcapConfig.layers) { // Getting the reference radius - double test = elay->surfaceRepresentation().binningPositionValue( - gctx, BinningValue::binR); + double test = elay->surfaceRepresentation().referencePositionValue( + gctx, AxisDirection::AxisR); // Find the right bin auto ringVolume = std::ranges::find_if(volumeRminRmax, [&](const auto& vrr) { diff --git a/Core/src/Geometry/CylinderVolumeHelper.cpp b/Core/src/Geometry/CylinderVolumeHelper.cpp index 77d9dcaee8f..380072b437e 100644 --- a/Core/src/Geometry/CylinderVolumeHelper.cpp +++ b/Core/src/Geometry/CylinderVolumeHelper.cpp @@ -102,7 +102,7 @@ Acts::CylinderVolumeHelper::createTrackingVolume( double zMinRaw = 0.; double zMaxRaw = 0.; - BinningValue bValue = BinningValue::binR; + AxisDirection bValue = AxisDirection::AxisR; // check the dimension and fill raw data if (!estimateAndCheckDimension(gctx, layers, cylinderBounds, transform, @@ -139,7 +139,7 @@ Acts::CylinderVolumeHelper::createTrackingVolume( << bValue); // create the Layer Array - layerArray = (bValue == BinningValue::binR) + layerArray = (bValue == AxisDirection::AxisR) ? m_cfg.layerArrayCreator->layerArray(gctx, layers, rMin, rMax, bType, bValue) : m_cfg.layerArrayCreator->layerArray(gctx, layers, zMin, @@ -383,9 +383,9 @@ Acts::CylinderVolumeHelper::createContainerTrackingVolume( // create the volume array with the ITrackingVolumeArrayCreator std::shared_ptr volumeArray = (rCase) ? m_cfg.trackingVolumeArrayCreator->trackingVolumeArray( - gctx, volumes, BinningValue::binR) + gctx, volumes, AxisDirection::AxisR) : m_cfg.trackingVolumeArrayCreator->trackingVolumeArray( - gctx, volumes, BinningValue::binZ); + gctx, volumes, AxisDirection::AxisZ); if (volumeArray == nullptr) { ACTS_WARNING( "Creation of TrackingVolume array did not succeed - returning 0 "); @@ -417,7 +417,7 @@ bool Acts::CylinderVolumeHelper::estimateAndCheckDimension( const GeometryContext& gctx, const LayerVector& layers, std::shared_ptr& cylinderVolumeBounds, const Transform3& transform, double& rMinClean, double& rMaxClean, - double& zMinClean, double& zMaxClean, BinningValue& bValue, + double& zMinClean, double& zMaxClean, AxisDirection& bValue, BinningType /*bType*/) const { // some verbose output @@ -490,7 +490,7 @@ bool Acts::CylinderVolumeHelper::estimateAndCheckDimension( } // set the binning value - bValue = radial ? BinningValue::binR : BinningValue::binZ; + bValue = radial ? AxisDirection::AxisR : AxisDirection::AxisZ; ACTS_VERBOSE( "Estimate/check CylinderVolumeBounds from/w.r.t. enclosed " @@ -681,7 +681,7 @@ bool Acts::CylinderVolumeHelper::interGlueTrackingVolume( // create the outside volume array std::shared_ptr glueVolumesNegativeFaceArray = m_cfg.trackingVolumeArrayCreator->trackingVolumeArray( - gctx, glueVolumesNegativeFace, BinningValue::binR); + gctx, glueVolumesNegativeFace, AxisDirection::AxisR); // register the glue voluems glueDescr.registerGlueVolumes(negativeFaceXY, glueVolumesNegativeFaceArray); @@ -690,7 +690,7 @@ bool Acts::CylinderVolumeHelper::interGlueTrackingVolume( // create the outside volume array std::shared_ptr glueVolumesPositiveFaceArray = m_cfg.trackingVolumeArrayCreator->trackingVolumeArray( - gctx, glueVolumesPositiveFace, BinningValue::binR); + gctx, glueVolumesPositiveFace, AxisDirection::AxisR); // register the glue voluems glueDescr.registerGlueVolumes(positiveFaceXY, glueVolumesPositiveFaceArray); @@ -699,7 +699,7 @@ bool Acts::CylinderVolumeHelper::interGlueTrackingVolume( // create the outside volume array std::shared_ptr glueVolumesInnerTubeArray = m_cfg.trackingVolumeArrayCreator->trackingVolumeArray( - gctx, glueVolumesInnerTube, BinningValue::binZ); + gctx, glueVolumesInnerTube, AxisDirection::AxisZ); // register the glue voluems glueDescr.registerGlueVolumes(tubeInnerCover, glueVolumesInnerTubeArray); } @@ -707,7 +707,7 @@ bool Acts::CylinderVolumeHelper::interGlueTrackingVolume( // create the outside volume array std::shared_ptr glueVolumesOuterTubeArray = m_cfg.trackingVolumeArrayCreator->trackingVolumeArray( - gctx, glueVolumesOuterTube, BinningValue::binZ); + gctx, glueVolumesOuterTube, AxisDirection::AxisZ); // register the glue voluems glueDescr.registerGlueVolumes(tubeOuterCover, glueVolumesOuterTubeArray); } @@ -961,7 +961,7 @@ Acts::CylinderVolumeHelper::createCylinderLayer(double z, double r, // z-binning BinUtility layerBinUtility(binsZ, z - halflengthZ, z + halflengthZ, open, - BinningValue::binZ); + AxisDirection::AxisZ); if (binsPhi == 1) { // the BinUtility for the material // ---------------------> create material for the layer surface @@ -972,7 +972,7 @@ Acts::CylinderVolumeHelper::createCylinderLayer(double z, double r, // update the BinUtility: local position on Cylinder is rPhi, z BinUtility layerBinUtilityPhiZ(binsPhi, -r * std::numbers::pi, r * std::numbers::pi, closed, - BinningValue::binPhi); + AxisDirection::AxisPhi); layerBinUtilityPhiZ += layerBinUtility; // ---------------------> create material for the layer surface ACTS_VERBOSE(" -> Preparing the binned material with " @@ -997,7 +997,7 @@ std::shared_ptr Acts::CylinderVolumeHelper::createDiscLayer( const Transform3 transform(Translation3(0., 0., z)); // R is the primary binning for the material - BinUtility materialBinUtility(binsR, rMin, rMax, open, BinningValue::binR); + BinUtility materialBinUtility(binsR, rMin, rMax, open, AxisDirection::AxisR); if (binsPhi == 1) { ACTS_VERBOSE(" -> Preparing the binned material with " << binsR << " bins in R. "); @@ -1005,7 +1005,7 @@ std::shared_ptr Acts::CylinderVolumeHelper::createDiscLayer( // also binning in phi chosen materialBinUtility += BinUtility(binsPhi, -std::numbers::pi_v, - std::numbers::pi_v, closed, BinningValue::binPhi); + std::numbers::pi_v, closed, AxisDirection::AxisPhi); ACTS_VERBOSE(" -> Preparing the binned material with " << binsPhi << " / " << binsR << " bins in phi / R. "); } diff --git a/Core/src/Geometry/CylinderVolumeStack.cpp b/Core/src/Geometry/CylinderVolumeStack.cpp index 5350c3e764e..5761260c1f1 100644 --- a/Core/src/Geometry/CylinderVolumeStack.cpp +++ b/Core/src/Geometry/CylinderVolumeStack.cpp @@ -85,9 +85,9 @@ struct CylinderVolumeStack::VolumeTuple { }; CylinderVolumeStack::CylinderVolumeStack(std::vector& volumes, - BinningValue direction, - AttachmentStrategy strategy, - ResizeStrategy resizeStrategy, + AxisDirection direction, + VolumeAttachmentStrategy strategy, + VolumeResizeStrategy resizeStrategy, const Logger& logger) : Volume(initialVolume(volumes)), m_direction(direction), @@ -105,20 +105,20 @@ Volume& CylinderVolumeStack::initialVolume( return *volumes.front(); } -void CylinderVolumeStack::initializeOuterVolume(BinningValue direction, - AttachmentStrategy strategy, - const Logger& logger) { +void CylinderVolumeStack::initializeOuterVolume( + AxisDirection direction, VolumeAttachmentStrategy strategy, + const Logger& logger) { ACTS_DEBUG("Creating CylinderVolumeStack from " << m_volumes.size() << " volumes in direction " - << binningValueName(direction)); + << axisDirectionName(direction)); if (m_volumes.empty()) { throw std::invalid_argument( "CylinderVolumeStack requires at least one volume"); } - if (direction != Acts::BinningValue::binZ && - direction != Acts::BinningValue::binR) { - throw std::invalid_argument(binningValueName(direction) + + if (direction != Acts::AxisDirection::AxisZ && + direction != Acts::AxisDirection::AxisR) { + throw std::invalid_argument(axisDirectionName(direction) + " is not supported "); } @@ -161,7 +161,7 @@ void CylinderVolumeStack::initializeOuterVolume(BinningValue direction, ACTS_VERBOSE("Checking volume alignment"); checkVolumeAlignment(volumeTuples, logger); - if (direction == Acts::BinningValue::binZ) { + if (direction == Acts::AxisDirection::AxisZ) { ACTS_VERBOSE("Sorting by volume z position"); std::ranges::sort(volumeTuples, {}, [](const auto& v) { return v.localTransform.translation()[eZ]; @@ -222,7 +222,7 @@ void CylinderVolumeStack::initializeOuterVolume(BinningValue direction, // @TODO: We probably can reuse m_transform m_groupTransform = m_transform; - } else if (direction == Acts::BinningValue::binR) { + } else if (direction == Acts::AxisDirection::AxisR) { ACTS_VERBOSE("Sorting by volume r middle point"); std::ranges::sort(volumeTuples, {}, [](const auto& v) { return v.midR(); }); @@ -280,15 +280,15 @@ void CylinderVolumeStack::initializeOuterVolume(BinningValue direction, m_groupTransform = m_transform; } else { - ACTS_ERROR("Binning in " << binningValueName(direction) + ACTS_ERROR("Binning in " << axisDirectionName(direction) << " is not supported"); - throw std::invalid_argument(binningValueName(direction) + + throw std::invalid_argument(axisDirectionName(direction) + " is not supported "); } } void CylinderVolumeStack::overlapPrint( - BinningValue direction, const CylinderVolumeStack::VolumeTuple& a, + AxisDirection direction, const CylinderVolumeStack::VolumeTuple& a, const CylinderVolumeStack::VolumeTuple& b, const Logger& logger) { if (logger().doPrint(Acts::Logging::DEBUG)) { std::stringstream ss; @@ -299,36 +299,34 @@ void CylinderVolumeStack::overlapPrint( int w = 9; ACTS_VERBOSE("Checking overlap between"); - if (direction == BinningValue::binZ) { - ss << " - " - << " z: [ " << std::setw(w) << a.minZ() << " <- " << std::setw(w) - << a.midZ() << " -> " << std::setw(w) << a.maxZ() << " ]"; + if (direction == AxisDirection::AxisZ) { + ss << " - " << " z: [ " << std::setw(w) << a.minZ() << " <- " + << std::setw(w) << a.midZ() << " -> " << std::setw(w) << a.maxZ() + << " ]"; ACTS_VERBOSE(ss.str()); ss.str(""); - ss << " - " - << " z: [ " << std::setw(w) << b.minZ() << " <- " << std::setw(w) - << b.midZ() << " -> " << std::setw(w) << b.maxZ() << " ]"; + ss << " - " << " z: [ " << std::setw(w) << b.minZ() << " <- " + << std::setw(w) << b.midZ() << " -> " << std::setw(w) << b.maxZ() + << " ]"; ACTS_VERBOSE(ss.str()); } else { - ss << " - " - << " r: [ " << std::setw(w) << a.minR() << " <-> " << std::setw(w) - << a.maxR() << " ]"; + ss << " - " << " r: [ " << std::setw(w) << a.minR() << " <-> " + << std::setw(w) << a.maxR() << " ]"; ACTS_VERBOSE(ss.str()); ss.str(""); - ss << " - " - << " r: [ " << std::setw(w) << b.minR() << " <-> " << std::setw(w) - << b.maxR() << " ]"; + ss << " - " << " r: [ " << std::setw(w) << b.minR() << " <-> " + << std::setw(w) << b.maxR() << " ]"; ACTS_VERBOSE(ss.str()); } } } std::vector -CylinderVolumeStack::checkOverlapAndAttachInZ( - std::vector& volumes, - CylinderVolumeStack::AttachmentStrategy strategy, const Logger& logger) { +CylinderVolumeStack::checkOverlapAndAttachInZ(std::vector& volumes, + VolumeAttachmentStrategy strategy, + const Logger& logger) { // Preconditions: volumes are sorted by z std::vector gapVolumes; for (std::size_t i = 0; i < volumes.size() - 1; i++) { @@ -336,7 +334,7 @@ CylinderVolumeStack::checkOverlapAndAttachInZ( auto& a = volumes.at(i); auto& b = volumes.at(j); - overlapPrint(BinningValue::binZ, a, b, logger); + overlapPrint(AxisDirection::AxisZ, a, b, logger); if (a.maxZ() > b.minZ()) { ACTS_ERROR(" -> Overlap in z"); @@ -354,7 +352,7 @@ CylinderVolumeStack::checkOverlapAndAttachInZ( ACTS_VERBOSE("Synchronizing bounds in z with strategy: " << strategy); switch (strategy) { - case AttachmentStrategy::Midpoint: { + case VolumeAttachmentStrategy::Midpoint: { ACTS_VERBOSE(" -> Strategy: Expand both volumes to midpoint"); double aZMidNew = (a.minZ() + a.maxZ()) / 2.0 + gapWidth / 4.0; @@ -389,7 +387,7 @@ CylinderVolumeStack::checkOverlapAndAttachInZ( break; } - case AttachmentStrategy::First: { + case VolumeAttachmentStrategy::First: { ACTS_VERBOSE(" -> Strategy: Expand first volume"); double aZMidNew = (a.minZ() + b.minZ()) / 2.0; double aHlZNew = (b.minZ() - a.minZ()) / 2.0; @@ -408,7 +406,7 @@ CylinderVolumeStack::checkOverlapAndAttachInZ( break; } - case AttachmentStrategy::Second: { + case VolumeAttachmentStrategy::Second: { ACTS_VERBOSE(" -> Strategy: Expand second volume"); double bZMidNew = (a.maxZ() + b.maxZ()) / 2.0; double bHlZNew = (b.maxZ() - a.maxZ()) / 2.0; @@ -426,7 +424,7 @@ CylinderVolumeStack::checkOverlapAndAttachInZ( b.updatedBounds->set(CylinderVolumeBounds::eHalfLengthZ, bHlZNew); break; } - case AttachmentStrategy::Gap: { + case VolumeAttachmentStrategy::Gap: { ACTS_VERBOSE(" -> Strategy: Create a gap volume"); double gapHlZ = (b.minZ() - a.maxZ()) / 2.0; double gapMidZ = (b.minZ() + a.maxZ()) / 2.0; @@ -461,16 +459,16 @@ CylinderVolumeStack::checkOverlapAndAttachInZ( } std::vector -CylinderVolumeStack::checkOverlapAndAttachInR( - std::vector& volumes, - CylinderVolumeStack::AttachmentStrategy strategy, const Logger& logger) { +CylinderVolumeStack::checkOverlapAndAttachInR(std::vector& volumes, + VolumeAttachmentStrategy strategy, + const Logger& logger) { std::vector gapVolumes; for (std::size_t i = 0; i < volumes.size() - 1; i++) { std::size_t j = i + 1; auto& a = volumes.at(i); auto& b = volumes.at(j); - overlapPrint(BinningValue::binR, a, b, logger); + overlapPrint(AxisDirection::AxisR, a, b, logger); if (a.maxR() > b.minR()) { ACTS_ERROR(" -> Overlap in r"); @@ -488,7 +486,7 @@ CylinderVolumeStack::checkOverlapAndAttachInR( ACTS_VERBOSE("Synchronizing bounds in r with strategy: " << strategy); switch (strategy) { - case AttachmentStrategy::Midpoint: { + case VolumeAttachmentStrategy::Midpoint: { ACTS_VERBOSE(" -> Strategy: Expand both volumes to midpoint"); a.set({{CylinderVolumeBounds::eMaxR, a.maxR() + gapWidth / 2.0}}); @@ -496,21 +494,21 @@ CylinderVolumeStack::checkOverlapAndAttachInR( break; } - case AttachmentStrategy::First: { + case VolumeAttachmentStrategy::First: { ACTS_VERBOSE(" -> Strategy: Expand first volume"); a.set({{CylinderVolumeBounds::eMaxR, b.minR()}}); break; } - case AttachmentStrategy::Second: { + case VolumeAttachmentStrategy::Second: { ACTS_VERBOSE(" -> Strategy: Expand second volume"); b.set({{CylinderVolumeBounds::eMinR, a.maxR()}}); break; } - case AttachmentStrategy::Gap: { + case VolumeAttachmentStrategy::Gap: { ACTS_VERBOSE(" -> Strategy: Create a gap volume"); auto gapBounds = std::make_shared( @@ -758,7 +756,7 @@ void CylinderVolumeStack::update(std::shared_ptr volbounds, m_gaps, [&](const auto& gap) { return vol == gap.get(); }); }; - if (m_direction == BinningValue::binZ) { + if (m_direction == AxisDirection::AxisZ) { ACTS_VERBOSE("Stack direction is z"); std::vector volumeTuples; @@ -789,7 +787,7 @@ void CylinderVolumeStack::update(std::shared_ptr volbounds, if (same(newHlZ, oldHlZ)) { ACTS_VERBOSE("Halflength z is the same, no z resize needed"); } else { - if (m_resizeStrategy == ResizeStrategy::Expand) { + if (m_resizeStrategy == VolumeResizeStrategy::Expand) { if (newMinZ < oldMinZ) { ACTS_VERBOSE("Expanding first volume to new z bounds"); @@ -823,7 +821,7 @@ void CylinderVolumeStack::update(std::shared_ptr volbounds, last.setLocalTransform(Transform3{Translation3{0, 0, newMidZLast}}, m_groupTransform); } - } else if (m_resizeStrategy == ResizeStrategy::Gap) { + } else if (m_resizeStrategy == VolumeResizeStrategy::Gap) { ACTS_VERBOSE("Creating gap volumes to fill the new z bounds"); auto printGapDimensions = [&](const VolumeTuple& gap, @@ -920,7 +918,7 @@ void CylinderVolumeStack::update(std::shared_ptr volbounds, m_volumes.push_back(vt.volume); } - } else if (m_direction == BinningValue::binR) { + } else if (m_direction == AxisDirection::AxisR) { ACTS_VERBOSE("Stack direction is r"); std::vector volumeTuples; @@ -948,7 +946,7 @@ void CylinderVolumeStack::update(std::shared_ptr volbounds, if (oldMinR == newMinR && oldMaxR == newMaxR) { ACTS_VERBOSE("Radii are the same, no r resize needed"); } else { - if (m_resizeStrategy == ResizeStrategy::Expand) { + if (m_resizeStrategy == VolumeResizeStrategy::Expand) { if (oldMinR > newMinR) { // expand innermost volume auto& first = volumeTuples.front(); @@ -971,7 +969,7 @@ void CylinderVolumeStack::update(std::shared_ptr volbounds, << last.minR() << " <-> " << last.maxR() << " ]"); } - } else if (m_resizeStrategy == ResizeStrategy::Gap) { + } else if (m_resizeStrategy == VolumeResizeStrategy::Gap) { auto printGapDimensions = [&](const VolumeTuple& gap, const std::string& prefix = "") { ACTS_VERBOSE(" -> gap" << prefix << ": [ " << gap.minZ() << " <- " @@ -1092,36 +1090,4 @@ const std::vector>& CylinderVolumeStack::gaps() const { return m_gaps; } -std::ostream& operator<<(std::ostream& os, - CylinderVolumeStack::AttachmentStrategy strategy) { - switch (strategy) { - case CylinderVolumeStack::AttachmentStrategy::First: - os << "First"; - break; - case CylinderVolumeStack::AttachmentStrategy::Second: - os << "Second"; - break; - case CylinderVolumeStack::AttachmentStrategy::Midpoint: - os << "Midpoint"; - break; - case CylinderVolumeStack::AttachmentStrategy::Gap: - os << "Gap"; - break; - } - return os; -} - -std::ostream& operator<<(std::ostream& os, - CylinderVolumeStack::ResizeStrategy strategy) { - switch (strategy) { - case CylinderVolumeStack::ResizeStrategy::Expand: - os << "Expand"; - break; - case CylinderVolumeStack::ResizeStrategy::Gap: - os << "Gap"; - break; - } - return os; -} - } // namespace Acts diff --git a/Core/src/Geometry/Extent.cpp b/Core/src/Geometry/Extent.cpp index 8dfc33c1203..33aea5fb1d7 100644 --- a/Core/src/Geometry/Extent.cpp +++ b/Core/src/Geometry/Extent.cpp @@ -19,103 +19,103 @@ Acts::Extent::Extent(const ExtentEnvelope& envelope) : m_constrains(0), m_envelope(envelope) { - m_range[toUnderlying(BinningValue::binR)] = + m_range[toUnderlying(AxisDirection::AxisR)] = Range1D(0., std::numeric_limits::max()); - m_range[toUnderlying(BinningValue::binPhi)] = + m_range[toUnderlying(AxisDirection::AxisPhi)] = Range1D(-std::numbers::pi, std::numbers::pi); - m_range[toUnderlying(BinningValue::binRPhi)] = + m_range[toUnderlying(AxisDirection::AxisRPhi)] = Range1D(0., std::numeric_limits::max()); - m_range[toUnderlying(BinningValue::binMag)] = + m_range[toUnderlying(AxisDirection::AxisMag)] = Range1D(0., std::numeric_limits::max()); } void Acts::Extent::extend(const Vector3& vtx, - const std::vector& bValues, + const std::vector& aDirs, bool applyEnv, bool fillHistograms) { - for (auto bValue : bValues) { + for (auto aDir : aDirs) { // Get the casted value given the binning value description - double cValue = VectorHelpers::cast(vtx, bValue); + double cValue = VectorHelpers::cast(vtx, aDir); if (fillHistograms) { - m_valueHistograms[toUnderlying(bValue)].push_back(cValue); + m_valueHistograms[toUnderlying(aDir)].push_back(cValue); } // Apply envelope as suggested - double lEnv = applyEnv ? m_envelope[bValue][0] : 0.; - double hEnv = applyEnv ? m_envelope[bValue][1] : 0.; + double lEnv = applyEnv ? m_envelope[aDir][0] : 0.; + double hEnv = applyEnv ? m_envelope[aDir][1] : 0.; double mValue = cValue - lEnv; // Special protection for radial value - if (bValue == BinningValue::binR && mValue < 0.) { + if (aDir == AxisDirection::AxisR && mValue < 0.) { mValue = std::max(mValue, 0.); } - if (constrains(bValue)) { - m_range[toUnderlying(bValue)].expand(mValue, cValue + hEnv); + if (constrains(aDir)) { + m_range[toUnderlying(aDir)].expand(mValue, cValue + hEnv); } else { - m_range[toUnderlying(bValue)].shrink(mValue, cValue + hEnv); + m_range[toUnderlying(aDir)].shrink(mValue, cValue + hEnv); } - m_constrains.set(toUnderlying(bValue)); + m_constrains.set(toUnderlying(aDir)); } } void Acts::Extent::extend(const Extent& rhs, - const std::vector& bValues, + const std::vector& aDirs, bool applyEnv) { - for (auto bValue : bValues) { + for (auto aDir : aDirs) { // The value is constraint, envelope can be optional - if (rhs.constrains(bValue)) { - double lEnv = applyEnv ? m_envelope[bValue][0] : 0.; - double hEnv = applyEnv ? m_envelope[bValue][1] : 0.; - if (constrains(bValue)) { - m_range[toUnderlying(bValue)].expand( - rhs.range()[toUnderlying(bValue)].min() - lEnv, - rhs.range()[toUnderlying(bValue)].max() + hEnv); + if (rhs.constrains(aDir)) { + double lEnv = applyEnv ? m_envelope[aDir][0] : 0.; + double hEnv = applyEnv ? m_envelope[aDir][1] : 0.; + if (constrains(aDir)) { + m_range[toUnderlying(aDir)].expand( + rhs.range()[toUnderlying(aDir)].min() - lEnv, + rhs.range()[toUnderlying(aDir)].max() + hEnv); } else { - m_range[toUnderlying(bValue)].shrink( - rhs.range()[toUnderlying(bValue)].min() - lEnv, - rhs.range()[toUnderlying(bValue)].max() + hEnv); + m_range[toUnderlying(aDir)].shrink( + rhs.range()[toUnderlying(aDir)].min() - lEnv, + rhs.range()[toUnderlying(aDir)].max() + hEnv); } - m_constrains.set(toUnderlying(bValue)); - } else if (rhs.envelope()[bValue] != zeroEnvelope) { + m_constrains.set(toUnderlying(aDir)); + } else if (rhs.envelope()[aDir] != zeroEnvelope) { // Only an envelope given, but value is not constraint -> apply envelope - m_range[toUnderlying(bValue)].expand( - m_range[toUnderlying(bValue)].min() - rhs.envelope()[bValue][0], - m_range[toUnderlying(bValue)].max() + rhs.envelope()[bValue][1]); - m_constrains.set(toUnderlying(bValue)); + m_range[toUnderlying(aDir)].expand( + m_range[toUnderlying(aDir)].min() - rhs.envelope()[aDir][0], + m_range[toUnderlying(aDir)].max() + rhs.envelope()[aDir][1]); + m_constrains.set(toUnderlying(aDir)); } } } void Acts::Extent::addConstrain(const Acts::Extent& rhs, const ExtentEnvelope& envelope) { - for (const auto& bValue : allBinningValues()) { - if (rhs.constrains(bValue) && !constrains(bValue)) { - const auto& cRange = rhs.range(bValue); - m_range[toUnderlying(bValue)].setMin(cRange.min() - envelope[bValue][0u]); - m_range[toUnderlying(bValue)].setMax(cRange.max() + envelope[bValue][1u]); - m_constrains.set(toUnderlying(bValue)); + for (const auto& aDir : allAxisDirections()) { + if (rhs.constrains(aDir) && !constrains(aDir)) { + const auto& cRange = rhs.range(aDir); + m_range[toUnderlying(aDir)].setMin(cRange.min() - envelope[aDir][0u]); + m_range[toUnderlying(aDir)].setMax(cRange.max() + envelope[aDir][1u]); + m_constrains.set(toUnderlying(aDir)); } } } -void Acts::Extent::set(BinningValue bValue, double min, double max) { +void Acts::Extent::set(AxisDirection aDir, double min, double max) { double minval = min; - if (bValue == BinningValue::binR && minval < 0.) { + if (aDir == AxisDirection::AxisR && minval < 0.) { minval = 0.; } - m_range[toUnderlying(bValue)] = Range1D{minval, max}; - m_constrains.set(toUnderlying(bValue)); + m_range[toUnderlying(aDir)] = Range1D{minval, max}; + m_constrains.set(toUnderlying(aDir)); } -void Acts::Extent::setMin(BinningValue bValue, double min) { +void Acts::Extent::setMin(AxisDirection aDir, double min) { double minval = min; - if (bValue == BinningValue::binR && minval < 0.) { + if (aDir == AxisDirection::AxisR && minval < 0.) { minval = 0.; } - m_range[toUnderlying(bValue)].setMin(0u, minval); - m_constrains.set(toUnderlying(bValue)); + m_range[toUnderlying(aDir)].setMin(0u, minval); + m_constrains.set(toUnderlying(aDir)); } -void Acts::Extent::setMax(BinningValue bValue, double max) { - m_range[toUnderlying(bValue)].setMax(0u, max); - m_constrains.set(toUnderlying(bValue)); +void Acts::Extent::setMax(AxisDirection aDir, double max) { + m_range[toUnderlying(aDir)].setMax(0u, max); + m_constrains.set(toUnderlying(aDir)); } void Acts::Extent::setEnvelope(const ExtentEnvelope& envelope) { @@ -124,7 +124,7 @@ void Acts::Extent::setEnvelope(const ExtentEnvelope& envelope) { bool Acts::Extent::contains(const Vector3& vtx) const { Extent checkExtent; - for (const auto& bv : allBinningValues()) { + for (const auto& bv : allAxisDirections()) { if (constrains(bv)) { double vtxVal = VectorHelpers::cast(vtx, bv); checkExtent.set(bv, vtxVal, vtxVal); @@ -134,9 +134,9 @@ bool Acts::Extent::contains(const Vector3& vtx) const { } bool Acts::Extent::contains(const Extent& rhs, - std::optional bValue) const { + std::optional aDir) const { // Helper to check including a constraint bit set check - auto checkContainment = [&](BinningValue bvc) -> bool { + auto checkContainment = [&](AxisDirection bvc) -> bool { if (!constrains(bvc)) { return true; } @@ -144,17 +144,17 @@ bool Acts::Extent::contains(const Extent& rhs, }; // Check all - if (!bValue.has_value()) { - return std::ranges::all_of(allBinningValues(), checkContainment); + if (!aDir.has_value()) { + return std::ranges::all_of(allAxisDirections(), checkContainment); } // Check specific - return checkContainment(bValue.value()); + return checkContainment(aDir.value()); } bool Acts::Extent::intersects(const Extent& rhs, - std::optional bValue) const { + std::optional aDir) const { // Helper to check including a constraint bit set check - auto checkIntersect = [&](BinningValue bvc) -> bool { + auto checkIntersect = [&](AxisDirection bvc) -> bool { if (!constrains(bvc) || !rhs.constrains(bvc)) { return false; } @@ -162,15 +162,15 @@ bool Acts::Extent::intersects(const Extent& rhs, }; // Check all - if (!bValue.has_value()) { - return std::ranges::any_of(allBinningValues(), checkIntersect); + if (!aDir.has_value()) { + return std::ranges::any_of(allAxisDirections(), checkIntersect); } // Check specific - return checkIntersect(bValue.value()); + return checkIntersect(aDir.value()); } -bool Acts::Extent::constrains(BinningValue bValue) const { - return m_constrains.test(static_cast(bValue)); +bool Acts::Extent::constrains(AxisDirection aDir) const { + return m_constrains.test(static_cast(aDir)); } bool Acts::Extent::constrains() const { @@ -196,9 +196,9 @@ bool Acts::Extent::operator==(const Extent& e) const { std::string Acts::Extent::toString(const std::string& indent) const { std::stringstream sl; sl << indent << "Extent in space :" << std::endl; - for (const auto& bv : allBinningValues()) { + for (const auto& bv : allAxisDirections()) { if (constrains(bv)) { - sl << indent << " - value :" << std::setw(10) << binningValueName(bv) + sl << indent << " - value :" << std::setw(10) << axisDirectionName(bv) << " | range = [" << m_range[toUnderlying(bv)].min() << ", " << m_range[toUnderlying(bv)].max() << "]" << std::endl; } diff --git a/Core/src/Geometry/GridPortalLink.cpp b/Core/src/Geometry/GridPortalLink.cpp index ae6168e11cf..6a0917ba2ce 100644 --- a/Core/src/Geometry/GridPortalLink.cpp +++ b/Core/src/Geometry/GridPortalLink.cpp @@ -10,20 +10,23 @@ #include "Acts/Surfaces/PlaneSurface.hpp" #include "Acts/Surfaces/RadialBounds.hpp" +#include "Acts/Surfaces/RectangleBounds.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" +#include #include namespace Acts { std::unique_ptr GridPortalLink::make( const std::shared_ptr& surface, TrackingVolume& volume, - BinningValue direction) { + AxisDirection direction) { std::unique_ptr grid; if (const auto* cylinder = dynamic_cast(surface.get()); cylinder != nullptr) { - if (direction == BinningValue::binRPhi) { + if (direction == AxisDirection::AxisRPhi) { double r = cylinder->bounds().get(CylinderBounds::eR); if (cylinder->bounds().coversFullAzimuth()) { grid = GridPortalLink::make( @@ -35,7 +38,7 @@ std::unique_ptr GridPortalLink::make( grid = GridPortalLink::make(surface, direction, Axis{AxisBound, -hlPhi * r, hlPhi * r, 1}); } - } else if (direction == BinningValue::binZ) { + } else if (direction == AxisDirection::AxisZ) { double hlZ = cylinder->bounds().get(CylinderBounds::eHalfLengthZ); grid = GridPortalLink::make(surface, direction, Axis{AxisBound, -hlZ, hlZ, 1}); @@ -45,12 +48,12 @@ std::unique_ptr GridPortalLink::make( } else if (const auto* disc = dynamic_cast(surface.get()); disc != nullptr) { const auto& bounds = dynamic_cast(disc->bounds()); - if (direction == BinningValue::binR) { + if (direction == AxisDirection::AxisR) { double minR = bounds.get(RadialBounds::eMinR); double maxR = bounds.get(RadialBounds::eMaxR); grid = GridPortalLink::make(surface, direction, Axis{AxisBound, minR, maxR, 1}); - } else if (direction == BinningValue::binPhi) { + } else if (direction == AxisDirection::AxisPhi) { if (bounds.coversFullAzimuth()) { grid = GridPortalLink::make( surface, direction, @@ -66,8 +69,19 @@ std::unique_ptr GridPortalLink::make( } else if (const auto* plane = dynamic_cast(surface.get()); plane != nullptr) { - throw std::invalid_argument{"Plane surface is not implemented yet"}; - + const auto& bounds = dynamic_cast(plane->bounds()); + if (direction != AxisDirection::AxisX && + direction != AxisDirection::AxisY) { + throw std::invalid_argument{"Invalid binning direction"}; + } + double min = (direction == AxisDirection::AxisX) + ? bounds.get(RectangleBounds::eMinX) + : bounds.get(RectangleBounds::eMinY); + double max = (direction == AxisDirection::AxisX) + ? bounds.get(RectangleBounds::eMaxX) + : bounds.get(RectangleBounds::eMaxY); + grid = + GridPortalLink::make(surface, direction, Axis{AxisBound, min, max, 1}); } else { throw std::invalid_argument{"Surface type is not supported"}; } @@ -126,7 +140,7 @@ void GridPortalLink::checkConsistency(const CylinderSurface& cyl) const { if (dim() == 1) { const IAxis& axisLoc0 = *grid().axes().front(); - if (direction() == BinningValue::binRPhi) { + if (direction() == AxisDirection::AxisRPhi) { checkRPhi(axisLoc0); } else { checkZ(axisLoc0); @@ -188,7 +202,7 @@ void GridPortalLink::checkConsistency(const DiscSurface& disc) const { if (dim() == 1) { const IAxis& axisLoc0 = *grid().axes().front(); - if (direction() == BinningValue::binR) { + if (direction() == AxisDirection::AxisR) { checkR(axisLoc0); } else { checkPhi(axisLoc0); @@ -201,6 +215,39 @@ void GridPortalLink::checkConsistency(const DiscSurface& disc) const { } } +void GridPortalLink::checkConsistency(const PlaneSurface& plane) const { + constexpr auto tolerance = s_onSurfaceTolerance; + auto same = [](auto a, auto b) { return std::abs(a - b) < tolerance; }; + + const auto* bounds = dynamic_cast(&plane.bounds()); + if (bounds == nullptr) { + throw std::invalid_argument( + "GridPortalLink: PlaneBounds: invalid bounds type."); + } + auto check = [&bounds, same](const IAxis& axis, AxisDirection dir) { + double min = (dir == AxisDirection::AxisX) + ? bounds->get(RectangleBounds::eMinX) + : bounds->get(RectangleBounds::eMinY); + double max = (dir == AxisDirection::AxisX) + ? bounds->get(RectangleBounds::eMaxX) + : bounds->get(RectangleBounds::eMaxY); + if (!same(axis.getMin(), min) || !same(axis.getMax(), max)) { + throw std::invalid_argument( + "GridPortalLink: PlaneBounds: invalid setup."); + } + }; + + if (dim() == 1) { + const IAxis& axisLoc0 = *grid().axes().front(); + check(axisLoc0, direction()); + } else { // DIM == 2 + const auto& axisLoc0 = *grid().axes().front(); + const auto& axisLoc1 = *grid().axes().back(); + check(axisLoc0, AxisDirection::AxisX); + check(axisLoc1, AxisDirection::AxisY); + } +} + void GridPortalLink::printContents(std::ostream& os) const { std::size_t dim = grid().axes().size(); os << "----- GRID " << dim << "d -----" << std::endl; @@ -222,15 +269,15 @@ void GridPortalLink::printContents(std::ostream& os) const { if (surface().type() == Surface::Cylinder) { loc0 = "rPhi"; loc1 = "z"; - flipped = direction() != BinningValue::binRPhi; + flipped = direction() != AxisDirection::AxisRPhi; } else if (surface().type() == Surface::Disc) { loc0 = "r"; loc1 = "phi"; - flipped = direction() != BinningValue::binR; + flipped = direction() != AxisDirection::AxisR; } else if (surface().type() == Surface::Plane) { loc0 = "x"; loc1 = "y"; - flipped = direction() != BinningValue::binX; + flipped = direction() != AxisDirection::AxisX; } else { throw std::invalid_argument{"Unsupported surface type"}; } @@ -318,9 +365,9 @@ void GridPortalLink::fillGrid1dTo2d(FillDirection dir, std::unique_ptr GridPortalLink::extendTo2dImpl( const std::shared_ptr& surface, const IAxis* other) const { assert(dim() == 1); - if (direction() == BinningValue::binRPhi) { + if (direction() == AxisDirection::AxisRPhi) { const auto& axisRPhi = *grid().axes().front(); - // 1D direction is binRPhi, so add a Z axis + // 1D direction is AxisRPhi, so add a Z axis double hlZ = surface->bounds().get(CylinderBounds::eHalfLengthZ); auto grid = axisRPhi.visit([&](const auto& axis0) { @@ -338,7 +385,7 @@ std::unique_ptr GridPortalLink::extendTo2dImpl( } else { const auto& axisZ = *grid().axes().front(); - // 1D direction is binZ, so add an rPhi axis + // 1D direction is AxisZ, so add an rPhi axis double r = surface->bounds().get(CylinderBounds::eR); double hlPhi = surface->bounds().get(CylinderBounds::eHalfPhiSector); double hlRPhi = r * hlPhi; @@ -375,9 +422,9 @@ std::unique_ptr GridPortalLink::extendTo2dImpl( "GridPortalLink: DiscBounds: invalid bounds type."); } - if (direction() == BinningValue::binR) { + if (direction() == AxisDirection::AxisR) { const auto& axisR = *grid().axes().front(); - // 1D direction is binR, so add a phi axis + // 1D direction is AxisR, so add a phi axis double hlPhi = bounds->get(RadialBounds::eHalfPhiSector); auto makeGrid = [&](auto bdt) { @@ -401,7 +448,7 @@ std::unique_ptr GridPortalLink::extendTo2dImpl( } } else { const auto& axisPhi = *grid().axes().front(); - // 1D direction is binPhi, so add an R axis + // 1D direction is AxisPhi, so add an R axis double rMin = bounds->get(RadialBounds::eMinR); double rMax = bounds->get(RadialBounds::eMaxR); @@ -419,4 +466,41 @@ std::unique_ptr GridPortalLink::extendTo2dImpl( } } +std::unique_ptr GridPortalLink::extendTo2dImpl( + const std::shared_ptr& surface, const IAxis* other) const { + assert(dim() == 1); + + const auto* bounds = dynamic_cast(&surface->bounds()); + if (bounds == nullptr) { + throw std::invalid_argument( + "GridPortalLink: RectangleBounds: invalid bounds type."); + } + + bool dirX = direction() == AxisDirection::AxisX; + const auto& thisAxis = *grid().axes().front(); + + double minExtend = dirX ? bounds->get(RectangleBounds::BoundValues::eMinY) + : bounds->get(RectangleBounds::BoundValues::eMinX); + double maxExtend = dirX ? bounds->get(RectangleBounds::BoundValues::eMaxY) + : bounds->get(RectangleBounds::BoundValues::eMaxX); + + FillDirection fillDir = dirX ? FillDirection::loc1 : FillDirection::loc0; + + auto grid = thisAxis.visit([&](const auto& axis0) { + Axis axisExtend{AxisBound, minExtend, maxExtend, 1}; + const IAxis* axis = other != nullptr ? other : &axisExtend; + return axis->visit( + [&](const auto& axis1) -> std::unique_ptr { + if (dirX) { + return GridPortalLink::make(surface, axis0, axis1); + } else { + return GridPortalLink::make(surface, axis1, axis0); + } + }); + }); + + fillGrid1dTo2d(fillDir, *this, *grid); + return grid; +} + } // namespace Acts diff --git a/Core/src/Geometry/GridPortalLinkMerging.cpp b/Core/src/Geometry/GridPortalLinkMerging.cpp index f475822876b..c013e7a19b0 100644 --- a/Core/src/Geometry/GridPortalLinkMerging.cpp +++ b/Core/src/Geometry/GridPortalLinkMerging.cpp @@ -26,7 +26,7 @@ namespace { template std::unique_ptr makeGrid( - const std::shared_ptr& surface, BinningValue direction, + const std::shared_ptr& surface, AxisDirection direction, const Logger& logger, std::tuple args, const IAxis* otherAxis, bool prepend) { // @TODO: PlaneSurface support @@ -65,7 +65,8 @@ std::unique_ptr makeGrid( // Check if we're in the cylinder or disc case, and the resulting bounds wrap // around and should have closed binning - if (direction == BinningValue::binPhi || direction == BinningValue::binRPhi) { + if (direction == AxisDirection::AxisPhi || + direction == AxisDirection::AxisRPhi) { if (const auto* cylinder = dynamic_cast(surface.get()); cylinder != nullptr) { @@ -88,7 +89,7 @@ std::unique_ptr makeGrid( std::unique_ptr mergeVariable( const std::shared_ptr& mergedSurface, const IAxis& axisA, - const IAxis& axisB, double /*tolerance*/, BinningValue direction, + const IAxis& axisB, double /*tolerance*/, AxisDirection direction, const Logger& logger, const IAxis* otherAxis, bool prepend) { ACTS_VERBOSE("Variable merge: direction is " << direction); @@ -101,7 +102,7 @@ std::unique_ptr mergeVariable( auto edgesA = axisA.getBinEdges(); - if (direction == BinningValue::binR) { + if (direction == AxisDirection::AxisR) { ACTS_VERBOSE("Performing asymmetric merge"); std::ranges::copy(edgesA, std::back_inserter(binEdges)); @@ -131,7 +132,7 @@ std::unique_ptr mergeVariable( std::unique_ptr mergeEquidistant( const std::shared_ptr& mergedSurface, const IAxis& axisA, - const IAxis& axisB, double tolerance, BinningValue direction, + const IAxis& axisB, double tolerance, AxisDirection direction, const Logger& logger, const IAxis* otherAxis, bool prepend) { ACTS_VERBOSE("===> potentially equidistant merge: checking bin widths"); @@ -151,7 +152,7 @@ std::unique_ptr mergeEquidistant( double min = std::numeric_limits::signaling_NaN(); double max = std::numeric_limits::signaling_NaN(); - if (direction == BinningValue::binR) { + if (direction == AxisDirection::AxisR) { ACTS_VERBOSE("Performing asymmetric merge"); min = axisA.getMin(); max = axisB.getMax(); @@ -183,7 +184,7 @@ std::unique_ptr mergeEquidistant( std::unique_ptr colinearMerge( const std::shared_ptr& mergedSurface, const IAxis& axisA, - const IAxis& axisB, double tolerance, BinningValue direction, + const IAxis& axisB, double tolerance, AxisDirection direction, const Logger& logger, const IAxis* otherAxis, bool prepend) { AxisType aType = axisA.getType(); AxisType bType = axisB.getType(); @@ -226,7 +227,7 @@ std::unique_ptr colinearMerge( std::unique_ptr mergeGridPortals( const GridPortalLink* a, const GridPortalLink* b, const RegularSurface* surfaceA, const RegularSurface* surfaceB, - BinningValue loc0, BinningValue loc1, BinningValue direction, + AxisDirection loc0, AxisDirection loc1, AxisDirection direction, const Logger& logger) { assert(surfaceA != nullptr); assert(surfaceB != nullptr); @@ -256,7 +257,8 @@ std::unique_ptr mergeGridPortals( dynamic_cast(*surfaceB), direction, true, logger); } else if (const auto* planeA = dynamic_cast(surfaceA); planeA != nullptr) { - throw std::logic_error{"Plane surfaces not implemented yet"}; + std::tie(mergedSurface, reversed) = planeA->mergedWith( + dynamic_cast(*surfaceB), direction, logger); } else { throw std::invalid_argument{"Unsupported surface type"}; } @@ -425,9 +427,9 @@ std::unique_ptr mergeGridPortals( std::unique_ptr mergeGridPortals(const GridPortalLink* a, const GridPortalLink* b, - BinningValue direction, + AxisDirection direction, const Logger& logger) { - using enum BinningValue; + using enum AxisDirection; assert(a->dim() == 2 || a->dim() == 1); assert(b->dim() == 2 || b->dim() == 1); @@ -441,6 +443,7 @@ std::unique_ptr mergeGridPortals(const GridPortalLink* a, const auto* cylinder = dynamic_cast(&a->surface()); const auto* disc = dynamic_cast(&a->surface()); + const auto* plane = dynamic_cast(&a->surface()); if (a->dim() == b->dim()) { ACTS_VERBOSE("Grid both have same dimension: " << a->dim()); @@ -448,13 +451,16 @@ std::unique_ptr mergeGridPortals(const GridPortalLink* a, if (cylinder != nullptr) { return mergeGridPortals( a, b, cylinder, &dynamic_cast(b->surface()), - binRPhi, binZ, direction, logger); + AxisRPhi, AxisZ, direction, logger); } else if (disc != nullptr) { return mergeGridPortals(a, b, disc, &dynamic_cast(b->surface()), - binR, binPhi, direction, logger); + AxisR, AxisPhi, direction, logger); + } else if (plane != nullptr) { + return mergeGridPortals(a, b, plane, + &dynamic_cast(b->surface()), + AxisX, AxisY, direction, logger); } else { - // @TODO: Support PlaneSurface ACTS_VERBOSE("Surface type is not supported here, falling back"); return nullptr; } @@ -467,11 +473,11 @@ std::unique_ptr mergeGridPortals(const GridPortalLink* a, ACTS_VERBOSE("~> Adding complementary axis"); if (cylinder != nullptr) { - otherAxis = direction == binRPhi ? a->grid().axes().back() - : a->grid().axes().front(); + otherAxis = direction == AxisRPhi ? a->grid().axes().back() + : a->grid().axes().front(); } else if (disc != nullptr) { - otherAxis = direction == binR ? a->grid().axes().back() - : a->grid().axes().front(); + otherAxis = direction == AxisR ? a->grid().axes().back() + : a->grid().axes().front(); } else { ACTS_VERBOSE("Surface type is not supported here, falling back"); return nullptr; @@ -491,7 +497,7 @@ std::unique_ptr mergeGridPortals(const GridPortalLink* a, void GridPortalLink::fillMergedGrid(const GridPortalLink& a, const GridPortalLink& b, GridPortalLink& merged, - BinningValue direction, + AxisDirection direction, const Logger& logger) { ACTS_VERBOSE("Filling merged grid"); assert(a.dim() == b.dim()); @@ -554,7 +560,7 @@ void GridPortalLink::fillMergedGrid(const GridPortalLink& a, std::unique_ptr GridPortalLink::merge(const GridPortalLink& a, const GridPortalLink& b, - BinningValue direction, + AxisDirection direction, const Logger& logger) { ACTS_VERBOSE("Merging two GridPortalLinks"); diff --git a/Core/src/Geometry/KDTreeTrackingGeometryBuilder.cpp b/Core/src/Geometry/KDTreeTrackingGeometryBuilder.cpp index c0a45763372..8a0e086aaff 100644 --- a/Core/src/Geometry/KDTreeTrackingGeometryBuilder.cpp +++ b/Core/src/Geometry/KDTreeTrackingGeometryBuilder.cpp @@ -51,10 +51,10 @@ Acts::KDTreeTrackingGeometryBuilder::trackingGeometry( surfacesMeasured.reserve(m_cfg.surfaces.size()); for (auto& s : m_cfg.surfaces) { auto ext = s->polyhedronRepresentation(gctx, 1u).extent(); - surfacesMeasured.push_back( - MeasuredSurface{std::array{ext.medium(BinningValue::binZ), - ext.medium(BinningValue::binR)}, - s}); + surfacesMeasured.push_back(MeasuredSurface{ + std::array{ext.medium(AxisDirection::AxisZ), + ext.medium(AxisDirection::AxisR)}, + s}); } // Create the KDTree @@ -84,8 +84,8 @@ Acts::KDTreeTrackingGeometryBuilder::translateVolume( std::vector> translatedVolumes = {}; // Volume extent - auto rangeR = ptVolume.extent.range(Acts::BinningValue::binR); - auto rangeZ = ptVolume.extent.range(Acts::BinningValue::binZ); + auto rangeR = ptVolume.extent.range(Acts::AxisDirection::AxisR); + auto rangeZ = ptVolume.extent.range(Acts::AxisDirection::AxisZ); // Simple gap volume if (!ptVolume.container.has_value()) { @@ -158,8 +158,8 @@ Acts::KDTreeTrackingGeometryBuilder::translateLayer( // Try to pull from the kd tree RangeXD<2u, double> zrRange; - zrRange[0u] = plVolume.extent.range(Acts::BinningValue::binZ); - zrRange[1u] = plVolume.extent.range(Acts::BinningValue::binR); + zrRange[0u] = plVolume.extent.range(Acts::AxisDirection::AxisZ); + zrRange[1u] = plVolume.extent.range(Acts::AxisDirection::AxisR); auto layerSurfaces = kdt.rangeSearchWithKey(zrRange); ACTS_VERBOSE(indent + ">> looking z/r range = " << zrRange.toString()); diff --git a/Core/src/Geometry/LayerArrayCreator.cpp b/Core/src/Geometry/LayerArrayCreator.cpp index e8b972cb6d1..40149e05a13 100644 --- a/Core/src/Geometry/LayerArrayCreator.cpp +++ b/Core/src/Geometry/LayerArrayCreator.cpp @@ -30,18 +30,18 @@ std::unique_ptr Acts::LayerArrayCreator::layerArray( const GeometryContext& gctx, const LayerVector& layersInput, double min, - double max, BinningType bType, BinningValue bValue) const { + double max, BinningType bType, AxisDirection aDir) const { ACTS_VERBOSE("Build LayerArray with " << layersInput.size() << " layers at input."); ACTS_VERBOSE(" min/max provided : " << min << " / " << max); ACTS_VERBOSE(" binning type : " << bType); - ACTS_VERBOSE(" binning value : " << bValue); + ACTS_VERBOSE(" binning value : " << aDir); // create a local copy of the layer vector LayerVector layers(layersInput); // sort it accordingly to the binning value - GeometryObjectSorterT> layerSorter(gctx, bValue); + GeometryObjectSorterT> layerSorter(gctx, aDir); std::ranges::sort(layers, layerSorter); // useful typedef using LayerOrderPosition = std::pair, Vector3>; @@ -57,13 +57,13 @@ std::unique_ptr Acts::LayerArrayCreator::layerArray( // loop over layers and put them in for (auto& layIter : layers) { ACTS_VERBOSE("equidistant : registering a Layer at binning position : " - << (layIter->binningPosition(gctx, bValue))); + << (layIter->referencePosition(gctx, aDir))); layerOrderVector.push_back(LayerOrderPosition( - layIter, layIter->binningPosition(gctx, bValue))); + layIter, layIter->referencePosition(gctx, aDir))); } // create the binUitlity binUtility = std::make_unique(layers.size(), min, max, - open, bValue); + open, aDir); ACTS_VERBOSE("equidistant : created a BinUtility as " << *binUtility); } break; @@ -80,7 +80,7 @@ std::unique_ptr Acts::LayerArrayCreator::layerArray( for (auto& layIter : layers) { // estimate the offset layerThickness = layIter->thickness(); - layerValue = layIter->binningPositionValue(gctx, bValue); + layerValue = layIter->referencePositionValue(gctx, aDir); // register the new boundaries in the step vector boundaries.push_back(layerValue - 0.5 * layerThickness); boundaries.push_back(layerValue + 0.5 * layerThickness); @@ -107,25 +107,25 @@ std::unique_ptr Acts::LayerArrayCreator::layerArray( // create the navigation layer surface from the layer std::shared_ptr navLayerSurface = - createNavigationSurface(gctx, *layIter, bValue, + createNavigationSurface(gctx, *layIter, aDir, -std::abs(layerValue - navigationValue)); ACTS_VERBOSE( "arbitrary : creating a NavigationLayer at " - << (navLayerSurface->binningPosition(gctx, bValue)).x() << ", " - << (navLayerSurface->binningPosition(gctx, bValue)).y() << ", " - << (navLayerSurface->binningPosition(gctx, bValue)).z()); + << (navLayerSurface->referencePosition(gctx, aDir)).x() << ", " + << (navLayerSurface->referencePosition(gctx, aDir)).y() << ", " + << (navLayerSurface->referencePosition(gctx, aDir)).z()); navLayer = NavigationLayer::create(std::move(navLayerSurface)); // push the navigation layer in layerOrderVector.push_back(LayerOrderPosition( - navLayer, navLayer->binningPosition(gctx, bValue))); + navLayer, navLayer->referencePosition(gctx, aDir))); // push the original layer in layerOrderVector.push_back(LayerOrderPosition( - layIter, layIter->binningPosition(gctx, bValue))); + layIter, layIter->referencePosition(gctx, aDir))); ACTS_VERBOSE("arbitrary : registering MaterialLayer at " - << (layIter->binningPosition(gctx, bValue)).x() << ", " - << (layIter->binningPosition(gctx, bValue)).y() << ", " - << (layIter->binningPosition(gctx, bValue)).z()); + << (layIter->referencePosition(gctx, aDir)).x() << ", " + << (layIter->referencePosition(gctx, aDir)).y() << ", " + << (layIter->referencePosition(gctx, aDir)).z()); // remember the last lastLayer = layIter; } @@ -137,17 +137,17 @@ std::unique_ptr Acts::LayerArrayCreator::layerArray( if (navigationValue != max && lastLayer != nullptr) { // create the navigation layer surface from the layer std::shared_ptr navLayerSurface = - createNavigationSurface(gctx, *lastLayer, bValue, + createNavigationSurface(gctx, *lastLayer, aDir, navigationValue - layerValue); ACTS_VERBOSE( "arbitrary : creating a NavigationLayer at " - << (navLayerSurface->binningPosition(gctx, bValue)).x() << ", " - << (navLayerSurface->binningPosition(gctx, bValue)).y() << ", " - << (navLayerSurface->binningPosition(gctx, bValue)).z()); + << (navLayerSurface->referencePosition(gctx, aDir)).x() << ", " + << (navLayerSurface->referencePosition(gctx, aDir)).y() << ", " + << (navLayerSurface->referencePosition(gctx, aDir)).z()); navLayer = NavigationLayer::create(std::move(navLayerSurface)); // push the navigation layer in layerOrderVector.push_back(LayerOrderPosition( - navLayer, navLayer->binningPosition(gctx, bValue))); + navLayer, navLayer->referencePosition(gctx, aDir))); } // now close the boundaries boundaries.push_back(max); @@ -155,7 +155,7 @@ std::unique_ptr Acts::LayerArrayCreator::layerArray( ACTS_VERBOSE(layerOrderVector.size() << " Layers (material + navigation) built. "); // create the BinUtility - binUtility = std::make_unique(boundaries, open, bValue); + binUtility = std::make_unique(boundaries, open, aDir); ACTS_VERBOSE("arbitrary : created a BinUtility as " << *binUtility); } break; @@ -170,28 +170,28 @@ std::unique_ptr Acts::LayerArrayCreator::layerArray( } std::shared_ptr Acts::LayerArrayCreator::createNavigationSurface( - const GeometryContext& gctx, const Layer& layer, BinningValue bValue, + const GeometryContext& gctx, const Layer& layer, AxisDirection aDir, double offset) const { // surface reference const Surface& layerSurface = layer.surfaceRepresentation(); // translation to be applied Vector3 translation(0., 0., 0.); // switching he binnig values - switch (bValue) { + switch (aDir) { // case x - case BinningValue::binX: { + case AxisDirection::AxisX: { translation = Vector3(offset, 0., 0.); } break; // case y - case BinningValue::binY: { + case AxisDirection::AxisY: { translation = Vector3(0., offset, 0.); } break; // case z - case BinningValue::binZ: { + case AxisDirection::AxisZ: { translation = Vector3(0., 0., offset); } break; // case R - case BinningValue::binR: { + case AxisDirection::AxisR: { // binning in R and cylinder surface means something different if (layerSurface.type() == Surface::Cylinder) { break; diff --git a/Core/src/Geometry/LayerBlueprintNode.cpp b/Core/src/Geometry/LayerBlueprintNode.cpp index de2e2cdb8cd..dc0f5ce7fd2 100644 --- a/Core/src/Geometry/LayerBlueprintNode.cpp +++ b/Core/src/Geometry/LayerBlueprintNode.cpp @@ -52,23 +52,23 @@ Volume& LayerBlueprintNode::build(const BlueprintOptions& options, void LayerBlueprintNode::buildVolume(const Extent& extent, const Logger& logger) { ACTS_VERBOSE(prefix() << "Building volume for layer " << name()); - using enum BinningValue; + using enum AxisDirection; using enum LayerType; std::shared_ptr bounds; switch (m_layerType) { case Cylinder: case Disc: { - double minR = extent.min(binR); - double maxR = extent.max(binR); - double hlZ = extent.interval(binZ) / 2.0; + double minR = extent.min(AxisR); + double maxR = extent.max(AxisR); + double hlZ = extent.interval(AxisZ) / 2.0; bounds = std::make_shared(minR, maxR, hlZ); break; } case Plane: { - double hlX = extent.interval(binX) / 2.0; - double hlY = extent.interval(binY) / 2.0; - double hlZ = extent.interval(binZ) / 2.0; + double hlX = extent.interval(AxisX) / 2.0; + double hlY = extent.interval(AxisY) / 2.0; + double hlZ = extent.interval(AxisZ) / 2.0; bounds = std::make_shared(hlX, hlY, hlZ); break; } @@ -80,7 +80,7 @@ void LayerBlueprintNode::buildVolume(const Extent& extent, Transform3 transform = m_transform; transform.translation() = - Vector3{extent.medium(binX), extent.medium(binY), extent.medium(binZ)}; + Vector3{extent.medium(AxisX), extent.medium(AxisY), extent.medium(AxisZ)}; ACTS_VERBOSE(prefix() << " -> adjusted transform:\n" << transform.matrix()); diff --git a/Core/src/Geometry/LayerCreator.cpp b/Core/src/Geometry/LayerCreator.cpp index e24ff8e0661..69694741a82 100644 --- a/Core/src/Geometry/LayerCreator.cpp +++ b/Core/src/Geometry/LayerCreator.cpp @@ -59,26 +59,26 @@ Acts::MutableLayerPtr Acts::LayerCreator::cylinderLayer( _protoLayer ? *_protoLayer : ProtoLayer(gctx, surfaces); // Remaining layer parameters - they include the envelopes - double layerR = protoLayer.medium(BinningValue::binR); - double layerZ = protoLayer.medium(BinningValue::binZ); - double layerHalfZ = 0.5 * protoLayer.range(BinningValue::binZ); - double layerThickness = protoLayer.range(BinningValue::binR); + double layerR = protoLayer.medium(AxisDirection::AxisR); + double layerZ = protoLayer.medium(AxisDirection::AxisZ); + double layerHalfZ = 0.5 * protoLayer.range(AxisDirection::AxisZ); + double layerThickness = protoLayer.range(AxisDirection::AxisR); ACTS_VERBOSE("Creating a cylindrical Layer:"); ACTS_VERBOSE(" - with layer R = " << layerR); ACTS_VERBOSE(" - from R min/max = " - << protoLayer.min(BinningValue::binR, false) << " / " - << protoLayer.max(BinningValue::binR, false)); + << protoLayer.min(AxisDirection::AxisR, false) << " / " + << protoLayer.max(AxisDirection::AxisR, false)); ACTS_VERBOSE(" - with R thickness = " << layerThickness); ACTS_VERBOSE(" - incl envelope = " - << protoLayer.envelope[BinningValue::binR][0u] << " / " - << protoLayer.envelope[BinningValue::binR][1u]); + << protoLayer.envelope[AxisDirection::AxisR][0u] << " / " + << protoLayer.envelope[AxisDirection::AxisR][1u]); ACTS_VERBOSE(" - with z min/max = " - << protoLayer.min(BinningValue::binZ, false) << " (-" - << protoLayer.envelope[BinningValue::binZ][0u] << ") / " - << protoLayer.max(BinningValue::binZ, false) << " (+" - << protoLayer.envelope[BinningValue::binZ][1u] << ")"); + << protoLayer.min(AxisDirection::AxisZ, false) << " (-" + << protoLayer.envelope[AxisDirection::AxisZ][0u] << ") / " + << protoLayer.max(AxisDirection::AxisZ, false) << " (+" + << protoLayer.envelope[AxisDirection::AxisZ][1u] << ")"); ACTS_VERBOSE(" - z center = " << layerZ); ACTS_VERBOSE(" - halflength z = " << layerHalfZ); @@ -93,8 +93,8 @@ Acts::MutableLayerPtr Acts::LayerCreator::cylinderLayer( } ACTS_VERBOSE(" - with phi min/max = " - << protoLayer.min(BinningValue::binPhi, false) << " / " - << protoLayer.max(BinningValue::binPhi, false)); + << protoLayer.min(AxisDirection::AxisPhi, false) << " / " + << protoLayer.max(AxisDirection::AxisPhi, false)); ACTS_VERBOSE(" - # of modules = " << surfaces.size() << " ordered in ( " << binsPhi << " x " << binsZ << ")"); std::unique_ptr sArray; @@ -132,26 +132,26 @@ Acts::MutableLayerPtr Acts::LayerCreator::cylinderLayer( _protoLayer ? *_protoLayer : ProtoLayer(gctx, surfaces); // remaining layer parameters - double layerR = protoLayer.medium(BinningValue::binR); - double layerZ = protoLayer.medium(BinningValue::binZ); - double layerHalfZ = 0.5 * protoLayer.range(BinningValue::binZ); - double layerThickness = protoLayer.range(BinningValue::binR); + double layerR = protoLayer.medium(AxisDirection::AxisR); + double layerZ = protoLayer.medium(AxisDirection::AxisZ); + double layerHalfZ = 0.5 * protoLayer.range(AxisDirection::AxisZ); + double layerThickness = protoLayer.range(AxisDirection::AxisR); // adjust the layer radius ACTS_VERBOSE("Creating a cylindrical Layer:"); ACTS_VERBOSE(" - with layer R = " << layerR); ACTS_VERBOSE(" - from R min/max = " - << protoLayer.min(BinningValue::binR, false) << " / " - << protoLayer.max(BinningValue::binR, false)); + << protoLayer.min(AxisDirection::AxisR, false) << " / " + << protoLayer.max(AxisDirection::AxisR, false)); ACTS_VERBOSE(" - with R thickness = " << layerThickness); ACTS_VERBOSE(" - incl envelope = " - << protoLayer.envelope[BinningValue::binR][0u] << " / " - << protoLayer.envelope[BinningValue::binR][1u]); + << protoLayer.envelope[AxisDirection::AxisR][0u] << " / " + << protoLayer.envelope[AxisDirection::AxisR][1u]); ACTS_VERBOSE(" - with z min/max = " - << protoLayer.min(BinningValue::binZ, false) << " (-" - << protoLayer.envelope[BinningValue::binZ][0u] << ") / " - << protoLayer.max(BinningValue::binZ, false) << " (+" - << protoLayer.envelope[BinningValue::binZ][1u] << ")"); + << protoLayer.min(AxisDirection::AxisZ, false) << " (-" + << protoLayer.envelope[AxisDirection::AxisZ][0u] << ") / " + << protoLayer.max(AxisDirection::AxisZ, false) << " (+" + << protoLayer.envelope[AxisDirection::AxisZ][1u] << ")"); ACTS_VERBOSE(" - z center = " << layerZ); ACTS_VERBOSE(" - halflength z = " << layerHalfZ); @@ -166,8 +166,8 @@ Acts::MutableLayerPtr Acts::LayerCreator::cylinderLayer( } ACTS_VERBOSE(" - with phi min/max = " - << protoLayer.min(BinningValue::binPhi, false) << " / " - << protoLayer.max(BinningValue::binPhi, false)); + << protoLayer.min(AxisDirection::AxisPhi, false) << " / " + << protoLayer.max(AxisDirection::AxisPhi, false)); ACTS_VERBOSE(" - # of modules = " << surfaces.size() << ""); // create the surface array @@ -205,27 +205,27 @@ Acts::MutableLayerPtr Acts::LayerCreator::discLayer( ProtoLayer protoLayer = _protoLayer ? *_protoLayer : ProtoLayer(gctx, surfaces); - double layerZ = protoLayer.medium(BinningValue::binZ); - double layerThickness = protoLayer.range(BinningValue::binZ); + double layerZ = protoLayer.medium(AxisDirection::AxisZ); + double layerThickness = protoLayer.range(AxisDirection::AxisZ); // adjust the layer radius ACTS_VERBOSE("Creating a disk Layer:"); ACTS_VERBOSE(" - at Z position = " << layerZ); ACTS_VERBOSE(" - from Z min/max = " - << protoLayer.min(BinningValue::binZ, false) << " / " - << protoLayer.max(BinningValue::binZ, false)); + << protoLayer.min(AxisDirection::AxisZ, false) << " / " + << protoLayer.max(AxisDirection::AxisZ, false)); ACTS_VERBOSE(" - with Z thickness = " << layerThickness); ACTS_VERBOSE(" - incl envelope = " - << protoLayer.envelope[BinningValue::binZ][0u] << " / " - << protoLayer.envelope[BinningValue::binZ][1u]); + << protoLayer.envelope[AxisDirection::AxisZ][0u] << " / " + << protoLayer.envelope[AxisDirection::AxisZ][1u]); ACTS_VERBOSE(" - with R min/max = " - << protoLayer.min(BinningValue::binR, false) << " (-" - << protoLayer.envelope[BinningValue::binR][0u] << ") / " - << protoLayer.max(BinningValue::binR, false) << " (+" - << protoLayer.envelope[BinningValue::binR][1u] << ")"); + << protoLayer.min(AxisDirection::AxisR, false) << " (-" + << protoLayer.envelope[AxisDirection::AxisR][0u] << ") / " + << protoLayer.max(AxisDirection::AxisR, false) << " (+" + << protoLayer.envelope[AxisDirection::AxisR][1u] << ")"); ACTS_VERBOSE(" - with phi min/max = " - << protoLayer.min(BinningValue::binPhi, false) << " / " - << protoLayer.max(BinningValue::binPhi, false)); + << protoLayer.min(AxisDirection::AxisPhi, false) << " / " + << protoLayer.max(AxisDirection::AxisPhi, false)); ACTS_VERBOSE(" - # of modules = " << surfaces.size() << " ordered in ( " << binsR << " x " << binsPhi << ")"); @@ -245,7 +245,8 @@ Acts::MutableLayerPtr Acts::LayerCreator::discLayer( // create the share disc bounds auto dBounds = std::make_shared( - protoLayer.min(BinningValue::binR), protoLayer.max(BinningValue::binR)); + protoLayer.min(AxisDirection::AxisR), + protoLayer.max(AxisDirection::AxisR)); // create the layers // we use the same transform here as for the layer itself @@ -270,27 +271,27 @@ Acts::MutableLayerPtr Acts::LayerCreator::discLayer( ProtoLayer protoLayer = _protoLayer ? *_protoLayer : ProtoLayer(gctx, surfaces); - double layerZ = protoLayer.medium(BinningValue::binZ); - double layerThickness = protoLayer.range(BinningValue::binZ); + double layerZ = protoLayer.medium(AxisDirection::AxisZ); + double layerThickness = protoLayer.range(AxisDirection::AxisZ); // adjust the layer radius ACTS_VERBOSE("Creating a disk Layer:"); ACTS_VERBOSE(" - at Z position = " << layerZ); ACTS_VERBOSE(" - from Z min/max = " - << protoLayer.min(BinningValue::binZ, false) << " / " - << protoLayer.max(BinningValue::binZ, false)); + << protoLayer.min(AxisDirection::AxisZ, false) << " / " + << protoLayer.max(AxisDirection::AxisZ, false)); ACTS_VERBOSE(" - with Z thickness = " << layerThickness); ACTS_VERBOSE(" - incl envelope = " - << protoLayer.envelope[BinningValue::binZ][0u] << " / " - << protoLayer.envelope[BinningValue::binZ][1u]); + << protoLayer.envelope[AxisDirection::AxisZ][0u] << " / " + << protoLayer.envelope[AxisDirection::AxisZ][1u]); ACTS_VERBOSE(" - with R min/max = " - << protoLayer.min(BinningValue::binR, false) << " (-" - << protoLayer.envelope[BinningValue::binR][0u] << ") / " - << protoLayer.max(BinningValue::binR, false) << " (+" - << protoLayer.envelope[BinningValue::binR][1u] << ")"); + << protoLayer.min(AxisDirection::AxisR, false) << " (-" + << protoLayer.envelope[AxisDirection::AxisR][0u] << ") / " + << protoLayer.max(AxisDirection::AxisR, false) << " (+" + << protoLayer.envelope[AxisDirection::AxisR][1u] << ")"); ACTS_VERBOSE(" - with phi min/max = " - << protoLayer.min(BinningValue::binPhi, false) << " / " - << protoLayer.max(BinningValue::binPhi, false)); + << protoLayer.min(AxisDirection::AxisPhi, false) << " / " + << protoLayer.max(AxisDirection::AxisPhi, false)); ACTS_VERBOSE(" - # of modules = " << surfaces.size()); // create the layer transforms if not given @@ -310,7 +311,8 @@ Acts::MutableLayerPtr Acts::LayerCreator::discLayer( // create the shared disc bounds auto dBounds = std::make_shared( - protoLayer.min(BinningValue::binR), protoLayer.max(BinningValue::binR)); + protoLayer.min(AxisDirection::AxisR), + protoLayer.max(AxisDirection::AxisR)); // create the layers MutableLayerPtr dLayer = @@ -327,7 +329,7 @@ Acts::MutableLayerPtr Acts::LayerCreator::discLayer( Acts::MutableLayerPtr Acts::LayerCreator::planeLayer( const GeometryContext& gctx, std::vector> surfaces, std::size_t bins1, - std::size_t bins2, BinningValue bValue, + std::size_t bins2, AxisDirection aDir, std::optional _protoLayer, const Transform3& transform, std::unique_ptr ad) const { ProtoLayer protoLayer = @@ -335,58 +337,58 @@ Acts::MutableLayerPtr Acts::LayerCreator::planeLayer( // remaining layer parameters double layerHalf1 = 0, layerHalf2 = 0, layerThickness = 0; - switch (bValue) { - case BinningValue::binX: { - layerHalf1 = 0.5 * (protoLayer.max(BinningValue::binY) - - protoLayer.min(BinningValue::binY)); - layerHalf2 = 0.5 * (protoLayer.max(BinningValue::binZ) - - protoLayer.min(BinningValue::binZ)); - layerThickness = (protoLayer.max(BinningValue::binX) - - protoLayer.min(BinningValue::binX)); + switch (aDir) { + case AxisDirection::AxisX: { + layerHalf1 = 0.5 * (protoLayer.max(AxisDirection::AxisY) - + protoLayer.min(AxisDirection::AxisY)); + layerHalf2 = 0.5 * (protoLayer.max(AxisDirection::AxisZ) - + protoLayer.min(AxisDirection::AxisZ)); + layerThickness = (protoLayer.max(AxisDirection::AxisX) - + protoLayer.min(AxisDirection::AxisX)); break; } - case BinningValue::binY: { - layerHalf1 = 0.5 * (protoLayer.max(BinningValue::binX) - - protoLayer.min(BinningValue::binX)); - layerHalf2 = 0.5 * (protoLayer.max(BinningValue::binZ) - - protoLayer.min(BinningValue::binZ)); - layerThickness = (protoLayer.max(BinningValue::binY) - - protoLayer.min(BinningValue::binY)); + case AxisDirection::AxisY: { + layerHalf1 = 0.5 * (protoLayer.max(AxisDirection::AxisX) - + protoLayer.min(AxisDirection::AxisX)); + layerHalf2 = 0.5 * (protoLayer.max(AxisDirection::AxisZ) - + protoLayer.min(AxisDirection::AxisZ)); + layerThickness = (protoLayer.max(AxisDirection::AxisY) - + protoLayer.min(AxisDirection::AxisY)); break; } - case BinningValue::binZ: { - layerHalf1 = 0.5 * (protoLayer.max(BinningValue::binX) - - protoLayer.min(BinningValue::binX)); - layerHalf2 = 0.5 * (protoLayer.max(BinningValue::binY) - - protoLayer.min(BinningValue::binY)); - layerThickness = (protoLayer.max(BinningValue::binZ) - - protoLayer.min(BinningValue::binZ)); + case AxisDirection::AxisZ: { + layerHalf1 = 0.5 * (protoLayer.max(AxisDirection::AxisX) - + protoLayer.min(AxisDirection::AxisX)); + layerHalf2 = 0.5 * (protoLayer.max(AxisDirection::AxisY) - + protoLayer.min(AxisDirection::AxisY)); + layerThickness = (protoLayer.max(AxisDirection::AxisZ) - + protoLayer.min(AxisDirection::AxisZ)); break; } default: throw std::invalid_argument("Invalid binning value"); } - double centerX = 0.5 * (protoLayer.max(BinningValue::binX) + - protoLayer.min(BinningValue::binX)); - double centerY = 0.5 * (protoLayer.max(BinningValue::binY) + - protoLayer.min(BinningValue::binY)); - double centerZ = 0.5 * (protoLayer.max(BinningValue::binZ) + - protoLayer.min(BinningValue::binZ)); + double centerX = 0.5 * (protoLayer.max(AxisDirection::AxisX) + + protoLayer.min(AxisDirection::AxisX)); + double centerY = 0.5 * (protoLayer.max(AxisDirection::AxisY) + + protoLayer.min(AxisDirection::AxisY)); + double centerZ = 0.5 * (protoLayer.max(AxisDirection::AxisZ) + + protoLayer.min(AxisDirection::AxisZ)); ACTS_VERBOSE("Creating a plane Layer:"); ACTS_VERBOSE(" - with layer center = " << "(" << centerX << ", " << centerY << ", " << centerZ << ")"); - ACTS_VERBOSE(" - from X min/max = " << protoLayer.min(BinningValue::binX) - << " / " - << protoLayer.max(BinningValue::binX)); - ACTS_VERBOSE(" - from Y min/max = " << protoLayer.min(BinningValue::binY) - << " / " - << protoLayer.max(BinningValue::binY)); + ACTS_VERBOSE(" - from X min/max = " + << protoLayer.min(AxisDirection::AxisX) << " / " + << protoLayer.max(AxisDirection::AxisX)); + ACTS_VERBOSE(" - from Y min/max = " + << protoLayer.min(AxisDirection::AxisY) << " / " + << protoLayer.max(AxisDirection::AxisY)); ACTS_VERBOSE(" - with Z thickness = " << layerThickness); - ACTS_VERBOSE(" - incl envelope = " << protoLayer.envelope[bValue][0u] + ACTS_VERBOSE(" - incl envelope = " << protoLayer.envelope[aDir][0u] << " / " - << protoLayer.envelope[bValue][1u]); + << protoLayer.envelope[aDir][1u]); // create the layer transforms if not given // we need to transform in case centerX/centerY/centerZ != 0, so that the @@ -401,7 +403,7 @@ Acts::MutableLayerPtr Acts::LayerCreator::planeLayer( std::unique_ptr sArray; if (!surfaces.empty()) { sArray = m_cfg.surfaceArrayCreator->surfaceArrayOnPlane( - gctx, std::move(surfaces), bins1, bins2, bValue, protoLayer, transform); + gctx, std::move(surfaces), bins1, bins2, aDir, protoLayer, transform); checkBinning(gctx, *sArray); } @@ -488,8 +490,8 @@ bool Acts::LayerCreator::checkBinning(const GeometryContext& gctx, // print all inaccessibles ACTS_ERROR(" -- Inaccessible surfaces: "); for (const auto& srf : diff) { - // have to choose BinningValue here - Vector3 ctr = srf->binningPosition(gctx, BinningValue::binR); + // have to choose AxisDirection here + Vector3 ctr = srf->referencePosition(gctx, AxisDirection::AxisR); ACTS_ERROR(" Surface(x=" << ctr.x() << ", y=" << ctr.y() << ", z=" << ctr.z() << ", r=" << perp(ctr) << ", phi=" << phi(ctr) << ")"); diff --git a/Core/src/Geometry/MaterialDesignatorBlueprintNode.cpp b/Core/src/Geometry/MaterialDesignatorBlueprintNode.cpp index 0e89b65d6e3..4bf4c3f8445 100644 --- a/Core/src/Geometry/MaterialDesignatorBlueprintNode.cpp +++ b/Core/src/Geometry/MaterialDesignatorBlueprintNode.cpp @@ -56,23 +56,23 @@ void MaterialDesignatorBlueprintNode::handleCylinderBinning( for (auto& [face, loc0, loc1] : binning) { if (face == OuterCylinder || face == InnerCylinder) { - if (loc0.binValue != BinningValue::binRPhi) { + if (loc0.axisDir != AxisDirection::AxisRPhi) { ACTS_ERROR(prefix() << "Binning is not in RPhi"); throw std::runtime_error("Binning is not in RPhi"); } - if (loc1.binValue != BinningValue::binZ) { + if (loc1.axisDir != AxisDirection::AxisZ) { ACTS_ERROR(prefix() << "Binning is not in Z"); throw std::runtime_error("Binning is not in Z"); } } if (face == PositiveDisc || face == NegativeDisc) { - if (loc0.binValue != BinningValue::binR) { + if (loc0.axisDir != AxisDirection::AxisR) { ACTS_ERROR(prefix() << "Binning is not in R"); throw std::runtime_error("Binning is not in R"); } - if (loc1.binValue != BinningValue::binPhi) { + if (loc1.axisDir != AxisDirection::AxisPhi) { ACTS_ERROR(prefix() << "Binning is not in Phi"); throw std::runtime_error("Binning is not in Phi"); } @@ -164,8 +164,8 @@ void MaterialDesignatorBlueprintNode::addToGraphviz(std::ostream& os) const { Experimental::ProtoBinning>>& binning) { for (const auto& [face, loc0, loc1] : binning) { ss << "
" << face; - ss << ": " << loc0.binValue << "=" << loc0.bins(); - ss << ", " << loc1.binValue << "=" << loc1.bins(); + ss << ": " << loc0.axisDir << "=" << loc0.bins(); + ss << ", " << loc1.axisDir << "=" << loc1.bins(); } }, [](const auto& /*binning*/) { diff --git a/Core/src/Geometry/Polyhedron.cpp b/Core/src/Geometry/Polyhedron.cpp index 5f7336ca3fc..38d9a44d3b1 100644 --- a/Core/src/Geometry/Polyhedron.cpp +++ b/Core/src/Geometry/Polyhedron.cpp @@ -50,11 +50,11 @@ Acts::Extent Acts::Polyhedron::extent(const Transform3& transform) const { return (vt); }); - // Special checks of BinningValue::binR for hyper plane surfaces + // Special checks of AxisDirection::AxisR for hyper plane surfaces if (detail::VerticesHelper::onHyperPlane(vtxs)) { // Check inclusion of origin (i.e. convex around origin) Vector3 origin = - transform * Vector3(0., 0., extent.medium(BinningValue::binZ)); + transform * Vector3(0., 0., extent.medium(AxisDirection::AxisZ)); for (const auto& face : faces) { std::vector tface; tface.reserve(face.size()); @@ -62,8 +62,8 @@ Acts::Extent Acts::Polyhedron::extent(const Transform3& transform) const { tface.push_back(vtxs[f]); } if (detail::VerticesHelper::isInsidePolygon(origin, tface)) { - extent.range(BinningValue::binR).setMin(0.); - extent.range(BinningValue::binPhi) + extent.range(AxisDirection::AxisR).setMin(0.); + extent.range(AxisDirection::AxisPhi) .set(-std::numbers::pi, std::numbers::pi); break; } @@ -93,7 +93,7 @@ Acts::Extent Acts::Polyhedron::extent(const Transform3& transform) const { for (std::size_t iv = 1; iv < vtxs.size() + 1; ++iv) { std::size_t fpoint = iv < vtxs.size() ? iv : 0; double testR = radialDistance(vtxs[fpoint], vtxs[iv - 1]); - extent.range(BinningValue::binR).expandMin(testR); + extent.range(AxisDirection::AxisR).expandMin(testR); } } } diff --git a/Core/src/Geometry/Portal.cpp b/Core/src/Geometry/Portal.cpp index 69cab13b8e0..b667b566cca 100644 --- a/Core/src/Geometry/Portal.cpp +++ b/Core/src/Geometry/Portal.cpp @@ -40,7 +40,7 @@ Portal::Portal(Direction direction, std::unique_ptr link) { m_surface = link->surfacePtr(); - if (direction == Direction::AlongNormal) { + if (direction == Direction::AlongNormal()) { m_alongNormal = std::move(link); } else { m_oppositeNormal = std::move(link); @@ -60,10 +60,10 @@ Portal::Portal(const GeometryContext& gctx, } if (alongNormal != nullptr) { - setLink(gctx, Direction::AlongNormal, std::move(alongNormal)); + setLink(gctx, Direction::AlongNormal(), std::move(alongNormal)); } if (oppositeNormal != nullptr) { - setLink(gctx, Direction::OppositeNormal, std::move(oppositeNormal)); + setLink(gctx, Direction::OppositeNormal(), std::move(oppositeNormal)); } } @@ -73,12 +73,12 @@ Portal::Portal(const GeometryContext& gctx, Arguments&& args) { } if (args.alongNormal.surface) { - setLink(gctx, Direction::AlongNormal, + setLink(gctx, Direction::AlongNormal(), std::make_unique( std::move(args.alongNormal.surface), *args.alongNormal.volume)); } if (args.oppositeNormal.surface) { - setLink(gctx, Direction::OppositeNormal, + setLink(gctx, Direction::OppositeNormal(), std::make_unique( std::move(args.oppositeNormal.surface), *args.oppositeNormal.volume)); @@ -92,9 +92,9 @@ void Portal::setLink(const GeometryContext& gctx, Direction direction, } auto& target = - direction == Direction::AlongNormal ? m_alongNormal : m_oppositeNormal; + direction == Direction::AlongNormal() ? m_alongNormal : m_oppositeNormal; const auto& other = - direction == Direction::AlongNormal ? m_oppositeNormal : m_alongNormal; + direction == Direction::AlongNormal() ? m_oppositeNormal : m_alongNormal; // check if surfaces are identical if (m_surface != nullptr && @@ -136,7 +136,7 @@ void Portal::setLink(const GeometryContext& gctx, Direction direction, } const PortalLinkBase* Portal::getLink(Direction direction) const { - if (direction == Direction::AlongNormal) { + if (direction == Direction::AlongNormal()) { return m_alongNormal.get(); } else { return m_oppositeNormal.get(); @@ -150,7 +150,7 @@ Result Portal::resolveVolume( const Vector3 normal = m_surface->normal(gctx, position); Direction side = Direction::fromScalarZeroAsPositive(normal.dot(direction)); - const PortalLinkBase* link = side == Direction::AlongNormal + const PortalLinkBase* link = side == Direction::AlongNormal() ? m_alongNormal.get() : m_oppositeNormal.get(); @@ -182,7 +182,7 @@ RegularSurface& Portal::surface() { } Portal Portal::merge(const GeometryContext& gctx, Portal& aPortal, - Portal& bPortal, BinningValue direction, + Portal& bPortal, AxisDirection direction, const Logger& logger) { ACTS_VERBOSE("Merging two portals along " << direction); diff --git a/Core/src/Geometry/PortalLinkBase.cpp b/Core/src/Geometry/PortalLinkBase.cpp index f558fe19238..58560103633 100644 --- a/Core/src/Geometry/PortalLinkBase.cpp +++ b/Core/src/Geometry/PortalLinkBase.cpp @@ -14,6 +14,7 @@ #include "Acts/Surfaces/CylinderSurface.hpp" #include "Acts/Surfaces/DiscSurface.hpp" #include "Acts/Surfaces/RadialBounds.hpp" +#include "Acts/Surfaces/RectangleBounds.hpp" #include "Acts/Surfaces/RegularSurface.hpp" #include "Acts/Utilities/ThrowAssert.hpp" @@ -21,7 +22,7 @@ namespace Acts { void PortalLinkBase::checkMergePreconditions(const PortalLinkBase& a, const PortalLinkBase& b, - BinningValue direction) { + AxisDirection direction) { const auto& surfaceA = a.surface(); const auto& surfaceB = b.surface(); @@ -40,22 +41,34 @@ void PortalLinkBase::checkMergePreconditions(const PortalLinkBase& a, throw_assert(cylB != nullptr, "Cannot merge CylinderSurface with " "non-CylinderSurface"); - throw_assert( - direction == BinningValue::binZ || direction == BinningValue::binRPhi, - "Invalid binning direction: " + binningValueName(direction)); + throw_assert(direction == AxisDirection::AxisZ || + direction == AxisDirection::AxisRPhi, + "Invalid binning direction: " + axisDirectionName(direction)); } else if (const auto* discA = dynamic_cast(&surfaceA); discA != nullptr) { const auto* discB = dynamic_cast(&surfaceB); throw_assert(discB != nullptr, "Cannot merge DiscSurface with non-DiscSurface"); - throw_assert( - direction == BinningValue::binR || direction == BinningValue::binPhi, - "Invalid binning direction: " + binningValueName(direction)); + throw_assert(direction == AxisDirection::AxisR || + direction == AxisDirection::AxisPhi, + "Invalid binning direction: " + axisDirectionName(direction)); throw_assert(dynamic_cast(&discA->bounds()) && dynamic_cast(&discB->bounds()), "DiscSurface bounds must be RadialBounds"); + } else if (const auto* planeA = dynamic_cast(&surfaceA); + planeA != nullptr) { + const auto* planeB = dynamic_cast(&surfaceB); + throw_assert(planeB != nullptr, + "Cannot merge PlaneSurface with non-PlaneSurface"); + throw_assert( + direction == AxisDirection::AxisX || direction == AxisDirection::AxisY, + "Invalid binning direction: " + axisDirectionName(direction)); + + throw_assert(dynamic_cast(&planeA->bounds()) && + dynamic_cast(&planeB->bounds()), + "PlaneSurface bounds must be RectangleBounds"); } else { throw std::logic_error{"Surface type is not supported"}; } @@ -63,7 +76,7 @@ void PortalLinkBase::checkMergePreconditions(const PortalLinkBase& a, std::unique_ptr PortalLinkBase::merge( std::unique_ptr a, std::unique_ptr b, - BinningValue direction, const Logger& logger) { + AxisDirection direction, const Logger& logger) { ACTS_VERBOSE("Merging two arbitrary portals"); ACTS_VERBOSE(" - a: " << *a); diff --git a/Core/src/Geometry/PortalShell.cpp b/Core/src/Geometry/PortalShell.cpp index 5b2d8e167c8..dbd9e4e8e0d 100644 --- a/Core/src/Geometry/PortalShell.cpp +++ b/Core/src/Geometry/PortalShell.cpp @@ -134,7 +134,7 @@ std::string SingleCylinderPortalShell::label() const { CylinderStackPortalShell::CylinderStackPortalShell( const GeometryContext& gctx, std::vector shells, - BinningValue direction, const Logger& logger) + AxisDirection direction, const Logger& logger) : m_direction{direction}, m_shells{std::move(shells)} { ACTS_VERBOSE("Making cylinder stack shell in " << m_direction << " direction"); @@ -198,7 +198,7 @@ CylinderStackPortalShell::CylinderStackPortalShell( } }; - if (direction == BinningValue::binR) { + if (direction == AxisDirection::AxisR) { ACTS_VERBOSE("Merging portals at positive and negative discs"); merge(PositiveDisc); merge(NegativeDisc); @@ -206,7 +206,7 @@ CylinderStackPortalShell::CylinderStackPortalShell( ACTS_VERBOSE("Fusing portals at outer and inner cylinders"); fuse(OuterCylinder, InnerCylinder); - } else if (direction == BinningValue::binZ) { + } else if (direction == AxisDirection::AxisZ) { bool allHaveInnerCylinders = std::ranges::all_of( m_shells, [](const auto* shell) { return shell->size() == 4; }); @@ -250,7 +250,7 @@ Portal* CylinderStackPortalShell::portal(Face face) { } std::shared_ptr CylinderStackPortalShell::portalPtr(Face face) { - if (m_direction == BinningValue::binR) { + if (m_direction == AxisDirection::AxisR) { switch (face) { case NegativeDisc: return m_shells.front()->portalPtr(NegativeDisc); @@ -296,7 +296,7 @@ void CylinderStackPortalShell::setPortal(std::shared_ptr portal, Face face) { assert(portal != nullptr); - if (m_direction == BinningValue::binR) { + if (m_direction == AxisDirection::AxisR) { switch (face) { case NegativeDisc: [[fallthrough]]; diff --git a/Core/src/Geometry/ProtoLayer.cpp b/Core/src/Geometry/ProtoLayer.cpp index c8f190d4293..2956e6a2788 100644 --- a/Core/src/Geometry/ProtoLayer.cpp +++ b/Core/src/Geometry/ProtoLayer.cpp @@ -44,26 +44,26 @@ ProtoLayer::ProtoLayer(const GeometryContext& gctx, measure(gctx, m_surfaces); } -double ProtoLayer::min(BinningValue bval, bool addenv) const { +double ProtoLayer::min(AxisDirection aDir, bool addenv) const { if (addenv) { - return extent.min(bval) - envelope[bval][0u]; + return extent.min(aDir) - envelope[aDir][0u]; } - return extent.min(bval); + return extent.min(aDir); } -double ProtoLayer::max(BinningValue bval, bool addenv) const { +double ProtoLayer::max(AxisDirection aDir, bool addenv) const { if (addenv) { - return extent.max(bval) + envelope[bval][1u]; + return extent.max(aDir) + envelope[aDir][1u]; } - return extent.max(bval); + return extent.max(aDir); } -double ProtoLayer::medium(BinningValue bval, bool addenv) const { - return 0.5 * (min(bval, addenv) + max(bval, addenv)); +double ProtoLayer::medium(AxisDirection aDir, bool addenv) const { + return 0.5 * (min(aDir, addenv) + max(aDir, addenv)); } -double ProtoLayer::range(BinningValue bval, bool addenv) const { - return std::abs(max(bval, addenv) - min(bval, addenv)); +double ProtoLayer::range(AxisDirection aDir, bool addenv) const { + return std::abs(max(aDir, addenv) - min(aDir, addenv)); } std::ostream& ProtoLayer::toStream(std::ostream& sl) const { diff --git a/Core/src/Geometry/ProtoLayerHelper.cpp b/Core/src/Geometry/ProtoLayerHelper.cpp index ae3dfc4896b..4a779988e9c 100644 --- a/Core/src/Geometry/ProtoLayerHelper.cpp +++ b/Core/src/Geometry/ProtoLayerHelper.cpp @@ -69,7 +69,7 @@ std::vector Acts::ProtoLayerHelper::protoLayers( std::vector> sortSurfaces = {surfaces}; for (const auto& sorting : sortings) { ACTS_VERBOSE("-> Sorting a set of " << sortSurfaces.size() << " in " - << binningValueName(sorting.first)); + << axisDirectionName(sorting.first)); std::vector> subSurfaces; for (const auto& ssurfaces : sortSurfaces) { ACTS_VERBOSE("-> Surfaces for this sorting step: " << ssurfaces.size()); diff --git a/Core/src/Geometry/SurfaceArrayCreator.cpp b/Core/src/Geometry/SurfaceArrayCreator.cpp index 3ec85b020f6..514618281b3 100644 --- a/Core/src/Geometry/SurfaceArrayCreator.cpp +++ b/Core/src/Geometry/SurfaceArrayCreator.cpp @@ -44,12 +44,13 @@ Acts::SurfaceArrayCreator::surfaceArrayOnCylinder( << binsPhi * binsZ << " bins."); Transform3 ftransform = transform; - ProtoAxis pAxisPhi = createEquidistantAxis( - gctx, surfacesRaw, BinningValue::binPhi, protoLayer, ftransform, binsPhi); + ProtoAxis pAxisPhi = + createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisPhi, + protoLayer, ftransform, binsPhi); ProtoAxis pAxisZ = createEquidistantAxis( - gctx, surfacesRaw, BinningValue::binZ, protoLayer, ftransform, binsZ); + gctx, surfacesRaw, AxisDirection::AxisZ, protoLayer, ftransform, binsZ); - double R = protoLayer.medium(BinningValue::binR, true); + double R = protoLayer.medium(AxisDirection::AxisR, true); Transform3 itransform = ftransform.inverse(); // Transform lambda captures the transform matrix @@ -85,7 +86,7 @@ Acts::SurfaceArrayCreator::surfaceArrayOnCylinder( ProtoLayer protoLayer = protoLayerOpt ? *protoLayerOpt : ProtoLayer(gctx, surfacesRaw); - double R = protoLayer.medium(BinningValue::binR, true); + double R = protoLayer.medium(AxisDirection::AxisR, true); ProtoAxis pAxisPhi; ProtoAxis pAxisZ; @@ -93,18 +94,18 @@ Acts::SurfaceArrayCreator::surfaceArrayOnCylinder( Transform3 ftransform = transform; if (bTypePhi == equidistant) { - pAxisPhi = createEquidistantAxis(gctx, surfacesRaw, BinningValue::binPhi, + pAxisPhi = createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisPhi, protoLayer, ftransform, 0); } else { - pAxisPhi = createVariableAxis(gctx, surfacesRaw, BinningValue::binPhi, + pAxisPhi = createVariableAxis(gctx, surfacesRaw, AxisDirection::AxisPhi, protoLayer, ftransform); } if (bTypeZ == equidistant) { - pAxisZ = createEquidistantAxis(gctx, surfacesRaw, BinningValue::binZ, + pAxisZ = createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisZ, protoLayer, ftransform); } else { - pAxisZ = createVariableAxis(gctx, surfacesRaw, BinningValue::binZ, + pAxisZ = createVariableAxis(gctx, surfacesRaw, AxisDirection::AxisZ, protoLayer, ftransform); } @@ -155,11 +156,12 @@ Acts::SurfaceArrayCreator::surfaceArrayOnDisc( Transform3 ftransform = transform; ProtoAxis pAxisR = createEquidistantAxis( - gctx, surfacesRaw, BinningValue::binR, protoLayer, ftransform, binsR); - ProtoAxis pAxisPhi = createEquidistantAxis( - gctx, surfacesRaw, BinningValue::binPhi, protoLayer, ftransform, binsPhi); + gctx, surfacesRaw, AxisDirection::AxisR, protoLayer, ftransform, binsR); + ProtoAxis pAxisPhi = + createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisPhi, + protoLayer, ftransform, binsPhi); - double Z = protoLayer.medium(BinningValue::binZ, true); + double Z = protoLayer.medium(AxisDirection::AxisZ, true); ACTS_VERBOSE("- z-position of disk estimated as " << Z); Transform3 itransform = transform.inverse(); @@ -212,10 +214,10 @@ Acts::SurfaceArrayCreator::surfaceArrayOnDisc( Transform3 ftransform = transform; if (bTypeR == equidistant) { - pAxisR = createEquidistantAxis(gctx, surfacesRaw, BinningValue::binR, + pAxisR = createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisR, protoLayer, ftransform); } else { - pAxisR = createVariableAxis(gctx, surfacesRaw, BinningValue::binR, + pAxisR = createVariableAxis(gctx, surfacesRaw, AxisDirection::AxisR, protoLayer, ftransform); } @@ -226,7 +228,7 @@ Acts::SurfaceArrayCreator::surfaceArrayOnDisc( // this FORCES equidistant binning std::vector> phiModules(pAxisR.nBins); for (const auto& srf : surfacesRaw) { - Vector3 bpos = srf->binningPosition(gctx, BinningValue::binR); + Vector3 bpos = srf->referencePosition(gctx, AxisDirection::AxisR); std::size_t bin = pAxisR.getBin(perp(bpos)); phiModules.at(bin).push_back(srf); } @@ -234,7 +236,7 @@ Acts::SurfaceArrayCreator::surfaceArrayOnDisc( std::vector nPhiModules; auto matcher = m_cfg.surfaceMatcher; auto equal = [&gctx, &matcher](const Surface* a, const Surface* b) { - return matcher(gctx, BinningValue::binPhi, a, b); + return matcher(gctx, AxisDirection::AxisPhi, a, b); }; std::transform( @@ -252,21 +254,21 @@ Acts::SurfaceArrayCreator::surfaceArrayOnDisc( // @TODO: check in extrapolation std::size_t nBinsPhi = (*std::min_element(nPhiModules.begin(), nPhiModules.end())); - pAxisPhi = createEquidistantAxis(gctx, surfacesRaw, BinningValue::binPhi, + pAxisPhi = createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisPhi, protoLayer, ftransform, nBinsPhi); } else { // use regular determination if (bTypePhi == equidistant) { - pAxisPhi = createEquidistantAxis(gctx, surfacesRaw, BinningValue::binPhi, - protoLayer, ftransform, 0); + pAxisPhi = createEquidistantAxis( + gctx, surfacesRaw, AxisDirection::AxisPhi, protoLayer, ftransform, 0); } else { - pAxisPhi = createVariableAxis(gctx, surfacesRaw, BinningValue::binPhi, + pAxisPhi = createVariableAxis(gctx, surfacesRaw, AxisDirection::AxisPhi, protoLayer, ftransform); } } - double Z = protoLayer.medium(BinningValue::binZ, true); + double Z = protoLayer.medium(AxisDirection::AxisZ, true); ACTS_VERBOSE("- z-position of disk estimated as " << Z); Transform3 itransform = ftransform.inverse(); @@ -306,7 +308,7 @@ std::unique_ptr Acts::SurfaceArrayCreator::surfaceArrayOnPlane( const GeometryContext& gctx, std::vector> surfaces, std::size_t bins1, - std::size_t bins2, BinningValue bValue, + std::size_t bins2, AxisDirection aDir, std::optional protoLayerOpt, const Transform3& transform) const { std::vector surfacesRaw = unpack_shared_vector(surfaces); @@ -332,32 +334,38 @@ Acts::SurfaceArrayCreator::surfaceArrayOnPlane( std::unique_ptr sl; // Axis along the binning - switch (bValue) { - case BinningValue::binX: { - ProtoAxis pAxis1 = createEquidistantAxis( - gctx, surfacesRaw, BinningValue::binY, protoLayer, ftransform, bins1); - ProtoAxis pAxis2 = createEquidistantAxis( - gctx, surfacesRaw, BinningValue::binZ, protoLayer, ftransform, bins2); + switch (aDir) { + case AxisDirection::AxisX: { + ProtoAxis pAxis1 = + createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisY, + protoLayer, ftransform, bins1); + ProtoAxis pAxis2 = + createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisZ, + protoLayer, ftransform, bins2); sl = makeSurfaceGridLookup2D( globalToLocal, localToGlobal, pAxis1, pAxis2); break; } - case BinningValue::binY: { - ProtoAxis pAxis1 = createEquidistantAxis( - gctx, surfacesRaw, BinningValue::binX, protoLayer, ftransform, bins1); - ProtoAxis pAxis2 = createEquidistantAxis( - gctx, surfacesRaw, BinningValue::binZ, protoLayer, ftransform, bins2); + case AxisDirection::AxisY: { + ProtoAxis pAxis1 = + createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisX, + protoLayer, ftransform, bins1); + ProtoAxis pAxis2 = + createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisZ, + protoLayer, ftransform, bins2); sl = makeSurfaceGridLookup2D( globalToLocal, localToGlobal, pAxis1, pAxis2); break; } - case BinningValue::binZ: { - ProtoAxis pAxis1 = createEquidistantAxis( - gctx, surfacesRaw, BinningValue::binX, protoLayer, ftransform, bins1); - ProtoAxis pAxis2 = createEquidistantAxis( - gctx, surfacesRaw, BinningValue::binY, protoLayer, ftransform, bins2); + case AxisDirection::AxisZ: { + ProtoAxis pAxis1 = + createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisX, + protoLayer, ftransform, bins1); + ProtoAxis pAxis2 = + createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisY, + protoLayer, ftransform, bins2); sl = makeSurfaceGridLookup2D( globalToLocal, localToGlobal, pAxis1, pAxis2); @@ -401,10 +409,10 @@ std::vector Acts::SurfaceArrayCreator::findKeySurfaces( std::size_t Acts::SurfaceArrayCreator::determineBinCount( const GeometryContext& gctx, const std::vector& surfaces, - BinningValue bValue) const { + AxisDirection aDir) const { auto matcher = m_cfg.surfaceMatcher; - auto equal = [&gctx, &bValue, &matcher](const Surface* a, const Surface* b) { - return matcher(gctx, bValue, a, b); + auto equal = [&gctx, &aDir, &matcher](const Surface* a, const Surface* b) { + return matcher(gctx, aDir, a, b); }; std::vector keys = findKeySurfaces(surfaces, equal); @@ -414,7 +422,7 @@ std::size_t Acts::SurfaceArrayCreator::determineBinCount( Acts::SurfaceArrayCreator::ProtoAxis Acts::SurfaceArrayCreator::createVariableAxis( const GeometryContext& gctx, const std::vector& surfaces, - BinningValue bValue, const ProtoLayer& protoLayer, + AxisDirection aDir, const ProtoLayer& protoLayer, Transform3& transform) const { if (surfaces.empty()) { throw std::logic_error( @@ -426,44 +434,45 @@ Acts::SurfaceArrayCreator::createVariableAxis( // bind matcher with binning type auto matcher = m_cfg.surfaceMatcher; // find the key surfaces - auto equal = [&gctx, &bValue, &matcher](const Surface* a, const Surface* b) { - return matcher(gctx, bValue, a, b); + auto equal = [&gctx, &aDir, &matcher](const Surface* a, const Surface* b) { + return matcher(gctx, aDir, a, b); }; std::vector keys = findKeySurfaces(surfaces, equal); - std::vector bValues; - if (bValue == Acts::BinningValue::binPhi) { + std::vector aDirs; + if (aDir == Acts::AxisDirection::AxisPhi) { std::stable_sort( keys.begin(), keys.end(), [&gctx](const Acts::Surface* a, const Acts::Surface* b) { - return (phi(a->binningPosition(gctx, BinningValue::binPhi)) < - phi(b->binningPosition(gctx, BinningValue::binPhi))); + return (phi(a->referencePosition(gctx, AxisDirection::AxisPhi)) < + phi(b->referencePosition(gctx, AxisDirection::AxisPhi))); }); AxisScalar maxPhi = - 0.5 * (phi(keys.at(0)->binningPosition(gctx, BinningValue::binPhi)) + - phi(keys.at(1)->binningPosition(gctx, BinningValue::binPhi))); + 0.5 * + (phi(keys.at(0)->referencePosition(gctx, AxisDirection::AxisPhi)) + + phi(keys.at(1)->referencePosition(gctx, AxisDirection::AxisPhi))); // create rotation, so that maxPhi is +pi AxisScalar angle = -(std::numbers::pi + maxPhi); transform = (transform)*AngleAxis3(angle, Vector3::UnitZ()); - // iterate over all key surfaces, and use their mean position as bValues, + // iterate over all key surfaces, and use their mean position as aDirs, // but // rotate using transform from before AxisScalar previous = - phi(keys.at(0)->binningPosition(gctx, BinningValue::binPhi)); + phi(keys.at(0)->referencePosition(gctx, AxisDirection::AxisPhi)); // go through key surfaces for (std::size_t i = 1; i < keys.size(); i++) { const Surface* surface = keys.at(i); // create central binning values which is the mean of the center // positions in the binning direction of the current and previous // surface - AxisScalar edge = 0.5 * (previous + phi(surface->binningPosition( - gctx, BinningValue::binPhi))) + + AxisScalar edge = 0.5 * (previous + phi(surface->referencePosition( + gctx, AxisDirection::AxisPhi))) + angle; - bValues.push_back(edge); - previous = phi(surface->binningPosition(gctx, BinningValue::binPhi)); + aDirs.push_back(edge); + previous = phi(surface->referencePosition(gctx, AxisDirection::AxisPhi)); } // segments @@ -487,71 +496,73 @@ Acts::SurfaceArrayCreator::createVariableAxis( return phi(a) < phi(b); })); - bValues.push_back(maxBValue); + aDirs.push_back(maxBValue); - bValues.push_back(std::numbers::pi_v); + aDirs.push_back(std::numbers::pi_v); - } else if (bValue == Acts::BinningValue::binZ) { + } else if (aDir == Acts::AxisDirection::AxisZ) { std::stable_sort( keys.begin(), keys.end(), [&gctx](const Acts::Surface* a, const Acts::Surface* b) { - return (a->binningPosition(gctx, BinningValue::binZ).z() < - b->binningPosition(gctx, BinningValue::binZ).z()); + return (a->referencePosition(gctx, AxisDirection::AxisZ).z() < + b->referencePosition(gctx, AxisDirection::AxisZ).z()); }); - bValues.push_back(protoLayer.min(BinningValue::binZ)); - bValues.push_back(protoLayer.max(BinningValue::binZ)); + aDirs.push_back(protoLayer.min(AxisDirection::AxisZ)); + aDirs.push_back(protoLayer.max(AxisDirection::AxisZ)); // the z-center position of the previous surface AxisScalar previous = - keys.front()->binningPosition(gctx, BinningValue::binZ).z(); + keys.front()->referencePosition(gctx, AxisDirection::AxisZ).z(); // go through key surfaces for (auto surface = keys.begin() + 1; surface != keys.end(); surface++) { // create central binning values which is the mean of the center // positions in the binning direction of the current and previous // surface - bValues.push_back( - 0.5 * (previous + - (*surface)->binningPosition(gctx, BinningValue::binZ).z())); - previous = (*surface)->binningPosition(gctx, BinningValue::binZ).z(); + aDirs.push_back( + 0.5 * + (previous + + (*surface)->referencePosition(gctx, AxisDirection::AxisZ).z())); + previous = (*surface)->referencePosition(gctx, AxisDirection::AxisZ).z(); } - } else { // BinningValue::binR + } else { // AxisDirection::AxisR std::stable_sort( keys.begin(), keys.end(), [&gctx](const Acts::Surface* a, const Acts::Surface* b) { - return (perp(a->binningPosition(gctx, BinningValue::binR)) < - perp(b->binningPosition(gctx, BinningValue::binR))); + return (perp(a->referencePosition(gctx, AxisDirection::AxisR)) < + perp(b->referencePosition(gctx, AxisDirection::AxisR))); }); - bValues.push_back(protoLayer.min(BinningValue::binR)); - bValues.push_back(protoLayer.max(BinningValue::binR)); + aDirs.push_back(protoLayer.min(AxisDirection::AxisR)); + aDirs.push_back(protoLayer.max(AxisDirection::AxisR)); // the r-center position of the previous surface AxisScalar previous = - perp(keys.front()->binningPosition(gctx, BinningValue::binR)); + perp(keys.front()->referencePosition(gctx, AxisDirection::AxisR)); // go through key surfaces for (auto surface = keys.begin() + 1; surface != keys.end(); surface++) { // create central binning values which is the mean of the center // positions in the binning direction of the current and previous // surface - bValues.push_back(0.5 * (previous + perp((*surface)->binningPosition( - gctx, BinningValue::binR)))); - previous = perp((*surface)->binningPosition(gctx, BinningValue::binR)); + aDirs.push_back(0.5 * (previous + perp((*surface)->referencePosition( + gctx, AxisDirection::AxisR)))); + previous = + perp((*surface)->referencePosition(gctx, AxisDirection::AxisR)); } } - std::ranges::sort(bValues); + std::ranges::sort(aDirs); ACTS_VERBOSE("Create variable binning Axis for binned SurfaceArray"); - ACTS_VERBOSE(" BinningValue: " << bValue); - ACTS_VERBOSE(" Number of bins: " << (bValues.size() - 1)); - ACTS_VERBOSE(" (Min/Max) = (" << bValues.front() << "/" - << bValues.back() << ")"); + ACTS_VERBOSE(" AxisDirection: " << aDir); + ACTS_VERBOSE(" Number of bins: " << (aDirs.size() - 1)); + ACTS_VERBOSE(" (Min/Max) = (" << aDirs.front() << "/" << aDirs.back() + << ")"); ProtoAxis pAxis; pAxis.bType = arbitrary; - pAxis.bValue = bValue; - pAxis.binEdges = bValues; - pAxis.nBins = bValues.size() - 1; + pAxis.axisDir = aDir; + pAxis.binEdges = aDirs; + pAxis.nBins = aDirs.size() - 1; return pAxis; } @@ -559,7 +570,7 @@ Acts::SurfaceArrayCreator::createVariableAxis( Acts::SurfaceArrayCreator::ProtoAxis Acts::SurfaceArrayCreator::createEquidistantAxis( const GeometryContext& gctx, const std::vector& surfaces, - BinningValue bValue, const ProtoLayer& protoLayer, Transform3& transform, + AxisDirection aDir, const ProtoLayer& protoLayer, Transform3& transform, std::size_t nBins) const { if (surfaces.empty()) { throw std::logic_error( @@ -580,7 +591,7 @@ Acts::SurfaceArrayCreator::createEquidistantAxis( std::size_t binNumber = 0; if (nBins == 0) { // determine bin count - binNumber = determineBinCount(gctx, surfaces, bValue); + binNumber = determineBinCount(gctx, surfaces, aDir); } else { // use bin count binNumber = nBins; @@ -590,7 +601,7 @@ Acts::SurfaceArrayCreator::createEquidistantAxis( auto matcher = m_cfg.surfaceMatcher; // now check the binning value - if (bValue == BinningValue::binPhi) { + if (aDir == AxisDirection::AxisPhi) { if (m_cfg.doPhiBinningOptimization) { // Phi binning // set the binning option for phi @@ -598,14 +609,14 @@ Acts::SurfaceArrayCreator::createEquidistantAxis( const Acts::Surface* maxElem = *std::max_element( surfaces.begin(), surfaces.end(), [&gctx](const Acts::Surface* a, const Acts::Surface* b) { - return phi(a->binningPosition(gctx, BinningValue::binR)) < - phi(b->binningPosition(gctx, BinningValue::binR)); + return phi(a->referencePosition(gctx, AxisDirection::AxisR)) < + phi(b->referencePosition(gctx, AxisDirection::AxisR)); }); // get the key surfaces at the different phi positions - auto equal = [&gctx, &bValue, &matcher](const Surface* a, - const Surface* b) { - return matcher(gctx, bValue, a, b); + auto equal = [&gctx, &aDir, &matcher](const Surface* a, + const Surface* b) { + return matcher(gctx, aDir, a, b); }; keys = findKeySurfaces(surfaces, equal); @@ -621,15 +632,16 @@ Acts::SurfaceArrayCreator::createEquidistantAxis( // rotate to max phi module plus one half step // this should make sure that phi wrapping at +- pi // never falls on a module center - double max = phi(maxElem->binningPosition(gctx, BinningValue::binR)); + double max = + phi(maxElem->referencePosition(gctx, AxisDirection::AxisR)); double angle = std::numbers::pi - (max + 0.5 * step); // replace given transform ref transform = (transform)*AngleAxis3(angle, Vector3::UnitZ()); } else { - minimum = protoLayer.min(BinningValue::binPhi, true); - maximum = protoLayer.max(BinningValue::binPhi, true); + minimum = protoLayer.min(AxisDirection::AxisPhi, true); + maximum = protoLayer.max(AxisDirection::AxisPhi, true); // we do not need a transform in this case } } else { @@ -637,13 +649,13 @@ Acts::SurfaceArrayCreator::createEquidistantAxis( maximum = std::numbers::pi; } } else { - maximum = protoLayer.max(bValue, false); - minimum = protoLayer.min(bValue, false); + maximum = protoLayer.max(aDir, false); + minimum = protoLayer.min(aDir, false); } // assign the bin size ACTS_VERBOSE("Create equidistant binning Axis for binned SurfaceArray"); - ACTS_VERBOSE(" BinningValue: " << bValue); + ACTS_VERBOSE(" AxisDirection: " << aDir); ACTS_VERBOSE(" Number of bins: " << binNumber); ACTS_VERBOSE(" (Min/Max) = (" << minimum << "/" << maximum << ")"); @@ -651,7 +663,7 @@ Acts::SurfaceArrayCreator::createEquidistantAxis( pAxis.max = maximum; pAxis.min = minimum; pAxis.bType = equidistant; - pAxis.bValue = bValue; + pAxis.axisDir = aDir; pAxis.nBins = binNumber; return pAxis; diff --git a/Core/src/Geometry/TrackingGeometry.cpp b/Core/src/Geometry/TrackingGeometry.cpp index f9207afbd18..d54a31dce04 100644 --- a/Core/src/Geometry/TrackingGeometry.cpp +++ b/Core/src/Geometry/TrackingGeometry.cpp @@ -8,15 +8,12 @@ #include "Acts/Geometry/TrackingGeometry.hpp" +#include "Acts/Definitions/Tolerance.hpp" #include "Acts/Geometry/GeometryIdentifier.hpp" #include "Acts/Geometry/TrackingVolume.hpp" -#include "Acts/Surfaces/PerigeeSurface.hpp" #include "Acts/Surfaces/Surface.hpp" -#include "Acts/Surfaces/SurfaceArray.hpp" -#include #include -#include Acts::TrackingGeometry::TrackingGeometry( const MutableTrackingVolumePtr& highestVolume, @@ -41,7 +38,7 @@ Acts::TrackingGeometry::~TrackingGeometry() = default; const Acts::TrackingVolume* Acts::TrackingGeometry::lowestTrackingVolume( const GeometryContext& gctx, const Acts::Vector3& gp) const { - return m_world->lowestTrackingVolume(gctx, gp); + return m_world->lowestTrackingVolume(gctx, gp, s_onSurfaceTolerance); } const Acts::TrackingVolume* Acts::TrackingGeometry::highestTrackingVolume() diff --git a/Core/src/Geometry/TrackingVolume.cpp b/Core/src/Geometry/TrackingVolume.cpp index 6d3880bd4db..ac56a59ee13 100644 --- a/Core/src/Geometry/TrackingVolume.cpp +++ b/Core/src/Geometry/TrackingVolume.cpp @@ -114,7 +114,7 @@ const TrackingVolumeBoundaries& TrackingVolume::boundarySurfaces() const { void TrackingVolume::connectDenseBoundarySurfaces( MutableTrackingVolumeVector& confinedDenseVolumes) { if (!confinedDenseVolumes.empty()) { - Direction dir = Direction::Positive; + Direction dir = Direction::Positive(); // Walk over each dense volume for (auto& confDenseVol : confinedDenseVolumes) { // Walk over each boundary surface of the volume @@ -133,12 +133,12 @@ void TrackingVolume::connectDenseBoundarySurfaces( boundSur.at(i)); if (mutableBs->m_oppositeVolume != nullptr && mutableBs->m_alongVolume == nullptr) { - dir = Direction::Positive; + dir = Direction::Positive(); mutableBs->attachVolume(this, dir); } else { if (mutableBs->m_oppositeVolume == nullptr && mutableBs->m_alongVolume != nullptr) { - dir = Direction::Negative; + dir = Direction::Negative(); mutableBs->attachVolume(this, dir); } } @@ -163,7 +163,7 @@ void TrackingVolume::createBoundarySurfaces() { for (auto& osf : orientedSurfaces) { TrackingVolume* opposite = nullptr; TrackingVolume* along = nullptr; - if (osf.direction == Direction::OppositeNormal) { + if (osf.direction == Direction::OppositeNormal()) { opposite = this; } else { along = this; @@ -177,11 +177,11 @@ void TrackingVolume::glueTrackingVolume(const GeometryContext& gctx, BoundarySurfaceFace bsfMine, TrackingVolume* neighbor, BoundarySurfaceFace bsfNeighbor) { - // Find the connection of the two tracking volumes: BinningValue::binR returns - // the center except for cylindrical volumes - Vector3 bPosition(binningPosition(gctx, BinningValue::binR)); - Vector3 distance = - Vector3(neighbor->binningPosition(gctx, BinningValue::binR) - bPosition); + // Find the connection of the two tracking volumes: AxisDirection::AxisR + // returns the center except for cylindrical volumes + Vector3 bPosition(referencePosition(gctx, AxisDirection::AxisR)); + Vector3 distance = Vector3( + neighbor->referencePosition(gctx, AxisDirection::AxisR) - bPosition); // glue to the face std::shared_ptr> bSurfaceMine = boundarySurfaces().at(bsfMine); @@ -221,13 +221,13 @@ void TrackingVolume::glueTrackingVolumes( const GeometryContext& gctx, BoundarySurfaceFace bsfMine, const std::shared_ptr& neighbors, BoundarySurfaceFace bsfNeighbor) { - // find the connection of the two tracking volumes : BinningValue::binR + // find the connection of the two tracking volumes : AxisDirection::AxisR // returns the center except for cylindrical volumes std::shared_ptr nRefVolume = neighbors->arrayObjects().at(0); // get the distance - Vector3 bPosition(binningPosition(gctx, BinningValue::binR)); - Vector3 distance(nRefVolume->binningPosition(gctx, BinningValue::binR) - + Vector3 bPosition(referencePosition(gctx, AxisDirection::AxisR)); + Vector3 distance(nRefVolume->referencePosition(gctx, AxisDirection::AxisR) - bPosition); // take the normal at the binning positio std::shared_ptr> bSurfaceMine = @@ -746,6 +746,10 @@ void TrackingVolume::visualize(IVisualization3D& helper, surface.visualize(helper, gctx, sensitiveViewConfig); } + for (const auto& portal : portals()) { + portal.surface().visualize(helper, gctx, portalViewConfig); + } + for (const auto& child : volumes()) { child.visualize(helper, gctx, viewConfig, portalViewConfig, sensitiveViewConfig); diff --git a/Core/src/Geometry/TrackingVolumeArrayCreator.cpp b/Core/src/Geometry/TrackingVolumeArrayCreator.cpp index 61727f9dee0..a280c036872 100644 --- a/Core/src/Geometry/TrackingVolumeArrayCreator.cpp +++ b/Core/src/Geometry/TrackingVolumeArrayCreator.cpp @@ -21,14 +21,14 @@ std::shared_ptr Acts::TrackingVolumeArrayCreator::trackingVolumeArray( const GeometryContext& gctx, const TrackingVolumeVector& tVolumes, - BinningValue bValue) const { + AxisDirection aDir) const { // MSG_VERBOSE("Create VolumeArray of "<< tVolumes.size() << " TrackingVolumes - // with binning in : " << binningValueName(bValue) ); + // with binning in : " << axisDirectionName(aDir) ); // let's copy and sort TrackingVolumeVector volumes(tVolumes); // sort it accordingly to the binning value GeometryObjectSorterT> volumeSorter( - gctx, bValue); + gctx, aDir); std::ranges::sort(volumes, volumeSorter); // prepare what we need : @@ -41,24 +41,23 @@ Acts::TrackingVolumeArrayCreator::trackingVolumeArray( // let's loop over the (sorted) volumes for (auto& tVolume : volumes) { // get the binning position - Vector3 binningPosition = tVolume->binningPosition(gctx, bValue); - double binningBorder = tVolume->volumeBounds().binningBorder(bValue); + Vector3 referencePosition = tVolume->referencePosition(gctx, aDir); + double referenceBorder = tVolume->volumeBounds().referenceBorder(aDir); // get the center value according to the bin - double value = tVolume->binningPositionValue(gctx, bValue); + double value = tVolume->referencePositionValue(gctx, aDir); // for the first one take low and high boundary if (boundaries.empty()) { - boundaries.push_back(value - binningBorder); + boundaries.push_back(value - referenceBorder); } // always take the high boundary - boundaries.push_back(value + binningBorder); + boundaries.push_back(value + referenceBorder); // record the volume to be ordered tVolumesOrdered.push_back( - TrackingVolumeOrderPosition(tVolume, binningPosition)); + TrackingVolumeOrderPosition(tVolume, referencePosition)); } // now create the bin utility - auto binUtility = - std::make_unique(boundaries, open, bValue); + auto binUtility = std::make_unique(boundaries, open, aDir); // and return the newly created binned array return std::make_shared>( diff --git a/Core/src/Geometry/TrapezoidVolumeBounds.cpp b/Core/src/Geometry/TrapezoidVolumeBounds.cpp index 2034ce6f302..5c96932dc04 100644 --- a/Core/src/Geometry/TrapezoidVolumeBounds.cpp +++ b/Core/src/Geometry/TrapezoidVolumeBounds.cpp @@ -74,12 +74,12 @@ std::vector TrapezoidVolumeBounds::orientedSurfaces( auto nzTransform = transform * Translation3(0., 0., -get(eHalfLengthZ)); auto sf = Surface::makeShared(nzTransform, m_faceXYTrapezoidBounds); - oSurfaces.push_back(OrientedSurface{std::move(sf), Direction::AlongNormal}); + oSurfaces.push_back(OrientedSurface{std::move(sf), Direction::AlongNormal()}); // (2) - At positive local z auto pzTransform = transform * Translation3(0., 0., get(eHalfLengthZ)); sf = Surface::makeShared(pzTransform, m_faceXYTrapezoidBounds); oSurfaces.push_back( - OrientedSurface{std::move(sf), Direction::OppositeNormal}); + OrientedSurface{std::move(sf), Direction::OppositeNormal()}); double poshOffset = get(eHalfLengthY) / std::tan(get(eAlpha)); double neghOffset = get(eHalfLengthY) / std::tan(get(eBeta)); @@ -94,7 +94,7 @@ std::vector TrapezoidVolumeBounds::orientedSurfaces( s_planeYZ; sf = Surface::makeShared(fbTransform, m_faceBetaRectangleBounds); - oSurfaces.push_back(OrientedSurface{std::move(sf), Direction::AlongNormal}); + oSurfaces.push_back(OrientedSurface{std::move(sf), Direction::AlongNormal()}); // (4) - At point A, attached to alpha opening angle Vector3 faPosition(get(eHalfLengthXnegY) + poshOffset, 0., 0.); @@ -105,7 +105,7 @@ std::vector TrapezoidVolumeBounds::orientedSurfaces( sf = Surface::makeShared(faTransform, m_faceAlphaRectangleBounds); oSurfaces.push_back( - OrientedSurface{std::move(sf), Direction::OppositeNormal}); + OrientedSurface{std::move(sf), Direction::OppositeNormal()}); // Face surfaces zx // (5) - At negative local y @@ -113,14 +113,14 @@ std::vector TrapezoidVolumeBounds::orientedSurfaces( transform * Translation3(0., -get(eHalfLengthY), 0.) * s_planeZX; sf = Surface::makeShared(nxTransform, m_faceZXRectangleBoundsBottom); - oSurfaces.push_back(OrientedSurface{std::move(sf), Direction::AlongNormal}); + oSurfaces.push_back(OrientedSurface{std::move(sf), Direction::AlongNormal()}); // (6) - At positive local y auto pxTransform = transform * Translation3(topShift, get(eHalfLengthY), 0.) * s_planeZX; sf = Surface::makeShared(pxTransform, m_faceZXRectangleBoundsTop); oSurfaces.push_back( - OrientedSurface{std::move(sf), Direction::OppositeNormal}); + OrientedSurface{std::move(sf), Direction::OppositeNormal()}); return oSurfaces; } @@ -153,7 +153,7 @@ bool TrapezoidVolumeBounds::inside(const Vector3& pos, double tol) const { } Vector2 locp(pos.x(), pos.y()); bool inside(m_faceXYTrapezoidBounds->inside( - locp, BoundaryTolerance::AbsoluteBound{tol, tol})); + locp, BoundaryTolerance::AbsoluteBound(tol, tol))); return inside; } diff --git a/Core/src/Geometry/TrivialPortalLink.cpp b/Core/src/Geometry/TrivialPortalLink.cpp index 6976388dbc0..5e3b3ad5023 100644 --- a/Core/src/Geometry/TrivialPortalLink.cpp +++ b/Core/src/Geometry/TrivialPortalLink.cpp @@ -16,7 +16,7 @@ namespace Acts { std::unique_ptr TrivialPortalLink::makeGrid( - BinningValue direction) const { + AxisDirection direction) const { return GridPortalLink::make(m_surface, *m_volume, direction); } diff --git a/Core/src/Geometry/Volume.cpp b/Core/src/Geometry/Volume.cpp index 7aac6f8b9d6..674c3123340 100644 --- a/Core/src/Geometry/Volume.cpp +++ b/Core/src/Geometry/Volume.cpp @@ -33,13 +33,13 @@ Volume::Volume(const Volume& vol, const Transform3& shift) m_center(m_transform.translation()), m_volumeBounds(vol.m_volumeBounds) {} -Vector3 Volume::binningPosition(const GeometryContext& /*gctx*/, - BinningValue bValue) const { +Vector3 Volume::referencePosition(const GeometryContext& /*gctx*/, + AxisDirection aDir) const { // for most of the binning types it is actually the center, // just for R-binning types the - if (bValue == BinningValue::binR || bValue == BinningValue::binRPhi) { + if (aDir == AxisDirection::AxisR || aDir == AxisDirection::AxisRPhi) { // the binning Position for R-type may have an offset - return (center() + m_volumeBounds->binningOffset(bValue)); + return (center() + m_volumeBounds->referenceOffset(aDir)); } // return the center return center(); diff --git a/Core/src/Geometry/VolumeAttachmentStrategy.cpp b/Core/src/Geometry/VolumeAttachmentStrategy.cpp new file mode 100644 index 00000000000..425328b7bd4 --- /dev/null +++ b/Core/src/Geometry/VolumeAttachmentStrategy.cpp @@ -0,0 +1,33 @@ +// 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/VolumeAttachmentStrategy.hpp" + +namespace Acts { +std::ostream& operator<<(std::ostream& os, VolumeAttachmentStrategy strategy) { + switch (strategy) { + case VolumeAttachmentStrategy::First: + os << "First"; + break; + case VolumeAttachmentStrategy::Second: + os << "Second"; + break; + case VolumeAttachmentStrategy::Midpoint: + os << "Midpoint"; + break; + case VolumeAttachmentStrategy::Gap: + os << "Gap"; + break; + default: + os << "Unknown"; + break; + } + return os; +} + +} // namespace Acts diff --git a/Core/src/Geometry/VolumeResizeStrategy.cpp b/Core/src/Geometry/VolumeResizeStrategy.cpp new file mode 100644 index 00000000000..c8a382edad9 --- /dev/null +++ b/Core/src/Geometry/VolumeResizeStrategy.cpp @@ -0,0 +1,28 @@ +// 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/VolumeResizeStrategy.hpp" + +namespace Acts { + +std::ostream& operator<<(std::ostream& os, VolumeResizeStrategy strategy) { + switch (strategy) { + case VolumeResizeStrategy::Expand: + os << "Expand"; + break; + case VolumeResizeStrategy::Gap: + os << "Gap"; + break; + default: + os << "Unknown"; + break; + } + return os; +} + +} // namespace Acts diff --git a/Core/src/Material/MaterialGridHelper.cpp b/Core/src/Material/MaterialGridHelper.cpp index 83c7946f77c..e4dbab79164 100644 --- a/Core/src/Material/MaterialGridHelper.cpp +++ b/Core/src/Material/MaterialGridHelper.cpp @@ -84,44 +84,44 @@ Acts::Grid3D Acts::createGrid(Acts::MaterialGridAxisData gridAxis1, } std::function Acts::globalToLocalFromBin( - Acts::BinningValue& type) { + Acts::AxisDirection& type) { std::function transfoGlobalToLocal; switch (type) { - case Acts::BinningValue::binX: + case Acts::AxisDirection::AxisX: transfoGlobalToLocal = [](const Acts::Vector3& pos) -> double { return (pos.x()); }; break; - case Acts::BinningValue::binY: + case Acts::AxisDirection::AxisY: transfoGlobalToLocal = [](const Acts::Vector3& pos) -> double { return (pos.y()); }; break; - case Acts::BinningValue::binR: + case Acts::AxisDirection::AxisR: transfoGlobalToLocal = [](const Acts::Vector3& pos) -> double { return (Acts::VectorHelpers::perp(pos)); }; break; - case Acts::BinningValue::binPhi: + case Acts::AxisDirection::AxisPhi: transfoGlobalToLocal = [](const Acts::Vector3& pos) -> double { return (Acts::VectorHelpers::phi(pos)); }; break; - case Acts::BinningValue::binZ: + case Acts::AxisDirection::AxisZ: transfoGlobalToLocal = [](const Acts::Vector3& pos) -> double { return (pos.z()); }; break; - // case Acts::BinningValue::binRPhi: - // case Acts::BinningValue::binEta: - // case Acts::BinningValue::binH: - // case Acts::BinningValue::binMag: + // case Acts::AxisDirection::AxisRPhi: + // case Acts::AxisDirection::AxisEta: + // case Acts::AxisDirection::AxisTheta: + // case Acts::AxisDirection::AxisMag: default: throw std::invalid_argument("Incorrect bin, should be x,y,z,r,phi"); } @@ -137,12 +137,12 @@ Acts::Grid2D Acts::createGrid2D( bool isCylindrical = false; for (std::size_t b = 0; b < bu.size(); b++) { - if (bu[b].binvalue == Acts::BinningValue::binX || - bu[b].binvalue == Acts::BinningValue::binY) { + if (bu[b].binvalue == Acts::AxisDirection::AxisX || + bu[b].binvalue == Acts::AxisDirection::AxisY) { isCartesian = true; } - if (bu[b].binvalue == Acts::BinningValue::binR || - bu[b].binvalue == Acts::BinningValue::binPhi) { + if (bu[b].binvalue == Acts::AxisDirection::AxisR || + bu[b].binvalue == Acts::AxisDirection::AxisPhi) { isCylindrical = true; } } @@ -177,12 +177,12 @@ Acts::Grid3D Acts::createGrid3D( bool isCylindrical = false; for (std::size_t b = 0; b < bu.size(); b++) { - if (bu[b].binvalue == Acts::BinningValue::binX || - bu[b].binvalue == Acts::BinningValue::binY) { + if (bu[b].binvalue == Acts::AxisDirection::AxisX || + bu[b].binvalue == Acts::AxisDirection::AxisY) { isCartesian = true; } - if (bu[b].binvalue == Acts::BinningValue::binR || - bu[b].binvalue == Acts::BinningValue::binPhi) { + if (bu[b].binvalue == Acts::AxisDirection::AxisR || + bu[b].binvalue == Acts::AxisDirection::AxisPhi) { isCylindrical = true; } } diff --git a/Core/src/Propagator/PropagatorError.cpp b/Core/src/Propagator/PropagatorError.cpp index 20931b27515..3973038b53a 100644 --- a/Core/src/Propagator/PropagatorError.cpp +++ b/Core/src/Propagator/PropagatorError.cpp @@ -24,10 +24,11 @@ class PropagatorErrorCategory : public std::error_category { switch (static_cast(c)) { case PropagatorError::Failure: return "Propagation failed"; - case PropagatorError::WrongDirection: - return "Propagation occurred in the wrong direction"; case PropagatorError::StepCountLimitReached: return "Propagation reached the configured maximum number of steps"; + case PropagatorError::NextTargetLimitReached: + return "Propagation reached the configured maximum number of next " + "target calls"; default: return "unknown"; } diff --git a/Core/src/Surfaces/BoundaryTolerance.cpp b/Core/src/Surfaces/BoundaryTolerance.cpp index 971a026d7de..3bedc6ab8ff 100644 --- a/Core/src/Surfaces/BoundaryTolerance.cpp +++ b/Core/src/Surfaces/BoundaryTolerance.cpp @@ -15,49 +15,32 @@ namespace Acts { -BoundaryTolerance::BoundaryTolerance(const Infinite& infinite) - : m_variant{infinite} {} - -BoundaryTolerance::BoundaryTolerance(const None& none) : m_variant{none} {} - -BoundaryTolerance::BoundaryTolerance(const AbsoluteBound& absoluteBound) - : m_variant{absoluteBound} {} - -BoundaryTolerance::BoundaryTolerance(const AbsoluteCartesian& absoluteCartesian) - : m_variant{absoluteCartesian} {} - -BoundaryTolerance::BoundaryTolerance(const AbsoluteEuclidean& absoluteEuclidean) - : m_variant{absoluteEuclidean} {} - -BoundaryTolerance::BoundaryTolerance(const Chi2Bound& chi2Bound) - : m_variant{chi2Bound} {} - BoundaryTolerance::BoundaryTolerance(Variant variant) : m_variant{std::move(variant)} {} bool BoundaryTolerance::isInfinite() const { - return holdsVariant(); + return holdsVariant(); } bool BoundaryTolerance::isNone() const { - return holdsVariant(); + return holdsVariant(); } bool BoundaryTolerance::hasAbsoluteBound(bool isCartesian) const { - return holdsVariant() || holdsVariant() || - (isCartesian && holdsVariant()); + return holdsVariant() || holdsVariant() || + (isCartesian && holdsVariant()); } bool BoundaryTolerance::hasAbsoluteCartesian() const { - return holdsVariant(); + return holdsVariant(); } bool BoundaryTolerance::hasAbsoluteEuclidean() const { - return holdsVariant(); + return holdsVariant(); } bool BoundaryTolerance::hasChi2Bound() const { - return holdsVariant(); + return holdsVariant(); } BoundaryTolerance::ToleranceMode BoundaryTolerance::toleranceMode() const { @@ -70,7 +53,7 @@ BoundaryTolerance::ToleranceMode BoundaryTolerance::toleranceMode() const { return None; } - if (const auto* absoluteBound = getVariantPtr(); + if (const auto* absoluteBound = getVariantPtr(); absoluteBound != nullptr) { if (absoluteBound->tolerance0 == 0. && absoluteBound->tolerance1 == 0.) { return None; @@ -79,7 +62,7 @@ BoundaryTolerance::ToleranceMode BoundaryTolerance::toleranceMode() const { return Extend; } - if (const auto* absoluteCartesian = getVariantPtr(); + if (const auto* absoluteCartesian = getVariantPtr(); absoluteCartesian != nullptr) { if (absoluteCartesian->tolerance0 == 0. && absoluteCartesian->tolerance1 == 0.) { @@ -89,7 +72,7 @@ BoundaryTolerance::ToleranceMode BoundaryTolerance::toleranceMode() const { return Extend; } - if (const auto* absoluteEuclidean = getVariantPtr(); + if (const auto* absoluteEuclidean = getVariantPtr(); absoluteEuclidean != nullptr) { if (absoluteEuclidean->tolerance == 0.) { return None; @@ -100,7 +83,7 @@ BoundaryTolerance::ToleranceMode BoundaryTolerance::toleranceMode() const { } } - if (const auto* chi2Bound = getVariantPtr(); + if (const auto* chi2Bound = getVariantPtr(); chi2Bound != nullptr) { if (chi2Bound->maxChi2 == 0.) { return None; @@ -115,35 +98,36 @@ BoundaryTolerance::ToleranceMode BoundaryTolerance::toleranceMode() const { return None; } -BoundaryTolerance::AbsoluteBound BoundaryTolerance::asAbsoluteBound( +BoundaryTolerance::AbsoluteBoundParams BoundaryTolerance::asAbsoluteBound( bool isCartesian) const { if (isNone()) { - return AbsoluteBound{0., 0.}; + return AbsoluteBoundParams{0., 0.}; } if (isCartesian && hasAbsoluteCartesian()) { - const auto& cartesian = getVariant(); - return AbsoluteBound{cartesian.tolerance0, cartesian.tolerance1}; + const auto& cartesian = getVariant(); + return AbsoluteBoundParams{cartesian.tolerance0, cartesian.tolerance1}; } - return getVariant(); + return getVariant(); } -const BoundaryTolerance::AbsoluteCartesian& +const BoundaryTolerance::AbsoluteCartesianParams& BoundaryTolerance::asAbsoluteCartesian() const { - return getVariant(); + return getVariant(); } -const BoundaryTolerance::AbsoluteEuclidean& +const BoundaryTolerance::AbsoluteEuclideanParams& BoundaryTolerance::asAbsoluteEuclidean() const { - return getVariant(); + return getVariant(); } -const BoundaryTolerance::Chi2Bound& BoundaryTolerance::asChi2Bound() const { - return getVariant(); +const BoundaryTolerance::Chi2BoundParams& BoundaryTolerance::asChi2Bound() + const { + return getVariant(); } -std::optional +std::optional BoundaryTolerance::asAbsoluteBoundOpt(bool isCartesian) const { return hasAbsoluteBound(isCartesian) ? std::optional(asAbsoluteBound(isCartesian)) @@ -161,13 +145,13 @@ bool BoundaryTolerance::isTolerated( return distance == Vector2::Zero(); } - if (const auto* absoluteBound = getVariantPtr(); + if (const auto* absoluteBound = getVariantPtr(); absoluteBound != nullptr) { return std::abs(distance[0]) <= absoluteBound->tolerance0 && std::abs(distance[1]) <= absoluteBound->tolerance1; } - if (const auto* chi2Bound = getVariantPtr(); + if (const auto* chi2Bound = getVariantPtr(); chi2Bound != nullptr) { // Mahalanobis distances mean is 2 in 2-dim. cut is 1-d sigma. double chi2 = distance.transpose() * chi2Bound->weight * distance; @@ -187,13 +171,13 @@ bool BoundaryTolerance::isTolerated( cartesianDistance = jacobian * distance; } - if (const auto* absoluteCartesian = getVariantPtr(); + if (const auto* absoluteCartesian = getVariantPtr(); absoluteCartesian != nullptr) { return std::abs(cartesianDistance[0]) <= absoluteCartesian->tolerance0 && std::abs(cartesianDistance[1]) <= absoluteCartesian->tolerance1; } - if (const auto* absoluteEuclidean = getVariantPtr(); + if (const auto* absoluteEuclidean = getVariantPtr(); absoluteEuclidean != nullptr) { if (absoluteEuclidean->tolerance < 0) { return cartesianDistance.norm() > std::abs(absoluteEuclidean->tolerance); @@ -214,7 +198,8 @@ SquareMatrix2 BoundaryTolerance::getMetric( bool isCartesian = !jacobianOpt.has_value(); SquareMatrix2 metric = SquareMatrix2::Identity(); - if (const auto* chi2Bound = getVariantPtr(); + if (const auto* chi2Bound = + getVariantPtr(); chi2Bound != nullptr) { metric = chi2Bound->weight; } else if (!isCartesian) { diff --git a/Core/src/Surfaces/ConeSurface.cpp b/Core/src/Surfaces/ConeSurface.cpp index bb8f8ed4cf4..1b9c1906856 100644 --- a/Core/src/Surfaces/ConeSurface.cpp +++ b/Core/src/Surfaces/ConeSurface.cpp @@ -61,19 +61,19 @@ ConeSurface::ConeSurface(const Transform3& transform, throw_assert(m_bounds, "ConeBounds must not be nullptr"); } -Vector3 ConeSurface::binningPosition(const GeometryContext& gctx, - BinningValue bValue) const { +Vector3 ConeSurface::referencePosition(const GeometryContext& gctx, + AxisDirection aDir) const { const Vector3& sfCenter = center(gctx); // special binning type for R-type methods - if (bValue == BinningValue::binR || bValue == BinningValue::binRPhi) { + if (aDir == AxisDirection::AxisR || aDir == AxisDirection::AxisRPhi) { return Vector3(sfCenter.x() + bounds().r(sfCenter.z()), sfCenter.y(), sfCenter.z()); } // give the center as default for all of these binning types - // BinningValue::binX, BinningValue::binY, BinningValue::binZ, - // BinningValue::binR, BinningValue::binPhi, BinningValue::binRPhi, - // BinningValue::binH, BinningValue::binEta + // AxisDirection::AxisX, AxisDirection::AxisY, AxisDirection::AxisZ, + // AxisDirection::AxisR, AxisDirection::AxisPhi, AxisDirection::AxisRPhi, + // AxisDirection::AxisTheta, AxisDirection::AxisEta return sfCenter; } diff --git a/Core/src/Surfaces/CylinderSurface.cpp b/Core/src/Surfaces/CylinderSurface.cpp index 7990b4fd8d2..45ec85ae1a8 100644 --- a/Core/src/Surfaces/CylinderSurface.cpp +++ b/Core/src/Surfaces/CylinderSurface.cpp @@ -76,18 +76,18 @@ CylinderSurface& CylinderSurface::operator=(const CylinderSurface& other) { } // return the binning position for ordering in the BinnedArray -Vector3 CylinderSurface::binningPosition(const GeometryContext& gctx, - BinningValue bValue) const { +Vector3 CylinderSurface::referencePosition(const GeometryContext& gctx, + AxisDirection aDir) const { // special binning type for R-type methods - if (bValue == BinningValue::binR || bValue == BinningValue::binRPhi) { + if (aDir == AxisDirection::AxisR || aDir == AxisDirection::AxisRPhi) { double R = bounds().get(CylinderBounds::eR); double phi = bounds().get(CylinderBounds::eAveragePhi); return localToGlobal(gctx, Vector2{phi * R, 0}, Vector3{}); } // give the center as default for all of these binning types - // BinningValue::binX, BinningValue::binY, BinningValue::binZ, - // BinningValue::binR, BinningValue::binPhi, BinningValue::binRPhi, - // BinningValue::binH, BinningValue::binEta + // AxisDirection::AxisX, AxisDirection::AxisY, AxisDirection::AxisZ, + // AxisDirection::AxisR, AxisDirection::AxisPhi, AxisDirection::AxisRPhi, + // AxisDirection::AxisTheta, AxisDirection::AxisEta return center(gctx); } @@ -355,11 +355,11 @@ ActsMatrix<2, 3> CylinderSurface::localCartesianToBoundLocalDerivative( } std::pair, bool> CylinderSurface::mergedWith( - const CylinderSurface& other, BinningValue direction, bool externalRotation, - const Logger& logger) const { + const CylinderSurface& other, AxisDirection direction, + bool externalRotation, const Logger& logger) const { using namespace UnitLiterals; - ACTS_VERBOSE("Merging cylinder surfaces in " << binningValueName(direction) + ACTS_VERBOSE("Merging cylinder surfaces in " << axisDirectionName(direction) << " direction"); if (m_associatedDetElement != nullptr || @@ -448,7 +448,7 @@ std::pair, bool> CylinderSurface::mergedWith( double otherHlPhi = other.bounds().get(CylinderBounds::eHalfPhiSector); double otherAvgPhi = other.bounds().get(CylinderBounds::eAveragePhi); - if (direction == BinningValue::binZ) { + if (direction == AxisDirection::AxisZ) { // z shift must match the bounds if (std::abs(otherLocal.linear().col(eY)[eX]) >= tolerance && @@ -495,7 +495,7 @@ std::pair, bool> CylinderSurface::mergedWith( return {Surface::makeShared(newTransform, newBounds), zShift < 0}; - } else if (direction == BinningValue::binRPhi) { + } else if (direction == AxisDirection::AxisRPhi) { // no z shift is allowed if (std::abs(translation[2]) > tolerance) { ACTS_ERROR( @@ -555,7 +555,7 @@ std::pair, bool> CylinderSurface::mergedWith( } else { throw SurfaceMergingException(getSharedPtr(), other.getSharedPtr(), "CylinderSurface::merge: invalid direction " + - binningValueName(direction)); + axisDirectionName(direction)); } } diff --git a/Core/src/Surfaces/DiscSurface.cpp b/Core/src/Surfaces/DiscSurface.cpp index 8981bb24c5e..99d2f21885d 100644 --- a/Core/src/Surfaces/DiscSurface.cpp +++ b/Core/src/Surfaces/DiscSurface.cpp @@ -337,9 +337,9 @@ Vector3 DiscSurface::normal(const GeometryContext& gctx) const { return Vector3(tMatrix(0, 2), tMatrix(1, 2), tMatrix(2, 2)); } -Vector3 DiscSurface::binningPosition(const GeometryContext& gctx, - BinningValue bValue) const { - if (bValue == BinningValue::binR || bValue == BinningValue::binPhi) { +Vector3 DiscSurface::referencePosition(const GeometryContext& gctx, + AxisDirection aDir) const { + if (aDir == AxisDirection::AxisR || aDir == AxisDirection::AxisPhi) { double r = m_bounds->binningValueR(); double phi = m_bounds->binningValuePhi(); return localToGlobal(gctx, Vector2{r, phi}, Vector3{}); @@ -347,16 +347,16 @@ Vector3 DiscSurface::binningPosition(const GeometryContext& gctx, return center(gctx); } -double DiscSurface::binningPositionValue(const GeometryContext& gctx, - BinningValue bValue) const { - if (bValue == BinningValue::binR) { - return VectorHelpers::perp(binningPosition(gctx, bValue)); +double DiscSurface::referencePositionValue(const GeometryContext& gctx, + AxisDirection aDir) const { + if (aDir == AxisDirection::AxisR) { + return VectorHelpers::perp(referencePosition(gctx, aDir)); } - if (bValue == BinningValue::binPhi) { - return VectorHelpers::phi(binningPosition(gctx, bValue)); + if (aDir == AxisDirection::AxisPhi) { + return VectorHelpers::phi(referencePosition(gctx, aDir)); } - return GeometryObject::binningPositionValue(gctx, bValue); + return GeometryObject::referencePositionValue(gctx, aDir); } double DiscSurface::pathCorrection(const GeometryContext& gctx, @@ -367,7 +367,7 @@ double DiscSurface::pathCorrection(const GeometryContext& gctx, } std::pair, bool> DiscSurface::mergedWith( - const DiscSurface& other, BinningValue direction, bool externalRotation, + const DiscSurface& other, AxisDirection direction, bool externalRotation, const Logger& logger) const { using namespace UnitLiterals; @@ -443,7 +443,7 @@ std::pair, bool> DiscSurface::mergedWith( << otherAvgPhi / 1_degree << " +- " << otherHlPhi / 1_degree); - if (direction == BinningValue::binR) { + if (direction == AxisDirection::AxisR) { if (std::abs(otherLocal.linear().col(eY)[eX]) >= tolerance && (!bounds->coversFullAzimuth() || !otherBounds->coversFullAzimuth())) { throw SurfaceMergingException(getSharedPtr(), other.getSharedPtr(), @@ -483,7 +483,7 @@ std::pair, bool> DiscSurface::mergedWith( return {Surface::makeShared(*m_transform, newBounds), minR > otherMinR}; - } else if (direction == BinningValue::binPhi) { + } else if (direction == AxisDirection::AxisPhi) { if (std::abs(maxR - otherMaxR) > tolerance || std::abs(minR - otherMinR) > tolerance) { ACTS_ERROR("DiscSurface::merge: surfaces don't have same r bounds"); @@ -535,9 +535,9 @@ std::pair, bool> DiscSurface::mergedWith( } else { ACTS_ERROR("DiscSurface::merge: invalid direction " << direction); - throw SurfaceMergingException( - getSharedPtr(), other.getSharedPtr(), - "DiscSurface::merge: invalid direction " + binningValueName(direction)); + throw SurfaceMergingException(getSharedPtr(), other.getSharedPtr(), + "DiscSurface::merge: invalid direction " + + axisDirectionName(direction)); } } diff --git a/Core/src/Surfaces/LineSurface.cpp b/Core/src/Surfaces/LineSurface.cpp index 68957d5824b..6f6350625d6 100644 --- a/Core/src/Surfaces/LineSurface.cpp +++ b/Core/src/Surfaces/LineSurface.cpp @@ -119,8 +119,8 @@ double LineSurface::pathCorrection(const GeometryContext& /*gctx*/, return 1.; } -Vector3 LineSurface::binningPosition(const GeometryContext& gctx, - BinningValue /*bValue*/) const { +Vector3 LineSurface::referencePosition(const GeometryContext& gctx, + AxisDirection /*aDir*/) const { return center(gctx); } diff --git a/Core/src/Surfaces/PlaneSurface.cpp b/Core/src/Surfaces/PlaneSurface.cpp index aebc75315ef..9437937afc4 100644 --- a/Core/src/Surfaces/PlaneSurface.cpp +++ b/Core/src/Surfaces/PlaneSurface.cpp @@ -8,14 +8,17 @@ #include "Acts/Surfaces/PlaneSurface.hpp" +#include "Acts/Definitions/Algebra.hpp" #include "Acts/Geometry/GeometryObject.hpp" #include "Acts/Surfaces/BoundaryTolerance.hpp" #include "Acts/Surfaces/CurvilinearSurface.hpp" #include "Acts/Surfaces/EllipseBounds.hpp" #include "Acts/Surfaces/InfiniteBounds.hpp" #include "Acts/Surfaces/PlanarBounds.hpp" +#include "Acts/Surfaces/RectangleBounds.hpp" #include "Acts/Surfaces/SurfaceBounds.hpp" #include "Acts/Surfaces/SurfaceError.hpp" +#include "Acts/Surfaces/SurfaceMergingException.hpp" #include "Acts/Surfaces/detail/FacesHelper.hpp" #include "Acts/Surfaces/detail/PlanarHelper.hpp" #include "Acts/Utilities/Intersection.hpp" @@ -23,6 +26,7 @@ #include #include +#include #include #include #include @@ -145,8 +149,8 @@ Vector3 PlaneSurface::normal(const GeometryContext& gctx) const { return transform(gctx).linear().col(2); } -Vector3 PlaneSurface::binningPosition(const GeometryContext& gctx, - BinningValue /*bValue*/) const { +Vector3 PlaneSurface::referencePosition(const GeometryContext& gctx, + AxisDirection /*aDir*/) const { return center(gctx); } @@ -190,4 +194,117 @@ ActsMatrix<2, 3> PlaneSurface::localCartesianToBoundLocalDerivative( return loc3DToLocBound; } +std::pair, bool> PlaneSurface::mergedWith( + const PlaneSurface& other, AxisDirection direction, + const Logger& logger) const { + ACTS_VERBOSE("Merging plane surfaces in " << axisDirectionName(direction) + << " direction"); + + if (m_associatedDetElement != nullptr || + other.m_associatedDetElement != nullptr) { + throw SurfaceMergingException(getSharedPtr(), other.getSharedPtr(), + "PlaneSurface::merge: surfaces are " + "associated with a detector element"); + } + + assert(m_transform != nullptr && other.m_transform != nullptr); + + Transform3 otherLocal = m_transform->inverse() * *other.m_transform; + + // TODO: Is it a good tolerance? + constexpr auto tolerance = s_onSurfaceTolerance; + + // Surface cannot have any relative rotation + if ((otherLocal.rotation().matrix() - RotationMatrix3::Identity()).norm() > + tolerance) { + ACTS_ERROR("PlaneSurface::merge: surfaces have relative rotation"); + throw SurfaceMergingException( + getSharedPtr(), other.getSharedPtr(), + "PlaneSurface::merge: surfaces have relative rotation"); + } + + const auto* thisBounds = dynamic_cast(&bounds()); + const auto* otherBounds = + dynamic_cast(&other.bounds()); + + if (thisBounds == nullptr || otherBounds == nullptr) { + throw SurfaceMergingException( + getSharedPtr(), other.getSharedPtr(), + "PlaneSurface::merge: only Rectangle Bounds are supported"); + } + + if (direction != AxisDirection::AxisX && direction != AxisDirection::AxisY) { + throw SurfaceMergingException(getSharedPtr(), other.getSharedPtr(), + "PlaneSurface::merge: invalid direction " + + axisDirectionName(direction)); + } + + bool mergeX = direction == AxisDirection::AxisX; + + double thisHalfMerge = + mergeX ? thisBounds->halfLengthX() : thisBounds->halfLengthY(); + double otherHalfMerge = + mergeX ? otherBounds->halfLengthX() : otherBounds->halfLengthY(); + + double thisHalfNonMerge = + mergeX ? thisBounds->halfLengthY() : thisBounds->halfLengthX(); + double otherHalfNonMerge = + mergeX ? otherBounds->halfLengthY() : otherBounds->halfLengthX(); + + if (std::abs(thisHalfNonMerge - otherHalfNonMerge) > tolerance) { + ACTS_ERROR( + "PlaneSurface::merge: surfaces have different non-merging lengths"); + throw SurfaceMergingException( + getSharedPtr(), other.getSharedPtr(), + "PlaneSurface::merge: surfaces have different non-merging lengths"); + } + Vector3 otherTranslation = otherLocal.translation(); + + // No translation in non-merging direction/z is allowed + double nonMergeShift = mergeX ? otherTranslation.y() : otherTranslation.x(); + + if (std::abs(nonMergeShift) > tolerance || + std::abs(otherTranslation.z()) > tolerance) { + ACTS_ERROR( + "PlaneSurface::merge: surfaces have relative translation in y/z"); + throw SurfaceMergingException( + getSharedPtr(), other.getSharedPtr(), + "PlaneSurface::merge: surfaces have relative translation in y/z"); + } + + double mergeShift = mergeX ? otherTranslation.x() : otherTranslation.y(); + + double thisMinMerge = -thisHalfMerge; + double thisMaxMerge = thisHalfMerge; + + double otherMinMerge = mergeShift - otherHalfMerge; + double otherMaxMerge = mergeShift + otherHalfMerge; + + // Surfaces have to "touch" along merging direction + if (std::abs(thisMaxMerge - otherMinMerge) > tolerance && + std::abs(thisMinMerge - otherMaxMerge) > tolerance) { + ACTS_ERROR( + "PlaneSurface::merge: surfaces have incompatible merge bound location"); + throw SurfaceMergingException( + getSharedPtr(), other.getSharedPtr(), + "PlaneSurface::merge: surfaces have incompatible merge bound location"); + } + + double newMaxMerge = std::max(thisMaxMerge, otherMaxMerge); + double newMinMerge = std::min(thisMinMerge, otherMinMerge); + + double newHalfMerge = std::midpoint(newMaxMerge, -newMinMerge); + double newMidMerge = std::midpoint(newMaxMerge, newMinMerge); + + auto newBounds = + mergeX + ? std::make_shared(newHalfMerge, thisHalfNonMerge) + : std::make_shared(thisHalfNonMerge, newHalfMerge); + + Vector3 unitDir = mergeX ? Vector3::UnitX() : Vector3::UnitY(); + Transform3 newTransform = *m_transform * Translation3{unitDir * newMidMerge}; + return {Surface::makeShared(newTransform, newBounds), + mergeShift < 0}; +} + } // namespace Acts diff --git a/Core/src/Utilities/AxisDefinitions.cpp b/Core/src/Utilities/AxisDefinitions.cpp new file mode 100644 index 00000000000..e7adf5347c6 --- /dev/null +++ b/Core/src/Utilities/AxisDefinitions.cpp @@ -0,0 +1,66 @@ +// 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/Utilities/AxisDefinitions.hpp" + +#include +#include +#include + +namespace Acts { + +namespace { + +// Legacy binning value names +// +// NOTE: this should be removed once the BinUtility is removed +const std::vector s_legacyBinningValueNames = { + "binX", "binY", "binZ", "binR", "binPhi", + "binRPhi", "binH", "binEta", "binMag"}; +// end of legacy binning values + +const std::vector s_axisDirectionNames = { + "AxisX", "AxisY", "AxisZ", "AxisR", "AxisPhi", + "AxisRPhi", "AxisTheta", "AxisEta", "AxisMag"}; + +const std::vector s_axisDirections = { + AxisDirection::AxisX, AxisDirection::AxisY, AxisDirection::AxisZ, + AxisDirection::AxisR, AxisDirection::AxisPhi, AxisDirection::AxisRPhi, + AxisDirection::AxisTheta, AxisDirection::AxisEta, AxisDirection::AxisMag}; + +} // namespace + +const std::vector& allAxisDirections() { + return s_axisDirections; +} + +AxisDirection axisDirectionFromName(const std::string& name) { + auto it = std::ranges::find(s_axisDirectionNames, name); + if (it == s_axisDirectionNames.end()) { + // Legacy binning check - this should be removed once BinUtility is gone + it = std::ranges::find(s_legacyBinningValueNames, name); + if (it == s_legacyBinningValueNames.end()) { + throw std::invalid_argument("Unknown AxisDirection value name: " + name); + } + // both legacy and current failed + } + return static_cast( + std::distance(s_axisDirectionNames.begin(), it)); +} + +const std::string& axisDirectionName(AxisDirection aDir) { + return s_axisDirectionNames.at( + static_cast>(aDir)); +} + +std::ostream& operator<<(std::ostream& os, AxisDirection aDir) { + os << axisDirectionName(aDir); + return os; +} + +} // namespace Acts diff --git a/Core/src/Utilities/BinningType.cpp b/Core/src/Utilities/BinningType.cpp deleted file mode 100644 index 8faa7dcd856..00000000000 --- a/Core/src/Utilities/BinningType.cpp +++ /dev/null @@ -1,53 +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 "Acts/Utilities/BinningType.hpp" - -#include -#include -#include - -namespace Acts { - -namespace { - -static const std::vector s_binningValueNames = { - "binX", "binY", "binZ", "binR", "binPhi", - "binRPhi", "binH", "binEta", "binMag"}; - -static const std::vector s_binningValues = { - BinningValue::binX, BinningValue::binY, BinningValue::binZ, - BinningValue::binR, BinningValue::binPhi, BinningValue::binRPhi, - BinningValue::binH, BinningValue::binEta, BinningValue::binMag}; - -} // namespace - -const std::vector& allBinningValues() { - return s_binningValues; -} - -BinningValue binningValueFromName(const std::string& name) { - auto it = std::ranges::find(s_binningValueNames, name); - if (it == s_binningValueNames.end()) { - throw std::invalid_argument("Unknown binning value name: " + name); - } - return static_cast( - std::distance(s_binningValueNames.begin(), it)); -} - -const std::string& binningValueName(BinningValue bValue) { - return s_binningValueNames.at( - static_cast>(bValue)); -} - -std::ostream& operator<<(std::ostream& os, BinningValue bValue) { - os << binningValueName(bValue); - return os; -} - -} // namespace Acts diff --git a/Core/src/Utilities/CMakeLists.txt b/Core/src/Utilities/CMakeLists.txt index 1fb61813cd3..58ccedf6a8d 100644 --- a/Core/src/Utilities/CMakeLists.txt +++ b/Core/src/Utilities/CMakeLists.txt @@ -2,10 +2,12 @@ target_sources( ActsCore PRIVATE AnnealingUtility.cpp + AxisDefinitions.cpp Logger.cpp SpacePointUtility.cpp TrackHelpers.cpp - BinningType.cpp Intersection.cpp + IAxis.cpp GraphViz.cpp + ProtoAxis.cpp ) diff --git a/Core/src/Utilities/IAxis.cpp b/Core/src/Utilities/IAxis.cpp new file mode 100644 index 00000000000..e8f5dfb5f9c --- /dev/null +++ b/Core/src/Utilities/IAxis.cpp @@ -0,0 +1,71 @@ +// 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/Utilities/IAxis.hpp" + +#include "Acts/Utilities/Axis.hpp" + +#include +#include + +std::unique_ptr Acts::IAxis::createEquidistant( + AxisBoundaryType aBoundaryType, double min, double max, std::size_t nbins) { + using enum AxisType; + using enum AxisBoundaryType; + + if (min >= max) { + std::string msg = "IAxis: Invalid axis range'"; + msg += "', min edge (" + std::to_string(min) + ") "; + msg += " needs to be smaller than max edge ("; + msg += std::to_string(max) + ")."; + throw std::invalid_argument(msg); + } + if (nbins < 1u) { + throw std::invalid_argument( + "IAxis: Invalid binning, at least one bin is needed."); + } + + switch (aBoundaryType) { + case Open: + return std::make_unique>(min, max, nbins); + case Bound: + return std::make_unique>(min, max, nbins); + case Closed: + return std::make_unique>(min, max, nbins); + default: // should never happen + throw std::logic_error("Unknown axis boundary type"); + } +} + +std::unique_ptr Acts::IAxis::createVariable( + AxisBoundaryType aBoundaryType, const std::vector& edges) { + using enum AxisType; + using enum AxisBoundaryType; + + // Not enough edges + if (edges.size() < 2) { + throw std::invalid_argument( + "IAxis: Invalid binning, at least two bin edges are needed."); + } + + // Not sorted + if (!std::ranges::is_sorted(edges)) { + throw std::invalid_argument( + "IAxis: Invalid binning, bin edges are not sorted."); + } + switch (aBoundaryType) { + case Open: + return std::make_unique>(edges); + case Bound: + return std::make_unique>(edges); + case Closed: + return std::make_unique>(edges); + default: // should never happen + throw std::logic_error("Unknown axis boundary type"); + } +} diff --git a/Core/src/Utilities/ProtoAxis.cpp b/Core/src/Utilities/ProtoAxis.cpp new file mode 100644 index 00000000000..ab6661ce3ad --- /dev/null +++ b/Core/src/Utilities/ProtoAxis.cpp @@ -0,0 +1,92 @@ +// 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/Utilities/ProtoAxis.hpp" + +#include + +namespace { +void checkConsistency(Acts::AxisDirection aDir, Acts::AxisBoundaryType abType) { + if (abType == Acts::AxisBoundaryType::Closed && + aDir != Acts::AxisDirection::AxisPhi && + aDir != Acts::AxisDirection::AxisRPhi) { + std::string msg = + "ProtoAxis: Invalid axis boundary type 'Closed' for direction '"; + msg += axisDirectionName(aDir) + + "'. Closed boundary type is only valid for " + "AxisPhi and AxisRPhi directions."; + throw std::invalid_argument(msg); + } +} +} // namespace + +Acts::ProtoAxis::ProtoAxis(AxisDirection aDir, Acts::AxisBoundaryType abType, + const std::vector& edges) + : m_axisDir(aDir), m_axis(IAxis::createVariable(abType, edges)) { + checkConsistency(aDir, abType); +} + +Acts::ProtoAxis::ProtoAxis(AxisDirection aDir, AxisBoundaryType abType, + double minE, double maxE, std::size_t nbins) + : m_axisDir(aDir), + m_axis(IAxis::createEquidistant(abType, minE, maxE, nbins)) { + checkConsistency(aDir, abType); +} + +Acts::ProtoAxis::ProtoAxis(AxisDirection aDir, AxisBoundaryType abType, + std::size_t nbins) + : m_axisDir(aDir), + m_axis(IAxis::createEquidistant(abType, 0., 1., nbins)), + m_autorange(true) { + checkConsistency(aDir, abType); +} + +Acts::AxisDirection Acts::ProtoAxis::getAxisDirection() const { + return m_axisDir; +} + +const Acts::IAxis& Acts::ProtoAxis::getAxis() const { + return *m_axis; +} + +void Acts::ProtoAxis::setRange(double minE, double maxE) { + if (!m_autorange) { + throw std::invalid_argument("ProtoAxis::setRange: Range is already set."); + } + if (m_axis->getType() != AxisType::Equidistant) { + throw std::invalid_argument( + "ProtoAxis::setRange: Range can only be set for equidistant binning."); + } + m_axis = IAxis::createEquidistant(m_axis->getBoundaryType(), minE, maxE, + m_axis->getNBins()); + m_autorange = false; +} + +bool Acts::ProtoAxis::isAutorange() const { + return m_autorange; +} + +void Acts::ProtoAxis::toStream(std::ostream& os) const { + os << toString(); +} + +std::string Acts::ProtoAxis::toString() const { + std::stringstream ss; + const auto& axis = getAxis(); + ss << "ProtoAxis: " << axis.getNBins() << " bins in " + << axisDirectionName(getAxisDirection()); + ss << (axis.getType() == AxisType::Variable ? ", variable " + : ", equidistant "); + if (!m_autorange) { + const auto& edges = axis.getBinEdges(); + ss << "within [" << edges.front() << ", " << edges.back() << "]"; + } else { + ss << "within automatic range"; + } + return ss.str(); +} diff --git a/Core/src/Vertexing/ImpactPointEstimator.cpp b/Core/src/Vertexing/ImpactPointEstimator.cpp index 51f0ebe24db..a58ee19de96 100644 --- a/Core/src/Vertexing/ImpactPointEstimator.cpp +++ b/Core/src/Vertexing/ImpactPointEstimator.cpp @@ -509,7 +509,7 @@ Result> ImpactPointEstimator::getLifetimeSignOfTrack( // Create propagator options PropagatorPlainOptions pOptions(gctx, mctx); - pOptions.direction = Direction::Backward; + pOptions.direction = Direction::Backward(); // Do the propagation to the perigeee auto result = @@ -548,7 +548,7 @@ Result ImpactPointEstimator::get3DLifetimeSignOfTrack( // Create propagator options PropagatorPlainOptions pOptions(gctx, mctx); - pOptions.direction = Direction::Backward; + pOptions.direction = Direction::Backward(); // Do the propagation to the perigeee auto result = diff --git a/Core/src/Visualization/GeometryView3D.cpp b/Core/src/Visualization/GeometryView3D.cpp index f16d9e809cc..d915a5ae633 100644 --- a/Core/src/Visualization/GeometryView3D.cpp +++ b/Core/src/Visualization/GeometryView3D.cpp @@ -79,9 +79,9 @@ void Acts::GeometryView3D::drawSurfaceArray( auto axes = surfaceArray.getAxes(); if (!binning.empty() && binning.size() == 2 && axes.size() == 2) { // Cylinder surface array - if (binning[0] == BinningValue::binPhi && - binning[1] == BinningValue::binZ) { - double R = arrayExtent.medium(BinningValue::binR) + gridConfig.offset; + if (binning[0] == AxisDirection::AxisPhi && + binning[1] == AxisDirection::AxisZ) { + double R = arrayExtent.medium(AxisDirection::AxisR) + gridConfig.offset; auto phiValues = axes[0]->getBinEdges(); auto zValues = axes[1]->getBinEdges(); ViewConfig gridRadConfig = gridConfig; @@ -103,9 +103,9 @@ void Acts::GeometryView3D::drawSurfaceArray( } } - } else if (binning[0] == BinningValue::binR && - binning[1] == BinningValue::binPhi) { - double z = arrayExtent.medium(BinningValue::binZ) + gridConfig.offset; + } else if (binning[0] == AxisDirection::AxisR && + binning[1] == AxisDirection::AxisPhi) { + double z = arrayExtent.medium(AxisDirection::AxisZ) + gridConfig.offset; auto rValues = axes[0]->getBinEdges(); auto phiValues = axes[1]->getBinEdges(); ViewConfig gridRadConfig = gridConfig; diff --git a/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/Smearers.hpp b/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/Smearers.hpp index 8d0130831ae..08c1ba06a74 100644 --- a/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/Smearers.hpp +++ b/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/Smearers.hpp @@ -8,7 +8,7 @@ #pragma once -#include "Acts/Utilities/BinningData.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Result.hpp" #include "ActsExamples/Framework/RandomNumbers.hpp" #include "ActsFatras/Digitization/DigitizationError.hpp" @@ -142,7 +142,7 @@ struct Uniform { /// Construct with a @param pitch standard deviation and @param range Uniform(double pitch, const std::pair& range_) : binningData( - Acts::open, Acts::BinningValue::binX, + Acts::open, Acts::AxisDirection::AxisX, static_cast((range_.second - range_.first) / pitch), range_.first, range_.second) {} @@ -180,7 +180,7 @@ struct Digital { /// Construct with a @param pitch standard deviation and @param range Digital(double pitch, const std::pair& range_) : binningData( - Acts::open, Acts::BinningValue::binX, + Acts::open, Acts::AxisDirection::AxisX, static_cast((range_.second - range_.first) / pitch), range_.first, range_.second) {} diff --git a/Examples/Algorithms/Digitization/scripts/smearing-config.py b/Examples/Algorithms/Digitization/scripts/smearing-config.py index 64dc1b1e3e9..61437a03aef 100644 --- a/Examples/Algorithms/Digitization/scripts/smearing-config.py +++ b/Examples/Algorithms/Digitization/scripts/smearing-config.py @@ -145,7 +145,7 @@ def block_to_json(args): data["bindata"] = [ 0, # Acts::Open, - 0, # Acts::BinningValue::binX, + 0, # Acts::AxisDirection::AxisX, (high - low) / pitch, low, high, diff --git a/Examples/Algorithms/Digitization/src/DigitizationConfigurator.cpp b/Examples/Algorithms/Digitization/src/DigitizationConfigurator.cpp index 8542b2fdd5b..fdac7783db2 100644 --- a/Examples/Algorithms/Digitization/src/DigitizationConfigurator.cpp +++ b/Examples/Algorithms/Digitization/src/DigitizationConfigurator.cpp @@ -81,17 +81,17 @@ void ActsExamples::DigitizationConfigurator::operator()( // The module is a rectangle module case Acts::SurfaceBounds::eRectangle: { if (inputSegmentation.binningData()[0].binvalue == - Acts::BinningValue::binX) { + Acts::AxisDirection::AxisX) { double minX = boundValues[Acts::RectangleBounds::eMinX]; double maxX = boundValues[Acts::RectangleBounds::eMaxX]; unsigned int nBins = static_cast(std::round( (maxX - minX) / inputSegmentation.binningData()[0].step)); outputSegmentation += Acts::BinUtility( nBins, static_cast(minX), static_cast(maxX), - Acts::open, Acts::BinningValue::binX); + Acts::open, Acts::AxisDirection::AxisX); } if (inputSegmentation.binningData()[0].binvalue == - Acts::BinningValue::binY || + Acts::AxisDirection::AxisY || inputSegmentation.dimensions() == 2) { unsigned int accessBin = inputSegmentation.dimensions() == 2 ? 1 : 0; @@ -102,14 +102,14 @@ void ActsExamples::DigitizationConfigurator::operator()( inputSegmentation.binningData()[accessBin].step)); outputSegmentation += Acts::BinUtility( nBins, static_cast(minY), static_cast(maxY), - Acts::open, Acts::BinningValue::binY); + Acts::open, Acts::AxisDirection::AxisY); } } break; // The module is a trapezoid module case Acts::SurfaceBounds::eTrapezoid: { if (inputSegmentation.binningData()[0].binvalue == - Acts::BinningValue::binX) { + Acts::AxisDirection::AxisX) { double maxX = std::max( boundValues[Acts::TrapezoidBounds::eHalfLengthXnegY], boundValues[Acts::TrapezoidBounds::eHalfLengthXposY]); @@ -117,10 +117,10 @@ void ActsExamples::DigitizationConfigurator::operator()( 2 * maxX / inputSegmentation.binningData()[0].step)); outputSegmentation += Acts::BinUtility( nBins, -static_cast(maxX), static_cast(maxX), - Acts::open, Acts::BinningValue::binX); + Acts::open, Acts::AxisDirection::AxisX); } if (inputSegmentation.binningData()[0].binvalue == - Acts::BinningValue::binY || + Acts::AxisDirection::AxisY || inputSegmentation.dimensions() == 2) { unsigned int accessBin = inputSegmentation.dimensions() == 2 ? 1 : 0; @@ -130,24 +130,24 @@ void ActsExamples::DigitizationConfigurator::operator()( inputSegmentation.binningData()[accessBin].step)); outputSegmentation += Acts::BinUtility( nBins, -static_cast(maxY), static_cast(maxY), - Acts::open, Acts::BinningValue::binY); + Acts::open, Acts::AxisDirection::AxisY); } } break; // The module is an annulus module case Acts::SurfaceBounds::eAnnulus: { if (inputSegmentation.binningData()[0].binvalue == - Acts::BinningValue::binR) { + Acts::AxisDirection::AxisR) { double minR = boundValues[Acts::AnnulusBounds::eMinR]; double maxR = boundValues[Acts::AnnulusBounds::eMaxR]; unsigned int nBins = static_cast(std::round( (maxR - minR) / inputSegmentation.binningData()[0].step)); outputSegmentation += Acts::BinUtility( nBins, static_cast(minR), static_cast(maxR), - Acts::open, Acts::BinningValue::binR); + Acts::open, Acts::AxisDirection::AxisR); } if (inputSegmentation.binningData()[0].binvalue == - Acts::BinningValue::binPhi || + Acts::AxisDirection::AxisPhi || inputSegmentation.dimensions() == 2) { unsigned int accessBin = inputSegmentation.dimensions() == 2 ? 1 : 0; @@ -161,7 +161,7 @@ void ActsExamples::DigitizationConfigurator::operator()( inputSegmentation.binningData()[accessBin].step)); outputSegmentation += Acts::BinUtility( nBins, static_cast(minPhi), static_cast(maxPhi), - Acts::open, Acts::BinningValue::binPhi); + Acts::open, Acts::AxisDirection::AxisPhi); } } break; @@ -172,15 +172,15 @@ void ActsExamples::DigitizationConfigurator::operator()( double maxR = boundValues[Acts::DiscTrapezoidBounds::eMaxR]; if (inputSegmentation.binningData()[0].binvalue == - Acts::BinningValue::binR) { + Acts::AxisDirection::AxisR) { unsigned int nBins = static_cast(std::round( (maxR - minR) / inputSegmentation.binningData()[0].step)); outputSegmentation += Acts::BinUtility( nBins, static_cast(minR), static_cast(maxR), - Acts::open, Acts::BinningValue::binR); + Acts::open, Acts::AxisDirection::AxisR); } if (inputSegmentation.binningData()[0].binvalue == - Acts::BinningValue::binPhi || + Acts::AxisDirection::AxisPhi || inputSegmentation.dimensions() == 2) { unsigned int accessBin = inputSegmentation.dimensions() == 2 ? 1 : 0; @@ -199,24 +199,24 @@ void ActsExamples::DigitizationConfigurator::operator()( outputSegmentation += Acts::BinUtility( nBins, static_cast(averagePhi - alpha), static_cast(averagePhi + alpha), Acts::open, - Acts::BinningValue::binPhi); + Acts::AxisDirection::AxisPhi); } } break; case Acts::SurfaceBounds::eDisc: { if (inputSegmentation.binningData()[0].binvalue == - Acts::BinningValue::binR) { + Acts::AxisDirection::AxisR) { double minR = boundValues[Acts::RadialBounds::eMinR]; double maxR = boundValues[Acts::RadialBounds::eMaxR]; unsigned int nBins = static_cast(std::round( (maxR - minR) / inputSegmentation.binningData()[0].step)); outputSegmentation += Acts::BinUtility( nBins, static_cast(minR), static_cast(maxR), - Acts::open, Acts::BinningValue::binR); + Acts::open, Acts::AxisDirection::AxisR); } if (inputSegmentation.binningData()[0].binvalue == - Acts::BinningValue::binPhi || + Acts::AxisDirection::AxisPhi || inputSegmentation.dimensions() == 2) { unsigned int accessBin = inputSegmentation.dimensions() == 2 ? 1 : 0; @@ -232,7 +232,7 @@ void ActsExamples::DigitizationConfigurator::operator()( inputSegmentation.binningData()[accessBin].step)); outputSegmentation += Acts::BinUtility( nBins, static_cast(minPhi), static_cast(maxPhi), - Acts::open, Acts::BinningValue::binPhi); + Acts::open, Acts::AxisDirection::AxisPhi); } } break; diff --git a/Examples/Algorithms/Geant4/src/SensitiveSteppingAction.cpp b/Examples/Algorithms/Geant4/src/SensitiveSteppingAction.cpp index 9d3121cdc44..7aae103ff4a 100644 --- a/Examples/Algorithms/Geant4/src/SensitiveSteppingAction.cpp +++ b/Examples/Algorithms/Geant4/src/SensitiveSteppingAction.cpp @@ -98,7 +98,7 @@ Acts::detail::Step stepFromG4Step(const G4Step* step) { auto [preStepPosition, preStepMomentum, postStepPosition, postStepMomentum] = kinematicsOfStep(step); - pStep.navDir = Acts::Direction::Forward; + pStep.navDir = Acts::Direction::Forward(); pStep.position = 0.5 * (preStepPosition + postStepPosition).block<3, 1>(0, 0); pStep.momentum = 0.5 * (preStepMomentum + postStepMomentum).block<3, 1>(0, 0); pStep.nTotalTrials = 1; diff --git a/Examples/Algorithms/MaterialMapping/include/ActsExamples/MaterialMapping/MappingMaterialDecorator.hpp b/Examples/Algorithms/MaterialMapping/include/ActsExamples/MaterialMapping/MappingMaterialDecorator.hpp index e61d6e6ba5a..c343fbe58d6 100644 --- a/Examples/Algorithms/MaterialMapping/include/ActsExamples/MaterialMapping/MappingMaterialDecorator.hpp +++ b/Examples/Algorithms/MaterialMapping/include/ActsExamples/MaterialMapping/MappingMaterialDecorator.hpp @@ -202,11 +202,11 @@ class MappingMaterialDecorator : public IMaterialDecorator { std::numbers::pi) < Acts::s_epsilon ? Acts::closed : Acts::open, - Acts::BinningValue::binPhi); + Acts::AxisDirection::AxisPhi); bUtility += Acts::BinUtility(binning.second, static_cast(radialBounds->rMin()), static_cast(radialBounds->rMax()), - Acts::open, Acts::BinningValue::binR); + Acts::open, Acts::AxisDirection::AxisR); } if (cylinderBounds != nullptr) { bUtility += Acts::BinUtility( @@ -219,32 +219,32 @@ class MappingMaterialDecorator : public IMaterialDecorator { std::numbers::pi) < Acts::s_epsilon ? Acts::closed : Acts::open, - Acts::BinningValue::binPhi); + Acts::AxisDirection::AxisPhi); bUtility += Acts::BinUtility( binning.second, -1 * cylinderBounds->get(Acts::CylinderBounds::eHalfLengthZ), cylinderBounds->get(Acts::CylinderBounds::eHalfLengthZ), Acts::open, - Acts::BinningValue::binZ); + Acts::AxisDirection::AxisZ); } if (annulusBounds != nullptr) { bUtility += Acts::BinUtility( binning.first, annulusBounds->get(Acts::AnnulusBounds::eMinPhiRel), annulusBounds->get(Acts::AnnulusBounds::eMaxPhiRel), Acts::open, - Acts::BinningValue::binPhi); + Acts::AxisDirection::AxisPhi); bUtility += Acts::BinUtility(binning.second, static_cast(annulusBounds->rMin()), static_cast(annulusBounds->rMax()), - Acts::open, Acts::BinningValue::binR); + Acts::open, Acts::AxisDirection::AxisR); } if (rectangleBounds != nullptr) { bUtility += Acts::BinUtility( binning.first, rectangleBounds->get(Acts::RectangleBounds::eMinX), rectangleBounds->get(Acts::RectangleBounds::eMaxX), Acts::open, - Acts::BinningValue::binX); + Acts::AxisDirection::AxisX); bUtility += Acts::BinUtility( binning.second, rectangleBounds->get(Acts::RectangleBounds::eMinY), rectangleBounds->get(Acts::RectangleBounds::eMaxY), Acts::open, - Acts::BinningValue::binY); + Acts::AxisDirection::AxisY); } if (trapezoidBounds != nullptr) { double halfLengthX = std::max( @@ -253,12 +253,12 @@ class MappingMaterialDecorator : public IMaterialDecorator { bUtility += Acts::BinUtility(binning.first, static_cast(-1 * halfLengthX), static_cast(halfLengthX), - Acts::open, Acts::BinningValue::binX); + Acts::open, Acts::AxisDirection::AxisX); bUtility += Acts::BinUtility( binning.second, -1 * trapezoidBounds->get(Acts::TrapezoidBounds::eHalfLengthY), trapezoidBounds->get(Acts::TrapezoidBounds::eHalfLengthY), - Acts::open, Acts::BinningValue::binY); + Acts::open, Acts::AxisDirection::AxisY); } } return std::make_shared(bUtility); diff --git a/Examples/Algorithms/Propagation/src/SimHitToSummaryConversion.cpp b/Examples/Algorithms/Propagation/src/SimHitToSummaryConversion.cpp index a653794dec1..567923776c1 100644 --- a/Examples/Algorithms/Propagation/src/SimHitToSummaryConversion.cpp +++ b/Examples/Algorithms/Propagation/src/SimHitToSummaryConversion.cpp @@ -99,7 +99,7 @@ ActsExamples::ProcessCode ActsExamples::SimHitToSummaryConversion::execute( step.position = Acts::Vector3(hx, hy, hz); step.momentum = simHit.direction(); step.geoID = moduleGeoId; - step.navDir = Acts::Direction::Forward; + step.navDir = Acts::Direction::Forward(); moduleSteps[paritcleId].push_back(step); } // Loop over and fill into the trackSteps diff --git a/Examples/Algorithms/Traccc/include/ActsExamples/Traccc/DetrayPropagator.hpp b/Examples/Algorithms/Traccc/include/ActsExamples/Traccc/DetrayPropagator.hpp index d27902c7739..27c435c80fb 100644 --- a/Examples/Algorithms/Traccc/include/ActsExamples/Traccc/DetrayPropagator.hpp +++ b/Examples/Algorithms/Traccc/include/ActsExamples/Traccc/DetrayPropagator.hpp @@ -129,8 +129,9 @@ class DetrayPropagator : public PropagatorInterface { Acts::detail::Step step; step.position = Acts::Vector3(dposition[0], dposition[1], dposition[2]); step.geoID = geoID; - step.navDir = object.intersection.direction ? Acts::Direction::Forward - : Acts::Direction::Backward; + step.navDir = object.intersection.direction + ? Acts::Direction::Forward() + : Acts::Direction::Backward(); summary.steps.emplace_back(step); } } else { diff --git a/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/GbtsSeedingAlgorithm.hpp b/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/GbtsSeedingAlgorithm.hpp index b422eab9e85..97ed34e8db3 100644 --- a/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/GbtsSeedingAlgorithm.hpp +++ b/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/GbtsSeedingAlgorithm.hpp @@ -10,7 +10,6 @@ #pragma once -#include "Acts/Seeding/SeedFilterConfig.hpp" #include "Acts/Seeding/SeedFinderGbts.hpp" #include "Acts/Seeding/SeedFinderGbtsConfig.hpp" #include "ActsExamples/EventData/Cluster.hpp" @@ -36,7 +35,6 @@ class GbtsSeedingAlgorithm final : public IAlgorithm { std::string outputSeeds; - Acts::SeedFilterConfig seedFilterConfig; Acts::SeedFinderGbtsConfig seedFinderConfig; Acts::SeedFinderOptions seedFinderOptions; diff --git a/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/TrackFindingAlgorithm.hpp b/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/TrackFindingAlgorithm.hpp index 804d554515d..cafaa8e524e 100644 --- a/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/TrackFindingAlgorithm.hpp +++ b/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/TrackFindingAlgorithm.hpp @@ -53,8 +53,7 @@ class TrackFindingAlgorithm final : public IAlgorithm { /// Track finder function that takes input measurements, initial trackstate /// and track finder options and returns some track-finder-specific result. using TrackFinderOptions = - Acts::CombinatorialKalmanFilterOptions; + Acts::CombinatorialKalmanFilterOptions; using TrackFinderResult = Acts::Result>; diff --git a/Examples/Algorithms/TrackFinding/src/GbtsSeedingAlgorithm.cpp b/Examples/Algorithms/TrackFinding/src/GbtsSeedingAlgorithm.cpp index c126225aea1..a129a8a65d4 100644 --- a/Examples/Algorithms/TrackFinding/src/GbtsSeedingAlgorithm.cpp +++ b/Examples/Algorithms/TrackFinding/src/GbtsSeedingAlgorithm.cpp @@ -9,7 +9,6 @@ #include "ActsExamples/TrackFinding/GbtsSeedingAlgorithm.hpp" #include "Acts/Geometry/GeometryIdentifier.hpp" -#include "Acts/Seeding/SeedFilter.hpp" #include "ActsExamples/EventData/IndexSourceLink.hpp" #include "ActsExamples/EventData/Measurement.hpp" #include "ActsExamples/EventData/ProtoTrack.hpp" @@ -39,8 +38,6 @@ ActsExamples::GbtsSeedingAlgorithm::GbtsSeedingAlgorithm( // fill config struct m_cfg.layerMappingFile = m_cfg.layerMappingFile; - m_cfg.seedFilterConfig = m_cfg.seedFilterConfig.toInternalUnits(); - m_cfg.seedFinderConfig = m_cfg.seedFinderConfig.toInternalUnits().calculateDerivedQuantities(); @@ -70,7 +67,7 @@ ActsExamples::GbtsSeedingAlgorithm::GbtsSeedingAlgorithm( m_cfg.seedFinderConfig.m_layerGeometry = LayerNumbering(); std::ifstream input_ifstream( - m_cfg.seedFinderConfig.connector_input_file.c_str(), std::ifstream::in); + m_cfg.seedFinderConfig.ConnectorInputFile.c_str(), std::ifstream::in); // connector std::unique_ptr inputConnector = @@ -89,16 +86,14 @@ ActsExamples::ProcessCode ActsExamples::GbtsSeedingAlgorithm::execute( MakeGbtsSpacePoints(ctx, m_cfg.ActsGbtsMap); for (auto sp : GbtsSpacePoints) { - ACTS_DEBUG("Gbts space points: Gbts_id: " - << sp.gbtsID << " z: " << sp.SP->z() << " r: " << sp.SP->r() - << " ACTS volume: " - << sp.SP->sourceLinks() - .front() - .get() - .geometryId() - .volume()); + const auto &links = sp.SP->sourceLinks(); + if (!links.empty()) { + ACTS_DEBUG("Gbts space points: Gbts_id: " + << sp.gbtsID << " z: " << sp.SP->z() << " r: " << sp.SP->r() + << " ACTS volume: " + << links.front().get().geometryId().volume()); + } } - // this is now calling on a core algorithm Acts::SeedFinderGbts finder( m_cfg.seedFinderConfig, *m_gbtsGeo, @@ -222,8 +217,11 @@ ActsExamples::GbtsSeedingAlgorithm::MakeGbtsSpacePoints( int eta_mod = Find->second.second; int combined_id = Gbts_id * 1000 + eta_mod; + float ClusterWidth = + 0; // false input as this is not available in examples // fill Gbts vector with current sapce point and ID - gbtsSpacePoints.emplace_back(&spacePoint, Gbts_id, combined_id); + gbtsSpacePoints.emplace_back(&spacePoint, Gbts_id, combined_id, + ClusterWidth); // make new GbtsSP here ! } } ACTS_VERBOSE("Space points successfully assigned Gbts ID"); diff --git a/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp b/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp index 53b47a86d07..8169bba61c7 100644 --- a/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp +++ b/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp @@ -27,6 +27,7 @@ #include "Acts/Surfaces/PerigeeSurface.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/TrackFinding/CombinatorialKalmanFilter.hpp" +#include "Acts/TrackFinding/TrackStateCreator.hpp" #include "Acts/TrackFitting/GainMatrixUpdater.hpp" #include "Acts/Utilities/Enumerate.hpp" #include "Acts/Utilities/Logger.hpp" @@ -318,33 +319,40 @@ ProcessCode TrackFindingAlgorithm::execute(const AlgorithmContext& ctx) const { PassThroughCalibrator pcalibrator; MeasurementCalibratorAdapter calibrator(pcalibrator, measurements); Acts::GainMatrixUpdater kfUpdater; - MeasurementSelector measSel{ - Acts::MeasurementSelector(m_cfg.measurementSelectorCfg)}; using Extensions = Acts::CombinatorialKalmanFilterExtensions; BranchStopper branchStopper(m_cfg); + MeasurementSelector measSel{ + Acts::MeasurementSelector(m_cfg.measurementSelectorCfg)}; + + IndexSourceLinkAccessor slAccessor; + slAccessor.container = &measurements.orderedIndices(); + + using TrackStateCreatorType = + Acts::TrackStateCreator; + TrackStateCreatorType trackStateCreator; + trackStateCreator.sourceLinkAccessor + .template connect<&IndexSourceLinkAccessor::range>(&slAccessor); + trackStateCreator.calibrator + .template connect<&MeasurementCalibratorAdapter::calibrate>(&calibrator); + trackStateCreator.measurementSelector + .template connect<&MeasurementSelector::select>(&measSel); Extensions extensions; - extensions.calibrator.connect<&MeasurementCalibratorAdapter::calibrate>( - &calibrator); extensions.updater.connect<&Acts::GainMatrixUpdater::operator()< typename TrackContainer::TrackStateContainerBackend>>(&kfUpdater); - extensions.measurementSelector.connect<&MeasurementSelector::select>( - &measSel); extensions.branchStopper.connect<&BranchStopper::operator()>(&branchStopper); - - IndexSourceLinkAccessor slAccessor; - slAccessor.container = &measurements.orderedIndices(); - Acts::SourceLinkAccessorDelegate - slAccessorDelegate; - slAccessorDelegate.connect<&IndexSourceLinkAccessor::range>(&slAccessor); + extensions.createTrackStates + .template connect<&TrackStateCreatorType ::createTrackStates>( + &trackStateCreator); Acts::PropagatorPlainOptions firstPropOptions(ctx.geoContext, ctx.magFieldContext); firstPropOptions.maxSteps = m_cfg.maxSteps; - firstPropOptions.direction = m_cfg.reverseSearch ? Acts::Direction::Backward - : Acts::Direction::Forward; + firstPropOptions.direction = m_cfg.reverseSearch ? Acts::Direction::Backward() + : Acts::Direction::Forward(); firstPropOptions.constrainToVolumeIds = m_cfg.constrainToVolumeIds; firstPropOptions.endOfWorldVolumeIds = m_cfg.endOfWorldVolumeIds; @@ -357,13 +365,14 @@ ProcessCode TrackFindingAlgorithm::execute(const AlgorithmContext& ctx) const { // Set the CombinatorialKalmanFilter options TrackFinderOptions firstOptions(ctx.geoContext, ctx.magFieldContext, - ctx.calibContext, slAccessorDelegate, - extensions, firstPropOptions); + ctx.calibContext, extensions, + firstPropOptions); + firstOptions.targetSurface = m_cfg.reverseSearch ? pSurface.get() : nullptr; TrackFinderOptions secondOptions(ctx.geoContext, ctx.magFieldContext, - ctx.calibContext, slAccessorDelegate, - extensions, secondPropOptions); + ctx.calibContext, extensions, + secondPropOptions); secondOptions.targetSurface = m_cfg.reverseSearch ? nullptr : pSurface.get(); secondOptions.skipPrePropagationUpdate = true; diff --git a/Examples/Algorithms/TrackFindingExaTrkX/src/TrackFindingFromPrototrackAlgorithm.cpp b/Examples/Algorithms/TrackFindingExaTrkX/src/TrackFindingFromPrototrackAlgorithm.cpp index bf28b1743ba..2dab3e1a360 100644 --- a/Examples/Algorithms/TrackFindingExaTrkX/src/TrackFindingFromPrototrackAlgorithm.cpp +++ b/Examples/Algorithms/TrackFindingExaTrkX/src/TrackFindingFromPrototrackAlgorithm.cpp @@ -9,6 +9,7 @@ #include "ActsExamples/TrackFindingExaTrkX/TrackFindingFromPrototrackAlgorithm.hpp" #include "Acts/EventData/ProxyAccessor.hpp" +#include "Acts/TrackFinding/TrackStateCreator.hpp" #include "ActsExamples/EventData/IndexSourceLink.hpp" #include "ActsExamples/EventData/MeasurementCalibration.hpp" @@ -86,28 +87,35 @@ ActsExamples::ProcessCode TrackFindingFromPrototrackAlgorithm::execute( Acts::GainMatrixSmoother kfSmoother; Acts::MeasurementSelector measSel{m_cfg.measurementSelectorCfg}; - Acts::CombinatorialKalmanFilterExtensions extensions; - extensions.calibrator.connect<&MeasurementCalibratorAdapter::calibrate>( - &calibrator); - extensions.updater.connect<&Acts::GainMatrixUpdater::operator()< - typename TrackContainer::TrackStateContainerBackend>>(&kfUpdater); - extensions.measurementSelector.connect<&Acts::MeasurementSelector::select< - typename TrackContainer::TrackStateContainerBackend>>(&measSel); - // The source link accessor ProtoTrackSourceLinkAccessor sourceLinkAccessor; sourceLinkAccessor.loggerPtr = logger().clone("SourceLinkAccessor"); sourceLinkAccessor.container = &measurements.orderedIndices(); - Acts::SourceLinkAccessorDelegate - slAccessorDelegate; - slAccessorDelegate.connect<&ProtoTrackSourceLinkAccessor::range>( - &sourceLinkAccessor); + using TrackStateCreatorType = + Acts::TrackStateCreator; + TrackStateCreatorType trackStateCreator; + trackStateCreator.sourceLinkAccessor + .template connect<&ProtoTrackSourceLinkAccessor::range>( + &sourceLinkAccessor); + trackStateCreator.calibrator + .connect<&MeasurementCalibratorAdapter::calibrate>(&calibrator); + trackStateCreator.measurementSelector + .connect<&Acts::MeasurementSelector::select< + typename TrackContainer::TrackStateContainerBackend>>(&measSel); + + Acts::CombinatorialKalmanFilterExtensions extensions; + extensions.updater.connect<&Acts::GainMatrixUpdater::operator()< + typename TrackContainer::TrackStateContainerBackend>>(&kfUpdater); + extensions.createTrackStates + .template connect<&TrackStateCreatorType ::createTrackStates>( + &trackStateCreator); // Set the CombinatorialKalmanFilter options TrackFindingAlgorithm::TrackFinderOptions options( - ctx.geoContext, ctx.magFieldContext, ctx.calibContext, slAccessorDelegate, - extensions, pOptions, &(*pSurface)); + ctx.geoContext, ctx.magFieldContext, ctx.calibContext, extensions, + pOptions, &(*pSurface)); // Perform the track finding for all initial parameters ACTS_DEBUG("Invoke track finding with " << initialParameters.size() diff --git a/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/BuildGenericDetector.hpp b/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/BuildGenericDetector.hpp index aea978be935..f5f8f793f90 100644 --- a/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/BuildGenericDetector.hpp +++ b/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/BuildGenericDetector.hpp @@ -156,20 +156,21 @@ std::unique_ptr buildDetector( // Prepare the proto material - in case it's designed to do so // - cylindrical Acts::BinUtility pCylinderUtility(10, -1, 1, Acts::closed, - Acts::BinningValue::binPhi); + Acts::AxisDirection::AxisPhi); pCylinderUtility += - Acts::BinUtility(10, -1, 1, Acts::open, Acts::BinningValue::binZ); + Acts::BinUtility(10, -1, 1, Acts::open, Acts::AxisDirection::AxisZ); auto pCylinderMaterial = std::make_shared(pCylinderUtility); // - disc - Acts::BinUtility pDiscUtility(10, 0, 1, Acts::open, Acts::BinningValue::binR); + Acts::BinUtility pDiscUtility(10, 0, 1, Acts::open, + Acts::AxisDirection::AxisR); pDiscUtility += - Acts::BinUtility(10, -1, 1, Acts::closed, Acts::BinningValue::binPhi); + Acts::BinUtility(10, -1, 1, Acts::closed, Acts::AxisDirection::AxisPhi); auto pDiscMaterial = std::make_shared(pDiscUtility); // - plane Acts::BinUtility pPlaneUtility(1, -1, 1, Acts::open, - Acts::BinningValue::binX); + Acts::AxisDirection::AxisX); auto pPlaneMaterial = std::make_shared(pPlaneUtility); diff --git a/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/ProtoLayerCreatorT.hpp b/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/ProtoLayerCreatorT.hpp index d8e1ce24fb0..9eca8f20de5 100644 --- a/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/ProtoLayerCreatorT.hpp +++ b/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/ProtoLayerCreatorT.hpp @@ -280,14 +280,14 @@ ProtoLayerCreatorT::centralProtoLayers( auto moduleTransform = std::const_pointer_cast( mutableModuleTransform); // create the module - auto module = std::make_shared( + auto moduleElement = std::make_shared( moduleIdentifier, moduleTransform, moduleBounds, moduleThickness, moduleMaterialPtr); // put the module into the detector store - layerStore.push_back(module); + layerStore.push_back(moduleElement); // register the surface - sVector.push_back(module->surface().getSharedPtr()); + sVector.push_back(moduleElement->surface().getSharedPtr()); // IF double modules exist // and the backside one (if configured to do so) if (!m_cfg.centralModuleBacksideGap.empty()) { @@ -311,11 +311,11 @@ ProtoLayerCreatorT::centralProtoLayers( moduleTransform = std::const_pointer_cast( mutableModuleTransform); // create the backseide moulde - auto bsmodule = std::make_shared( + auto bsModuleElement = std::make_shared( moduleIdentifier, moduleTransform, moduleBounds, moduleThickness, moduleMaterialPtr); // everything is set for the next module - layerStore.push_back(std::move(bsmodule)); + layerStore.push_back(std::move(bsModuleElement)); } } @@ -326,10 +326,10 @@ ProtoLayerCreatorT::centralProtoLayers( // create the surface array - it will also fill the accessible binmember // cache if available Acts::ProtoLayer pl(gctx, sVector); - pl.envelope[Acts::BinningValue::binR] = {m_cfg.approachSurfaceEnvelope, - m_cfg.approachSurfaceEnvelope}; - pl.envelope[Acts::BinningValue::binZ] = {layerEnvelopeCoverZ, - layerEnvelopeCoverZ}; + pl.envelope[Acts::AxisDirection::AxisR] = {m_cfg.approachSurfaceEnvelope, + m_cfg.approachSurfaceEnvelope}; + pl.envelope[Acts::AxisDirection::AxisZ] = {layerEnvelopeCoverZ, + layerEnvelopeCoverZ}; // Record the proto layer and the surfaces for the later layer building ProtoLayerSurfaces pls{std::move(pl), sVector, phiBins, zBins}; @@ -456,10 +456,10 @@ ProtoLayerCreatorT::createProtoLayers( static_cast(imodule++); // create the module - auto module = std::make_shared( + auto moduleElement = std::make_shared( moduleIdentifier, moduleTransform, moduleBounds, moduleThickness, moduleMaterialPtr); - layerStore.push_back(module); + layerStore.push_back(moduleElement); // now deal with the potential backside if (!m_cfg.posnegModuleBacksideGap.empty()) { @@ -485,14 +485,14 @@ ProtoLayerCreatorT::createProtoLayers( moduleTransform = std::const_pointer_cast( mutableModuleTransform); // everything is set for the next module - auto bsmodule = std::make_shared( + auto bsModuleElement = std::make_shared( moduleIdentifier, moduleTransform, moduleBounds, moduleThickness, moduleMaterialPtr); // Put into the detector store - layerStore.push_back(std::move(bsmodule)); + layerStore.push_back(std::move(bsModuleElement)); } // create the surface - esVector.push_back(module->surface().getSharedPtr()); + esVector.push_back(moduleElement->surface().getSharedPtr()); } // counter of rings ++ipnR; @@ -512,9 +512,10 @@ ProtoLayerCreatorT::createProtoLayers( } // create the layers with the surface arrays Acts::ProtoLayer ple(gctx, esVector); - ple.envelope[Acts::BinningValue::binR] = {layerEnvelopeR, layerEnvelopeR}; - ple.envelope[Acts::BinningValue::binZ] = {m_cfg.approachSurfaceEnvelope, - m_cfg.approachSurfaceEnvelope}; + ple.envelope[Acts::AxisDirection::AxisR] = {layerEnvelopeR, + layerEnvelopeR}; + ple.envelope[Acts::AxisDirection::AxisZ] = { + m_cfg.approachSurfaceEnvelope, m_cfg.approachSurfaceEnvelope}; // push it into the layer vector ProtoLayerSurfaces ples{std::move(ple), esVector, layerBinsR, diff --git a/Examples/Detectors/MagneticField/include/ActsExamples/MagneticField/MagneticField.hpp b/Examples/Detectors/MagneticField/include/ActsExamples/MagneticField/MagneticField.hpp index e694f0fdd35..9e1997e97a2 100644 --- a/Examples/Detectors/MagneticField/include/ActsExamples/MagneticField/MagneticField.hpp +++ b/Examples/Detectors/MagneticField/include/ActsExamples/MagneticField/MagneticField.hpp @@ -14,7 +14,7 @@ #include "Acts/MagneticField/MagneticFieldProvider.hpp" #include "Acts/MagneticField/NullBField.hpp" #include "Acts/Utilities/Axis.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Grid.hpp" #include "Acts/Utilities/Result.hpp" #include "Acts/Utilities/detail/grid_helper.hpp" diff --git a/Examples/Detectors/TGeoDetector/src/TGeoDetector.cpp b/Examples/Detectors/TGeoDetector/src/TGeoDetector.cpp index 884cfc8345d..4b6c2982fe3 100644 --- a/Examples/Detectors/TGeoDetector/src/TGeoDetector.cpp +++ b/Examples/Detectors/TGeoDetector/src/TGeoDetector.cpp @@ -63,14 +63,14 @@ std::vector makeLayerBuilderConfigs( // configure surface autobinning std::vector> binTolerances( - Acts::numBinningValues(), {0., 0.}); - binTolerances[toUnderlying(Acts::BinningValue::binR)] = { + Acts::numAxisDirections(), {0., 0.}); + binTolerances[toUnderlying(Acts::AxisDirection::AxisR)] = { volume.binToleranceR.lower.value_or(0.), volume.binToleranceR.upper.value_or(0.)}; - binTolerances[toUnderlying(Acts::BinningValue::binZ)] = { + binTolerances[toUnderlying(Acts::AxisDirection::AxisZ)] = { volume.binToleranceZ.lower.value_or(0.), volume.binToleranceZ.upper.value_or(0.)}; - binTolerances[toUnderlying(Acts::BinningValue::binPhi)] = { + binTolerances[toUnderlying(Acts::AxisDirection::AxisPhi)] = { volume.binTolerancePhi.lower.value_or(0.), volume.binTolerancePhi.upper.value_or(0.)}; @@ -101,18 +101,18 @@ std::vector makeLayerBuilderConfigs( auto zMin = zR.lower.value_or(-std::numeric_limits::max()); auto zMax = zR.upper.value_or(std::numeric_limits::max()); lConfig.parseRanges = { - {Acts::BinningValue::binR, {rMin, rMax}}, - {Acts::BinningValue::binZ, {zMin, zMax}}, + {Acts::AxisDirection::AxisR, {rMin, rMax}}, + {Acts::AxisDirection::AxisZ, {zMin, zMax}}, }; // Fill the layer splitting parameters in r/z auto str = volume.splitTolR.at(ncp); auto stz = volume.splitTolZ.at(ncp); if (0 < str) { - lConfig.splitConfigs.emplace_back(Acts::BinningValue::binR, str); + lConfig.splitConfigs.emplace_back(Acts::AxisDirection::AxisR, str); } if (0 < stz) { - lConfig.splitConfigs.emplace_back(Acts::BinningValue::binZ, stz); + lConfig.splitConfigs.emplace_back(Acts::AxisDirection::AxisZ, stz); } lConfig.binning0 = volume.binning0.at(ncp); lConfig.binning1 = volume.binning1.at(ncp); @@ -284,7 +284,7 @@ std::shared_ptr buildTGeoDetector( -> void { for (const auto& lcfg : lConfigs) { for (const auto& scfg : lcfg.splitConfigs) { - if (scfg.first == Acts::BinningValue::binR && scfg.second > 0.) { + if (scfg.first == Acts::AxisDirection::AxisR && scfg.second > 0.) { volumeConfig.ringTolerance = std::max(volumeConfig.ringTolerance, scfg.second); volumeConfig.checkRingLayout = true; diff --git a/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/BuildTelescopeDetector.hpp b/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/BuildTelescopeDetector.hpp index 6e3b4e31cdf..f79621bea6f 100644 --- a/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/BuildTelescopeDetector.hpp +++ b/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/BuildTelescopeDetector.hpp @@ -9,7 +9,7 @@ #pragma once #include "Acts/Geometry/TrackingGeometry.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include #include @@ -51,6 +51,6 @@ std::unique_ptr buildTelescopeDetector( const std::vector& stereoAngles, const std::array& offsets, const std::array& bounds, double thickness, TelescopeSurfaceType surfaceType, - Acts::BinningValue binValue = Acts::BinningValue::binZ); + Acts::AxisDirection binValue = Acts::AxisDirection::AxisZ); } // namespace ActsExamples diff --git a/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/TelescopeDetector.hpp b/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/TelescopeDetector.hpp index 17145d4d301..679e3bb066f 100644 --- a/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/TelescopeDetector.hpp +++ b/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/TelescopeDetector.hpp @@ -9,6 +9,7 @@ #pragma once #include "Acts/Definitions/Units.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Logger.hpp" #include "ActsExamples/DetectorCommons/Detector.hpp" diff --git a/Examples/Detectors/TelescopeDetector/src/BuildTelescopeDetector.cpp b/Examples/Detectors/TelescopeDetector/src/BuildTelescopeDetector.cpp index d436d577235..2232867e6d8 100644 --- a/Examples/Detectors/TelescopeDetector/src/BuildTelescopeDetector.cpp +++ b/Examples/Detectors/TelescopeDetector/src/BuildTelescopeDetector.cpp @@ -44,7 +44,7 @@ ActsExamples::buildTelescopeDetector( const std::vector& stereoAngles, const std::array& offsets, const std::array& bounds, double thickness, TelescopeSurfaceType surfaceType, - Acts::BinningValue binValue) { + Acts::AxisDirection binValue) { using namespace Acts::UnitLiterals; // The rectangle bounds for plane surface @@ -62,14 +62,14 @@ ActsExamples::buildTelescopeDetector( std::make_shared(matProp); // Construct the rotation - // This assumes the binValue is binX, binY or binZ. No reset is necessary in - // case of binZ + // This assumes the direction is AxisX, AxisY or AxisZ. No reset is necessary + // in case of AxisZ Acts::RotationMatrix3 rotation = Acts::RotationMatrix3::Identity(); - if (binValue == Acts::BinningValue::binX) { + if (binValue == Acts::AxisDirection::AxisX) { rotation.col(0) = Acts::Vector3(0, 0, -1); rotation.col(1) = Acts::Vector3(0, 1, 0); rotation.col(2) = Acts::Vector3(1, 0, 0); - } else if (binValue == Acts::BinningValue::binY) { + } else if (binValue == Acts::AxisDirection::AxisY) { rotation.col(0) = Acts::Vector3(1, 0, 0); rotation.col(1) = Acts::Vector3(0, 0, -1); rotation.col(2) = Acts::Vector3(0, 1, 0); diff --git a/Examples/Detectors/TelescopeDetector/src/TelescopeDetector.cpp b/Examples/Detectors/TelescopeDetector/src/TelescopeDetector.cpp index 414658204b8..a3ccfb34cfd 100644 --- a/Examples/Detectors/TelescopeDetector/src/TelescopeDetector.cpp +++ b/Examples/Detectors/TelescopeDetector/src/TelescopeDetector.cpp @@ -44,7 +44,7 @@ TelescopeDetector::TelescopeDetector(const Config& cfg) m_nominalGeometryContext, m_detectorStore, m_cfg.positions, m_cfg.stereos, m_cfg.offsets, m_cfg.bounds, m_cfg.thickness, static_cast(m_cfg.surfaceType), - static_cast(m_cfg.binValue)); + static_cast(m_cfg.binValue)); } } // namespace ActsExamples diff --git a/Examples/Detectors/TelescopeDetector/src/TelescopeG4DetectorConstruction.cpp b/Examples/Detectors/TelescopeDetector/src/TelescopeG4DetectorConstruction.cpp index 2566c069f61..157204be9df 100644 --- a/Examples/Detectors/TelescopeDetector/src/TelescopeG4DetectorConstruction.cpp +++ b/Examples/Detectors/TelescopeDetector/src/TelescopeG4DetectorConstruction.cpp @@ -65,14 +65,14 @@ G4VPhysicalVolume* TelescopeG4DetectorConstruction::Construct() { new G4Material("Silicon", 14, 28.0855 * g / mole, 2.329 * g / cm3); // Construct the rotation - // This assumes the binValue is BinningValue::binX, BinningValue::binY or - // BinningValue::binZ. No reset is necessary in case of BinningValue::binZ + // This assumes the binValue is AxisDirection::AxisX, AxisDirection::AxisY or + // AxisDirection::AxisZ. No reset is necessary in case of AxisDirection::AxisZ G4RotationMatrix* rotation = nullptr; - if (static_cast(m_cfg.binValue) == - Acts::BinningValue::binX) { + if (static_cast(m_cfg.binValue) == + Acts::AxisDirection::AxisX) { rotation = new G4RotationMatrix({0, 0, 1}, {0, 1, 0}, {-1, 0, 0}); - } else if (static_cast(m_cfg.binValue) == - Acts::BinningValue::binY) { + } else if (static_cast(m_cfg.binValue) == + Acts::AxisDirection::AxisY) { rotation = new G4RotationMatrix({1, 0, 0}, {0, 0, 1}, {0, -1, 0}); } diff --git a/Examples/Framework/CMakeLists.txt b/Examples/Framework/CMakeLists.txt index 032627e0b89..26e280b4dd3 100644 --- a/Examples/Framework/CMakeLists.txt +++ b/Examples/Framework/CMakeLists.txt @@ -15,6 +15,7 @@ add_library( src/Framework/RandomNumbers.cpp src/Framework/Sequencer.cpp src/Framework/DataHandle.cpp + src/Framework/BufferedReader.cpp src/Utilities/EventDataTransforms.cpp src/Utilities/Paths.cpp src/Utilities/Options.cpp diff --git a/Examples/Framework/include/ActsExamples/EventData/GeometryContainers.hpp b/Examples/Framework/include/ActsExamples/EventData/GeometryContainers.hpp index e88e8e9db38..3ffb0c0ac3b 100644 --- a/Examples/Framework/include/ActsExamples/EventData/GeometryContainers.hpp +++ b/Examples/Framework/include/ActsExamples/EventData/GeometryContainers.hpp @@ -162,11 +162,11 @@ template inline auto selectModule(const GeometryIdMultiset& container, Acts::GeometryIdentifier::Value volume, Acts::GeometryIdentifier::Value layer, - Acts::GeometryIdentifier::Value module) { + Acts::GeometryIdentifier::Value sensitive) { return selectModule( container, Acts::GeometryIdentifier().setVolume(volume).setLayer(layer).setSensitive( - module)); + sensitive)); } /// Select all elements for the lowest non-zero identifier component. @@ -176,9 +176,9 @@ inline auto selectModule(const GeometryIdMultiset& container, /// applies to the lower components and not to intermediate zeros. /// /// Examples: -/// - volume=2,layer=0,module=3 -> select all elements in the module -/// - volume=1,layer=2,module=0 -> select all elements in the layer -/// - volume=3,layer=0,module=0 -> select all elements in the volume +/// - volume=2,layer=0,sensitive=3 -> select all elements in the sensitive +/// - volume=1,layer=2,sensitive=0 -> select all elements in the layer +/// - volume=3,layer=0,sensitive=0 -> select all elements in the volume /// /// @note An identifier with all components set to zero selects the whole input /// container. diff --git a/Examples/Framework/include/ActsExamples/Framework/BufferedReader.hpp b/Examples/Framework/include/ActsExamples/Framework/BufferedReader.hpp new file mode 100644 index 00000000000..5f12c5df30a --- /dev/null +++ b/Examples/Framework/include/ActsExamples/Framework/BufferedReader.hpp @@ -0,0 +1,73 @@ +// 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/Framework/AlgorithmContext.hpp" +#include "ActsExamples/Framework/IReader.hpp" +#include "ActsExamples/Framework/ProcessCode.hpp" + +#include + +namespace ActsExamples { + +class WhiteBoard; + +/// Event data reader that takes a concrete reader instance, reads a number of +/// events in a buffer, and selects events from that buffer instead of directly +/// reading them from disk. +/// The purpose is to avoid IO bottlenecks in timing measurements +class BufferedReader final : public IReader { + public: + struct Config { + /// The upstream reader that should be used + std::shared_ptr upstreamReader; + + /// The seed for sampling events from the buffer + std::size_t selectionSeed = 123456; + + /// Buffer size. The reader will throw and exception if the downstream + /// reader does not provide enough events + std::size_t bufferSize = 1; + }; + + /// Constructed the reader + BufferedReader(const Config& config, Acts::Logging::Level level); + + /// Return the config + const Config& config() const { return m_cfg; } + + /// Give the reader a understandable name + std::string name() const override { + return "Buffered" + m_cfg.upstreamReader->name(); + } + + /// The buffered reader provides the maximum available event range + std::pair availableEvents() const override { + return {0, std::numeric_limits::max()}; + } + + /// Return a event from the buffer + ProcessCode read(const AlgorithmContext& ctx) override; + + /// Fulfill the algorithm interface + ProcessCode initialize() override { return ProcessCode::SUCCESS; } + + /// Fulfill the algorithm interface + ProcessCode finalize() override { return ProcessCode::SUCCESS; } + + private: + Config m_cfg; + std::unique_ptr m_logger; + std::vector> m_buffer; + + const Acts::Logger& logger() const { return *m_logger; } +}; + +} // namespace ActsExamples diff --git a/Examples/Framework/include/ActsExamples/Framework/SequenceElement.hpp b/Examples/Framework/include/ActsExamples/Framework/SequenceElement.hpp index 4db3b8d1af6..591579af2cd 100644 --- a/Examples/Framework/include/ActsExamples/Framework/SequenceElement.hpp +++ b/Examples/Framework/include/ActsExamples/Framework/SequenceElement.hpp @@ -51,6 +51,8 @@ class SequenceElement { template friend class ReadDataHandle; + friend class BufferedReader; + std::vector m_writeHandles; std::vector m_readHandles; }; diff --git a/Examples/Framework/include/ActsExamples/Framework/Sequencer.hpp b/Examples/Framework/include/ActsExamples/Framework/Sequencer.hpp index a8f2ad27950..e7ec0285c0e 100644 --- a/Examples/Framework/include/ActsExamples/Framework/Sequencer.hpp +++ b/Examples/Framework/include/ActsExamples/Framework/Sequencer.hpp @@ -177,7 +177,7 @@ class Sequencer { std::vector m_sequenceElements; std::unique_ptr m_logger; - std::unordered_map m_whiteboardObjectAliases; + std::unordered_multimap m_whiteboardObjectAliases; std::unordered_map m_whiteBoardState; diff --git a/Examples/Framework/include/ActsExamples/Framework/WhiteBoard.hpp b/Examples/Framework/include/ActsExamples/Framework/WhiteBoard.hpp index 777d27fe898..61f73296bef 100644 --- a/Examples/Framework/include/ActsExamples/Framework/WhiteBoard.hpp +++ b/Examples/Framework/include/ActsExamples/Framework/WhiteBoard.hpp @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -34,32 +33,25 @@ namespace ActsExamples { /// Its lifetime is bound to the lifetime of the white board. class WhiteBoard { public: - WhiteBoard(std::unique_ptr logger = - Acts::getDefaultLogger("WhiteBoard", Acts::Logging::INFO), - std::unordered_map objectAliases = {}); + WhiteBoard( + std::unique_ptr logger = + Acts::getDefaultLogger("WhiteBoard", Acts::Logging::INFO), + std::unordered_multimap objectAliases = {}); - // A WhiteBoard holds unique elements and can not be copied WhiteBoard(const WhiteBoard& other) = delete; WhiteBoard& operator=(const WhiteBoard&) = delete; + WhiteBoard(WhiteBoard&& other) = default; + WhiteBoard& operator=(WhiteBoard&& other) = default; + bool exists(const std::string& name) const; - private: - /// Store an object on the white board and transfer ownership. - /// - /// @param name Non-empty identifier to store it under - /// @param object Movable reference to the transferable object - /// @throws std::invalid_argument on empty or duplicate name - template - void add(const std::string& name, T&& object); - - /// Get access to a stored object. - /// - /// @param[in] name Identifier for the object - /// @return reference to the stored object - /// @throws std::out_of_range if no object is stored under the requested name - template - const T& get(const std::string& name) const; + /// Copies key from another whiteboard to this whiteboard. + /// This is a low overhead operation, since the data holders are + /// shared pointers. + /// Throws an exception if this whiteboard already contains one of + /// the keys in the other whiteboard. + void copyFrom(const WhiteBoard& other); private: /// Find similar names for suggestions with levenshtein-distance @@ -80,9 +72,34 @@ class WhiteBoard { const std::type_info& type() const override { return typeid(T); } }; + /// Store a holder on the white board. + /// + /// @param name Non-empty identifier to store it under + /// @param holder The holder to store + /// @throws std::invalid_argument on empty or duplicate name + void addHolder(const std::string& name, + const std::shared_ptr& holder); + + /// Store an object on the white board and transfer ownership. + /// + /// @param name Non-empty identifier to store it under + /// @param object Movable reference to the transferable object + template + void add(const std::string& name, T&& object) { + addHolder(name, std::make_shared>(std::forward(object))); + } + + /// Get access to a stored object. + /// + /// @param[in] name Identifier for the object + /// @return reference to the stored object + /// @throws std::out_of_range if no object is stored under the requested name + template + const T& get(const std::string& name) const; + std::unique_ptr m_logger; std::unordered_map> m_store; - std::unordered_map m_objectAliases; + std::unordered_multimap m_objectAliases; const Acts::Logger& logger() const { return *m_logger; } @@ -100,26 +117,9 @@ class WhiteBoard { inline ActsExamples::WhiteBoard::WhiteBoard( std::unique_ptr logger, - std::unordered_map objectAliases) + std::unordered_multimap objectAliases) : m_logger(std::move(logger)), m_objectAliases(std::move(objectAliases)) {} -template -inline void ActsExamples::WhiteBoard::add(const std::string& name, T&& object) { - if (name.empty()) { - throw std::invalid_argument("Object can not have an empty name"); - } - if (m_store.contains(name)) { - throw std::invalid_argument("Object '" + name + "' already exists"); - } - auto holder = std::make_shared>(std::forward(object)); - m_store.emplace(name, holder); - ACTS_VERBOSE("Added object '" << name << "' of type " << typeid(T).name()); - if (auto it = m_objectAliases.find(name); it != m_objectAliases.end()) { - m_store[it->second] = holder; - ACTS_VERBOSE("Added alias object '" << it->second << "'"); - } -} - template inline const T& ActsExamples::WhiteBoard::get(const std::string& name) const { ACTS_VERBOSE("Attempt to get object '" << name << "' of type " diff --git a/Examples/Framework/include/ActsExamples/Utilities/Range.hpp b/Examples/Framework/include/ActsExamples/Utilities/Range.hpp index 5acc97f082b..db1574ae72c 100644 --- a/Examples/Framework/include/ActsExamples/Utilities/Range.hpp +++ b/Examples/Framework/include/ActsExamples/Utilities/Range.hpp @@ -27,10 +27,10 @@ template class Range { public: Range(Iterator b, Iterator e) : m_begin(b), m_end(e) {} - Range(Range&&) = default; + Range(Range&&) noexcept = default; Range(const Range&) = default; ~Range() = default; - Range& operator=(Range&&) = default; + Range& operator=(Range&&) noexcept = default; Range& operator=(const Range&) = default; Iterator begin() const { return m_begin; } diff --git a/Examples/Framework/src/Framework/BufferedReader.cpp b/Examples/Framework/src/Framework/BufferedReader.cpp new file mode 100644 index 00000000000..4431fd99f5d --- /dev/null +++ b/Examples/Framework/src/Framework/BufferedReader.cpp @@ -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/. + +#include "ActsExamples/Framework/BufferedReader.hpp" + +#include "Acts/Utilities/Logger.hpp" +#include "ActsExamples/Framework/AlgorithmContext.hpp" +#include "ActsExamples/Framework/WhiteBoard.hpp" + +#include +#include + +namespace ActsExamples { + +BufferedReader::BufferedReader(const Config &config, Acts::Logging::Level level) + : m_cfg(config), m_logger(Acts::getDefaultLogger(name(), level)) { + if (!m_cfg.upstreamReader) { + throw std::invalid_argument("No upstream reader provided!"); + } + + // Register write and read handles of the upstream reader + for (auto rh : m_cfg.upstreamReader->readHandles()) { + registerReadHandle(*rh); + } + + for (auto wh : m_cfg.upstreamReader->writeHandles()) { + registerWriteHandle(*wh); + } + + // Read the events + auto [ebegin, eend] = m_cfg.upstreamReader->availableEvents(); + if (eend - ebegin < m_cfg.bufferSize) { + throw std::runtime_error("Reader does not provide enough events"); + } + + ACTS_INFO("Start reading events into buffer..."); + + m_buffer.reserve(eend - ebegin); + for (auto i = ebegin; i < ebegin + m_cfg.bufferSize; ++i) { + auto board = std::make_unique(m_logger->clone()); + ActsExamples::AlgorithmContext ctx(0, i, *board); + + ACTS_DEBUG("Read event " << i << " into buffer"); + m_cfg.upstreamReader->read(ctx); + m_buffer.emplace_back(std::move(board)); + } + + ACTS_INFO("Filled " << m_buffer.size() << " events into the buffer"); +} + +ProcessCode BufferedReader::read(const AlgorithmContext &ctx) { + // Set up a random event selection that is consistent if multiple + // BufferedReader are used within a workflow The linear congruential engine is + // chosen since it is cheap to instantiate. For each eventNumber, it is put in + // a reproducible state. + std::minstd_rand rng(m_cfg.selectionSeed); + rng.discard(ctx.eventNumber); + + /// Sample from the buffer and transfer the content + std::uniform_int_distribution dist(0, m_cfg.bufferSize - 1); + + const auto entry = dist(rng); + ctx.eventStore.copyFrom(*m_buffer.at(entry)); + + ACTS_DEBUG("Use buffer entry " << entry << " for event " << ctx.eventNumber); + + return ProcessCode::SUCCESS; +} + +} // namespace ActsExamples diff --git a/Examples/Framework/src/Framework/Sequencer.cpp b/Examples/Framework/src/Framework/Sequencer.cpp index eb9bf8fd1c0..a16ef785c48 100644 --- a/Examples/Framework/src/Framework/Sequencer.cpp +++ b/Examples/Framework/src/Framework/Sequencer.cpp @@ -9,7 +9,6 @@ #include "ActsExamples/Framework/Sequencer.hpp" #include "Acts/Plugins/FpeMonitoring/FpeMonitor.hpp" -#include "Acts/Utilities/Helpers.hpp" #include "Acts/Utilities/Logger.hpp" #include "ActsExamples/Framework/AlgorithmContext.hpp" #include "ActsExamples/Framework/DataHandle.hpp" @@ -26,9 +25,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -256,20 +253,26 @@ void Sequencer::addElement(const std::shared_ptr& element) { void Sequencer::addWhiteboardAlias(const std::string& aliasName, const std::string& objectName) { - auto [it, success] = - m_whiteboardObjectAliases.insert({objectName, aliasName}); - if (!success) { - ACTS_INFO("Key '" << objectName << "' aliased to '" << aliasName - << "' already set"); - return; + const auto range = m_whiteboardObjectAliases.equal_range(objectName); + for (auto it = range.first; it != range.second; ++it) { + const auto& [key, value] = *it; + if (value == aliasName) { + ACTS_INFO("Key '" << objectName << "' aliased to '" << aliasName + << "' already set"); + return; + } } - ACTS_INFO("Key '" << objectName << "' aliased to '" << aliasName << "'"); + m_whiteboardObjectAliases.insert({objectName, aliasName}); - if (auto oit = m_whiteBoardState.find(objectName); - oit != m_whiteBoardState.end()) { - m_whiteBoardState[aliasName] = oit->second; + auto oit = m_whiteBoardState.find(objectName); + if (oit == m_whiteBoardState.end()) { + ACTS_ERROR("Key '" << objectName << "' does not exist"); + return; } + + ACTS_INFO("Key '" << objectName << "' aliased to '" << aliasName << "'"); + m_whiteBoardState[aliasName] = oit->second; } std::vector Sequencer::listAlgorithmNames() const { diff --git a/Examples/Framework/src/Framework/WhiteBoard.cpp b/Examples/Framework/src/Framework/WhiteBoard.cpp index 099eac53efc..19f300909cb 100644 --- a/Examples/Framework/src/Framework/WhiteBoard.cpp +++ b/Examples/Framework/src/Framework/WhiteBoard.cpp @@ -37,9 +37,9 @@ inline int levenshteinDistance(const std::string_view &a, } // Fill matrix - for (std::size_t j = 1; j < b.size() + 1; ++j) { - for (std::size_t i = 1; i < a.size() + 1; ++i) { - const auto substitutionCost = a[i] == b[j] ? 0 : 1; + for (std::size_t j = 1; j < b.size(); ++j) { + for (std::size_t i = 1; i < a.size(); ++i) { + const auto substitutionCost = a.at(i) == b.at(j) ? 0 : 1; std::array possibilities = {{ d(i - 1, j) + 1, // deletion @@ -67,6 +67,11 @@ std::vector ActsExamples::WhiteBoard::similarNames( names.push_back({d, n}); } } + for (const auto &[from, to] : m_objectAliases) { + if (const auto d = levenshteinDistance(from, name); d < distThreshold) { + names.push_back({d, from}); + } + } std::ranges::sort(names, {}, [](const auto &n) { return n.first; }); @@ -84,3 +89,38 @@ std::string ActsExamples::WhiteBoard::typeMismatchMessage( boost::core::demangle(req) + " but actually " + boost::core::demangle(act)}; } + +void ActsExamples::WhiteBoard::copyFrom(const WhiteBoard &other) { + for (auto &[key, val] : other.m_store) { + addHolder(key, val); + ACTS_VERBOSE("Copied key '" << key << "' to whiteboard"); + } +} + +void ActsExamples::WhiteBoard::addHolder( + const std::string &name, const std::shared_ptr &holder) { + if (name.empty()) { + throw std::invalid_argument("Object can not have an empty name"); + } + + if (holder == nullptr) { + throw std::invalid_argument("Object '" + name + "' is nullptr"); + } + + auto [storeIt, success] = m_store.insert({name, holder}); + + if (!success) { + throw std::invalid_argument("Object '" + name + "' already exists"); + } + ACTS_VERBOSE("Added object '" << name << "' of type " + << storeIt->second->type().name()); + + if (success) { + // deal with aliases + auto range = m_objectAliases.equal_range(name); + for (auto it = range.first; it != range.second; ++it) { + m_store[it->second] = holder; + ACTS_VERBOSE("Added alias object '" << it->second << "'"); + } + } +} diff --git a/Examples/Io/Root/include/ActsExamples/Io/Root/RootMaterialDecorator.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/RootMaterialDecorator.hpp index 0cc10482c9e..7397a2ae255 100644 --- a/Examples/Io/Root/include/ActsExamples/Io/Root/RootMaterialDecorator.hpp +++ b/Examples/Io/Root/include/ActsExamples/Io/Root/RootMaterialDecorator.hpp @@ -64,7 +64,7 @@ class RootMaterialDecorator : public Acts::IMaterialDecorator { std::string sentag = "_sen"; /// The bin number tag std::string ntag = "n"; - /// The value tag -> binning values: binZ, binR, binPhi, etc. + /// The value tag -> binning values: AxisZ, AxisR, AxisPhi, etc. std::string vtag = "v"; /// The option tag -> binning options: open, closed std::string otag = "o"; diff --git a/Examples/Io/Root/include/ActsExamples/Io/Root/RootMaterialWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/RootMaterialWriter.hpp index ec6142e65f9..a4c4a4675ee 100644 --- a/Examples/Io/Root/include/ActsExamples/Io/Root/RootMaterialWriter.hpp +++ b/Examples/Io/Root/include/ActsExamples/Io/Root/RootMaterialWriter.hpp @@ -85,7 +85,7 @@ class RootMaterialWriter : public IMaterialWriter { std::string sentag = "_sen"; /// The bin number tag std::string ntag = "n"; - /// The value tag -> binning values: binZ, binR, binPhi, etc. + /// The value tag -> binning values: AxisZ, AxisR, AxisPhi, etc. std::string vtag = "v"; /// The option tag -> binning options: open, closed std::string otag = "o"; diff --git a/Examples/Io/Root/src/RootAthenaDumpReader.cpp b/Examples/Io/Root/src/RootAthenaDumpReader.cpp index 421affa36ba..b791dbf2eba 100644 --- a/Examples/Io/Root/src/RootAthenaDumpReader.cpp +++ b/Examples/Io/Root/src/RootAthenaDumpReader.cpp @@ -398,8 +398,8 @@ RootAthenaDumpReader::readMeasurements( bool inside = surface->isOnSurface(gctx, cluster.globalPosition, {}, - Acts::BoundaryTolerance::AbsoluteEuclidean{ - m_cfg.absBoundaryTolerance}, + Acts::BoundaryTolerance::AbsoluteEuclidean( + m_cfg.absBoundaryTolerance), std::numeric_limits::max()); if (!inside) { diff --git a/Examples/Io/Root/src/RootMaterialDecorator.cpp b/Examples/Io/Root/src/RootMaterialDecorator.cpp index 37f396bb86c..79077fe72fd 100644 --- a/Examples/Io/Root/src/RootMaterialDecorator.cpp +++ b/Examples/Io/Root/src/RootMaterialDecorator.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -183,10 +184,8 @@ ActsExamples::RootMaterialDecorator::RootMaterialDecorator( Acts::BinUtility bUtility; for (int ib = 1; ib < n->GetNbinsX() + 1; ++ib) { std::size_t nbins = static_cast(n->GetBinContent(ib)); - Acts::BinningValue val = - static_cast(v->GetBinContent(ib)); - Acts::BinningOption opt = - static_cast(o->GetBinContent(ib)); + auto val = static_cast(v->GetBinContent(ib)); + auto opt = static_cast(o->GetBinContent(ib)); float rmin = min->GetBinContent(ib); float rmax = max->GetBinContent(ib); bUtility += Acts::BinUtility(nbins, rmin, rmax, opt, val); @@ -268,8 +267,8 @@ ActsExamples::RootMaterialDecorator::RootMaterialDecorator( Acts::BinUtility bUtility; for (int ib = 1; ib < dim + 1; ++ib) { std::size_t nbins = static_cast(n->GetBinContent(ib)); - Acts::BinningValue val = - static_cast(v->GetBinContent(ib)); + Acts::AxisDirection val = + static_cast(v->GetBinContent(ib)); Acts::BinningOption opt = static_cast(o->GetBinContent(ib)); float rmin = min->GetBinContent(ib); diff --git a/Examples/Io/Root/src/RootMeasurementWriter.cpp b/Examples/Io/Root/src/RootMeasurementWriter.cpp index df095557664..ffce34af0c3 100644 --- a/Examples/Io/Root/src/RootMeasurementWriter.cpp +++ b/Examples/Io/Root/src/RootMeasurementWriter.cpp @@ -37,6 +37,7 @@ struct RootMeasurementWriter::DigitizationTree { int volumeID = 0; int layerID = 0; int surfaceID = 0; + int extraID = 0; // Reconstruction information float recBound[Acts::eBoundSize] = {}; @@ -74,6 +75,7 @@ struct RootMeasurementWriter::DigitizationTree { tree->Branch("volume_id", &volumeID); tree->Branch("layer_id", &layerID); tree->Branch("surface_id", &surfaceID); + tree->Branch("extra_id", &extraID); for (auto ib : recoIndices) { tree->Branch(("rec_" + bNames[ib]).c_str(), &recBound[ib]); @@ -120,6 +122,7 @@ struct RootMeasurementWriter::DigitizationTree { volumeID = geoId.volume(); layerID = geoId.layer(); surfaceID = geoId.sensitive(); + extraID = geoId.extra(); } /// Convenience function to register the truth parameters diff --git a/Examples/Io/Root/src/RootPropagationStepsWriter.cpp b/Examples/Io/Root/src/RootPropagationStepsWriter.cpp index 643956a6ed1..97a94567cf6 100644 --- a/Examples/Io/Root/src/RootPropagationStepsWriter.cpp +++ b/Examples/Io/Root/src/RootPropagationStepsWriter.cpp @@ -191,9 +191,10 @@ ActsExamples::ProcessCode ActsExamples::RootPropagationStepsWriter::writeT( m_dz.push_back(direction.z()); double accuracy = step.stepSize.accuracy(); - double actor = step.stepSize.value(Acts::ConstrainedStep::actor); - double aborter = step.stepSize.value(Acts::ConstrainedStep::aborter); - double user = step.stepSize.value(Acts::ConstrainedStep::user); + double actor = + step.stepSize.value(Acts::ConstrainedStep::Type::Navigator); + double aborter = step.stepSize.value(Acts::ConstrainedStep::Type::Actor); + double user = step.stepSize.value(Acts::ConstrainedStep::Type::User); double actAbs = std::abs(actor); double accAbs = std::abs(accuracy); double aboAbs = std::abs(aborter); diff --git a/Examples/Python/CMakeLists.txt b/Examples/Python/CMakeLists.txt index acca27e91f4..610efe57c17 100644 --- a/Examples/Python/CMakeLists.txt +++ b/Examples/Python/CMakeLists.txt @@ -268,9 +268,11 @@ foreach(f ${py_files}) CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/python/acts/${f} ${_target} SYMBOLIC ) -endforeach() -install( - DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/python/acts/ - DESTINATION ${_python_install_dir} -) + get_filename_component(_rel ${f} DIRECTORY) + + install( + FILES ${CMAKE_CURRENT_SOURCE_DIR}/python/acts/${f} + DESTINATION ${_python_install_dir}/${_rel} + ) +endforeach() diff --git a/Examples/Python/python/acts/examples/reconstruction.py b/Examples/Python/python/acts/examples/reconstruction.py index 0e30961fe39..5a67f180f7b 100644 --- a/Examples/Python/python/acts/examples/reconstruction.py +++ b/Examples/Python/python/acts/examples/reconstruction.py @@ -278,7 +278,7 @@ def addSeeding( field: acts.MagneticFieldProvider, geoSelectionConfigFile: Optional[Union[Path, str]] = None, layerMappingConfigFile: Optional[Union[Path, str]] = None, - connector_inputConfigFile: Optional[Union[Path, str]] = None, + ConnectorInputConfigFile: Optional[Union[Path, str]] = None, seedingAlgorithm: SeedingAlgorithm = SeedingAlgorithm.Default, trackSmearingSigmas: TrackSmearingSigmas = TrackSmearingSigmas(), initialSigmas: Optional[list] = None, @@ -430,12 +430,11 @@ def addSeeding( spacePoints, seedFinderConfigArg, seedFinderOptionsArg, - seedFilterConfigArg, trackingGeometry, logLevel, layerMappingConfigFile, geoSelectionConfigFile, - connector_inputConfigFile, + ConnectorInputConfigFile, ) elif seedingAlgorithm == SeedingAlgorithm.Hashing: logger.info("Using Hashing seeding") @@ -1088,24 +1087,22 @@ def addGbtsSeeding( spacePoints: str, seedFinderConfigArg: SeedFinderConfigArg, seedFinderOptionsArg: SeedFinderOptionsArg, - seedFilterConfigArg: SeedFilterConfigArg, trackingGeometry: acts.TrackingGeometry, logLevel: acts.logging.Level = None, layerMappingConfigFile: Union[Path, str] = None, geoSelectionConfigFile: Union[Path, str] = None, - connector_inputConfigFile: Union[Path, str] = None, + ConnectorInputConfigFile: Union[Path, str] = None, ): """Gbts seeding""" logLevel = acts.examples.defaultLogging(sequence, logLevel)() layerMappingFile = str(layerMappingConfigFile) # turn path into string - connector_inputFile = str(connector_inputConfigFile) + ConnectorInputFileStr = str(ConnectorInputConfigFile) seedFinderConfig = acts.SeedFinderGbtsConfig( **acts.examples.defaultKWArgs( sigmaScattering=seedFinderConfigArg.sigmaScattering, - maxSeedsPerSpM=seedFinderConfigArg.maxSeedsPerSpM, minPt=seedFinderConfigArg.minPt, - connector_input_file=connector_inputFile, + ConnectorInputFile=ConnectorInputFileStr, m_useClusterWidth=False, ), ) @@ -1121,33 +1118,11 @@ def addGbtsSeeding( bFieldInZ=seedFinderOptionsArg.bFieldInZ, ) ) - seedFilterConfig = acts.SeedFilterConfig( - **acts.examples.defaultKWArgs( - maxSeedsPerSpM=seedFinderConfig.maxSeedsPerSpM, - deltaRMin=( - seedFinderConfigArg.deltaR[0] - if seedFilterConfigArg.deltaRMin is None - else seedFilterConfigArg.deltaRMin - ), - impactWeightFactor=seedFilterConfigArg.impactWeightFactor, - zOriginWeightFactor=seedFilterConfigArg.zOriginWeightFactor, - compatSeedWeight=seedFilterConfigArg.compatSeedWeight, - compatSeedLimit=seedFilterConfigArg.compatSeedLimit, - numSeedIncrement=seedFilterConfigArg.numSeedIncrement, - seedWeightIncrement=seedFilterConfigArg.seedWeightIncrement, - seedConfirmation=seedFilterConfigArg.seedConfirmation, - # curvatureSortingInFilter=seedFilterConfigArg.curvatureSortingInFilter, - maxSeedsPerSpMConf=seedFilterConfigArg.maxSeedsPerSpMConf, - maxQualitySeedsPerSpMConf=seedFilterConfigArg.maxQualitySeedsPerSpMConf, - useDeltaRorTopRadius=seedFilterConfigArg.useDeltaRorTopRadius, - ) - ) seedingAlg = acts.examples.GbtsSeedingAlgorithm( level=logLevel, inputSpacePoints=[spacePoints], outputSeeds="seeds", - seedFilterConfig=seedFilterConfig, seedFinderConfig=seedFinderConfig, seedFinderOptions=seedFinderOptions, layerMappingFile=layerMappingFile, @@ -1798,7 +1773,7 @@ def addExaTrkX( acts.examples.OnnxEdgeClassifier(**filterConfig), acts.examples.OnnxEdgeClassifier(**gnnConfig), ] - trackBuilder = acts.examples.CugraphTrackBuilding(customLogLevel()) + trackBuilder = acts.examples.BoostTrackBuilding(customLogLevel()) findingAlg = acts.examples.TrackFindingAlgorithmExaTrkX( level=customLogLevel(), @@ -2149,9 +2124,9 @@ def addVertexFitting( trackParameters = converter.config.outputTrackParameters tracks = tracks if tracks is not None else "" - inputParticles = "particles_input" + inputParticles = "particles" selectedParticles = "particles_selected" - inputTruthVertices = "vertices_input" + inputTruthVertices = "vertices_truth" if vertexFinder == VertexFinder.Truth: findVertices = TruthVertexFinder( @@ -2245,7 +2220,7 @@ def addSingleSeedVertexFinding( ) s.addAlgorithm(findSingleSeedVertex) - inputParticles = "particles_input" + inputParticles = "particles" selectedParticles = "particles_selected" if outputDirRoot is not None: diff --git a/Examples/Python/python/acts/examples/simulation.py b/Examples/Python/python/acts/examples/simulation.py index a82c16e4198..ce05f27c3ed 100644 --- a/Examples/Python/python/acts/examples/simulation.py +++ b/Examples/Python/python/acts/examples/simulation.py @@ -51,6 +51,34 @@ ) +def _getParticleSelectionKWargs(config: ParticleSelectorConfig) -> dict: + return { + "rhoMin": config.rho[0], + "rhoMax": config.rho[1], + "absZMin": config.absZ[0], + "absZMax": config.absZ[1], + "timeMin": config.time[0], + "timeMax": config.time[1], + "phiMin": config.phi[0], + "phiMax": config.phi[1], + "etaMin": config.eta[0], + "etaMax": config.eta[1], + "absEtaMin": config.absEta[0], + "absEtaMax": config.absEta[1], + "ptMin": config.pt[0], + "ptMax": config.pt[1], + "mMin": config.m[0], + "mMax": config.m[1], + "hitsMin": config.hits[0], + "hitsMax": config.hits[1], + "measurementsMin": config.measurements[0], + "measurementsMax": config.measurements[1], + "removeCharged": config.removeCharged, + "removeNeutral": config.removeNeutral, + "removeSecondaries": config.removeSecondaries, + } + + @acts.examples.NamedTypeArgs( momentumConfig=MomentumConfig, etaConfig=EtaConfig, @@ -101,10 +129,8 @@ def addParticleGun( customLogLevel = acts.examples.defaultLogging(s, logLevel) - # Preliminaries rnd = rnd or RandomNumbers(seed=228) - # Input evGen = EventGenerator( level=customLogLevel(), generators=[ @@ -132,16 +158,17 @@ def addParticleGun( ), ) ], - outputParticles="particles_input", - outputVertices="vertices_input", + outputParticles="particles_generated", + outputVertices="vertices_generated", randomNumbers=rnd, ) - s.addReader(evGen) s.addWhiteboardAlias("particles", evGen.config.outputParticles) s.addWhiteboardAlias("vertices_truth", evGen.config.outputVertices) + s.addWhiteboardAlias("particles_generated_selected", evGen.config.outputParticles) + if printParticles: s.addAlgorithm( ParticlesPrinter( @@ -236,11 +263,12 @@ def addPythia8( customLogLevel = acts.examples.defaultLogging(s, logLevel) - # Preliminaries rnd = rnd or acts.examples.RandomNumbers() + vtxGen = vtxGen or acts.examples.GaussianVertexGenerator( stddev=acts.Vector4(0, 0, 0, 0), mean=acts.Vector4(0, 0, 0, 0) ) + if not isinstance(beam, Iterable): beam = (beam, beam) @@ -292,20 +320,20 @@ def addPythia8( ) ) - # Input evGen = acts.examples.EventGenerator( level=customLogLevel(), generators=generators, - outputParticles="particles_input", - outputVertices="vertices_input", + outputParticles="particles_generated", + outputVertices="vertices_generated", randomNumbers=rnd, ) - s.addReader(evGen) s.addWhiteboardAlias("particles", evGen.config.outputParticles) s.addWhiteboardAlias("vertices_truth", evGen.config.outputVertices) + s.addWhiteboardAlias("particles_generated_selected", evGen.config.outputParticles) + if printParticles: s.addAlgorithm( acts.examples.ParticlesPrinter( @@ -352,15 +380,13 @@ def addPythia8( return s -def addParticleSelection( +def addGenParticleSelection( s: acts.examples.Sequencer, config: ParticleSelectorConfig, - inputParticles: str, - outputParticles: str, logLevel: Optional[acts.logging.Level] = None, ) -> None: """ - This function steers the particle selection. + This function steers the particle selection after generation. Parameters ---------- @@ -368,44 +394,20 @@ def addParticleSelection( the sequencer module to which we add the ParticleSelector config: ParticleSelectorConfig the particle selection configuration - inputParticles: str - the identifier for the input particles to be selected - outputParticles: str - the identifier for the selected particle collection """ customLogLevel = acts.examples.defaultLogging(s, logLevel) - s.addAlgorithm( - acts.examples.ParticleSelector( - **acts.examples.defaultKWArgs( - rhoMin=config.rho[0], - rhoMax=config.rho[1], - absZMin=config.absZ[0], - absZMax=config.absZ[1], - timeMin=config.time[0], - timeMax=config.time[1], - phiMin=config.phi[0], - phiMax=config.phi[1], - etaMin=config.eta[0], - etaMax=config.eta[1], - absEtaMin=config.absEta[0], - absEtaMax=config.absEta[1], - ptMin=config.pt[0], - ptMax=config.pt[1], - mMin=config.m[0], - mMax=config.m[1], - hitsMin=config.hits[0], - hitsMax=config.hits[1], - measurementsMin=config.measurements[0], - measurementsMax=config.measurements[1], - removeCharged=config.removeCharged, - removeNeutral=config.removeNeutral, - removeSecondaries=config.removeSecondaries, - ), - level=customLogLevel(), - inputParticles=inputParticles, - outputParticles=outputParticles, - ) + selector = acts.examples.ParticleSelector( + **acts.examples.defaultKWArgs(**_getParticleSelectionKWargs(config)), + level=customLogLevel(), + inputParticles="particles_generated", + outputParticles="tmp_particles_generated_selected", + ) + s.addAlgorithm(selector) + + s.addWhiteboardAlias("particles_selected", selector.config.outputParticles) + s.addWhiteboardAlias( + "particles_generated_selected", selector.config.outputParticles ) @@ -414,11 +416,9 @@ def addFatras( trackingGeometry: acts.TrackingGeometry, field: acts.MagneticFieldProvider, rnd: acts.examples.RandomNumbers, - preSelectParticles: Optional[ParticleSelectorConfig] = ParticleSelectorConfig(), - postSelectParticles: Optional[ParticleSelectorConfig] = None, enableInteractions: bool = True, pMin: Optional[float] = None, - inputParticles: str = "particles_input", + inputParticles: str = "particles_generated_selected", outputParticles: str = "particles_simulated", outputSimHits: str = "simhits", outputDirCsv: Optional[Union[Path, str]] = None, @@ -436,12 +436,6 @@ def addFatras( field : magnetic field rnd : RandomNumbers random number generator - preSelectParticles : ParticleSelectorConfig(rho, absZ, time, phi, eta, absEta, pt, removeCharged, removeNeutral), None - ParticleSelector configuration to select particles as input to Fatras. Each range is specified as a tuple of (min,max). - Default of no selections specified in Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSelector.hpp - Specify preSelectParticles=None to inhibit ParticleSelector altogether. - postSelectParticles : ParticleSelectorConfig(rho, absZ, time, phi, eta, absEta, pt, removeCharged, removeNeutral), None - Similar to preSelectParticles but applied after simulation to "particles_simulated", therefore also filters secondaries. enableInteractions : Enable the particle interactions in the simulation pMin : Minimum monmentum of particles simulated by FATRAS outputDirCsv : Path|str, path, None @@ -454,25 +448,10 @@ def addFatras( customLogLevel = acts.examples.defaultLogging(s, logLevel) - # Selector - if preSelectParticles is not None: - particlesPreSelected = "fatras_particles_preselected" - addParticleSelection( - s, - preSelectParticles, - inputParticles=inputParticles, - outputParticles=particlesPreSelected, - ) - else: - particlesPreSelected = inputParticles - - s.addWhiteboardAlias("particles_selected", particlesPreSelected) - - # Simulation alg = acts.examples.FatrasSimulation( **acts.examples.defaultKWArgs( level=customLogLevel(), - inputParticles=particlesPreSelected, + inputParticles=inputParticles, outputParticles=outputParticles, outputSimHits=outputSimHits, randomNumbers=rnd, @@ -486,31 +465,16 @@ def addFatras( pMin=pMin, ) ) - - # Sequencer s.addAlgorithm(alg) s.addWhiteboardAlias("particles", outputParticles) - # Selector - if postSelectParticles is not None: - particlesPostSelected = "fatras_particles_postselected" - addParticleSelection( - s, - postSelectParticles, - inputParticles=outputParticles, - outputParticles=particlesPostSelected, - ) - else: - particlesPostSelected = outputParticles - - s.addWhiteboardAlias("particles_selected", particlesPostSelected) + s.addWhiteboardAlias("particles_simulated_selected", outputParticles) - # Output addSimWriters( s, alg.config.outputSimHits, - particlesPostSelected, + outputParticles, outputDirCsv, outputDirRoot, outputDirObj, @@ -597,11 +561,9 @@ def addGeant4( rnd: acts.examples.RandomNumbers, volumeMappings: List[str] = [], materialMappings: List[str] = ["Silicon"], - inputParticles: str = "particles_input", + inputParticles: str = "particles_generated_selected", outputParticles: str = "particles_simulated", outputSimHits: str = "simhits", - preSelectParticles: Optional[ParticleSelectorConfig] = ParticleSelectorConfig(), - postSelectParticles: Optional[ParticleSelectorConfig] = None, recordHitsOfSecondaries=True, keepParticlesWithoutHits=True, outputDirCsv: Optional[Union[Path, str]] = None, @@ -624,12 +586,6 @@ def addGeant4( field : magnetic field rnd : RandomNumbers, None random number generator - preSelectParticles : ParticleSelectorConfig(rho, absZ, time, phi, eta, absEta, pt, removeCharged, removeNeutral), None - ParticleSelector configuration to select particles as input to Geant4. Each range is specified as a tuple of (min,max). - Default of no selections specified in Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSelector.hpp - Specify preSelectParticles=None to inhibit ParticleSelector altogether. - postSelectParticles : ParticleSelectorConfig(rho, absZ, time, phi, eta, absEta, pt, removeCharged, removeNeutral), None - Similar to preSelectParticles but applied after simulation to "particles_simulated", therefore also filters secondaries. outputDirCsv : Path|str, path, None the output folder for the Csv output, None triggers no output outputDirRoot : Path|str, path, None @@ -648,20 +604,6 @@ def addGeant4( customLogLevel = acts.examples.defaultLogging(s, logLevel) - # Selector - if preSelectParticles is not None: - particlesPreSelected = "geant4_particles_preselected" - addParticleSelection( - s, - preSelectParticles, - inputParticles=inputParticles, - outputParticles=particlesPreSelected, - ) - else: - particlesPreSelected = inputParticles - - s.addWhiteboardAlias("particles_selected", particlesPreSelected) - global __geant4Handle smmConfig = SensitiveSurfaceMapper.Config() @@ -671,13 +613,12 @@ def addGeant4( smmConfig, customLogLevel(), trackingGeometry ) - # Simulation alg = Geant4Simulation( level=customLogLevel(), geant4Handle=__geant4Handle, detector=detector, randomNumbers=rnd, - inputParticles=particlesPreSelected, + inputParticles=inputParticles, outputParticles=outputParticles, outputSimHits=outputSimHits, sensitiveSurfaceMapper=sensitiveMapper, @@ -693,30 +634,17 @@ def addGeant4( recordPropagationSummaries=False, keepParticlesWithoutHits=keepParticlesWithoutHits, ) - __geant4Handle = alg.geant4Handle - s.addAlgorithm(alg) - # Selector - if postSelectParticles is not None: - particlesPostSelected = "geant4_particles_postselected" - addParticleSelection( - s, - postSelectParticles, - inputParticles=outputParticles, - outputParticles=particlesPostSelected, - ) - else: - particlesPostSelected = outputParticles + s.addWhiteboardAlias("particles", outputParticles) - s.addWhiteboardAlias("particles_selected", particlesPostSelected) + s.addWhiteboardAlias("particles_simulated_selected", outputParticles) - # Output addSimWriters( s, alg.config.outputSimHits, - particlesPostSelected, + outputParticles, outputDirCsv, outputDirRoot, outputDirObj, @@ -726,6 +654,37 @@ def addGeant4( return s +def addSimParticleSelection( + s: acts.examples.Sequencer, + config: ParticleSelectorConfig, + logLevel: Optional[acts.logging.Level] = None, +) -> None: + """ + This function steers the particle selection after simulation. + + Parameters + ---------- + s: Sequencer + the sequencer module to which we add the ParticleSelector + config: ParticleSelectorConfig + the particle selection configuration + """ + customLogLevel = acts.examples.defaultLogging(s, logLevel) + + selector = acts.examples.ParticleSelector( + **acts.examples.defaultKWArgs(**_getParticleSelectionKWargs(config)), + level=customLogLevel(), + inputParticles="particles_simulated", + outputParticles="tmp_particles_simulated_selected", + ) + s.addAlgorithm(selector) + + s.addWhiteboardAlias("particles_selected", selector.config.outputParticles) + s.addWhiteboardAlias( + "particles_simulated_selected", selector.config.outputParticles + ) + + def addDigitization( s: acts.examples.Sequencer, trackingGeometry: Union[acts.TrackingGeometry, acts.Detector], @@ -758,10 +717,8 @@ def addDigitization( customLogLevel = acts.examples.defaultLogging(s, logLevel) - # Preliminaries rnd = rnd or acts.examples.RandomNumbers() - # Digitization digiCfg = acts.examples.DigitizationAlgorithm.Config( digitizationConfigs=acts.examples.readDigiConfigFromJson( str(digiConfigFile), @@ -816,3 +773,35 @@ def addDigitization( ) return s + + +def addDigiParticleSelection( + s: acts.examples.Sequencer, + config: ParticleSelectorConfig, + logLevel: Optional[acts.logging.Level] = None, +) -> None: + """ + This function steers the particle selection after digitization. + + Parameters + ---------- + s: Sequencer + the sequencer module to which we add the ParticleSelector + config: ParticleSelectorConfig + the particle selection configuration + """ + customLogLevel = acts.examples.defaultLogging(s, logLevel) + + selector = acts.examples.ParticleSelector( + **acts.examples.defaultKWArgs(**_getParticleSelectionKWargs(config)), + level=customLogLevel(), + inputParticles="particles_simulated_selected", + inputParticleMeasurementsMap="particle_measurements_map", + outputParticles="tmp_particles_digitized_selected", + ) + s.addAlgorithm(selector) + + s.addWhiteboardAlias("particles_selected", selector.config.outputParticles) + s.addWhiteboardAlias( + "particles_digitized_selected", selector.config.outputParticles + ) diff --git a/Examples/Python/src/Base.cpp b/Examples/Python/src/Base.cpp index cc8a5f67dc1..1dde957c04b 100644 --- a/Examples/Python/src/Base.cpp +++ b/Examples/Python/src/Base.cpp @@ -13,7 +13,7 @@ #include "Acts/MagneticField/MagneticFieldContext.hpp" #include "Acts/Plugins/Python/Utilities.hpp" #include "Acts/Utilities/Any.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/BinningData.hpp" #include "Acts/Utilities/CalibrationContext.hpp" #include "Acts/Utilities/Logger.hpp" @@ -359,16 +359,16 @@ void addAlgebra(Acts::Python::Context& ctx) { void addBinning(Context& ctx) { auto& m = ctx.get("main"); - auto binningValue = py::enum_(m, "BinningValue") - .value("binX", Acts::BinningValue::binX) - .value("binY", Acts::BinningValue::binY) - .value("binZ", Acts::BinningValue::binZ) - .value("binR", Acts::BinningValue::binR) - .value("binPhi", Acts::BinningValue::binPhi) - .value("binRPhi", Acts::BinningValue::binRPhi) - .value("binH", Acts::BinningValue::binH) - .value("binEta", Acts::BinningValue::binEta) - .value("binMag", Acts::BinningValue::binMag); + auto binningValue = py::enum_(m, "AxisDirection") + .value("AxisX", Acts::AxisDirection::AxisX) + .value("AxisY", Acts::AxisDirection::AxisY) + .value("AxisZ", Acts::AxisDirection::AxisZ) + .value("AxisR", Acts::AxisDirection::AxisR) + .value("AxisPhi", Acts::AxisDirection::AxisPhi) + .value("AxisRPhi", Acts::AxisDirection::AxisRPhi) + .value("AxisTheta", Acts::AxisDirection::AxisTheta) + .value("AxisEta", Acts::AxisDirection::AxisEta) + .value("AxisMag", Acts::AxisDirection::AxisMag); auto boundaryType = py::enum_(m, "AxisBoundaryType") .value("Bound", Acts::AxisBoundaryType::Bound) diff --git a/Examples/Python/src/Blueprint.cpp b/Examples/Python/src/Blueprint.cpp index f5ce4ddc3d0..8f14f1c89e9 100644 --- a/Examples/Python/src/Blueprint.cpp +++ b/Examples/Python/src/Blueprint.cpp @@ -15,9 +15,11 @@ #include "Acts/Geometry/LayerBlueprintNode.hpp" #include "Acts/Geometry/MaterialDesignatorBlueprintNode.hpp" #include "Acts/Geometry/StaticBlueprintNode.hpp" +#include "Acts/Geometry/VolumeAttachmentStrategy.hpp" +#include "Acts/Geometry/VolumeResizeStrategy.hpp" #include "Acts/Navigation/NavigationStream.hpp" #include "Acts/Plugins/Python/Utilities.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Logger.hpp" #include @@ -338,14 +340,11 @@ void addBlueprint(Context& ctx) { py::class_>( m, "CylinderContainerBlueprintNode") - .def(py::init(), + .def(py::init(), py::arg("name"), py::arg("direction"), - py::arg("attachmentStrategy") = - CylinderVolumeStack::AttachmentStrategy::Gap, - py::arg("resizeStrategy") = - CylinderVolumeStack::ResizeStrategy::Gap) + py::arg("attachmentStrategy") = VolumeAttachmentStrategy::Gap, + py::arg("resizeStrategy") = VolumeResizeStrategy::Gap) .def_property( "attachmentStrategy", &Acts::CylinderContainerBlueprintNode::attachmentStrategy, @@ -362,7 +361,8 @@ void addBlueprint(Context& ctx) { addNodeMethods( "CylinderContainer", - [](BlueprintNode& self, const std::string& name, BinningValue direction) { + [](BlueprintNode& self, const std::string& name, + AxisDirection direction) { auto cylinder = std::make_shared(name, direction); self.addChild(cylinder); diff --git a/Examples/Python/src/ExaTrkXTrackFinding.cpp b/Examples/Python/src/ExaTrkXTrackFinding.cpp index c7a30b51d2e..5ef30a17df3 100644 --- a/Examples/Python/src/ExaTrkXTrackFinding.cpp +++ b/Examples/Python/src/ExaTrkXTrackFinding.cpp @@ -7,7 +7,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. #include "Acts/Plugins/ExaTrkX/BoostTrackBuilding.hpp" -#include "Acts/Plugins/ExaTrkX/CugraphTrackBuilding.hpp" +#include "Acts/Plugins/ExaTrkX/CudaTrackBuilding.hpp" #include "Acts/Plugins/ExaTrkX/ExaTrkXPipeline.hpp" #include "Acts/Plugins/ExaTrkX/OnnxEdgeClassifier.hpp" #include "Acts/Plugins/ExaTrkX/OnnxMetricLearning.hpp" @@ -113,6 +113,25 @@ void addExaTrkXTrackFinding(Context &ctx) { } #endif +#ifdef ACTS_EXATRKX_WITH_CUDA + { + using Alg = Acts::CudaTrackBuilding; + using Config = Alg::Config; + + auto alg = py::class_>( + mex, "CudaTrackBuilding") + .def(py::init([](const Config &c, Logging::Level lvl) { + return std::make_shared( + c, getDefaultLogger("TrackBuilding", lvl)); + }), + "config"_a, "level"_a); + + auto c = py::class_(alg, "Config").def(py::init<>()); + ACTS_PYTHON_STRUCT_BEGIN(c, Config); + ACTS_PYTHON_STRUCT_END(); + } +#endif + #ifdef ACTS_EXATRKX_ONNX_BACKEND { using Alg = Acts::OnnxMetricLearning; @@ -157,17 +176,6 @@ void addExaTrkXTrackFinding(Context &ctx) { ACTS_PYTHON_MEMBER(cut); ACTS_PYTHON_STRUCT_END(); } - { - using Alg = Acts::CugraphTrackBuilding; - - auto alg = py::class_>( - mex, "CugraphTrackBuilding") - .def(py::init([](Logging::Level lvl) { - return std::make_shared( - getDefaultLogger("EdgeClassifier", lvl)); - }), - py::arg("level")); - } #endif ACTS_PYTHON_DECLARE_ALGORITHM( diff --git a/Examples/Python/src/Geometry.cpp b/Examples/Python/src/Geometry.cpp index e9bbbfa350e..b0fbc40ed3e 100644 --- a/Examples/Python/src/Geometry.cpp +++ b/Examples/Python/src/Geometry.cpp @@ -33,12 +33,14 @@ #include "Acts/Geometry/ProtoLayer.hpp" #include "Acts/Geometry/TrackingGeometry.hpp" #include "Acts/Geometry/Volume.hpp" +#include "Acts/Geometry/VolumeAttachmentStrategy.hpp" #include "Acts/Geometry/VolumeBounds.hpp" +#include "Acts/Geometry/VolumeResizeStrategy.hpp" #include "Acts/Material/ISurfaceMaterial.hpp" #include "Acts/Plugins/Python/Utilities.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Surfaces/SurfaceArray.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Helpers.hpp" #include "Acts/Utilities/RangeXD.hpp" #include "Acts/Visualization/ViewConfig.hpp" @@ -97,7 +99,6 @@ void addBlueprint(Context& ctx); void addGeometry(Context& ctx) { auto m = ctx.get("main"); - { py::class_(m, "GeometryIdentifier") .def(py::init<>()) @@ -242,33 +243,33 @@ void addGeometry(Context& ctx) { .def(py::init<>()) .def(py::init()) .def(py::init([](Envelope x, Envelope y, Envelope z, Envelope r, - Envelope phi, Envelope rPhi, Envelope h, Envelope eta, - Envelope mag) { + Envelope phi, Envelope rPhi, Envelope theta, + Envelope eta, Envelope mag) { return ExtentEnvelope({.x = x, .y = y, .z = z, .r = r, .phi = phi, .rPhi = rPhi, - .h = h, + .theta = theta, .eta = eta, .mag = mag}); }), py::arg("x") = zeroEnvelope, py::arg("y") = zeroEnvelope, py::arg("z") = zeroEnvelope, py::arg("r") = zeroEnvelope, py::arg("phi") = zeroEnvelope, py::arg("rPhi") = zeroEnvelope, - py::arg("h") = zeroEnvelope, py::arg("eta") = zeroEnvelope, + py::arg("theta") = zeroEnvelope, py::arg("eta") = zeroEnvelope, py::arg("mag") = zeroEnvelope) .def_static("Zero", &ExtentEnvelope::Zero) .def("__getitem__", [](ExtentEnvelope& self, - BinningValue bValue) { return self[bValue]; }) - .def("__setitem__", [](ExtentEnvelope& self, BinningValue bValue, + AxisDirection bValue) { return self[bValue]; }) + .def("__setitem__", [](ExtentEnvelope& self, AxisDirection bValue, const Envelope& value) { self[bValue] = value; }) .def("__str__", [](const ExtentEnvelope& self) { - std::array values; + std::array values; std::stringstream ss; - for (BinningValue val : allBinningValues()) { + for (AxisDirection val : allAxisDirections()) { ss << val << "=(" << self[val][0] << ", " << self[val][1] << ")"; values.at(toUnderlying(val)) = ss.str(); ss.str(""); @@ -286,24 +287,21 @@ void addGeometry(Context& ctx) { py::arg("envelope") = ExtentEnvelope::Zero()) .def("range", [](const Acts::Extent& self, - Acts::BinningValue bval) -> std::array { + Acts::AxisDirection bval) -> std::array { return {self.min(bval), self.max(bval)}; }) .def("__str__", &Extent::toString); { - auto cylStack = py::class_(m, "CylinderVolumeStack"); - - py::enum_(cylStack, - "AttachmentStrategy") - .value("Gap", CylinderVolumeStack::AttachmentStrategy::Gap) - .value("First", CylinderVolumeStack::AttachmentStrategy::First) - .value("Second", CylinderVolumeStack::AttachmentStrategy::Second) - .value("Midpoint", CylinderVolumeStack::AttachmentStrategy::Midpoint); - - py::enum_(cylStack, "ResizeStrategy") - .value("Gap", CylinderVolumeStack::ResizeStrategy::Gap) - .value("Expand", CylinderVolumeStack::ResizeStrategy::Expand); + py::enum_(m, "VolumeAttachmentStrategy") + .value("Gap", VolumeAttachmentStrategy::Gap) + .value("First", VolumeAttachmentStrategy::First) + .value("Second", VolumeAttachmentStrategy::Second) + .value("Midpoint", VolumeAttachmentStrategy::Midpoint); + + py::enum_(m, "VolumeResizeStrategy") + .value("Gap", VolumeResizeStrategy::Gap) + .value("Expand", VolumeResizeStrategy::Expand); } addBlueprint(ctx); @@ -346,8 +344,8 @@ void addExperimentalGeometry(Context& ctx) { extent.extend(volume->extent(gctx)); } auto bounds = std::make_shared( - 0., extent.max(Acts::BinningValue::binR), - extent.max(Acts::BinningValue::binZ)); + 0., extent.max(Acts::AxisDirection::AxisR), + extent.max(Acts::AxisDirection::AxisZ)); return std::make_shared(Transform3::Identity(), std::move(bounds)); @@ -387,13 +385,13 @@ void addExperimentalGeometry(Context& ctx) { { // Be able to construct a proto binning py::class_(m, "ProtoBinning") - .def(py::init&, std::size_t>(), "bValue"_a, "bType"_a, "e"_a, "exp"_a = 0u) - .def(py::init(), "bValue"_a, "bType"_a, "minE"_a, "maxE"_a, "nbins"_a, "exp"_a = 0u) - .def(py::init(), "bValue"_a, "bType"_a, "nbins"_a, "exp"_a = 0u); } @@ -457,7 +455,7 @@ void addExperimentalGeometry(Context& ctx) { m, "KdtSurfacesDim1Bin100") .def(py::init>&, - const std::array&>()) + const std::array&>()) .def("surfaces", py::overload_cast( &KdtSurfacesDim1Bin100::surfaces, py::const_)); @@ -487,7 +485,7 @@ void addExperimentalGeometry(Context& ctx) { m, "KdtSurfacesDim2Bin100") .def(py::init>&, - const std::array&>()) + const std::array&>()) .def("surfaces", py::overload_cast( &KdtSurfacesDim2Bin100::surfaces, py::const_)); @@ -619,7 +617,7 @@ void addExperimentalGeometry(Context& ctx) { std::shared_ptr< Acts::Experimental::IndexedRootVolumeFinderBuilder>>( m, "IndexedRootVolumeFinderBuilder") - .def(py::init>()); + .def(py::init>()); } { diff --git a/Examples/Python/src/Input.cpp b/Examples/Python/src/Input.cpp index b3ad9e1f657..60e0424b208 100644 --- a/Examples/Python/src/Input.cpp +++ b/Examples/Python/src/Input.cpp @@ -8,6 +8,7 @@ #include "Acts/Plugins/Python/Utilities.hpp" #include "ActsExamples/EventData/Cluster.hpp" +#include "ActsExamples/Framework/BufferedReader.hpp" #include "ActsExamples/Io/Csv/CsvDriftCircleReader.hpp" #include "ActsExamples/Io/Csv/CsvExaTrkXGraphReader.hpp" #include "ActsExamples/Io/Csv/CsvMeasurementReader.hpp" @@ -39,6 +40,11 @@ namespace Acts::Python { void addInput(Context& ctx) { auto mex = ctx.get("examples"); + // Buffered reader + ACTS_PYTHON_DECLARE_READER(ActsExamples::BufferedReader, mex, + "BufferedReader", upstreamReader, selectionSeed, + bufferSize); + // ROOT READERS ACTS_PYTHON_DECLARE_READER(ActsExamples::RootParticleReader, mex, "RootParticleReader", outputParticles, treeName, diff --git a/Examples/Python/src/TrackFinding.cpp b/Examples/Python/src/TrackFinding.cpp index 54eb7e76641..753574b7de7 100644 --- a/Examples/Python/src/TrackFinding.cpp +++ b/Examples/Python/src/TrackFinding.cpp @@ -203,12 +203,11 @@ void addTrackFinding(Context& ctx) { ACTS_PYTHON_MEMBER(sigmaScattering); ACTS_PYTHON_MEMBER(highland); ACTS_PYTHON_MEMBER(maxScatteringAngle2); - ACTS_PYTHON_MEMBER(connector_input_file); + ACTS_PYTHON_MEMBER(ConnectorInputFile); ACTS_PYTHON_MEMBER(m_phiSliceWidth); ACTS_PYTHON_MEMBER(m_nMaxPhiSlice); ACTS_PYTHON_MEMBER(m_useClusterWidth); ACTS_PYTHON_MEMBER(m_layerGeometry); - ACTS_PYTHON_MEMBER(maxSeedsPerSpM); ACTS_PYTHON_STRUCT_END(); patchKwargsConstructor(c); } @@ -273,9 +272,9 @@ void addTrackFinding(Context& ctx) { ACTS_PYTHON_DECLARE_ALGORITHM( ActsExamples::GbtsSeedingAlgorithm, mex, "GbtsSeedingAlgorithm", - inputSpacePoints, outputSeeds, seedFilterConfig, seedFinderConfig, - seedFinderOptions, layerMappingFile, geometrySelection, trackingGeometry, - ActsGbtsMap, fill_module_csv, inputClusters); + inputSpacePoints, outputSeeds, seedFinderConfig, seedFinderOptions, + layerMappingFile, geometrySelection, trackingGeometry, ActsGbtsMap, + fill_module_csv, inputClusters); ACTS_PYTHON_DECLARE_ALGORITHM( ActsExamples::HoughTransformSeeder, mex, "HoughTransformSeeder", diff --git a/Examples/Python/src/TruthTracking.cpp b/Examples/Python/src/TruthTracking.cpp index 4d3569f4656..ed29333b0e7 100644 --- a/Examples/Python/src/TruthTracking.cpp +++ b/Examples/Python/src/TruthTracking.cpp @@ -67,6 +67,7 @@ void addTruthTracking(Context& ctx) { ACTS_PYTHON_STRUCT_BEGIN(c, Config); ACTS_PYTHON_MEMBER(inputParticles); + ACTS_PYTHON_MEMBER(inputParticleMeasurementsMap); ACTS_PYTHON_MEMBER(outputParticles); ACTS_PYTHON_MEMBER(rhoMin); ACTS_PYTHON_MEMBER(rhoMax); diff --git a/Examples/Python/tests/conftest.py b/Examples/Python/tests/conftest.py index c1eb489bb62..f23cba21fba 100644 --- a/Examples/Python/tests/conftest.py +++ b/Examples/Python/tests/conftest.py @@ -211,8 +211,8 @@ def _basic_prop_seq_factory(geo, s=None): trkParamExtractor = acts.examples.ParticleTrackParamExtractor( level=acts.logging.WARNING, - inputParticles="particles_input", - outputTrackParameters="params_particles_input", + inputParticles="particles_generated", + outputTrackParameters="params_particles_generated", ) s.addAlgorithm(trkParamExtractor) @@ -225,7 +225,7 @@ def _basic_prop_seq_factory(geo, s=None): level=acts.logging.WARNING, propagatorImpl=prop, sterileLogger=False, - inputTrackParameters="params_particles_input", + inputTrackParameters="params_particles_generated", outputSummaryCollection="propagation_summary", ) s.addAlgorithm(alg) @@ -325,7 +325,7 @@ def _factory(s): ), ) ], - outputParticles="particles_input", + outputParticles="particles_generated", outputVertices="vertices_input", randomNumbers=rng, ) diff --git a/Examples/Python/tests/root_file_hashes.txt b/Examples/Python/tests/root_file_hashes.txt index 07d42c66ad1..35f5c093a87 100644 --- a/Examples/Python/tests/root_file_hashes.txt +++ b/Examples/Python/tests/root_file_hashes.txt @@ -6,33 +6,33 @@ test_geant4__hits.root: 4c9e704a75f47ed2e61652679a1d6f18fa4d9cf53faa8f8f5bbf7995 test_seeding__estimatedparams.root: 6759004f945cabe03098c94b3eea7e3323acd9f37edfa71641797007336643c8 test_seeding__performance_seeding.root: 992f9c611d30dde0d3f3ab676bab19ada61ab6a4442828e27b65ec5e5b7a2880 test_seeding__particles.root: c423bc666df3674f1a1140dec68ea13f44173232b8057e8a02572aee4f3e7d5b -test_seeding__particles_simulation.root: f937a4cc474e80cfbb6eac4384e42e9c5c7ac981fcd6870d624cc898d1a0c006 -test_hashing_seeding__estimatedparams.root: 6b52f27b2feac2fa46a8ed52abacfe6dc8e6319f86e031cdc2f9ba28a0393cb2 +test_seeding__particles_simulation.root: 87d9c6c82422ca381a17735096b36c547eacb5dda2f26d7377614bd97a70ab1a +test_hashing_seeding__estimatedparams.root: 1e750a9aaf029b210acbcc5af3d4c4cc8bbb93682972be6e4b86dd92392472f5 test_seeding_orthogonal__estimatedparams.root: 6cb69ee239e11ff112dd50c2bcfe945a6f7b00e43e13b2cba4e08f1bfcf6a583 test_seeding_orthogonal__performance_seeding.root: 60fbedcf5cb2b37cd8e526251940564432890d3a159d231ed819e915a904682c test_seeding_orthogonal__particles.root: c423bc666df3674f1a1140dec68ea13f44173232b8057e8a02572aee4f3e7d5b -test_seeding_orthogonal__particles_simulation.root: f937a4cc474e80cfbb6eac4384e42e9c5c7ac981fcd6870d624cc898d1a0c006 +test_seeding_orthogonal__particles_simulation.root: 87d9c6c82422ca381a17735096b36c547eacb5dda2f26d7377614bd97a70ab1a test_itk_seeding__estimatedparams.root: fc042037f12a434f2236df7d225b8ca24209b6910f04a4496ae3a06516a6ff8c test_itk_seeding__performance_seeding.root: 78ebda54cd0f026ba4b7f316724ffd946de56a932735914baf1b7bba9505c29d test_itk_seeding__particles.root: 907ff693262c0db14b12c74b16586cb20d79caf5f03f93b178943e41ed35a1b6 test_itk_seeding__particles_simulation.root: ef0246069aa697019f28a8b270a68de95312cae5f2f2c74848566c3ce4f70363 -test_propagation__propagation_summary.root: de0c105ab0de0096241855fe3db46d7c5d054d897625ede4df276472a7e43c57 +test_propagation__propagation_summary.root: 6e8dbf303c72dc9bba0971ec3140e3bf1a7e154a6af7c13cc8b09c6fec1caf34 test_material_recording__geant4_material_tracks.root: c022b9362249b29f57a07926b20644e3ab4ab8ebcf03f773fbf46c446fc1a0a1 -test_truth_tracking_gsf[generic]__trackstates_gsf.root: 4df2c69d5dd7d5446a547651e4e962daf17924f5c8617165a93a3223c8ba18fd +test_truth_tracking_gsf[generic]__trackstates_gsf.root: dace43da68574a2ad89a3b7e31f9f2eac04e34d6a703b2ae7ee31082e8a9b1f9 test_truth_tracking_gsf[generic]__tracksummary_gsf.root: 8c01d139cb865afa1959c62dbca76f3a1fb8b684c57ea4c2968baa6ffedadb6f -test_truth_tracking_gsf[odd]__trackstates_gsf.root: c7397e53ea093f2432943ae263fc99bc9aa774504ea6152c6907066a06d21caf +test_truth_tracking_gsf[odd]__trackstates_gsf.root: 4691352f2f83a15f96336705a7461cb54231c422ba21c25038670534c279a87c test_truth_tracking_gsf[odd]__tracksummary_gsf.root: 4562341f12a61ea0d5e25872b6bf466b79a73781dc95fc18ef9c6515f0a47916 test_particle_gun__particles.root: 669d0304eb8bcf244aa627809a117944e5e3b994fdfcfb8710f2b9a8f9a62d3b test_material_mapping__material-map_tracks.root: 938b1a855369e9304401cb10d2751df3fd7acf32a2573f2057eb1691cd94edf3 test_material_mapping__propagation-material.root: e2b4eade0d8124c03c89e01bf6ff5029dd12e3c9efc0a19c22a12c5cd2800e77 test_volume_material_mapping__material-map-volume_tracks.root: 98e212d32ca054fa3d01af4167c1f49755a139d43b82c57908197f5985e0a4ff test_volume_material_mapping__propagation-volume-material.root: 42bb2fd9c50d44210c914e487903bbdef65a0491f0a85a7159c0e078ac983a80 -test_digitization_example[smeared]__measurements.root: 2b583b886b76f94786c6c2832aa84d176059cbbc35882fb34b4fd1f22dd4c006 -test_digitization_example[geometric]__measurements.root: 85efa861d14207fd7d1798dab093edcd0a2685bc189b4fc9a96b07d1001013a0 +test_digitization_example[smeared]__measurements.root: a7980ac0186c772a2792045ca2aea6e2277f1a574ea0c6df7b0f84538f10f66f +test_digitization_example[geometric]__measurements.root: 9051599b058e3637672166c10df4881d905fdb1b1d7e096b359252845ac4bb27 test_digitization_example_input[smeared]__particles.root: 669d0304eb8bcf244aa627809a117944e5e3b994fdfcfb8710f2b9a8f9a62d3b -test_digitization_example_input[smeared]__measurements.root: 243c2f69b7b0db9dbeaa7494d4ea0f3dd1691dc90f16e10df6c0491ff4dc7d62 +test_digitization_example_input[smeared]__measurements.root: 8b1cfc670989b9acc50820744a64aa711ea8091f664282e6dc8b9a399fad3dad test_digitization_example_input[geometric]__particles.root: 669d0304eb8bcf244aa627809a117944e5e3b994fdfcfb8710f2b9a8f9a62d3b -test_digitization_example_input[geometric]__measurements.root: 63ec81635979058fb8976f94455bf490cf92b7b142c4a05cc39de6225f5de2fb +test_digitization_example_input[geometric]__measurements.root: ec545fc29d5a670bf4a47065058e8555ddb6c872c207b19a3e8ae1fabb2aa180 test_ckf_tracks_example[generic-full_seeding]__trackstates_ckf.root: f0b4c6018d0b2641024b88f6ac717f16a2ca486007c2e9bf166c85dc5e161739 test_ckf_tracks_example[generic-full_seeding]__tracksummary_ckf.root: e5187591a0902d7214dd211adf459e2ec43b200b43c7ebdb90e5af50ee828f91 test_ckf_tracks_example[generic-full_seeding]__performance_seeding_trees.root: 0e0676ffafdb27112fbda50d1cf627859fa745760f98073261dcf6db3f2f991e @@ -56,13 +56,13 @@ test_vertex_fitting_reading[AMVF-False-100]__performance_vertexing.root: 009e4b1 test_vertex_fitting_reading[AMVF-True-100]__performance_vertexing.root: 2d0dc1e02bfd1f7eaae26ef8ac657ce0291f70c7e4efddd35d171d31988a631e test_bfield_writing__solenoid.root: 7be51f0ed9cb99f59ae0271ba79cdb84635e6ee3d2109ea8a4b521875029c21d test_bfield_writing__solenoid2.root: 2db149336c9cd749dc50025076b49f9bc0586d53792b87a0fdd7f21a649a01a5 -test_root_prop_step_writer[configPosConstructor]__prop_steps.root: 200ece7cde60eb0dd8835cf4830835e9058d897ba5759099d96914b06a1df092 -test_root_prop_step_writer[configKwConstructor]__prop_steps.root: 200ece7cde60eb0dd8835cf4830835e9058d897ba5759099d96914b06a1df092 -test_root_prop_step_writer[kwargsConstructor]__prop_steps.root: 200ece7cde60eb0dd8835cf4830835e9058d897ba5759099d96914b06a1df092 +test_root_prop_step_writer[configPosConstructor]__prop_steps.root: b2c4036d0f1ae273ec2eb105187983c354cb73db4d8df43758b8c53a6b869859 +test_root_prop_step_writer[configKwConstructor]__prop_steps.root: b2c4036d0f1ae273ec2eb105187983c354cb73db4d8df43758b8c53a6b869859 +test_root_prop_step_writer[kwargsConstructor]__prop_steps.root: b2c4036d0f1ae273ec2eb105187983c354cb73db4d8df43758b8c53a6b869859 test_root_particle_writer[configPosConstructor]__particles.root: e5d723e138b4e121c6e74a6dba072072f622995e117a40b8e63755ac784baad6 test_root_particle_writer[configKwConstructor]__particles.root: e5d723e138b4e121c6e74a6dba072072f622995e117a40b8e63755ac784baad6 test_root_particle_writer[kwargsConstructor]__particles.root: e5d723e138b4e121c6e74a6dba072072f622995e117a40b8e63755ac784baad6 -test_root_meas_writer__meas.root: 0f7e51c3c6e0133c6c1fc0da6d936e16f59ca2b579d15108e6c7b82bdf0a1e73 +test_root_meas_writer__meas.root: 8a60b56ff82e994c27506a5de5c61833e337fec6593442fb1520f83b12decbc0 test_root_simhits_writer[configPosConstructor]__meas.root: 66fee65a672bbf28098aac7af59ef181c2ac8331f87a379132873da86bdb1ba5 test_root_simhits_writer[configKwConstructor]__meas.root: 66fee65a672bbf28098aac7af59ef181c2ac8331f87a379132873da86bdb1ba5 test_root_simhits_writer[kwargsConstructor]__meas.root: 66fee65a672bbf28098aac7af59ef181c2ac8331f87a379132873da86bdb1ba5 @@ -74,14 +74,14 @@ test_exatrkx[cpu-torch]__performance_track_finding.root: 36b3045589c4c17c038dbc8 test_exatrkx[gpu-onnx]__performance_track_finding.root: 9090de10ffb1489d3f1993e2a3081a3038227e3e5c453e98a9a4f33ea3d6d817 test_exatrkx[gpu-torch]__performance_track_finding.root: 6b658fa22c7532e082eaab7aa4b71b852f1c324adcc59d1156aff45124b222d9 test_ML_Ambiguity_Solver__performance_finding_ambiML.root: 166dd8bb189097c4957b7b02c04c41267868d72d9a08c4bb892985b06849cb76 -test_refitting[odd]__trackstates_gsf_refit.root: e297749dc1e7eda3b8dea13defa0499986c584740d93e723a901b498b8e90c71 -test_refitting[odd]__tracksummary_gsf_refit.root: d5085882e45a0b699194dff9f40a36e9291227bf65f9aaaf9087f9242ef5ae22 -test_refitting[generic]__trackstates_gsf_refit.root: 4424fdf2f27575db825c1a59f8e53a1595946211cbd5b2c8d3a2f71cdcc77ae9 -test_refitting[generic]__tracksummary_gsf_refit.root: 562deecee4cfb97ceee72eff53d63da079e3249fb62d6bcd556e6f27d495dfd9 -test_truth_tracking_kalman[generic-0.0]__trackstates_kf.root: 9f77962b92037cb760b1629a602b1dae61f45e659c45d9a87baa784f6190960e -test_truth_tracking_kalman[generic-0.0]__tracksummary_kf.root: 562deecee4cfb97ceee72eff53d63da079e3249fb62d6bcd556e6f27d495dfd9 -test_truth_tracking_kalman[generic-1000.0]__trackstates_kf.root: 56a1bd989b9c1316b9098c65fa75df9e6683e62e35ae68d8f72d27220be0fd7d -test_truth_tracking_kalman[generic-1000.0]__tracksummary_kf.root: 2d85be3a5dff01a1076e80f8c225aca32f65b30dc9c3551b610ac2f12d006a39 +test_refitting[odd]__trackstates_gsf_refit.root: 74551db2ca2ff1699fbb3f9760906abfcfdbe9e63343de242eb3433f22e35bc7 +test_refitting[odd]__tracksummary_gsf_refit.root: 771160d8937f8436b6e9b75955c10e408cffda99779622286b3bff5cfdc0c7f2 +test_refitting[generic]__trackstates_gsf_refit.root: 5dc080f2bbd5b2fe49d0252970cdbce023844d82833240cd83aeb7e891dfe0b2 +test_refitting[generic]__tracksummary_gsf_refit.root: 0957b863d6a065b3688ecd569ddbb32bcfb30c369f7031cd75885307c0c20ba4 +test_truth_tracking_kalman[generic-0.0]__trackstates_kf.root: eba0b055e4f8e3e30dae2e27ef662f213fe4fc9a5c9ed00e44adb86e7219e068 +test_truth_tracking_kalman[generic-0.0]__tracksummary_kf.root: 94fad00ab0aa9f380a85135f89a81cc2e8761ab402d821a8af854e381f4982fc +test_truth_tracking_kalman[generic-1000.0]__trackstates_kf.root: 85d397a24d5546d580bd5c69fa60655d78db7392915ed67343717e99885f97d9 +test_truth_tracking_kalman[generic-1000.0]__tracksummary_kf.root: 8a1b1a05fddfd0149b4359fdce8e43ec24a859e5ce0dc72f4ce57396dfec4d3c test_truth_tracking_kalman[odd-0.0]__trackstates_kf.root: 7e144571b19aaf00002aef4f5bec5d488b96fb9ed8e1b2904c3756b31be83513 test_truth_tracking_kalman[odd-0.0]__tracksummary_kf.root: d5085882e45a0b699194dff9f40a36e9291227bf65f9aaaf9087f9242ef5ae22 test_truth_tracking_kalman[odd-1000.0]__trackstates_kf.root: efdf37f56fa3ef85265cda61853f4c0f989e3d4f4745b5e351c9bcca78cd93cc diff --git a/Examples/Python/tests/test_blueprint.py b/Examples/Python/tests/test_blueprint.py index 8471bf52105..629753a8a49 100644 --- a/Examples/Python/tests/test_blueprint.py +++ b/Examples/Python/tests/test_blueprint.py @@ -6,7 +6,7 @@ m = acts.UnitConstants.m degree = acts.UnitConstants.degree -bv = acts.BinningValue +bv = acts.AxisDirection gctx = acts.GeometryContext() logLevel = acts.logging.VERBOSE @@ -25,7 +25,7 @@ def write(root: acts.BlueprintNode, stage: int): root = acts.Blueprint(envelope=acts.ExtentEnvelope(r=[10 * mm, 10 * mm])) assert root.depth == 0 - barrel = root.addCylinderContainer("Barrel", direction=bv.binR) + barrel = root.addCylinderContainer("Barrel", direction=bv.AxisR) assert barrel.depth == 1 @@ -42,11 +42,11 @@ def write(root: acts.BlueprintNode, stage: int): assert barrel.depth == 0 - det = root.addCylinderContainer("Detector", direction=bv.binZ) + det = root.addCylinderContainer("Detector", direction=bv.AxisZ) assert det.depth == 1 - with det.CylinderContainer("nEC", direction=bv.binZ) as ec: + with det.CylinderContainer("nEC", direction=bv.AxisZ) as ec: assert ec.depth == 2 z = -200 for i in range(1, 3): @@ -65,7 +65,7 @@ def write(root: acts.BlueprintNode, stage: int): write(det, 3) - with det.CylinderContainer("pEC", direction=bv.binZ) as ec: + with det.CylinderContainer("pEC", direction=bv.AxisZ) as ec: assert ec.depth == 2 z = 200 for i in range(1, 3): diff --git a/Examples/Python/tests/test_examples.py b/Examples/Python/tests/test_examples.py index 4e7ea9b14c3..67b36bd185e 100644 --- a/Examples/Python/tests/test_examples.py +++ b/Examples/Python/tests/test_examples.py @@ -402,9 +402,10 @@ def test_itk_seeding(tmp_path, trk_geo, field, assert_root_hash): EtaConfig, MomentumConfig, ParticleConfig, - ParticleSelectorConfig, addFatras, addDigitization, + ParticleSelectorConfig, + addDigiParticleSelection, ) addParticleGun( @@ -424,12 +425,6 @@ def test_itk_seeding(tmp_path, trk_geo, field, assert_root_hash): outputDirCsv=tmp_path / "csv", outputDirRoot=str(tmp_path), rnd=rnd, - postSelectParticles=ParticleSelectorConfig( - pt=(0.9 * u.GeV, None), - eta=(-4, 4), - hits=(9, None), - removeNeutral=True, - ), ) srcdir = Path(__file__).resolve().parent.parent.parent.parent @@ -442,6 +437,16 @@ def test_itk_seeding(tmp_path, trk_geo, field, assert_root_hash): rnd=rnd, ) + addDigiParticleSelection( + seq, + ParticleSelectorConfig( + pt=(0.9 * u.GeV, None), + eta=(-4, 4), + measurements=(9, None), + removeNeutral=True, + ), + ) + from acts.examples.reconstruction import ( addSeeding, ) diff --git a/Examples/Python/tests/test_propagation.py b/Examples/Python/tests/test_propagation.py index adfc55ba8c2..f1b35d3a14f 100644 --- a/Examples/Python/tests/test_propagation.py +++ b/Examples/Python/tests/test_propagation.py @@ -62,8 +62,8 @@ def test_steppers(conf_const, trk_geo): trkParamExtractor = acts.examples.ParticleTrackParamExtractor( level=acts.logging.WARNING, - inputParticles="particles_input", - outputTrackParameters="params_particles_input", + inputParticles="particles_generated", + outputTrackParameters="params_particles_generated", ) seq.addAlgorithm(trkParamExtractor) @@ -71,7 +71,7 @@ def test_steppers(conf_const, trk_geo): acts.examples.PropagationAlgorithm, level=acts.logging.WARNING, propagatorImpl=prop, - inputTrackParameters="params_particles_input", + inputTrackParameters="params_particles_generated", outputSummaryCollection="propagation_summary", sterileLogger=False, ) diff --git a/Examples/Python/tests/test_reader.py b/Examples/Python/tests/test_reader.py index 46b1c9c229f..0153cc3b8d7 100644 --- a/Examples/Python/tests/test_reader.py +++ b/Examples/Python/tests/test_reader.py @@ -53,13 +53,13 @@ def test_root_particle_reader(tmp_path, conf_const, ptcl_gun): conf_const( RootParticleReader, acts.logging.WARNING, - outputParticles="particles_input", + outputParticles="particles_generated", filePath=str(file), ) ) alg = AssertCollectionExistsAlg( - "particles_input", "check_alg", acts.logging.WARNING + "particles_generated", "check_alg", acts.logging.WARNING ) s2.addAlgorithm(alg) @@ -317,7 +317,7 @@ def test_edm4hep_simhit_particle_reader(tmp_path): "LongStripBarrelReadout", "LongStripEndcapReadout", ], - outputParticlesGenerator="particles_input", + outputParticlesGenerator="particles_generated", outputParticlesSimulation="particles_simulated", outputSimHits="simhits", dd4hepDetector=detector, @@ -329,7 +329,7 @@ def test_edm4hep_simhit_particle_reader(tmp_path): s.addAlgorithm(alg) alg = AssertCollectionExistsAlg( - "particles_input", "check_alg", acts.logging.WARNING + "particles_generated", "check_alg", acts.logging.WARNING ) s.addAlgorithm(alg) @@ -435,3 +435,52 @@ def test_edm4hep_tracks_reader(tmp_path): ) s.run() + + +@pytest.mark.root +def test_buffered_reader(tmp_path, conf_const, ptcl_gun): + # Test the buffered reader with the ROOT particle reader + # need to write out some particles first + eventsInBuffer = 5 + eventsToProcess = 10 + + s = Sequencer(numThreads=1, events=eventsInBuffer, logLevel=acts.logging.WARNING) + evGen = ptcl_gun(s) + + file = tmp_path / "particles.root" + s.addWriter( + conf_const( + RootParticleWriter, + acts.logging.WARNING, + inputParticles=evGen.config.outputParticles, + filePath=str(file), + ) + ) + + s.run() + + # reset sequencer for reading + s2 = Sequencer(events=eventsToProcess, numThreads=1, logLevel=acts.logging.WARNING) + + reader = acts.examples.RootParticleReader( + level=acts.logging.WARNING, + outputParticles="particles_input", + filePath=str(file), + ) + + s2.addReader( + acts.examples.BufferedReader( + level=acts.logging.WARNING, + upstreamReader=reader, + bufferSize=eventsInBuffer, + ) + ) + + alg = AssertCollectionExistsAlg( + "particles_input", "check_alg", acts.logging.WARNING + ) + s2.addAlgorithm(alg) + + s2.run() + + assert alg.events_seen == eventsToProcess diff --git a/Examples/Scripts/Optimization/ckf.py b/Examples/Scripts/Optimization/ckf.py index 7de27b98465..78d8abbd96a 100755 --- a/Examples/Scripts/Optimization/ckf.py +++ b/Examples/Scripts/Optimization/ckf.py @@ -116,9 +116,10 @@ def runCKFTracks( EtaConfig, PhiConfig, ParticleConfig, - ParticleSelectorConfig, addFatras, addDigitization, + ParticleSelectorConfig, + addDigiParticleSelection, ) from acts.examples.reconstruction import ( @@ -160,7 +161,7 @@ def runCKFTracks( RootParticleReader( level=acts.logging.INFO, filePath=str(inputParticlePath.resolve()), - outputParticles="particles_input", + outputParticles="particles_generated", ) ) @@ -169,11 +170,6 @@ def runCKFTracks( trackingGeometry, field, rnd=rnd, - postSelectParticles=ParticleSelectorConfig( - pt=(0.5 * u.GeV, None), - hits=(9, None), - removeNeutral=True, - ), ) addDigitization( @@ -184,6 +180,15 @@ def runCKFTracks( rnd=rnd, ) + addDigiParticleSelection( + s, + ParticleSelectorConfig( + pt=(0.5 * u.GeV, None), + measurements=(9, None), + removeNeutral=True, + ), + ) + addSeeding( s, trackingGeometry, diff --git a/Examples/Scripts/Python/blueprint.py b/Examples/Scripts/Python/blueprint.py index 0dca3a6629f..386a44076b1 100755 --- a/Examples/Scripts/Python/blueprint.py +++ b/Examples/Scripts/Python/blueprint.py @@ -10,7 +10,7 @@ root = acts.Blueprint(envelope=acts.ExtentEnvelope(r=[10 * mm, 10 * mm])) -pixel = root.addCylinderContainer(direction=acts.BinningValue.binZ, name="Pixel") +pixel = root.addCylinderContainer(direction=acts.AxisDirection.AxisZ, name="Pixel") print(repr(pixel)) trf = acts.Transform3.Identity() * acts.Translation3(acts.Vector3(0, 0, 0 * mm)) @@ -19,7 +19,7 @@ if True: barrel = acts.CylinderContainerBlueprintNode( "PixelBarrel", - acts.BinningValue.binR, + acts.AxisDirection.AxisR, attachmentStrategy=acts.CylinderVolumeStack.AttachmentStrategy.Gap, resizeStrategy=acts.CylinderVolumeStack.ResizeStrategy.Gap, ) @@ -37,7 +37,7 @@ if True: - with pixel.CylinderContainer("PixelPosEndcap", acts.BinningValue.binZ) as ec: + with pixel.CylinderContainer("PixelPosEndcap", acts.AxisDirection.AxisZ) as ec: print("Positive Endcap") ec.attachmentStrategy = acts.CylinderVolumeStack.AttachmentStrategy.Gap @@ -60,7 +60,7 @@ if True: with pixel.Material() as mat: with mat.CylinderContainer( - direction=acts.BinningValue.binZ, name="PixelNegEndcap" + direction=acts.AxisDirection.AxisZ, name="PixelNegEndcap" ) as ec: ec.attachmentStrategy = acts.CylinderVolumeStack.AttachmentStrategy.Gap diff --git a/Examples/Scripts/Python/ckf_tracks.py b/Examples/Scripts/Python/ckf_tracks.py index 1ef32c844ee..4be446e7716 100755 --- a/Examples/Scripts/Python/ckf_tracks.py +++ b/Examples/Scripts/Python/ckf_tracks.py @@ -27,9 +27,10 @@ def runCKFTracks( EtaConfig, PhiConfig, ParticleConfig, - ParticleSelectorConfig, addFatras, addDigitization, + ParticleSelectorConfig, + addDigiParticleSelection, ) from acts.examples.reconstruction import ( @@ -71,7 +72,7 @@ def runCKFTracks( RootParticleReader( level=acts.logging.INFO, filePath=str(inputParticlePath.resolve()), - outputParticles="particles_input", + outputParticles="particles_generated", ) ) @@ -80,11 +81,6 @@ def runCKFTracks( trackingGeometry, field, rnd=rnd, - postSelectParticles=ParticleSelectorConfig( - pt=(0.5 * u.GeV, None), - hits=(9, None), - removeNeutral=True, - ), ) addDigitization( @@ -95,6 +91,15 @@ def runCKFTracks( rnd=rnd, ) + addDigiParticleSelection( + s, + ParticleSelectorConfig( + pt=(0.5 * u.GeV, None), + measurements=(9, None), + removeNeutral=True, + ), + ) + addSeeding( s, trackingGeometry, diff --git a/Examples/Scripts/Python/detector_creation.py b/Examples/Scripts/Python/detector_creation.py index 071520b85fc..8c90078d8d5 100644 --- a/Examples/Scripts/Python/detector_creation.py +++ b/Examples/Scripts/Python/detector_creation.py @@ -70,7 +70,7 @@ volumeOptions.surfaceOptions = surfaceOptions # Transverse view - xyRange = acts.Extent([[acts.BinningValue.binZ, [-50, 50]]]) + xyRange = acts.Extent([[acts.AxisDirection.AxisZ, [-50, 50]]]) xyView = acts.svg.drawDetector( geoContext, detector, @@ -83,7 +83,7 @@ xyFile.write("odd_xy.svg") # Longitudinal view - zrRange = acts.Extent([[acts.BinningValue.binPhi, [-0.1, 0.1]]]) + zrRange = acts.Extent([[acts.AxisDirection.AxisPhi, [-0.1, 0.1]]]) zrView = acts.svg.drawDetector( geoContext, detector, diff --git a/Examples/Scripts/Python/digitization.py b/Examples/Scripts/Python/digitization.py index 3e2479983af..9d59e75cf50 100755 --- a/Examples/Scripts/Python/digitization.py +++ b/Examples/Scripts/Python/digitization.py @@ -49,10 +49,14 @@ def runDigitization( evGen = acts.examples.RootParticleReader( level=s.config.logLevel, filePath=str(particlesInput), - outputParticles="particles_input", + outputParticles="particles_generated", ) s.addReader(evGen) + s.addWhiteboardAlias( + "particles_generated_selected", evGen.config.outputParticles + ) + outputDir = Path(outputDir) addFatras( s, diff --git a/Examples/Scripts/Python/event_recording.py b/Examples/Scripts/Python/event_recording.py index 8c31799c768..959be3e7f5b 100755 --- a/Examples/Scripts/Python/event_recording.py +++ b/Examples/Scripts/Python/event_recording.py @@ -41,7 +41,7 @@ def runEventRecording(detector, outputDir, s=None): ), ) ], - outputParticles="particles_input", + outputParticles="particles_generated", outputVertices="vertices_input", randomNumbers=rnd, ) diff --git a/Examples/Scripts/Python/full_chain_itk.py b/Examples/Scripts/Python/full_chain_itk.py index afb1df6a12b..f5d7f37193c 100755 --- a/Examples/Scripts/Python/full_chain_itk.py +++ b/Examples/Scripts/Python/full_chain_itk.py @@ -5,11 +5,12 @@ MomentumConfig, EtaConfig, ParticleConfig, - ParticleSelectorConfig, addPythia8, - addFatras, ParticleSelectorConfig, + addGenParticleSelection, + addFatras, addDigitization, + addDigiParticleSelection, ) from acts.examples.reconstruction import ( addSeeding, @@ -56,27 +57,21 @@ outputDirRoot=outputDir, ) -addFatras( - s, - trackingGeometry, - field, - rnd=rnd, - preSelectParticles=( + addGenParticleSelection( + s, ParticleSelectorConfig( rho=(0.0 * u.mm, 28.0 * u.mm), absZ=(0.0 * u.mm, 1.0 * u.m), eta=(-4.0, 4.0), pt=(150 * u.MeV, None), - ) - if ttbar_pu200 - else ParticleSelectorConfig() - ), - postSelectParticles=ParticleSelectorConfig( - pt=(1.0 * u.GeV, None), - eta=(-4.0, 4.0), - hits=(9, None), - removeNeutral=True, - ), + ), + ) + +addFatras( + s, + trackingGeometry, + field, + rnd=rnd, outputDirRoot=outputDir, ) @@ -89,6 +84,16 @@ rnd=rnd, ) +addDigiParticleSelection( + s, + ParticleSelectorConfig( + pt=(1.0 * u.GeV, None), + eta=(-4.0, 4.0), + measurements=(9, None), + removeNeutral=True, + ), +) + addSeeding( s, trackingGeometry, diff --git a/Examples/Scripts/Python/full_chain_itk_Gbts.py b/Examples/Scripts/Python/full_chain_itk_Gbts.py index a939bd7e930..9801fa9b448 100755 --- a/Examples/Scripts/Python/full_chain_itk_Gbts.py +++ b/Examples/Scripts/Python/full_chain_itk_Gbts.py @@ -5,11 +5,12 @@ MomentumConfig, EtaConfig, ParticleConfig, - ParticleSelectorConfig, addPythia8, - addFatras, ParticleSelectorConfig, + addGenParticleSelection, + addFatras, addDigitization, + addDigiParticleSelection, ) from acts.examples.reconstruction import ( addSeeding, @@ -51,27 +52,21 @@ outputDirRoot=outputDir, ) -addFatras( - s, - trackingGeometry, - field, - rnd=rnd, - preSelectParticles=( + addGenParticleSelection( + s, ParticleSelectorConfig( rho=(0.0 * u.mm, 28.0 * u.mm), absZ=(0.0 * u.mm, 1.0 * u.m), eta=(-4.0, 4.0), pt=(150 * u.MeV, None), - ) - if ttbar_pu200 - else ParticleSelectorConfig() - ), - postSelectParticles=ParticleSelectorConfig( - pt=(1.0 * u.GeV, None), - eta=(-4.0, 4.0), - hits=(9, None), - removeNeutral=True, - ), + ), + ) + +addFatras( + s, + trackingGeometry, + field, + rnd=rnd, outputDirRoot=outputDir, ) @@ -85,6 +80,16 @@ rnd=rnd, ) +addDigiParticleSelection( + s, + ParticleSelectorConfig( + pt=(1.0 * u.GeV, None), + eta=(-4.0, 4.0), + measurements=(9, None), + removeNeutral=True, + ), +) + addSeeding( s, trackingGeometry, @@ -95,7 +100,7 @@ ), geoSelectionConfigFile=geo_dir / "itk-hgtd/geoSelection-ITk.json", layerMappingConfigFile=geo_dir / "itk-hgtd/ACTS_FTF_mapinput.csv", - connector_inputConfigFile=geo_dir / "itk-hgtd/binTables_ITK_RUN4.txt", + ConnectorInputConfigFile=geo_dir / "itk-hgtd/binTables_ITK_RUN4.txt", outputDirRoot=outputDir, ) diff --git a/Examples/Scripts/Python/full_chain_odd.py b/Examples/Scripts/Python/full_chain_odd.py index 3b7261c47dd..50fa2465e38 100755 --- a/Examples/Scripts/Python/full_chain_odd.py +++ b/Examples/Scripts/Python/full_chain_odd.py @@ -8,18 +8,19 @@ import acts import acts.examples from acts.examples.simulation import ( - addParticleGun, MomentumConfig, EtaConfig, PhiConfig, ParticleConfig, ParticleSelectorConfig, + addParticleGun, addPythia8, + addGenParticleSelection, addFatras, addGeant4, - ParticleSelectorConfig, + addSimParticleSelection, addDigitization, - addParticleSelection, + addDigiParticleSelection, ) from acts.examples.reconstruction import ( addSeeding, @@ -194,7 +195,7 @@ "LongStripBarrelReadout", "LongStripEndcapReadout", ], - outputParticlesGenerator="particles_input", + outputParticlesGenerator="particles_generated", outputParticlesSimulation="particles_simulated", outputSimHits="simhits", graphvizOutput="graphviz", @@ -204,19 +205,18 @@ level=acts.logging.INFO, ) s.addReader(edm4hepReader) + s.addWhiteboardAlias("particles", edm4hepReader.config.outputParticlesGenerator) - addParticleSelection( + addSimParticleSelection( s, - config=ParticleSelectorConfig( + ParticleSelectorConfig( rho=(0.0, 24 * u.mm), absZ=(0.0, 1.0 * u.m), eta=(-3.0, 3.0), pt=(150 * u.MeV, None), removeNeutral=True, ), - inputParticles="particles", - outputParticles="particles_selected", ) else: if not args.ttbar: @@ -257,6 +257,16 @@ outputDirCsv=outputDir if args.output_csv else None, ) + addGenParticleSelection( + s, + ParticleSelectorConfig( + rho=(0.0, 24 * u.mm), + absZ=(0.0, 1.0 * u.m), + eta=(-3.0, 3.0), + pt=(150 * u.MeV, None), + ), + ) + if args.geant4: if s.config.numThreads != 1: raise ValueError("Geant 4 simulation does not support multi-threading") @@ -269,18 +279,6 @@ detector, trackingGeometry, field, - preSelectParticles=ParticleSelectorConfig( - rho=(0.0, 24 * u.mm), - absZ=(0.0, 1.0 * u.m), - eta=(-3.0, 3.0), - pt=(150 * u.MeV, None), - ), - postSelectParticles=ParticleSelectorConfig( - pt=(1.0 * u.GeV, None), - eta=(-3.0, 3.0), - hits=(9, None), - removeNeutral=True, - ), outputDirRoot=outputDir if args.output_root else None, outputDirCsv=outputDir if args.output_csv else None, outputDirObj=outputDir if args.output_obj else None, @@ -293,22 +291,6 @@ s, trackingGeometry, field, - preSelectParticles=( - ParticleSelectorConfig( - rho=(0.0, 24 * u.mm), - absZ=(0.0, 1.0 * u.m), - eta=(-3.0, 3.0), - pt=(150 * u.MeV, None), - ) - if args.ttbar - else ParticleSelectorConfig() - ), - postSelectParticles=ParticleSelectorConfig( - pt=(1.0 * u.GeV, None), - eta=(-3.0, 3.0), - hits=(9, None), - removeNeutral=True, - ), enableInteractions=True, outputDirRoot=outputDir if args.output_root else None, outputDirCsv=outputDir if args.output_csv else None, @@ -326,6 +308,16 @@ rnd=rnd, ) +addDigiParticleSelection( + s, + ParticleSelectorConfig( + pt=(1.0 * u.GeV, None), + eta=(-3.0, 3.0), + measurements=(9, None), + removeNeutral=True, + ), +) + if args.reco: addSeeding( s, diff --git a/Examples/Scripts/Python/full_chain_odd_LRT.py b/Examples/Scripts/Python/full_chain_odd_LRT.py index 9c1f57074f6..fde8b3b418c 100644 --- a/Examples/Scripts/Python/full_chain_odd_LRT.py +++ b/Examples/Scripts/Python/full_chain_odd_LRT.py @@ -15,11 +15,13 @@ ParticleConfig, ParticleSelectorConfig, addPythia8, + ParticleSelectorConfig, + addGenParticleSelection, addFatras, addGeant4, - ParticleSelectorConfig, + addSimParticleSelection, addDigitization, - addParticleSelection, + addDigiParticleSelection, ) from acts.examples.reconstruction import ( addSeeding, @@ -194,7 +196,7 @@ "LongStripBarrelReadout", "LongStripEndcapReadout", ], - outputParticlesGenerator="particles_input", + outputParticlesGenerator="particles_generated", outputParticlesSimulation="particles_simulated", outputSimHits="simhits", graphvizOutput="graphviz", @@ -204,19 +206,18 @@ level=acts.logging.INFO, ) s.addReader(edm4hepReader) + s.addWhiteboardAlias("particles", edm4hepReader.config.outputParticlesGenerator) - addParticleSelection( + addSimParticleSelection( s, - config=ParticleSelectorConfig( + ParticleSelectorConfig( rho=(0.0, 24 * u.mm), absZ=(0.0, 1.0 * u.m), eta=(-3.0, 3.0), pt=(150 * u.MeV, None), removeNeutral=True, ), - inputParticles="particles", - outputParticles="particles_selected", ) else: if not args.ttbar: @@ -259,6 +260,16 @@ outputDirCsv=outputDir if args.output_csv else None, ) + addGenParticleSelection( + s, + ParticleSelectorConfig( + rho=(0.0, 24 * u.mm), + absZ=(0.0, 1.0 * u.m), + eta=(-3.0, 3.0), + pt=(150 * u.MeV, None), + ), + ) + if args.geant4: if s.config.numThreads != 1: raise ValueError("Geant 4 simulation does not support multi-threading") @@ -271,18 +282,6 @@ detector, trackingGeometry, field, - preSelectParticles=ParticleSelectorConfig( - rho=(0.0, 24 * u.mm), - absZ=(0.0, 1.0 * u.m), - eta=(-3.0, 3.0), - pt=(150 * u.MeV, None), - ), - postSelectParticles=ParticleSelectorConfig( - pt=(1.0 * u.GeV, None), - eta=(-3.0, 3.0), - hits=(9, None), - removeNeutral=True, - ), outputDirRoot=outputDir if args.output_root else None, outputDirCsv=outputDir if args.output_csv else None, outputDirObj=outputDir if args.output_obj else None, @@ -295,22 +294,6 @@ s, trackingGeometry, field, - preSelectParticles=( - ParticleSelectorConfig( - rho=(0.0, 24 * u.mm), - absZ=(0.0, 1.0 * u.m), - eta=(-3.0, 3.0), - pt=(150 * u.MeV, None), - ) - if args.ttbar - else ParticleSelectorConfig() - ), - postSelectParticles=ParticleSelectorConfig( - pt=(1.0 * u.GeV, None), - eta=(-3.0, 3.0), - hits=(9, None), - removeNeutral=True, - ), enableInteractions=True, outputDirRoot=outputDir if args.output_root else None, outputDirCsv=outputDir if args.output_csv else None, @@ -328,6 +311,16 @@ rnd=rnd, ) +addDigiParticleSelection( + s, + ParticleSelectorConfig( + pt=(1.0 * u.GeV, None), + eta=(-3.0, 3.0), + measurements=(9, None), + removeNeutral=True, + ), +) + if args.reco: addSeeding( s, diff --git a/Examples/Scripts/Python/full_chain_test.py b/Examples/Scripts/Python/full_chain_test.py index f09be753d46..492c823cb5f 100755 --- a/Examples/Scripts/Python/full_chain_test.py +++ b/Examples/Scripts/Python/full_chain_test.py @@ -401,7 +401,7 @@ def full_chain(args): "LongStripBarrelReadout", "LongStripEndcapReadout", ], - outputParticlesGenerator="particles_input", + outputParticlesGenerator="particles_generated", outputParticlesSimulation="particles_simulated", outputSimHits="simhits", graphvizOutput="graphviz", diff --git a/Examples/Scripts/Python/hashing_seeding.py b/Examples/Scripts/Python/hashing_seeding.py index b13ee204604..67484d40878 100755 --- a/Examples/Scripts/Python/hashing_seeding.py +++ b/Examples/Scripts/Python/hashing_seeding.py @@ -7,9 +7,11 @@ import acts.examples from acts.examples.simulation import ( addPythia8, - addFatras, ParticleSelectorConfig, + addGenParticleSelection, + addFatras, addDigitization, + addDigiParticleSelection, ) from acts.examples.reconstruction import ( @@ -204,20 +206,18 @@ def runHashingSeeding( rnd=rnd, ) + addGenParticleSelection( + s, + ParticleSelectorConfig( + rho=(0.0, 24 * u.mm), + absZ=(0.0, 1.0 * u.m), + ), + ) + addFatras( s, trackingGeometry, field, - preSelectParticles=ParticleSelectorConfig( - eta=(-eta, eta), - pt=(150 * u.MeV, None), - ), - postSelectParticles=ParticleSelectorConfig( - pt=(1.0 * u.GeV, None), - eta=(-eta, eta), - hits=(9, None), - removeNeutral=True, - ), enableInteractions=True, # outputDirRoot=outputDir, # RootParticle ERROR when setting the outputDirRoot outputDirCsv=outputDir if saveFiles else None, @@ -234,6 +234,16 @@ def runHashingSeeding( rnd=rnd, ) + addDigiParticleSelection( + s, + ParticleSelectorConfig( + pt=(1.0 * u.GeV, None), + eta=(-eta, eta), + measurements=(9, None), + removeNeutral=True, + ), + ) + import numpy as np cotThetaMax = 1 / (np.tan(2 * np.arctan(np.exp(-eta)))) # =1/tan(2×atan(e^(-eta))) diff --git a/Examples/Scripts/Python/material_mapping_core.py b/Examples/Scripts/Python/material_mapping_core.py index e5a6e865246..f01ece5cb8f 100644 --- a/Examples/Scripts/Python/material_mapping_core.py +++ b/Examples/Scripts/Python/material_mapping_core.py @@ -231,8 +231,8 @@ def runMaterialMapping(surfaces, inputFile, outputFile, outputMap, loglevel): gmBlueprintConfig = gm.GeoModelBlueprintCreater.Config() gmBlueprintConfig.detectorSurfaces = gmSurfaces gmBlueprintConfig.kdtBinning = [ - acts.BinningValue.binZ, - acts.BinningValue.binR, + acts.AxisDirection.AxisZ, + acts.AxisDirection.AxisR, ] gmBlueprintOptions = gm.GeoModelBlueprintCreater.Options() diff --git a/Examples/Scripts/Python/material_validation.py b/Examples/Scripts/Python/material_validation.py index a516262d2d4..b41eb43dd40 100755 --- a/Examples/Scripts/Python/material_validation.py +++ b/Examples/Scripts/Python/material_validation.py @@ -42,8 +42,8 @@ def runMaterialValidation( trkParamExtractor = acts.examples.ParticleTrackParamExtractor( level=acts.logging.INFO, - inputParticles="particles_input", - outputTrackParameters="params_particles_input", + inputParticles="particles_generated", + outputTrackParameters="params_particles_generated", ) s.addAlgorithm(trkParamExtractor) @@ -52,7 +52,7 @@ def runMaterialValidation( level=acts.logging.INFO, sterileLogger=True, recordMaterialInteractions=True, - inputTrackParameters="params_particles_input", + inputTrackParameters="params_particles_generated", outputSummaryCollection="propagation_summary", outputMaterialCollection="material_tracks", ) diff --git a/Examples/Scripts/Python/material_validation_core.py b/Examples/Scripts/Python/material_validation_core.py index 1d81054c091..305c1bfd862 100644 --- a/Examples/Scripts/Python/material_validation_core.py +++ b/Examples/Scripts/Python/material_validation_core.py @@ -171,8 +171,8 @@ def runMaterialValidation(s, ntracks, surfaces, outputFile, seed, loglevel): gmBlueprintConfig = gm.GeoModelBlueprintCreater.Config() gmBlueprintConfig.detectorSurfaces = gmSurfaces gmBlueprintConfig.kdtBinning = [ - acts.BinningValue.binZ, - acts.BinningValue.binR, + acts.AxisDirection.AxisZ, + acts.AxisDirection.AxisR, ] gmBlueprintOptions = gm.GeoModelBlueprintCreater.Options() diff --git a/Examples/Scripts/Python/material_validation_itk.py b/Examples/Scripts/Python/material_validation_itk.py index 4d5f095ef10..53e27de11ac 100755 --- a/Examples/Scripts/Python/material_validation_itk.py +++ b/Examples/Scripts/Python/material_validation_itk.py @@ -49,8 +49,8 @@ def runMaterialValidation( trkParamExtractor = acts.examples.ParticleTrackParamExtractor( level=acts.logging.INFO, - inputParticles="particles_input", - outputTrackParameters="params_particles_input", + inputParticles="particles_generated", + outputTrackParameters="params_particles_generated", ) s.addAlgorithm(trkParamExtractor) @@ -59,7 +59,7 @@ def runMaterialValidation( level=acts.logging.INFO, sterileLogger=False, recordMaterialInteractions=True, - inputTrackParameters="params_particles_input", + inputTrackParameters="params_particles_generated", outputPropagationSteps="propagation_steps", outputMaterialTracks="material-tracks", ) diff --git a/Examples/Scripts/Python/propagation.py b/Examples/Scripts/Python/propagation.py index 72401d8113e..699fd367044 100755 --- a/Examples/Scripts/Python/propagation.py +++ b/Examples/Scripts/Python/propagation.py @@ -33,8 +33,8 @@ def runPropagation(trackingGeometry, field, outputDir, s=None, decorators=[]): trkParamExtractor = acts.examples.ParticleTrackParamExtractor( level=acts.logging.WARNING, - inputParticles="particles_input", - outputTrackParameters="params_particles_input", + inputParticles="particles_generated", + outputTrackParameters="params_particles_generated", ) s.addAlgorithm(trkParamExtractor) @@ -50,7 +50,7 @@ def runPropagation(trackingGeometry, field, outputDir, s=None, decorators=[]): propagatorImpl=propagator, level=acts.logging.INFO, sterileLogger=True, - inputTrackParameters="params_particles_input", + inputTrackParameters="params_particles_generated", outputSummaryCollection="propagation_summary", ) s.addAlgorithm(propagationAlgorithm) diff --git a/Examples/Scripts/Python/seeding.py b/Examples/Scripts/Python/seeding.py index ce1914accc7..c225ec0190e 100755 --- a/Examples/Scripts/Python/seeding.py +++ b/Examples/Scripts/Python/seeding.py @@ -57,9 +57,10 @@ def runSeeding( EtaConfig, PhiConfig, ParticleConfig, - ParticleSelectorConfig, addFatras, addDigitization, + ParticleSelectorConfig, + addDigiParticleSelection, ) s = s or acts.examples.Sequencer( @@ -86,13 +87,6 @@ def runSeeding( outputDirCsv=outputDir / "csv", outputDirRoot=outputDir, rnd=rnd, - preSelectParticles=None, - postSelectParticles=ParticleSelectorConfig( - pt=(1.0 * u.GeV, None), - eta=(-2.5, 2.5), - hits=(9, None), - removeNeutral=True, - ), ) srcdir = Path(__file__).resolve().parent.parent.parent.parent @@ -105,6 +99,16 @@ def runSeeding( rnd=rnd, ) + addDigiParticleSelection( + s, + ParticleSelectorConfig( + pt=(1.0 * u.GeV, None), + eta=(-2.5, 2.5), + measurements=(9, None), + removeNeutral=True, + ), + ) + from acts.examples.reconstruction import ( addSeeding, SeedFinderConfigArg, diff --git a/Examples/Scripts/Python/telescope_track_params_lookup_generation.py b/Examples/Scripts/Python/telescope_track_params_lookup_generation.py index 4f3eada72b1..11247297c6d 100644 --- a/Examples/Scripts/Python/telescope_track_params_lookup_generation.py +++ b/Examples/Scripts/Python/telescope_track_params_lookup_generation.py @@ -47,10 +47,9 @@ def estimateLookup(trackingGeometry, numEvents, outputPath): s, trackingGeometry, field, - inputParticles="particles_input", + inputParticles="particles_generated", outputSimHits="sim_hits", rnd=rnd, - preSelectParticles=None, ) # Set up the track lookup grid writer @@ -66,7 +65,7 @@ def estimateLookup(trackingGeometry, numEvents, outputPath): refLayers={refGeometryId: refSurface}, bins=(1, 1000), inputHits="sim_hits", - inputParticles="particles_input", + inputParticles="particles_generated", trackLookupGridWriters=[jsonWriter], ) trackEstAlg = acts.examples.TrackParamsLookupEstimation( diff --git a/Examples/Scripts/Python/truth_tracking_gsf.py b/Examples/Scripts/Python/truth_tracking_gsf.py index 7d6e05c07c7..d78250c34b4 100755 --- a/Examples/Scripts/Python/truth_tracking_gsf.py +++ b/Examples/Scripts/Python/truth_tracking_gsf.py @@ -24,9 +24,10 @@ def runTruthTrackingGsf( EtaConfig, PhiConfig, MomentumConfig, - ParticleSelectorConfig, addFatras, addDigitization, + ParticleSelectorConfig, + addDigiParticleSelection, ) from acts.examples.reconstruction import ( addSeeding, @@ -67,7 +68,7 @@ def runTruthTrackingGsf( acts.examples.RootParticleReader( level=acts.logging.INFO, filePath=str(inputParticlePath.resolve()), - outputParticles="particles_input", + outputParticles="particles_generated", ) ) @@ -77,12 +78,6 @@ def runTruthTrackingGsf( field, rnd=rnd, enableInteractions=True, - postSelectParticles=ParticleSelectorConfig( - pt=(0.9 * u.GeV, None), - hits=(7, None), - removeNeutral=True, - removeSecondaries=True, - ), ) addDigitization( @@ -93,12 +88,22 @@ def runTruthTrackingGsf( rnd=rnd, ) + addDigiParticleSelection( + s, + ParticleSelectorConfig( + pt=(0.9 * u.GeV, None), + measurements=(7, None), + removeNeutral=True, + removeSecondaries=True, + ), + ) + addSeeding( s, trackingGeometry, field, rnd=rnd, - inputParticles="particles_input", + inputParticles="particles_generated", seedingAlgorithm=SeedingAlgorithm.TruthSmeared, particleHypothesis=acts.ParticleHypothesis.electron, ) diff --git a/Examples/Scripts/Python/truth_tracking_gx2f.py b/Examples/Scripts/Python/truth_tracking_gx2f.py index 2c692ca87cc..d1ea03699e9 100644 --- a/Examples/Scripts/Python/truth_tracking_gx2f.py +++ b/Examples/Scripts/Python/truth_tracking_gx2f.py @@ -23,9 +23,10 @@ def runTruthTrackingGx2f( EtaConfig, PhiConfig, MomentumConfig, - ParticleSelectorConfig, addFatras, addDigitization, + ParticleSelectorConfig, + addDigiParticleSelection, ) from acts.examples.reconstruction import ( addSeeding, @@ -64,7 +65,7 @@ def runTruthTrackingGx2f( acts.examples.RootParticleReader( level=acts.logging.INFO, filePath=str(inputParticlePath.resolve()), - outputParticles="particles_input", + outputParticles="particles_generated", ) ) @@ -74,12 +75,6 @@ def runTruthTrackingGx2f( field, rnd=rnd, enableInteractions=True, - postSelectParticles=ParticleSelectorConfig( - pt=(0.9 * u.GeV, None), - hits=(7, None), - removeNeutral=True, - removeSecondaries=True, - ), ) addDigitization( @@ -90,12 +85,22 @@ def runTruthTrackingGx2f( rnd=rnd, ) + addDigiParticleSelection( + s, + ParticleSelectorConfig( + pt=(0.9 * u.GeV, None), + measurements=(7, None), + removeNeutral=True, + removeSecondaries=True, + ), + ) + addSeeding( s, trackingGeometry, field, rnd=rnd, - inputParticles="particles_input", + inputParticles="particles_generated", seedingAlgorithm=SeedingAlgorithm.TruthSmeared, particleHypothesis=acts.ParticleHypothesis.muon, ) diff --git a/Examples/Scripts/Python/truth_tracking_kalman.py b/Examples/Scripts/Python/truth_tracking_kalman.py index 0102f1db8ee..694870d9b6d 100755 --- a/Examples/Scripts/Python/truth_tracking_kalman.py +++ b/Examples/Scripts/Python/truth_tracking_kalman.py @@ -26,9 +26,10 @@ def runTruthTrackingKalman( EtaConfig, PhiConfig, MomentumConfig, - ParticleSelectorConfig, addFatras, addDigitization, + ParticleSelectorConfig, + addDigiParticleSelection, ) from acts.examples.reconstruction import ( addSeeding, @@ -69,10 +70,10 @@ def runTruthTrackingKalman( acts.examples.RootParticleReader( level=acts.logging.INFO, filePath=str(inputParticlePath.resolve()), - outputParticles="particles_input", + outputParticles="particles_generated", ) ) - s.addWhiteboardAlias("particles", "particles_input") + s.addWhiteboardAlias("particles", "particles_generated") if inputHitsPath is None: addFatras( @@ -81,12 +82,6 @@ def runTruthTrackingKalman( field, rnd=rnd, enableInteractions=True, - postSelectParticles=ParticleSelectorConfig( - pt=(0.9 * u.GeV, None), - hits=(7, None), - removeNeutral=True, - removeSecondaries=True, - ), ) else: logger.info("Reading hits from %s", inputHitsPath.resolve()) @@ -107,12 +102,22 @@ def runTruthTrackingKalman( rnd=rnd, ) + addDigiParticleSelection( + s, + ParticleSelectorConfig( + pt=(0.9 * u.GeV, None), + measurements=(7, None), + removeNeutral=True, + removeSecondaries=True, + ), + ) + addSeeding( s, trackingGeometry, field, rnd=rnd, - inputParticles="particles_input", + inputParticles="particles_generated", seedingAlgorithm=SeedingAlgorithm.TruthSmeared, particleHypothesis=acts.ParticleHypothesis.muon, ) diff --git a/Examples/Scripts/Python/vertex_fitting.py b/Examples/Scripts/Python/vertex_fitting.py index 5add3b8f1c1..f32cb174d6d 100755 --- a/Examples/Scripts/Python/vertex_fitting.py +++ b/Examples/Scripts/Python/vertex_fitting.py @@ -33,7 +33,7 @@ def runVertexFitting( rnd = acts.examples.RandomNumbers(seed=42) - inputParticles = "particles_input" + inputParticles = "particles_generated" if inputParticlePath is None: logger.info("Generating particles using Pythia8") addPythia8(s, rnd) @@ -68,13 +68,13 @@ def runVertexFitting( trkParamExtractor = acts.examples.ParticleTrackParamExtractor( level=acts.logging.WARNING, inputParticles=selectedParticles, - outputTrackParameters="params_particles_input", + outputTrackParameters="params_particles_generated", ) s.addAlgorithm(trkParamExtractor) ptclSmearing = TrackParameterSmearing( level=acts.logging.INFO, - inputTrackParameters="params_particles_input", + inputTrackParameters="params_particles_generated", outputTrackParameters=trackParameters, randomNumbers=rnd, ) diff --git a/Fatras/include/ActsFatras/Kernel/detail/SimulationActor.hpp b/Fatras/include/ActsFatras/Kernel/detail/SimulationActor.hpp index bee570485b0..12bba048d6d 100644 --- a/Fatras/include/ActsFatras/Kernel/detail/SimulationActor.hpp +++ b/Fatras/include/ActsFatras/Kernel/detail/SimulationActor.hpp @@ -10,17 +10,15 @@ #include "Acts/Material/ISurfaceMaterial.hpp" #include "Acts/Propagator/ConstrainedStep.hpp" -#include "Acts/Propagator/Propagator.hpp" +#include "Acts/Propagator/PropagatorState.hpp" #include "Acts/Propagator/StandardAborters.hpp" #include "Acts/Surfaces/Surface.hpp" -#include "ActsFatras/EventData/Hit.hpp" #include "ActsFatras/EventData/Particle.hpp" #include "ActsFatras/Kernel/SimulationResult.hpp" #include #include #include -#include namespace ActsFatras::detail { @@ -124,8 +122,10 @@ struct SimulationActor { const auto stepSize = properTimeDiff * result.particle.absoluteMomentum() / result.particle.mass(); + stepper.releaseStepSize(state.stepping, + Acts::ConstrainedStep::Type::User); stepper.updateStepSize(state.stepping, stepSize, - Acts::ConstrainedStep::user); + Acts::ConstrainedStep::Type::User); } // arm the point-like interaction limits in the first step diff --git a/Fatras/src/Digitization/Segmentizer.cpp b/Fatras/src/Digitization/Segmentizer.cpp index 27dfb903efc..72b452ca802 100644 --- a/Fatras/src/Digitization/Segmentizer.cpp +++ b/Fatras/src/Digitization/Segmentizer.cpp @@ -117,7 +117,7 @@ ActsFatras::Segmentizer::segments(const Acts::GeometryContext& geoCtx, // The phi boundaries if (bstart[1] != bend[1]) { double referenceR = - surface.binningPositionValue(geoCtx, Acts::BinningValue::binR); + surface.referencePositionValue(geoCtx, Acts::AxisDirection::AxisR); Acts::Vector2 origin = {0., 0.}; const auto& phiboundaries = segmentation.binningData()[1].boundaries(); std::vector phibbounds = { diff --git a/Plugins/ActSVG/include/Acts/Plugins/ActSVG/GridSvgConverter.hpp b/Plugins/ActSVG/include/Acts/Plugins/ActSVG/GridSvgConverter.hpp index c81698de5c2..1efb229797b 100644 --- a/Plugins/ActSVG/include/Acts/Plugins/ActSVG/GridSvgConverter.hpp +++ b/Plugins/ActSVG/include/Acts/Plugins/ActSVG/GridSvgConverter.hpp @@ -31,7 +31,7 @@ using ProtoGrid = actsvg::proto::grid; namespace GridConverter { // An optional range and binning value -using AxisBound = std::tuple, BinningValue>; +using AxisBound = std::tuple, AxisDirection>; /// Nested Options struct struct Options { @@ -43,19 +43,19 @@ struct Options { /// Convert an ACTS grid into a actsvg protogrid, it currently works with /// -/// - 1D: [ binX ] , [ binY ], [ binR ] , [ binPhi ] -/// - 2D: [ binX, binY ], [ binZ, binPhi ], [ binR, binPhi ] +/// - 1D: [ AxisX ] , [ AxisY ], [ AxisR ] , [ AxisPhi ] +/// - 2D: [ AxisX, AxisY ], [ AxisZ, AxisPhi ], [ AxisR, AxisPhi ] /// /// @tparam grid_type is the type of the grid to be converted /// /// @param grid the grid to be converted -/// @param bValues the binning values identifying the axes +/// @param aDirs the axis directions of the grid /// @param cOptions the conversion options /// /// @return an ACTSVG proto grid for displaying template ProtoGrid convert(const grid_type& grid, - const std::array& bValues, + const std::array& aDirs, const GridConverter::Options& cOptions) { // The return object ProtoGrid pGrid; @@ -70,7 +70,7 @@ ProtoGrid convert(const grid_type& grid, // 1D case (more to be filled in later) if constexpr (grid_type::DIM == 1u) { - if (bValues[0u] == BinningValue::binPhi && + if (aDirs[0u] == AxisDirection::AxisPhi && axes[0]->getBoundaryType() == AxisBoundaryType::Closed) { // swap needed edges1 = axes[0]->getBinEdges(); @@ -78,7 +78,7 @@ ProtoGrid convert(const grid_type& grid, } if (cOptions.optionalBound.has_value()) { auto [boundRange, boundValue] = cOptions.optionalBound.value(); - if (boundValue == BinningValue::binR) { + if (boundValue == AxisDirection::AxisR) { // good - no swap needed edges0 = {boundRange[0u], boundRange[1u]}; } @@ -89,26 +89,26 @@ ProtoGrid convert(const grid_type& grid, // Assign edges0 = axes[0]->getBinEdges(); edges1 = axes[1]->getBinEdges(); - if (bValues[0] == BinningValue::binPhi && - bValues[1] == BinningValue::binZ) { + if (aDirs[0] == AxisDirection::AxisPhi && + aDirs[1] == AxisDirection::AxisZ) { // swap needed std::swap(edges0, edges1); pGrid._type = actsvg::proto::grid::e_z_phi; - } else if (bValues[0] == BinningValue::binPhi && - bValues[1] == BinningValue::binR) { + } else if (aDirs[0] == AxisDirection::AxisPhi && + aDirs[1] == AxisDirection::AxisR) { // swap needed std::swap(edges0, edges1); pGrid._type = actsvg::proto::grid::e_r_phi; - } else if (bValues[0] == BinningValue::binZ && - bValues[1] == BinningValue::binPhi) { + } else if (aDirs[0] == AxisDirection::AxisZ && + aDirs[1] == AxisDirection::AxisPhi) { // good - no swap needed pGrid._type = actsvg::proto::grid::e_z_phi; - } else if (bValues[0] == BinningValue::binR && - bValues[1] == BinningValue::binPhi) { + } else if (aDirs[0] == AxisDirection::AxisR && + aDirs[1] == AxisDirection::AxisPhi) { // good - no swap needed pGrid._type = actsvg::proto::grid::e_r_phi; - } else if (bValues[0] == BinningValue::binX && - bValues[1] == BinningValue::binY) { + } else if (aDirs[0] == AxisDirection::AxisX && + aDirs[1] == AxisDirection::AxisY) { // good - no swap needed pGrid._type = actsvg::proto::grid::e_x_y; } diff --git a/Plugins/ActSVG/include/Acts/Plugins/ActSVG/IndexedSurfacesSvgConverter.hpp b/Plugins/ActSVG/include/Acts/Plugins/ActSVG/IndexedSurfacesSvgConverter.hpp index b90803b07a5..b22a97f49e3 100644 --- a/Plugins/ActSVG/include/Acts/Plugins/ActSVG/IndexedSurfacesSvgConverter.hpp +++ b/Plugins/ActSVG/include/Acts/Plugins/ActSVG/IndexedSurfacesSvgConverter.hpp @@ -72,10 +72,10 @@ ProtoIndexedSurfaceGrid convertImpl(const GeometryContext& gctx, // - for 1D phi // - for 2D z-phi or phi-z bool estimateR = (index_grid::grid_type::DIM == 1 && - indexGrid.casts[0u] == BinningValue::binPhi) || + indexGrid.casts[0u] == AxisDirection::AxisPhi) || (index_grid::grid_type::DIM == 2 && - (indexGrid.casts[0u] == BinningValue::binPhi || - indexGrid.casts[1u] == BinningValue::binPhi)); + (indexGrid.casts[0u] == AxisDirection::AxisPhi || + indexGrid.casts[1u] == AxisDirection::AxisPhi)); for (auto [is, s] : enumerate(surfaces)) { // Create the surface converter options @@ -91,9 +91,9 @@ ProtoIndexedSurfaceGrid convertImpl(const GeometryContext& gctx, auto sExtent = s->polyhedronRepresentation(gctx, 4u).extent(); if constexpr (index_grid::grid_type::DIM == 2u) { pSurface._radii[0u] = - static_cast(sExtent.medium(BinningValue::binR)); + static_cast(sExtent.medium(AxisDirection::AxisR)); } - constrain.extend(sExtent, {BinningValue::binR}); + constrain.extend(sExtent, {AxisDirection::AxisR}); } // Add center info std::string centerInfo = " - center = ("; @@ -113,10 +113,10 @@ ProtoIndexedSurfaceGrid convertImpl(const GeometryContext& gctx, // Adjust the grid options if constexpr (index_grid::grid_type::DIM == 1u) { - if (indexGrid.casts[0u] == BinningValue::binPhi) { - auto estRangeR = constrain.range(BinningValue::binR); + if (indexGrid.casts[0u] == AxisDirection::AxisPhi) { + auto estRangeR = constrain.range(AxisDirection::AxisR); std::array rRange = {estRangeR.min(), estRangeR.max()}; - gridOptions.optionalBound = {rRange, BinningValue::binR}; + gridOptions.optionalBound = {rRange, AxisDirection::AxisR}; } } @@ -165,7 +165,7 @@ ProtoIndexedSurfaceGrid convertImpl(const GeometryContext& gctx, pGrid._bin_ids.push_back(binInfo); if (estimateR) { pGrid._reference_r = - static_cast(constrain.medium(BinningValue::binR)); + static_cast(constrain.medium(AxisDirection::AxisR)); } } } diff --git a/Plugins/ActSVG/src/LayerSvgConverter.cpp b/Plugins/ActSVG/src/LayerSvgConverter.cpp index 1de781d509e..ca999ade6a4 100644 --- a/Plugins/ActSVG/src/LayerSvgConverter.cpp +++ b/Plugins/ActSVG/src/LayerSvgConverter.cpp @@ -86,7 +86,7 @@ std::vector Acts::Svg::LayerConverter::convert( for (const auto& sf : layer.surfaceArray()->surfaces()) { // Surface center const Acts::Vector3 rCenter = - sf->binningPosition(gctx, Acts::BinningValue::binR); + sf->referencePosition(gctx, Acts::AxisDirection::AxisR); const Acts::Vector3 sfCenter = sf->center(gctx); double radius = Acts::VectorHelpers::perp(rCenter); double phi = Acts::VectorHelpers::phi(rCenter); diff --git a/Plugins/ActSVG/src/PortalSvgConverter.cpp b/Plugins/ActSVG/src/PortalSvgConverter.cpp index 1c779d86dd2..56e0d600b92 100644 --- a/Plugins/ActSVG/src/PortalSvgConverter.cpp +++ b/Plugins/ActSVG/src/PortalSvgConverter.cpp @@ -68,22 +68,22 @@ std::vector convertMultiLink( Acts::Vector3 position = refPosition; if constexpr (decltype(multiLink.indexedUpdater)::grid_type::DIM == 1u) { // Get the binning value - Acts::BinningValue bValue = casts[0u]; + Acts::AxisDirection bValue = casts[0u]; // Get the boundaries - take care, they are in local coordinates const auto& boundaries = multiLink.indexedUpdater.grid.axes()[0u]->getBinEdges(); double refC = 0.5 * (boundaries[il + 1u] + boundaries[il]); - if (bValue == Acts::BinningValue::binR) { + if (bValue == Acts::AxisDirection::AxisR) { double phi = Acts::VectorHelpers::phi(refPosition); position = Acts::Vector3(refC * std::cos(phi), refC * std::sin(phi), refPosition.z()); - } else if (bValue == Acts::BinningValue::binZ) { + } else if (bValue == Acts::AxisDirection::AxisZ) { // correct to global refC += surface.transform(gctx).translation().z(); position[2] = refC; - } else if (bValue == Acts::BinningValue::binPhi) { + } else if (bValue == Acts::AxisDirection::AxisPhi) { double r = Acts::VectorHelpers::perp(refPosition); position = Acts::Vector3(r * std::cos(refC), r * std::sin(refC), refPosition.z()); diff --git a/Plugins/ActSVG/src/SurfaceArraySvgConverter.cpp b/Plugins/ActSVG/src/SurfaceArraySvgConverter.cpp index 4b327fe5e08..3166adbb724 100644 --- a/Plugins/ActSVG/src/SurfaceArraySvgConverter.cpp +++ b/Plugins/ActSVG/src/SurfaceArraySvgConverter.cpp @@ -51,29 +51,29 @@ Acts::Svg::SurfaceArrayConverter::convert( }; // Walk through the binning and translate - if (binning[0] == BinningValue::binPhi && - binning[1] == BinningValue::binZ) { + if (binning[0] == AxisDirection::AxisPhi && + binning[1] == AxisDirection::AxisZ) { vType = cylinder; // flip to fit with actsvg convention edges1 = axes[0]->getBinEdges(); edges0 = axes[1]->getBinEdges(); pGrid._type = actsvg::proto::grid::e_z_phi; - } else if (binning[0] == BinningValue::binPhi && - binning[1] == BinningValue::binR) { + } else if (binning[0] == AxisDirection::AxisPhi && + binning[1] == AxisDirection::AxisR) { vType = polar; // flip to fit with actsvg convention edges1 = axes[0]->getBinEdges(); edges0 = axes[1]->getBinEdges(); pGrid._type = actsvg::proto::grid::e_r_phi; - } else if (binning[0] == BinningValue::binZ && - binning[1] == BinningValue::binPhi) { + } else if (binning[0] == AxisDirection::AxisZ && + binning[1] == AxisDirection::AxisPhi) { // good vType = cylinder; edges0 = axes[0]->getBinEdges(); edges1 = axes[1]->getBinEdges(); pGrid._type = actsvg::proto::grid::e_z_phi; - } else if (binning[0] == BinningValue::binR && - binning[1] == BinningValue::binPhi) { + } else if (binning[0] == AxisDirection::AxisR && + binning[1] == AxisDirection::AxisPhi) { // good vType = polar; edges0 = axes[0]->getBinEdges(); diff --git a/Plugins/Covfie/src/FieldConversion.cpp b/Plugins/Covfie/src/FieldConversion.cpp index 7aee611b0fa..92b0168e542 100644 --- a/Plugins/Covfie/src/FieldConversion.cpp +++ b/Plugins/Covfie/src/FieldConversion.cpp @@ -8,10 +8,6 @@ #include "Acts/Plugins/Covfie/FieldConversion.hpp" -#include "Acts/Utilities/Axis.hpp" -#include "Acts/Utilities/AxisFwd.hpp" -#include "Acts/Utilities/Grid.hpp" - #include #include #include diff --git a/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepBinningHelpers.hpp b/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepBinningHelpers.hpp index 6577905bbba..6ea2372780e 100644 --- a/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepBinningHelpers.hpp +++ b/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepBinningHelpers.hpp @@ -12,7 +12,7 @@ #include "Acts/Detector/ProtoBinning.hpp" #include "Acts/Geometry/Extent.hpp" #include "Acts/Plugins/DD4hep/DD4hepConversionHelpers.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/BinningData.hpp" #include @@ -25,29 +25,30 @@ namespace Acts { -static std::vector> allowedBinnings = { - {"x", BinningValue::binX}, - {"y", BinningValue::binY}, - {"z", BinningValue::binZ}, - {"phi", BinningValue::binPhi}, - {"r", BinningValue::binR}}; +static std::vector> allowedBinnings = { + {"x", AxisDirection::AxisX}, + {"y", AxisDirection::AxisY}, + {"z", AxisDirection::AxisZ}, + {"phi", AxisDirection::AxisPhi}, + {"r", AxisDirection::AxisR}}; /// Helper method to convert the string to binning value /// /// @param binningString /// /// @return a binningValue -inline BinningValue stringToBinningValue(const std::string &binningString) { +inline AxisDirection stringToAxisDirection(const std::string &binningString) { + using enum AxisDirection; if (binningString == "x") { - return BinningValue::binX; + return AxisX; } else if (binningString == "y") { - return BinningValue::binY; + return AxisY; } else if (binningString == "z") { - return BinningValue::binZ; + return AxisZ; } else if (binningString == "phi") { - return BinningValue::binPhi; + return AxisPhi; } else if (binningString == "r") { - return BinningValue::binR; + return AxisR; } else { throw std::invalid_argument("DD4hepBinningHelpers: Binning value " + binningString + " not allowed."); @@ -55,22 +56,22 @@ inline BinningValue stringToBinningValue(const std::string &binningString) { } /// Helper method to cenvert a binning list string to a vector of binning values -/// e.g. "r,z" -> {binR, binZ} +/// e.g. "r,z" -> {AxisR, AxisZ} /// /// @param binningString /// @param del the delimiter for the splitting /// /// @return a vector of binninng values -inline std::vector stringToBinningValues( +inline std::vector stringToAxisDirections( const std::string &binningString, const char &del = ',') { if (binningString.empty()) { return {}; } - std::vector bBinning; + std::vector bBinning; std::stringstream s(binningString); std::string b = ""; while (getline(s, b, del)) { - bBinning.push_back(stringToBinningValue(b)); + bBinning.push_back(stringToAxisDirection(b)); } return bBinning; } diff --git a/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepBlueprintFactory.hpp b/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepBlueprintFactory.hpp index 634a776a29a..d7996d24b1a 100644 --- a/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepBlueprintFactory.hpp +++ b/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepBlueprintFactory.hpp @@ -101,7 +101,7 @@ class DD4hepBlueprintFactory { /// /// @return a tuple of the bounds type, values and binning, auxiliary data std::tuple, - std::vector, std::string> + std::vector, std::string> extractExternals([[maybe_unused]] const GeometryContext& gctx, const dd4hep::DetElement& dd4hepElement, const std::string& baseName, diff --git a/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepDetectorSurfaceFactory.hpp b/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepDetectorSurfaceFactory.hpp index 948608f4d5a..8cff5250363 100644 --- a/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepDetectorSurfaceFactory.hpp +++ b/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepDetectorSurfaceFactory.hpp @@ -70,7 +70,7 @@ class DD4hepDetectorSurfaceFactory { /// Optionally provide an Extent object to measure the passive std::optional pExtent = std::nullopt; /// Optionally provide an Extent constraints to measure the layers - std::vector extentConstraints = {}; + std::vector extentConstraints = {}; /// The approximination of a circle quarter for extent measuring std::size_t nExtentQSegments = 1u; }; diff --git a/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepLayerStructure.hpp b/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepLayerStructure.hpp index a44e4341feb..9cb5a61a005 100644 --- a/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepLayerStructure.hpp +++ b/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepLayerStructure.hpp @@ -64,7 +64,7 @@ class DD4hepLayerStructure { // The extent structure - optionally std::optional extent = std::nullopt; /// The extent constraints - optionally - std::vector extentConstraints = {}; + std::vector extentConstraints = {}; /// Approximation for the polyhedron binning unsigned int quarterSegments = 1u; /// Patch the binning with the extent if possible diff --git a/Plugins/DD4hep/src/DD4hepBinningHelpers.cpp b/Plugins/DD4hep/src/DD4hepBinningHelpers.cpp index 5fee66d8231..ea1c33e6bd9 100644 --- a/Plugins/DD4hep/src/DD4hepBinningHelpers.cpp +++ b/Plugins/DD4hep/src/DD4hepBinningHelpers.cpp @@ -39,15 +39,15 @@ Acts::DD4hepBinningHelpers::convertBinning( } else { // Equidistant binning double minDefault = - bVal == BinningValue::binPhi ? -std::numbers::pi : 0.; + bVal == AxisDirection::AxisPhi ? -std::numbers::pi : 0.; double maxDefault = - bVal == BinningValue::binPhi ? std::numbers::pi : 0.; + bVal == AxisDirection::AxisPhi ? std::numbers::pi : 0.; auto min = getParamOr(bname + "_" + ab + "_min", dd4hepElement, minDefault); auto max = getParamOr(bname + "_" + ab + "_max", dd4hepElement, maxDefault); // Check for closed phi binning - if (bVal == BinningValue::binPhi && + if (bVal == AxisDirection::AxisPhi && (max - min) > 1.9 * std::numbers::pi) { bType = Acts::AxisBoundaryType::Closed; } @@ -62,7 +62,7 @@ Acts::DD4hepBinningHelpers::convertBinning( bname + "_" + ab + "_b" + std::to_string(ib), dd4hepElement, 0.)); } // Check for closed phi binning - if (bVal == BinningValue::binPhi && + if (bVal == AxisDirection::AxisPhi && (edges.back() - edges.front()) > 1.9 * std::numbers::pi) { bType = Acts::AxisBoundaryType::Closed; } diff --git a/Plugins/DD4hep/src/DD4hepBlueprintFactory.cpp b/Plugins/DD4hep/src/DD4hepBlueprintFactory.cpp index 06ff97153dd..28431f61043 100644 --- a/Plugins/DD4hep/src/DD4hepBlueprintFactory.cpp +++ b/Plugins/DD4hep/src/DD4hepBlueprintFactory.cpp @@ -32,7 +32,7 @@ Acts::Experimental::DD4hepBlueprintFactory::create( // Create the root node std::vector bValues = {0., 150., 1000.}; - std::vector binning = {Acts::BinningValue::binR}; + std::vector binning = {Acts::AxisDirection::AxisR}; auto root = std::make_unique( dd4hepElement.name(), Acts::Transform3::Identity(), Acts::VolumeBounds::eCylinder, bValues, binning); @@ -150,7 +150,7 @@ void Acts::Experimental::DD4hepBlueprintFactory::recursiveParse( } std::tuple, std::vector, std::string> + std::vector, std::vector, std::string> Acts::Experimental::DD4hepBlueprintFactory::extractExternals( [[maybe_unused]] const GeometryContext& gctx, const dd4hep::DetElement& dd4hepElement, const std::string& baseName, @@ -172,17 +172,17 @@ Acts::Experimental::DD4hepBlueprintFactory::extractExternals( // Set as defaults bValues = {0., 0., 0.}; auto parsedExtent = extOpt.value(); - if (parsedExtent.constrains(BinningValue::binR)) { - bValues[0u] = std::floor(parsedExtent.min(BinningValue::binR)); - bValues[1u] = std::ceil(parsedExtent.max(BinningValue::binR)); + if (parsedExtent.constrains(AxisDirection::AxisR)) { + bValues[0u] = std::floor(parsedExtent.min(AxisDirection::AxisR)); + bValues[1u] = std::ceil(parsedExtent.max(AxisDirection::AxisR)); } - if (parsedExtent.constrains(BinningValue::binZ)) { - double minZ = parsedExtent.min(BinningValue::binZ) > 0. - ? std::floor(parsedExtent.min(BinningValue::binZ)) - : std::ceil(parsedExtent.min(BinningValue::binZ)); - double maxZ = parsedExtent.max(BinningValue::binZ) > 0. - ? std::floor(parsedExtent.max(BinningValue::binZ)) - : std::ceil(parsedExtent.max(BinningValue::binZ)); + if (parsedExtent.constrains(AxisDirection::AxisZ)) { + double minZ = parsedExtent.min(AxisDirection::AxisZ) > 0. + ? std::floor(parsedExtent.min(AxisDirection::AxisZ)) + : std::ceil(parsedExtent.min(AxisDirection::AxisZ)); + double maxZ = parsedExtent.max(AxisDirection::AxisZ) > 0. + ? std::floor(parsedExtent.max(AxisDirection::AxisZ)) + : std::ceil(parsedExtent.max(AxisDirection::AxisZ)); bValues[2u] = 0.5 * (maxZ - minZ); transform.translation().z() = 0.5 * (maxZ + minZ); } @@ -201,8 +201,8 @@ Acts::Experimental::DD4hepBlueprintFactory::extractExternals( // Get the binning values auto binningString = getParamOr(baseName + "_binning", dd4hepElement, ""); - std::vector bBinning = - Acts::stringToBinningValues(binningString); + std::vector bBinning = + Acts::stringToAxisDirections(binningString); if (!binningString.empty()) { aux += "vol. binning : " + binningString; } @@ -253,19 +253,19 @@ Acts::Experimental::DD4hepBlueprintFactory::extractInternals( unitLength * Acts::getParamOr(baseName + "_internals_clearance", dd4hepElement, 0.); - auto internalBinningValues = stringToBinningValues(interenalsMeasure); - if (!internalBinningValues.empty()) { + auto internalAxisDirections = stringToAxisDirections(interenalsMeasure); + if (!internalAxisDirections.empty()) { ACTS_VERBOSE(" - internals extent measurement requested"); Extent internalsExtent; ExtentEnvelope clearance = ExtentEnvelope::Zero(); - for (const auto& bv : internalBinningValues) { - ACTS_VERBOSE(" -> measuring extent for " << binningValueName(bv)); + for (const auto& bv : internalAxisDirections) { + ACTS_VERBOSE(" -> measuring extent for " << axisDirectionName(bv)); ACTS_VERBOSE(" -> with clearance :" << internalsClearance); clearance[bv] = {internalsClearance, internalsClearance}; } internalsExtent.setEnvelope(clearance); lOptions.extent = internalsExtent; - lOptions.extentConstraints = internalBinningValues; + lOptions.extentConstraints = internalAxisDirections; } // Create the builder from the dd4hep element auto [ib, extOpt] = m_cfg.layerStructure->builder( @@ -284,8 +284,8 @@ Acts::Experimental::DD4hepBlueprintFactory::extractInternals( baseName + "_root_volume_finder", dd4hepElement, ""); if (rootFinder == "indexed") { aux[1u] = "root finder : indexed"; - std::vector binning = {BinningValue::binZ, - BinningValue::binR}; + std::vector binning = {AxisDirection::AxisZ, + AxisDirection::AxisR}; rootsFinderBuilder = std::make_shared( binning); diff --git a/Plugins/DD4hep/src/DD4hepLayerBuilder.cpp b/Plugins/DD4hep/src/DD4hepLayerBuilder.cpp index 3ae1ecd9145..9e33e40363d 100644 --- a/Plugins/DD4hep/src/DD4hepLayerBuilder.cpp +++ b/Plugins/DD4hep/src/DD4hepLayerBuilder.cpp @@ -115,10 +115,10 @@ const Acts::LayerVector Acts::DD4hepLayerBuilder::endcapLayers( params.contains("envelope_z_max")) { // set the values of the proto layer in case enevelopes are handed // over - pl.envelope[Acts::BinningValue::binR] = { + pl.envelope[Acts::AxisDirection::AxisR] = { params.get("envelope_r_min"), params.get("envelope_r_max")}; - pl.envelope[Acts::BinningValue::binZ] = { + pl.envelope[Acts::AxisDirection::AxisZ] = { params.get("envelope_z_min"), params.get("envelope_z_max")}; } else if (geoShape != nullptr) { @@ -152,22 +152,22 @@ const Acts::LayerVector Acts::DD4hepLayerBuilder::endcapLayers( // manually create a proto layer double eiz = (z != 0.) ? z - m_cfg.defaultThickness : 0.; double eoz = (z != 0.) ? z + m_cfg.defaultThickness : 0.; - pl.extent.range(Acts::BinningValue::binZ).set(eiz, eoz); - pl.extent.range(Acts::BinningValue::binR).set(rMin, rMax); - pl.envelope[Acts::BinningValue::binR] = {0., 0.}; - pl.envelope[Acts::BinningValue::binZ] = {0., 0.}; + pl.extent.range(Acts::AxisDirection::AxisZ).set(eiz, eoz); + pl.extent.range(Acts::AxisDirection::AxisR).set(rMin, rMax); + pl.envelope[Acts::AxisDirection::AxisR] = {0., 0.}; + pl.envelope[Acts::AxisDirection::AxisZ] = {0., 0.}; } else { ACTS_VERBOSE(" Disc layer has " << layerSurfaces.size() << " sensitive surfaces."); // set the values of the proto layer in case dimensions are given by // geometry - pl.envelope[Acts::BinningValue::binZ] = { - std::abs(zMin - pl.min(Acts::BinningValue::binZ)), - std::abs(zMax - pl.max(Acts::BinningValue::binZ))}; - pl.envelope[Acts::BinningValue::binR] = { - std::abs(rMin - pl.min(Acts::BinningValue::binR)), - std::abs(rMax - pl.max(Acts::BinningValue::binR))}; - pl.extent.range(Acts::BinningValue::binR).set(rMin, rMax); + pl.envelope[Acts::AxisDirection::AxisZ] = { + std::abs(zMin - pl.min(Acts::AxisDirection::AxisZ)), + std::abs(zMax - pl.max(Acts::AxisDirection::AxisZ))}; + pl.envelope[Acts::AxisDirection::AxisR] = { + std::abs(rMin - pl.min(Acts::AxisDirection::AxisR)), + std::abs(rMax - pl.max(Acts::AxisDirection::AxisR))}; + pl.extent.range(Acts::AxisDirection::AxisR).set(rMin, rMax); } } else { throw std::logic_error( @@ -204,9 +204,10 @@ 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::abs(pl.max(Acts::BinningValue::binZ) - - pl.min(Acts::BinningValue::binZ)); + pl.min(Acts::AxisDirection::AxisR), + pl.max(Acts::AxisDirection::AxisR)); + double thickness = std::abs(pl.max(Acts::AxisDirection::AxisZ) - + pl.min(Acts::AxisDirection::AxisZ)); // Create the layer containing the sensitive surface endcapLayer = DiscLayer::create(transform, dBounds, std::move(sArray), thickness, nullptr, Acts::active); @@ -287,10 +288,10 @@ const Acts::LayerVector Acts::DD4hepLayerBuilder::centralLayers( params.contains("envelope_z_min") && params.contains("envelope_z_max")) { // set the values of the proto layer in case enevelopes are handed over - pl.envelope[Acts::BinningValue::binR] = { + pl.envelope[Acts::AxisDirection::AxisR] = { params.get("envelope_r_min"), params.get("envelope_r_max")}; - pl.envelope[Acts::BinningValue::binZ] = { + pl.envelope[Acts::AxisDirection::AxisZ] = { params.get("envelope_z_min"), params.get("envelope_z_max")}; } else if (geoShape != nullptr) { @@ -315,19 +316,19 @@ const Acts::LayerVector Acts::DD4hepLayerBuilder::centralLayers( // manually create a proto layer double eir = (r != 0.) ? r - m_cfg.defaultThickness : 0.; double eor = (r != 0.) ? r + m_cfg.defaultThickness : 0.; - pl.extent.range(Acts::BinningValue::binR).set(eir, eor); - pl.extent.range(Acts::BinningValue::binZ).set(-dz, dz); - pl.envelope[Acts::BinningValue::binR] = {0., 0.}; - pl.envelope[Acts::BinningValue::binZ] = {0., 0.}; + pl.extent.range(Acts::AxisDirection::AxisR).set(eir, eor); + pl.extent.range(Acts::AxisDirection::AxisZ).set(-dz, dz); + pl.envelope[Acts::AxisDirection::AxisR] = {0., 0.}; + pl.envelope[Acts::AxisDirection::AxisZ] = {0., 0.}; } else { // set the values of the proto layer in case dimensions are given by // geometry - pl.envelope[Acts::BinningValue::binZ] = { - std::abs(-dz - pl.min(Acts::BinningValue::binZ)), - std::abs(dz - pl.max(Acts::BinningValue::binZ))}; - pl.envelope[Acts::BinningValue::binR] = { - std::abs(rMin - pl.min(Acts::BinningValue::binR)), - std::abs(rMax - pl.max(Acts::BinningValue::binR))}; + pl.envelope[Acts::AxisDirection::AxisZ] = { + std::abs(-dz - pl.min(Acts::AxisDirection::AxisZ)), + std::abs(dz - pl.max(Acts::AxisDirection::AxisZ))}; + pl.envelope[Acts::AxisDirection::AxisR] = { + std::abs(rMin - pl.min(Acts::AxisDirection::AxisR)), + std::abs(rMax - pl.max(Acts::AxisDirection::AxisR))}; } } else { throw std::logic_error( @@ -337,8 +338,8 @@ const Acts::LayerVector Acts::DD4hepLayerBuilder::centralLayers( "constructor!")); } - double halfZ = (pl.min(Acts::BinningValue::binZ) - - pl.max(Acts::BinningValue::binZ)) * + double halfZ = (pl.min(Acts::AxisDirection::AxisZ) - + pl.max(Acts::AxisDirection::AxisZ)) * 0.5; std::shared_ptr centralLayer = nullptr; @@ -351,11 +352,11 @@ const Acts::LayerVector Acts::DD4hepLayerBuilder::centralLayers( std::make_unique(sensitiveSurf); // create the layer - double layerR = (pl.min(Acts::BinningValue::binR) + - pl.max(Acts::BinningValue::binR)) * + double layerR = (pl.min(Acts::AxisDirection::AxisR) + + pl.max(Acts::AxisDirection::AxisR)) * 0.5; - double thickness = std::abs(pl.max(Acts::BinningValue::binR) - - pl.min(Acts::BinningValue::binR)); + double thickness = std::abs(pl.max(Acts::AxisDirection::AxisR) - + pl.min(Acts::AxisDirection::AxisR)); auto cBounds = std::make_shared(layerR, halfZ); // Create the layer containing the sensitive surface centralLayer = diff --git a/Plugins/DD4hep/src/DD4hepLayerStructure.cpp b/Plugins/DD4hep/src/DD4hepLayerStructure.cpp index 10a4e6eb9f0..5546df6d8c0 100644 --- a/Plugins/DD4hep/src/DD4hepLayerStructure.cpp +++ b/Plugins/DD4hep/src/DD4hepLayerStructure.cpp @@ -68,13 +68,13 @@ Acts::Experimental::DD4hepLayerStructure::builder( // Check if the binning ACTS_VERBOSE("Checking if surface binning ranges can be patched."); for (auto& b : fCache.binnings) { - if (extent.constrains(b.binValue)) { - ACTS_VERBOSE("Binning '" << binningValueName(b.binValue) + if (extent.constrains(b.axisDir)) { + ACTS_VERBOSE("Binning '" << axisDirectionName(b.axisDir) << "' is patched."); ACTS_VERBOSE(" <- from : [" << b.edges.front() << ", " << b.edges.back() << "]"); - b.edges.front() = extent.min(b.binValue); - b.edges.back() = extent.max(b.binValue); + b.edges.front() = extent.min(b.axisDir); + b.edges.back() = extent.max(b.axisDir); ACTS_VERBOSE(" -> to : [" << b.edges.front() << ", " << b.edges.back() << "]"); } diff --git a/Plugins/DD4hep/src/DD4hepMaterialHelpers.cpp b/Plugins/DD4hep/src/DD4hepMaterialHelpers.cpp index c3d6b346c72..845d1356b6a 100644 --- a/Plugins/DD4hep/src/DD4hepMaterialHelpers.cpp +++ b/Plugins/DD4hep/src/DD4hepMaterialHelpers.cpp @@ -36,7 +36,7 @@ std::shared_ptr Acts::createProtoMaterial( Acts::BinUtility bu; // Loop over the bins for (auto& bin : binning) { - BinningValue bval = binningValueFromName(bin.first); + AxisDirection bval = axisDirectionFromName(bin.first); Acts::BinningOption bopt = bin.second; double min = 0.; double max = 0.; diff --git a/Plugins/Detray/include/Acts/Plugins/Detray/DetrayConversionUtils.hpp b/Plugins/Detray/include/Acts/Plugins/Detray/DetrayConversionUtils.hpp index 2f827a08bea..7adc9bbe3f0 100644 --- a/Plugins/Detray/include/Acts/Plugins/Detray/DetrayConversionUtils.hpp +++ b/Plugins/Detray/include/Acts/Plugins/Detray/DetrayConversionUtils.hpp @@ -77,7 +77,7 @@ detray::axis::bounds convertBinningOption(BinningOption bOption); /// @param bValue the binning value /// /// @return a detray binning value -detray::axis::label convertBinningValue(BinningValue bValue); +detray::axis::label convertAxisDirection(AxisDirection bValue); /// Convert the binning type /// diff --git a/Plugins/Detray/src/DetrayConversionUtils.cpp b/Plugins/Detray/src/DetrayConversionUtils.cpp index b2a0f78138f..272b453511d 100644 --- a/Plugins/Detray/src/DetrayConversionUtils.cpp +++ b/Plugins/Detray/src/DetrayConversionUtils.cpp @@ -8,20 +8,20 @@ #include "Acts/Plugins/Detray/DetrayConversionUtils.hpp" -detray::axis::label Acts::DetrayConversionUtils::convertBinningValue( - BinningValue bValue) { +detray::axis::label Acts::DetrayConversionUtils::convertAxisDirection( + AxisDirection bValue) { switch (bValue) { - case BinningValue::binX: + case AxisDirection::AxisX: return detray::axis::label::e_x; - case BinningValue::binY: + case AxisDirection::AxisY: return detray::axis::label::e_y; - case BinningValue::binZ: + case AxisDirection::AxisZ: return detray::axis::label::e_z; - case BinningValue::binR: + case AxisDirection::AxisR: return detray::axis::label::e_r; - case BinningValue::binPhi: + case AxisDirection::AxisPhi: return detray::axis::label::e_phi; - case BinningValue::binRPhi: + case AxisDirection::AxisRPhi: return detray::axis::label::e_rphi; default: throw std::invalid_argument( @@ -69,7 +69,7 @@ detray::io::axis_payload Acts::DetrayConversionUtils::convertBinningData( // Set the binning option axis.bounds = convertBinningOption(bData.option); // Set the binning value - axis.label = convertBinningValue(bData.binvalue); + axis.label = convertAxisDirection(bData.binvalue); // Set the binning range axis.edges = {}; if (bData.type == BinningType::equidistant) { diff --git a/Plugins/Detray/src/DetrayGeometryConverter.cpp b/Plugins/Detray/src/DetrayGeometryConverter.cpp index 95fe27d3036..a4afbba0c72 100644 --- a/Plugins/Detray/src/DetrayGeometryConverter.cpp +++ b/Plugins/Detray/src/DetrayGeometryConverter.cpp @@ -149,13 +149,13 @@ Acts::DetrayGeometryConverter::convertPortal( std::array clipRange = {0., 0.}; std::vector boundValues = surfaceAdjusted->bounds().values(); if (surfaceType == Surface::SurfaceType::Cylinder && - cast == BinningValue::binZ) { + cast == AxisDirection::AxisZ) { double zPosition = surfaceAdjusted->center(gctx).z(); clipRange = { zPosition - boundValues[CylinderBounds::BoundValues::eHalfLengthZ], zPosition + boundValues[CylinderBounds::BoundValues::eHalfLengthZ]}; } else if (surfaceType == Surface::SurfaceType::Disc && - cast == BinningValue::binR) { + cast == AxisDirection::AxisR) { clipRange = {boundValues[RadialBounds::BoundValues::eMinR], boundValues[RadialBounds::BoundValues::eMaxR]}; } else { diff --git a/Plugins/Detray/src/DetrayMaterialConverter.cpp b/Plugins/Detray/src/DetrayMaterialConverter.cpp index f6b61236ec5..25242b85efa 100644 --- a/Plugins/Detray/src/DetrayMaterialConverter.cpp +++ b/Plugins/Detray/src/DetrayMaterialConverter.cpp @@ -143,27 +143,27 @@ Acts::DetrayMaterialConverter::convertGridSurfaceMaterial( BinUtility bUtility = binnedMaterial->binUtility(); // Turn the bin value into a 2D grid if (bUtility.dimensions() == 1u) { - if (bUtility.binningData()[0u].binvalue == BinningValue::binX) { + if (bUtility.binningData()[0u].binvalue == AxisDirection::AxisX) { // Turn to X-Y bUtility += BinUtility(1u, std::numeric_limits::lowest(), std::numeric_limits::max(), - BinningOption::closed, BinningValue::binY); - } else if (bUtility.binningData()[0u].binvalue == BinningValue::binY) { + BinningOption::closed, AxisDirection::AxisY); + } else if (bUtility.binningData()[0u].binvalue == AxisDirection::AxisY) { // Turn to X-Y BinUtility nbUtility(1u, std::numeric_limits::lowest(), std::numeric_limits::max(), - BinningOption::closed, BinningValue::binX); + BinningOption::closed, AxisDirection::AxisX); nbUtility += bUtility; bUtility = std::move(nbUtility); swapped = true; - } else if (bUtility.binningData()[0u].binvalue == BinningValue::binR) { + } else if (bUtility.binningData()[0u].binvalue == AxisDirection::AxisR) { // Turn to R-Phi bUtility += BinUtility(1u, -std::numbers::pi, std::numbers::pi, closed, - BinningValue::binPhi); - } else if (bUtility.binningData()[0u].binvalue == BinningValue::binZ) { + AxisDirection::AxisPhi); + } else if (bUtility.binningData()[0u].binvalue == AxisDirection::AxisZ) { // Turn to Phi-Z - swap needed BinUtility nbUtility(1u, -std::numbers::pi, std::numbers::pi, closed, - BinningValue::binPhi); + AxisDirection::AxisPhi); nbUtility += bUtility; bUtility = std::move(nbUtility); swapped = true; @@ -171,24 +171,25 @@ Acts::DetrayMaterialConverter::convertGridSurfaceMaterial( std::invalid_argument("Unsupported binning for Detray"); } } else if (bUtility.dimensions() == 2u && - bUtility.binningData()[0u].binvalue == BinningValue::binZ && - bUtility.binningData()[1u].binvalue == BinningValue::binPhi) { + bUtility.binningData()[0u].binvalue == AxisDirection::AxisZ && + bUtility.binningData()[1u].binvalue == AxisDirection::AxisPhi) { BinUtility nbUtility(bUtility.binningData()[1u]); - nbUtility += bUtility.binningData()[0u]; + nbUtility += BinUtility{bUtility.binningData()[0u]}; bUtility = std::move(nbUtility); swapped = true; } - BinningValue bVal0 = bUtility.binningData()[0u].binvalue; - BinningValue bVal1 = bUtility.binningData()[1u].binvalue; + AxisDirection bVal0 = bUtility.binningData()[0u].binvalue; + AxisDirection bVal1 = bUtility.binningData()[1u].binvalue; // Translate into grid index type detray::io::material_id gridIndexType = detray::io::material_id::unknown; - if (bVal0 == BinningValue::binR && bVal1 == BinningValue::binPhi) { + if (bVal0 == AxisDirection::AxisR && bVal1 == AxisDirection::AxisPhi) { gridIndexType = detray::io::material_id::ring2_map; - } else if (bVal0 == BinningValue::binPhi && bVal1 == BinningValue::binZ) { + } else if (bVal0 == AxisDirection::AxisPhi && + bVal1 == AxisDirection::AxisZ) { gridIndexType = detray::io::material_id::concentric_cylinder2_map; - } else if (bVal0 == BinningValue::binX && bVal1 == BinningValue::binY) { + } else if (bVal0 == AxisDirection::AxisX && bVal1 == AxisDirection::AxisY) { gridIndexType = detray::io::material_id::rectangle2_map; } else { std::runtime_error( diff --git a/Plugins/Detray/src/DetraySurfaceGridsConverter.cpp b/Plugins/Detray/src/DetraySurfaceGridsConverter.cpp index f1572b77c08..13e52cd23ac 100644 --- a/Plugins/Detray/src/DetraySurfaceGridsConverter.cpp +++ b/Plugins/Detray/src/DetraySurfaceGridsConverter.cpp @@ -111,8 +111,8 @@ Acts::DetraySurfaceGridsConverter::convertImpl(const index_grid& indexGrid) { if constexpr (index_grid::grid_type::DIM == 2u) { // Check for axis swap - swapAxes = (indexGrid.casts[0u] == Acts::BinningValue::binZ && - indexGrid.casts[1u] == Acts::BinningValue::binPhi); + swapAxes = (indexGrid.casts[0u] == Acts::AxisDirection::AxisZ && + indexGrid.casts[1u] == Acts::AxisDirection::AxisPhi); } detray::io::grid_payload grid_pd = diff --git a/Plugins/ExaTrkX/CMakeLists.txt b/Plugins/ExaTrkX/CMakeLists.txt index 802941e7367..e70a896b8d5 100644 --- a/Plugins/ExaTrkX/CMakeLists.txt +++ b/Plugins/ExaTrkX/CMakeLists.txt @@ -1,29 +1,29 @@ -set(SOURCES src/buildEdges.cpp src/ExaTrkXPipeline.cpp) +add_library(ActsPluginExaTrkX SHARED src/buildEdges.cpp src/ExaTrkXPipeline.cpp) + +if(ACTS_EXATRKX_ENABLE_CUDA) + target_compile_definitions(ActsPluginExaTrkX PUBLIC ACTS_EXATRKX_WITH_CUDA) + target_sources(ActsPluginExaTrkX PRIVATE src/CudaTrackBuilding.cu) +endif() if(ACTS_EXATRKX_ENABLE_ONNX) - list( - APPEND - SOURCES - src/OnnxEdgeClassifier.cpp - src/OnnxMetricLearning.cpp - src/CugraphTrackBuilding.cpp + target_sources( + ActsPluginExaTrkX + PRIVATE src/OnnxEdgeClassifier.cpp src/OnnxMetricLearning.cpp ) endif() if(ACTS_EXATRKX_ENABLE_TORCH) - list( - APPEND - SOURCES - src/TorchEdgeClassifier.cpp - src/TorchMetricLearning.cpp - src/BoostTrackBuilding.cpp - src/TorchTruthGraphMetricsHook.cpp - src/TorchGraphStoreHook.cpp + target_sources( + ActsPluginExaTrkX + PRIVATE + src/TorchEdgeClassifier.cpp + src/TorchMetricLearning.cpp + src/BoostTrackBuilding.cpp + src/TorchTruthGraphMetricsHook.cpp + src/TorchGraphStoreHook.cpp ) endif() -add_library(ActsPluginExaTrkX SHARED ${SOURCES}) - target_include_directories( ActsPluginExaTrkX PUBLIC @@ -42,18 +42,22 @@ target_link_libraries( if(ACTS_EXATRKX_ENABLE_CUDA) target_link_libraries(ActsPluginExaTrkX PRIVATE frnn) + target_compile_features(ActsPluginExaTrkX PUBLIC cuda_std_20) set_target_properties( ActsPluginExaTrkX - PROPERTIES - CUDA_STANDARD 17 - CUDA_STANDARD_REQUIRED ON - CUDA_SEPARABLE_COMPILATION ON + PROPERTIES CUDA_STANDARD_REQUIRED ON CUDA_SEPARABLE_COMPILATION ON + ) + target_compile_options( + ActsPluginExaTrkX + PRIVATE + $<$:-g + --generate-line-info + --extended-lambda> ) target_compile_definitions( ActsPluginExaTrkX PUBLIC CUDA_API_PER_THREAD_DEFAULT_STREAM ) - target_compile_definitions(ActsPluginExaTrkX PUBLIC NO_CUGRAPH_OPS) else() target_compile_definitions(ActsPluginExaTrkX PUBLIC ACTS_EXATRKX_CPUONLY) endif() @@ -64,10 +68,7 @@ if(ACTS_EXATRKX_ENABLE_ONNX) PUBLIC ACTS_EXATRKX_ONNX_BACKEND ) - target_link_libraries( - ActsPluginExaTrkX - PRIVATE OnnxRuntime cugraph::cugraph - ) + target_link_libraries(ActsPluginExaTrkX PRIVATE OnnxRuntime) endif() if(ACTS_EXATRKX_ENABLE_TORCH) diff --git a/Plugins/ExaTrkX/README.md b/Plugins/ExaTrkX/README.md index 8a7944bd7f2..5878ce83a15 100644 --- a/Plugins/ExaTrkX/README.md +++ b/Plugins/ExaTrkX/README.md @@ -23,7 +23,6 @@ This plugin is known to build without errors with (as of September 2022) - [libtorch](https://pytorch.org/) v1.10.2 for CUDA version 10.2 and cxx-11-abi ([download](https://download.pytorch.org/libtorch/cu102/libtorch-cxx11-abi-shared-with-deps-1.10.2%2Bcu102.zip)) *For the ONNX backend:* -- [cugraph](https://github.com/rapidsai/cugraph) v22.02.00 - [ONNX](https://github.com/microsoft/onnxruntime) v1.10.0 with CUDA support enabled *For the Torch backend* diff --git a/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/BoostTrackBuilding.hpp b/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/BoostTrackBuilding.hpp index a6905d5b06c..95d7f10e3b8 100644 --- a/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/BoostTrackBuilding.hpp +++ b/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/BoostTrackBuilding.hpp @@ -25,7 +25,7 @@ class BoostTrackBuilding final : public Acts::TrackBuildingBase { std::vector> operator()( std::any nodes, std::any edges, std::any edge_weights, std::vector &spacepointIDs, - torch::Device device = torch::Device(torch::kCPU)) override; + const ExecutionContext &execContext = {}) override; torch::Device device() const override { return m_device; }; private: diff --git a/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/CugraphTrackBuilding.hpp b/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/CudaTrackBuilding.hpp similarity index 69% rename from Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/CugraphTrackBuilding.hpp rename to Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/CudaTrackBuilding.hpp index 133ee79e187..69d2ddbc18e 100644 --- a/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/CugraphTrackBuilding.hpp +++ b/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/CudaTrackBuilding.hpp @@ -17,18 +17,25 @@ namespace Acts { -class CugraphTrackBuilding final : public Acts::TrackBuildingBase { +class CudaTrackBuilding final : public Acts::TrackBuildingBase { public: - CugraphTrackBuilding(std::unique_ptr logger) - : m_logger(std::move(logger)), m_device(torch::Device(torch::kCPU)) {} + struct Config { + // nothing yet + }; + + CudaTrackBuilding(const Config &cfg, std::unique_ptr logger) + : m_cfg(cfg), + m_logger(std::move(logger)), + m_device(torch::Device(torch::kCUDA)) {} std::vector> operator()( std::any nodes, std::any edges, std::any edge_weights, std::vector &spacepointIDs, - torch::Device device = torch::Device(torch::kCPU)) override; + const ExecutionContext &execContext = {}) override; torch::Device device() const override { return m_device; }; private: + Config m_cfg; std::unique_ptr m_logger; torch::Device m_device; const auto &logger() const { return *m_logger; } diff --git a/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/OnnxEdgeClassifier.hpp b/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/OnnxEdgeClassifier.hpp index 5682b7e84a9..529e31409d4 100644 --- a/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/OnnxEdgeClassifier.hpp +++ b/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/OnnxEdgeClassifier.hpp @@ -35,7 +35,7 @@ class OnnxEdgeClassifier final : public Acts::EdgeClassificationBase { std::tuple operator()( std::any nodeFeatures, std::any edgeIndex, std::any edgeFeatures = {}, - torch::Device device = torch::Device(torch::kCPU)) override; + const ExecutionContext &execContext = {}) override; Config config() const { return m_cfg; } torch::Device device() const override { return m_device; }; diff --git a/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/OnnxMetricLearning.hpp b/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/OnnxMetricLearning.hpp index d78139d0732..0a97ab697c3 100644 --- a/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/OnnxMetricLearning.hpp +++ b/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/OnnxMetricLearning.hpp @@ -39,7 +39,7 @@ class OnnxMetricLearning final : public Acts::GraphConstructionBase { std::tuple operator()( std::vector& inputValues, std::size_t numNodes, const std::vector& moduleIds, - torch::Device device = torch::Device(torch::kCPU)) override; + const ExecutionContext& execContext = {}) override; Config config() const { return m_cfg; } torch::Device device() const override { return m_device; }; diff --git a/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/Stages.hpp b/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/Stages.hpp index 1e35fb08a82..13753713917 100644 --- a/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/Stages.hpp +++ b/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/Stages.hpp @@ -13,6 +13,7 @@ #include #include +#include #include namespace Acts { @@ -20,6 +21,12 @@ namespace Acts { /// Error that is thrown if no edges are found struct NoEdgesError : std::exception {}; +/// Capture the context of the execution +struct ExecutionContext { + torch::Device device{torch::kCPU}; + std::optional stream; +}; + // TODO maybe replace std::any with some kind of variant, // unique_ptr>? // TODO maybe replace input for GraphConstructionBase with some kind of @@ -34,13 +41,12 @@ class GraphConstructionBase { /// then gives the number of features /// @param moduleIds Module IDs of the features (used for module-map-like /// graph construction) - /// @param device Which GPU device to pick. Not relevant for CPU-only builds - /// + /// @param execContext Device & stream information /// @return (node_features, edge_features, edge_index) virtual std::tuple operator()( std::vector &inputValues, std::size_t numNodes, const std::vector &moduleIds, - torch::Device device = torch::Device(torch::kCPU)) = 0; + const ExecutionContext &execContext = {}) = 0; virtual torch::Device device() const = 0; @@ -54,12 +60,12 @@ class EdgeClassificationBase { /// @param nodeFeatures Node tensor with shape (n_nodes, n_node_features) /// @param edgeIndex Edge-index tensor with shape (2, n_edges) /// @param edgeFeatures Edge-feature tensor with shape (n_edges, n_edge_features) - /// @param device Which GPU device to pick. Not relevant for CPU-only builds + /// @param execContext Device & stream information /// /// @return (node_features, edge_features, edge_index, edge_scores) virtual std::tuple operator()( std::any nodeFeatures, std::any edgeIndex, std::any edgeFeatures = {}, - torch::Device device = torch::Device(torch::kCPU)) = 0; + const ExecutionContext &execContext = {}) = 0; virtual torch::Device device() const = 0; @@ -74,13 +80,13 @@ class TrackBuildingBase { /// @param edgeIndex Edge-index tensor with shape (2, n_edges) /// @param edgeScores Scores of the previous edge classification phase /// @param spacepointIDs IDs of the nodes (must have size=n_nodes) - /// @param device Which GPU device to pick. Not relevant for CPU-only builds + /// @param execContext Device & stream information /// /// @return tracks (as vectors of node-IDs) virtual std::vector> operator()( std::any nodeFeatures, std::any edgeIndex, std::any edgeScores, std::vector &spacepointIDs, - torch::Device device = torch::Device(torch::kCPU)) = 0; + const ExecutionContext &execContext = {}) = 0; virtual torch::Device device() const = 0; diff --git a/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/TorchEdgeClassifier.hpp b/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/TorchEdgeClassifier.hpp index 4cf92a7115d..e7c1d04e9d6 100644 --- a/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/TorchEdgeClassifier.hpp +++ b/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/TorchEdgeClassifier.hpp @@ -42,7 +42,7 @@ class TorchEdgeClassifier final : public Acts::EdgeClassificationBase { std::tuple operator()( std::any nodeFeatures, std::any edgeIndex, std::any edgeFeatures = {}, - torch::Device device = torch::Device(torch::kCPU)) override; + const ExecutionContext &execContext = {}) override; Config config() const { return m_cfg; } torch::Device device() const override { return m_device; }; diff --git a/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/TorchMetricLearning.hpp b/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/TorchMetricLearning.hpp index 9d87e5c59d5..dba7d7f2220 100644 --- a/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/TorchMetricLearning.hpp +++ b/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/TorchMetricLearning.hpp @@ -44,7 +44,7 @@ class TorchMetricLearning final : public Acts::GraphConstructionBase { std::tuple operator()( std::vector &inputValues, std::size_t numNodes, const std::vector &moduleIds, - torch::Device device = torch::Device(torch::kCPU)) override; + const ExecutionContext &execContext = {}) override; Config config() const { return m_cfg; } torch::Device device() const override { return m_device; }; diff --git a/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/detail/ConnectedComponents.cuh b/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/detail/ConnectedComponents.cuh new file mode 100644 index 00000000000..2f16f2c6d18 --- /dev/null +++ b/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/detail/ConnectedComponents.cuh @@ -0,0 +1,171 @@ +// 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/Plugins/ExaTrkX/detail/CudaUtils.cuh" + +#include +#include + +namespace Acts::detail { + +template +__device__ void swap(T &a, T &b) { + T tmp = a; + a = b; + b = tmp; +} + +/// Implementation of the FastSV algorithm as shown in +/// https://arxiv.org/abs/1910.05971 +template +__global__ void labelConnectedComponents(std::size_t numEdges, + const TEdge *sourceEdges, + const TEdge *targetEdges, + std::size_t numNodes, TLabel *labels, + TLabel *labelsNext) { + // Currently this kernel works only with 1 block + assert(gridDim.x == 1 && gridDim.y == 1 && gridDim.z == 1); + + for (std::size_t i = threadIdx.x; i < numNodes; i += blockDim.x) { + labels[i] = i; + labelsNext[i] = i; + } + + bool changed = false; + + do { + changed = false; + + //printf("Iteration %i\n", n); + + // Tree hooking for each edge; + for (std::size_t i = threadIdx.x; i < numEdges; i += blockDim.x) { + auto u = sourceEdges[i]; + auto v = targetEdges[i]; + + if (labels[u] == labels[labels[u]] && labels[v] < labels[u]) { + labelsNext[labels[u]] = labels[v]; + changed = true; + //printf("Edge (%i,%i): set labelsNext[%i] = labels[%i] = %i\n", u, v, labels[u], v, labels[v]); + } else if (labels[v] == labels[labels[v]] && labels[u] < labels[v]) { + labelsNext[labels[v]] = labels[u]; + changed = true; + //printf("Edge (%i,%i): set labelsNext[%i] = labels[%i] = %i\n", u, v, labels[v], u, labels[u]); + } else { + //printf("Edge (%i,%i): no action\n", u, v); + } + } + __syncthreads(); + + for (std::size_t i = threadIdx.x; i < numNodes; i += blockDim.x) { + labels[i] = labelsNext[i]; + } + + /*if(threadIdx.x == 0 ) { + for(int i=0; i +__global__ void makeLabelMask(std::size_t nLabels, const T *labels, + T *labelMask) { + std::size_t i = threadIdx.x + blockDim.x * blockIdx.x; + + if (i >= nLabels) { + return; + } + + labelMask[labels[i]] = 1; +} + +template +__global__ void mapEdgeLabels(std::size_t nLabels, T *labels, + const T *mapping) { + std::size_t i = threadIdx.x + blockDim.x * blockIdx.x; + + if (i >= nLabels) { + return; + } + + labels[i] = mapping[labels[i]]; +} + +template +TLabel connectedComponentsCuda(std::size_t nEdges, const TEdges *sourceEdges, + const TEdges *targetEdges, std::size_t nNodes, + TLabel *labels, cudaStream_t stream) { + TLabel *tmpMemory; + ACTS_CUDA_CHECK(cudaMallocAsync(&tmpMemory, nNodes * sizeof(TLabel), stream)); + + // Make synchronization in one block, to avoid that inter-block sync is + // necessary + dim3 blockDim = 1024; + labelConnectedComponents<<<1, blockDim, 1, stream>>>( + nEdges, sourceEdges, targetEdges, nNodes, labels, tmpMemory); + ACTS_CUDA_CHECK(cudaGetLastError()); + + // Assume we have the following components: + // 0 3 5 3 0 0 + + // Fill a mask which labels survived the connected components algorithm + // 0 1 2 3 4 5 + // 1 0 0 1 0 1 + ACTS_CUDA_CHECK( + cudaMemsetAsync(tmpMemory, 0, nNodes * sizeof(TLabel), stream)); + dim3 gridDim = (nNodes + blockDim.x - 1) / blockDim.x; + makeLabelMask<<>>(nNodes, labels, tmpMemory); + ACTS_CUDA_CHECK(cudaGetLastError()); + + // Exclusive prefix sum on the label mask + // 0 1 2 3 4 5 + // 0 1 1 1 2 2 + thrust::exclusive_scan(thrust::device.on(stream), tmpMemory, + tmpMemory + nNodes, tmpMemory); + + // Remap edge labels with values in prefix sum + // 0 -> 0, 3 -> 1, 5 -> 2 + mapEdgeLabels<<>>(nNodes, labels, tmpMemory); + ACTS_CUDA_CHECK(cudaGetLastError()); + + TLabel nLabels; + ACTS_CUDA_CHECK(cudaMemcpyAsync(&nLabels, &tmpMemory[nNodes - 1], + sizeof(TLabel), cudaMemcpyDeviceToHost, + stream)); + + ACTS_CUDA_CHECK(cudaFreeAsync(tmpMemory, stream)); + ACTS_CUDA_CHECK(cudaStreamSynchronize(stream)); + + return nLabels; +} + +} // namespace Acts::detail diff --git a/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/detail/CudaUtils.cuh b/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/detail/CudaUtils.cuh new file mode 100644 index 00000000000..e0b8e615179 --- /dev/null +++ b/Plugins/ExaTrkX/include/Acts/Plugins/ExaTrkX/detail/CudaUtils.cuh @@ -0,0 +1,31 @@ +// 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 + +#include + +namespace Acts::detail { + +inline void cudaAssert(cudaError_t code, const char *file, int line) { + if (code != cudaSuccess) { + std::stringstream ss; + ss << "CUDA error: " << cudaGetErrorString(code) << ", " << file << ":" + << line; + throw std::runtime_error(ss.str()); + } +} + +} // namespace Acts::detail + +#define ACTS_CUDA_CHECK(ans) \ + do { \ + Acts::detail::cudaAssert((ans), __FILE__, __LINE__); \ + } while (0) diff --git a/Plugins/ExaTrkX/src/BoostTrackBuilding.cpp b/Plugins/ExaTrkX/src/BoostTrackBuilding.cpp index 0d75b31cedd..d46bc2f58d5 100644 --- a/Plugins/ExaTrkX/src/BoostTrackBuilding.cpp +++ b/Plugins/ExaTrkX/src/BoostTrackBuilding.cpp @@ -48,7 +48,7 @@ namespace Acts { std::vector> BoostTrackBuilding::operator()( std::any /*nodes*/, std::any edges, std::any weights, - std::vector& spacepointIDs, torch::Device) { + std::vector& spacepointIDs, const ExecutionContext& execContext) { ACTS_DEBUG("Start track building"); const auto edgeTensor = std::any_cast(edges).to(torch::kCPU); const auto edgeWeightTensor = diff --git a/Plugins/ExaTrkX/src/CudaTrackBuilding.cu b/Plugins/ExaTrkX/src/CudaTrackBuilding.cu new file mode 100644 index 00000000000..06b2323d403 --- /dev/null +++ b/Plugins/ExaTrkX/src/CudaTrackBuilding.cu @@ -0,0 +1,71 @@ +// 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/Plugins/ExaTrkX/CudaTrackBuilding.hpp" +#include "Acts/Plugins/ExaTrkX/detail/ConnectedComponents.cuh" +#include "Acts/Plugins/ExaTrkX/detail/CudaUtils.cuh" +#include "Acts/Utilities/Zip.hpp" + +#include +#include +#include + +namespace Acts { + +std::vector> CudaTrackBuilding::operator()( + std::any /*nodes*/, std::any edges, std::any weights, + std::vector& spacepointIDs, const ExecutionContext& execContext) { + ACTS_VERBOSE("Start CUDA track building"); + c10::cuda::CUDAStreamGuard guard(execContext.stream.value()); + + const auto edgeTensor = std::any_cast(edges).to(torch::kCUDA); + assert(edgeTensor.size(0) == 2); + + const auto numSpacepoints = spacepointIDs.size(); + const auto numEdges = static_cast(edgeTensor.size(1)); + + if (numEdges == 0) { + ACTS_WARNING("No edges remained after edge classification"); + return {}; + } + + auto stream = execContext.stream->stream(); + + auto cudaSrcPtr = edgeTensor.data_ptr(); + auto cudaTgtPtr = edgeTensor.data_ptr() + numEdges; + + int* cudaLabels; + ACTS_CUDA_CHECK( + cudaMallocAsync(&cudaLabels, numSpacepoints * sizeof(int), stream)); + + std::size_t numberLabels = detail::connectedComponentsCuda( + numEdges, cudaSrcPtr, cudaTgtPtr, numSpacepoints, cudaLabels, stream); + + // TODO not sure why there is an issue that is not detected in the unit tests + numberLabels += 1; + + std::vector trackLabels(numSpacepoints); + ACTS_CUDA_CHECK(cudaMemcpyAsync(trackLabels.data(), cudaLabels, + numSpacepoints * sizeof(int), + cudaMemcpyDeviceToHost, stream)); + ACTS_CUDA_CHECK(cudaFreeAsync(cudaLabels, stream)); + ACTS_CUDA_CHECK(cudaStreamSynchronize(stream)); + ACTS_CUDA_CHECK(cudaGetLastError()); + + ACTS_VERBOSE("Found " << numberLabels << " track candidates"); + + std::vector> trackCandidates(numberLabels); + + for (const auto [label, id] : Acts::zip(trackLabels, spacepointIDs)) { + trackCandidates[label].push_back(id); + } + + return trackCandidates; +} + +} // namespace Acts diff --git a/Plugins/ExaTrkX/src/CugraphTrackBuilding.cpp b/Plugins/ExaTrkX/src/CugraphTrackBuilding.cpp deleted file mode 100644 index 7750cd7b3ac..00000000000 --- a/Plugins/ExaTrkX/src/CugraphTrackBuilding.cpp +++ /dev/null @@ -1,84 +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 "Acts/Plugins/ExaTrkX/CugraphTrackBuilding.hpp" - -#include - -#include - -#include "weaklyConnectedComponentsCugraph.hpp" - -namespace Acts { - -std::vector> CugraphTrackBuilding::operator()( - std::any, std::any edges, std::any edge_weights, - std::vector &spacepointIDs, torch::Device) { - auto numSpacepoints = spacepointIDs.size(); - auto edgesAfterFiltering = std::any_cast>(edges); - auto numEdgesAfterF = edgesAfterFiltering.size() / 2; - auto gOutputCTen = std::any_cast(edge_weights); - - if (numEdgesAfterF == 0) { - return {}; - } - - // ************ - // Track Labeling with cugraph::connected_components - // ************ - std::vector rowIndices; - std::vector colIndices; - std::vector edgeWeights; - std::vector trackLabels(numSpacepoints); - std::copy(edgesAfterFiltering.begin(), - edgesAfterFiltering.begin() + numEdgesAfterF, - std::back_insert_iterator(rowIndices)); - std::copy(edgesAfterFiltering.begin() + numEdgesAfterF, - edgesAfterFiltering.end(), std::back_insert_iterator(colIndices)); - std::copy(gOutputCTen.data_ptr(), - gOutputCTen.data_ptr() + numEdgesAfterF, - std::back_insert_iterator(edgeWeights)); - - ACTS_VERBOSE("run weaklyConnectedComponents"); - weaklyConnectedComponents( - rowIndices, colIndices, edgeWeights, trackLabels, logger()); - - ACTS_DEBUG("size of components: " << trackLabels.size()); - if (trackLabels.size() == 0) { - return {}; - } - - std::vector> trackCandidates; - trackCandidates.clear(); - - int existTrkIdx = 0; - // map labeling from MCC to customized track id. - std::map trackLableToIds; - - for (auto idx = 0ul; idx < numSpacepoints; ++idx) { - int trackLabel = trackLabels[idx]; - int spacepointID = spacepointIDs[idx]; - - int trkId; - if (trackLableToIds.contains(trackLabel)) { - trkId = trackLableToIds[trackLabel]; - trackCandidates[trkId].push_back(spacepointID); - } else { - // a new track, assign the track id - // and create a vector - trkId = existTrkIdx; - trackCandidates.push_back(std::vector{trkId}); - trackLableToIds[trackLabel] = trkId; - existTrkIdx++; - } - } - - return trackCandidates; -} - -} // namespace Acts diff --git a/Plugins/ExaTrkX/src/ExaTrkXPipeline.cpp b/Plugins/ExaTrkX/src/ExaTrkXPipeline.cpp index 6a05ae96f8e..d81e94ab342 100644 --- a/Plugins/ExaTrkX/src/ExaTrkXPipeline.cpp +++ b/Plugins/ExaTrkX/src/ExaTrkXPipeline.cpp @@ -39,11 +39,18 @@ std::vector> ExaTrkXPipeline::run( std::vector &features, const std::vector &moduleIds, std::vector &spacepointIDs, const ExaTrkXHook &hook, ExaTrkXTiming *timing) const { + ExecutionContext ctx; + ctx.device = m_graphConstructor->device(); +#ifndef ACTS_EXATRKX_CPUONLY + if (ctx.device.type() == torch::kCUDA) { + ctx.stream = c10::cuda::getStreamFromPool(ctx.device.index()); + } +#endif + try { auto t0 = std::chrono::high_resolution_clock::now(); auto [nodeFeatures, edgeIndex, edgeFeatures] = - (*m_graphConstructor)(features, spacepointIDs.size(), moduleIds, - m_graphConstructor->device()); + (*m_graphConstructor)(features, spacepointIDs.size(), moduleIds, ctx); auto t1 = std::chrono::high_resolution_clock::now(); if (timing != nullptr) { @@ -59,7 +66,7 @@ std::vector> ExaTrkXPipeline::run( t0 = std::chrono::high_resolution_clock::now(); auto [newNodeFeatures, newEdgeIndex, newEdgeFeatures, newEdgeScores] = (*edgeClassifier)(std::move(nodeFeatures), std::move(edgeIndex), - std::move(edgeFeatures), edgeClassifier->device()); + std::move(edgeFeatures), ctx); t1 = std::chrono::high_resolution_clock::now(); if (timing != nullptr) { @@ -76,8 +83,7 @@ std::vector> ExaTrkXPipeline::run( t0 = std::chrono::high_resolution_clock::now(); auto res = (*m_trackBuilder)(std::move(nodeFeatures), std::move(edgeIndex), - std::move(edgeScores), spacepointIDs, - m_trackBuilder->device()); + std::move(edgeScores), spacepointIDs, ctx); t1 = std::chrono::high_resolution_clock::now(); if (timing != nullptr) { diff --git a/Plugins/ExaTrkX/src/OnnxEdgeClassifier.cpp b/Plugins/ExaTrkX/src/OnnxEdgeClassifier.cpp index 59452daec09..71cdd0097b5 100644 --- a/Plugins/ExaTrkX/src/OnnxEdgeClassifier.cpp +++ b/Plugins/ExaTrkX/src/OnnxEdgeClassifier.cpp @@ -90,7 +90,8 @@ std::ostream &operator<<(std::ostream &os, Ort::Value &v) { std::tuple OnnxEdgeClassifier::operator()(std::any inputNodes, std::any inputEdges, - std::any inEdgeFeatures, torch::Device) { + std::any inEdgeFeatures, + const ExecutionContext & /*unused*/) { auto torchDevice = torch::kCPU; Ort::MemoryInfo memoryInfo("Cpu", OrtArenaAllocator, /*device_id*/ 0, OrtMemTypeDefault); diff --git a/Plugins/ExaTrkX/src/TorchEdgeClassifier.cpp b/Plugins/ExaTrkX/src/TorchEdgeClassifier.cpp index b81335ad0a9..3aff05eb4e2 100644 --- a/Plugins/ExaTrkX/src/TorchEdgeClassifier.cpp +++ b/Plugins/ExaTrkX/src/TorchEdgeClassifier.cpp @@ -67,17 +67,23 @@ TorchEdgeClassifier::~TorchEdgeClassifier() {} std::tuple TorchEdgeClassifier::operator()(std::any inNodeFeatures, std::any inEdgeIndex, - std::any inEdgeFeatures, torch::Device device) { - decltype(std::chrono::high_resolution_clock::now()) t0, t1, t2, t3, t4, t5; + std::any inEdgeFeatures, + const ExecutionContext& execContext) { + const auto& device = execContext.device; + decltype(std::chrono::high_resolution_clock::now()) t0, t1, t2, t3, t4; t0 = std::chrono::high_resolution_clock::now(); ACTS_DEBUG("Start edge classification, use " << device); c10::InferenceMode guard(true); // add a protection to avoid calling for kCPU -#ifndef ACTS_EXATRKX_CPUONLY +#ifdef ACTS_EXATRKX_CPUONLY + assert(device == torch::Device(torch::kCPU)); +#else std::optional device_guard; + std::optional streamGuard; if (device.is_cuda()) { device_guard.emplace(device.index()); + streamGuard.emplace(execContext.stream.value()); } #endif diff --git a/Plugins/ExaTrkX/src/TorchMetricLearning.cpp b/Plugins/ExaTrkX/src/TorchMetricLearning.cpp index 08088a5d904..57cb271351a 100644 --- a/Plugins/ExaTrkX/src/TorchMetricLearning.cpp +++ b/Plugins/ExaTrkX/src/TorchMetricLearning.cpp @@ -69,15 +69,21 @@ TorchMetricLearning::~TorchMetricLearning() {} std::tuple TorchMetricLearning::operator()( std::vector &inputValues, std::size_t numNodes, - const std::vector & /*moduleIds*/, torch::Device device) { + const std::vector & /*moduleIds*/, + const ExecutionContext &execContext) { + const auto &device = execContext.device; ACTS_DEBUG("Start graph construction"); c10::InferenceMode guard(true); // add a protection to avoid calling for kCPU -#ifndef ACTS_EXATRKX_CPUONLY +#ifdef ACTS_EXATRKX_CPUONLY + assert(device == torch::Device(torch::kCPU)); +#else std::optional device_guard; + std::optional streamGuard; if (device.is_cuda()) { device_guard.emplace(device.index()); + streamGuard.emplace(execContext.stream.value()); } #endif diff --git a/Plugins/ExaTrkX/src/weaklyConnectedComponentsCugraph.hpp b/Plugins/ExaTrkX/src/weaklyConnectedComponentsCugraph.hpp deleted file mode 100644 index 4eb498a326d..00000000000 --- a/Plugins/ExaTrkX/src/weaklyConnectedComponentsCugraph.hpp +++ /dev/null @@ -1,108 +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 - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef CUDA_RT_CALL -#define CUDA_RT_CALL(call) \ - { \ - cudaError_t cudaStatus = call; \ - if (cudaSuccess != cudaStatus) { \ - fprintf(stderr, \ - "ERROR: CUDA RT call \"%s\" in line %d of file %s failed with " \ - "%s (%d).\n", \ - #call, __LINE__, __FILE__, cudaGetErrorString(cudaStatus), \ - cudaStatus); \ - } \ - } -#endif // CUDA_RT_CALL - -template -__global__ void weaklyConnectedComponents(std::vector& rowIndices, - std::vector& colIndices, - std::vector& edgeWeights, - std::vector& trackLabels, - const Acts::Logger& logger) { - cudaStream_t stream; - CUDA_RT_CALL(cudaStreamCreate(&stream)); - - ACTS_VERBOSE("Weakly components Start"); - ACTS_VERBOSE("edge size: " << rowIndices.size() << " " << colIndices.size()); - raft::handle_t handle{stream}; - - cugraph::graph_t graph(handle); - - // learn from matrix_market_file_utilities.cu - vertex_t maxVertexID_row = - *std::max_element(rowIndices.begin(), rowIndices.end()); - vertex_t maxVertexID_col = - *std::max_element(colIndices.begin(), colIndices.end()); - vertex_t maxVertex = std::max(maxVertexID_row, maxVertexID_col); - - vertex_t number_of_vertices = maxVertex; - rmm::device_uvector d_vertices(number_of_vertices, - handle.get_stream()); - std::vector vertex_idx(number_of_vertices); - for (vertex_t idx = 0; idx < number_of_vertices; idx++) { - vertex_idx[idx] = idx; - } - - rmm::device_uvector src_v(rowIndices.size(), handle.get_stream()); - rmm::device_uvector dst_v(colIndices.size(), handle.get_stream()); - rmm::device_uvector weights_v(edgeWeights.size(), - handle.get_stream()); - - raft::update_device(src_v.data(), rowIndices.data(), rowIndices.size(), - handle.get_stream()); - raft::update_device(dst_v.data(), colIndices.data(), colIndices.size(), - handle.get_stream()); - raft::update_device(weights_v.data(), edgeWeights.data(), edgeWeights.size(), - handle.get_stream()); - raft::update_device(d_vertices.data(), vertex_idx.data(), vertex_idx.size(), - handle.get_stream()); - - std::tie(graph, std::ignore) = - cugraph::create_graph_from_edgelist( - handle, std::move(d_vertices), std::move(src_v), std::move(dst_v), - std::move(weights_v), cugraph::graph_properties_t{true, false}, - false); - - auto graph_view = graph.view(); - CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement - - rmm::device_uvector d_components( - graph_view.get_number_of_vertices(), handle.get_stream()); - - ACTS_VERBOSE("2back from construct_graph"); - cugraph::weakly_connected_components(handle, graph_view, d_components.data()); - - ACTS_VERBOSE("number of components: " << d_components.size()); - raft::update_host(trackLabels.data(), d_components.data(), - d_components.size(), handle.get_stream()); -} diff --git a/Plugins/FpeMonitoring/include/Acts/Plugins/FpeMonitoring/FpeMonitor.hpp b/Plugins/FpeMonitoring/include/Acts/Plugins/FpeMonitoring/FpeMonitor.hpp index 022a07a3426..ee96ecdc29f 100644 --- a/Plugins/FpeMonitoring/include/Acts/Plugins/FpeMonitoring/FpeMonitor.hpp +++ b/Plugins/FpeMonitoring/include/Acts/Plugins/FpeMonitoring/FpeMonitor.hpp @@ -45,7 +45,7 @@ class FpeMonitor { m_size{bufferSize} {} Buffer(const Buffer &) = delete; - Buffer(Buffer &&other) { + Buffer(Buffer &&other) noexcept { m_data = std::move(other.m_data); m_size = other.m_size; m_offset = other.m_offset; diff --git a/Plugins/Geant4/include/Acts/Plugins/Geant4/Geant4SurfaceProvider.hpp b/Plugins/Geant4/include/Acts/Plugins/Geant4/Geant4SurfaceProvider.hpp index 64930b82ff6..de73cb6466d 100644 --- a/Plugins/Geant4/include/Acts/Plugins/Geant4/Geant4SurfaceProvider.hpp +++ b/Plugins/Geant4/include/Acts/Plugins/Geant4/Geant4SurfaceProvider.hpp @@ -69,7 +69,7 @@ class Geant4SurfaceProvider : public Acts::Experimental::ISurfacesProvider { Acts::RangeXD range; /// A set of binning values to perform the separation - std::array binningValues; + std::array binningValues; /// The maximum number of surfaces per leaf std::size_t leafSize = bSize; diff --git a/Plugins/GeoModel/include/Acts/Plugins/GeoModel/GeoModelBlueprintCreater.hpp b/Plugins/GeoModel/include/Acts/Plugins/GeoModel/GeoModelBlueprintCreater.hpp index e56b1ec573d..78dfca36996 100644 --- a/Plugins/GeoModel/include/Acts/Plugins/GeoModel/GeoModelBlueprintCreater.hpp +++ b/Plugins/GeoModel/include/Acts/Plugins/GeoModel/GeoModelBlueprintCreater.hpp @@ -39,7 +39,7 @@ class GeoModelBlueprintCreater { /// with a kdtree sorting structure std::vector> detectorSurfaces = {}; /// The binning values for the KDTree sorting - std::vector kdtBinning = {}; + std::vector kdtBinning = {}; /// Polyhedron approximation: number of segments per circlequarter unsigned int quarterSegments = 1u; }; @@ -140,7 +140,7 @@ class GeoModelBlueprintCreater { createInternalStructureBuilder( Cache& cache, const GeometryContext& gctx, const TableEntry& entry, const Extent& externalExtent = Extent(), - const std::vector& internalConstraints = {}) const; + const std::vector& internalConstraints = {}) const; /// @brief Parse bound value string from the database /// diff --git a/Plugins/GeoModel/include/Acts/Plugins/GeoModel/detail/GeoModelBinningHelper.hpp b/Plugins/GeoModel/include/Acts/Plugins/GeoModel/detail/GeoModelBinningHelper.hpp index 4cf2fde9b8d..5a50754673e 100644 --- a/Plugins/GeoModel/include/Acts/Plugins/GeoModel/detail/GeoModelBinningHelper.hpp +++ b/Plugins/GeoModel/include/Acts/Plugins/GeoModel/detail/GeoModelBinningHelper.hpp @@ -19,20 +19,21 @@ namespace Acts::detail::GeoModelBinningHelper { -/// @brief Helper to transform binning string to BinningValue enum +/// @brief Helper to transform binning string to AxisDirection enum /// /// @param binning the binning string -inline BinningValue toBinningValue(const std::string& binning) { +inline AxisDirection toAxisDirection(const std::string& binning) { + using enum AxisDirection; if (binning == "x") { - return BinningValue::binX; + return AxisX; } else if (binning == "y") { - return BinningValue::binY; + return AxisY; } else if (binning == "z") { - return BinningValue::binZ; + return AxisZ; } else if (binning == "r") { - return BinningValue::binR; + return AxisR; } else if (binning == "phi") { - return BinningValue::binPhi; + return AxisPhi; } throw std::invalid_argument("GeoModelBinningHelper: Unknown binning value '" + binning + "'"); diff --git a/Plugins/GeoModel/include/Acts/Plugins/GeoModel/detail/GeoModelExtentHelper.hpp b/Plugins/GeoModel/include/Acts/Plugins/GeoModel/detail/GeoModelExtentHelper.hpp index 5c27152b5f5..b0d792ca24d 100644 --- a/Plugins/GeoModel/include/Acts/Plugins/GeoModel/detail/GeoModelExtentHelper.hpp +++ b/Plugins/GeoModel/include/Acts/Plugins/GeoModel/detail/GeoModelExtentHelper.hpp @@ -25,15 +25,15 @@ namespace Acts::detail::GeoModelExentHelper { /// @param ctype the type of the constraint as string from the database /// /// @return a vector -std::vector readBoundsConstaints(const std::string& boundsEntry, - const std::string& ctype = "i"); +std::vector readBoundsConstaints(const std::string& boundsEntry, + const std::string& ctype = "i"); /// @brief Helper function to find out which ones are constraint needed for binning /// /// @param binningEntry the bounds entry from the database /// /// @return a vector -std::vector readBinningConstraints( +std::vector readBinningConstraints( const std::vector& binningEntry); /// @brief Helper function to create the extent from database volume entry diff --git a/Plugins/GeoModel/src/GeoModelBlueprintCreater.cpp b/Plugins/GeoModel/src/GeoModelBlueprintCreater.cpp index 081834d7069..293757b51be 100644 --- a/Plugins/GeoModel/src/GeoModelBlueprintCreater.cpp +++ b/Plugins/GeoModel/src/GeoModelBlueprintCreater.cpp @@ -54,8 +54,8 @@ Acts::GeoModelBlueprintCreater::create(const GeometryContext& gctx, // Prepare the KdtSurfaces if configured to do so // if (!m_cfg.detectorSurfaces.empty()) { - std::array kdtBinning = { - BinningValue::binX, BinningValue::binY, BinningValue::binZ}; + std::array kdtBinning = { + AxisDirection::AxisX, AxisDirection::AxisY, AxisDirection::AxisZ}; if (m_cfg.kdtBinning.empty()) { throw std::invalid_argument( "GeoModelBlueprintCreater: At least one binning value for KDTree " @@ -152,10 +152,10 @@ Acts::GeoModelBlueprintCreater::createNode( // Peak into the volume entry to understand which one should be constraint // by the internals building - std::vector internalConstraints = + std::vector internalConstraints = detail::GeoModelExentHelper::readBoundsConstaints(entry.bounds, "i"); // Check if the binnning will also use the internal constraints - std::vector binningConstraints = + std::vector binningConstraints = detail::GeoModelExentHelper::readBinningConstraints(entry.binnings); // Concatenate the binning constraints for (const auto& bc : binningConstraints) { @@ -168,7 +168,7 @@ Acts::GeoModelBlueprintCreater::createNode( ACTS_VERBOSE("Found " << internalConstraints.size() << " internal constraints to check for: "); for (const auto& ic : internalConstraints) { - ACTS_VERBOSE("- " << binningValueName(ic)); + ACTS_VERBOSE("- " << axisDirectionName(ic)); } } @@ -263,11 +263,11 @@ Acts::GeoModelBlueprintCreater::createNode( } // Create the binnings - std::vector binnings; + std::vector binnings; std::for_each( entry.binnings.begin(), entry.binnings.end(), [&binnings](const std::string& b) { - binnings.push_back(detail::GeoModelBinningHelper::toBinningValue(b)); + binnings.push_back(detail::GeoModelBinningHelper::toAxisDirection(b)); }); // Complete the children @@ -317,7 +317,7 @@ std::tuple, Acts::GeoModelBlueprintCreater::createInternalStructureBuilder( Cache& cache, const GeometryContext& gctx, const TableEntry& entry, const Extent& externalExtent, - const std::vector& internalConstraints) const { + const std::vector& internalConstraints) const { // Check if the internals entry is empty if (entry.internals.empty()) { return {nullptr, Extent()}; @@ -351,7 +351,7 @@ Acts::GeoModelBlueprintCreater::createInternalStructureBuilder( // Fill what we have - follow the convention to fill up with the last for (std::size_t ibv = 0; ibv < 3u; ++ibv) { if (ibv < m_cfg.kdtBinning.size()) { - BinningValue v = m_cfg.kdtBinning[ibv]; + AxisDirection v = m_cfg.kdtBinning[ibv]; mins[ibv] = rangeExtent.min(v); maxs[ibv] = rangeExtent.max(v); continue; @@ -424,10 +424,10 @@ Acts::GeoModelBlueprintCreater::parseBounds( // Switch on the bounds type if (boundsType == VolumeBounds::BoundsType::eCylinder) { // Create the translation & bound values - translation = Acts::Vector3(0., 0., extent.medium(BinningValue::binZ)); - boundValues = {extent.min(BinningValue::binR), - extent.max(BinningValue::binR), - 0.5 * extent.interval(BinningValue::binZ)}; + translation = Acts::Vector3(0., 0., extent.medium(AxisDirection::AxisZ)); + boundValues = {extent.min(AxisDirection::AxisR), + extent.max(AxisDirection::AxisR), + 0.5 * extent.interval(AxisDirection::AxisZ)}; } else { throw std::invalid_argument( "GeoModelBlueprintCreater: Unknown bounds type, only 'cyl' is " diff --git a/Plugins/GeoModel/src/detail/GeoModelBinningHelper.cpp b/Plugins/GeoModel/src/detail/GeoModelBinningHelper.cpp index cb138913fd1..d6c7551a174 100644 --- a/Plugins/GeoModel/src/detail/GeoModelBinningHelper.cpp +++ b/Plugins/GeoModel/src/detail/GeoModelBinningHelper.cpp @@ -17,7 +17,7 @@ Acts::detail::GeoModelBinningHelper::toProtoBinning( const std::string& binning, const std::optional& extent) { std::vector binningTokens; boost::split(binningTokens, binning, boost::is_any_of(",")); - BinningValue bValue = toBinningValue(binningTokens[0]); + AxisDirection bValue = toAxisDirection(binningTokens[0]); std::vector binningDetails = {binningTokens.begin() + 1, binningTokens.end()}; @@ -47,7 +47,7 @@ Acts::detail::GeoModelBinningHelper::toProtoBinning( // The Range double rangeMin = 0.; double rangeMax = 0.; - if (bValue == BinningValue::binPhi && + if (bValue == AxisDirection::AxisPhi && boundaryType == AxisBoundaryType::Closed) { rangeMin = -std::numbers::pi; rangeMax = std::numbers::pi; diff --git a/Plugins/GeoModel/src/detail/GeoModelExtentHelper.cpp b/Plugins/GeoModel/src/detail/GeoModelExtentHelper.cpp index 3734aefb8fe..3ef7da227aa 100644 --- a/Plugins/GeoModel/src/detail/GeoModelExtentHelper.cpp +++ b/Plugins/GeoModel/src/detail/GeoModelExtentHelper.cpp @@ -14,7 +14,7 @@ #include -std::vector +std::vector Acts::detail::GeoModelExentHelper::readBoundsConstaints( const std::string& boundsEntry, const std::string& ctype) { std::vector boundsEntrySplit; @@ -24,7 +24,7 @@ Acts::detail::GeoModelExentHelper::readBoundsConstaints( "GeoModelBlueprintCreater: Bounds entry has to have at least 2 " "entries (type, values)"); } - std::set constraints; + std::set constraints; // Switch on the bounds type if (boundsEntrySplit[0u] == "cyl") { // Capture the values @@ -36,9 +36,9 @@ Acts::detail::GeoModelExentHelper::readBoundsConstaints( "least 4 entries (rmin, rmax, zmin, zmax)"); } // Raw database values to extent entries - constexpr std::array bvCyl = { - BinningValue::binR, BinningValue::binR, BinningValue::binZ, - BinningValue::binZ, BinningValue::binPhi, BinningValue::binPhi}; + constexpr std::array bvCyl = { + AxisDirection::AxisR, AxisDirection::AxisR, AxisDirection::AxisZ, + AxisDirection::AxisZ, AxisDirection::AxisPhi, AxisDirection::AxisPhi}; for (auto [iv, value] : enumerate(valuesEntry)) { if (value == ctype || value[0u] == ctype[0u]) { @@ -49,10 +49,10 @@ Acts::detail::GeoModelExentHelper::readBoundsConstaints( return {constraints.begin(), constraints.end()}; } -std::vector +std::vector Acts::detail::GeoModelExentHelper::readBinningConstraints( const std::vector& binningEntry) { - std::set constraints; + std::set constraints; // Loop over the single binning Entries for (const auto& sbe : binningEntry) { if (sbe.empty()) { @@ -60,8 +60,8 @@ Acts::detail::GeoModelExentHelper::readBinningConstraints( } std::vector sbTokens; boost::split(sbTokens, sbe, boost::is_any_of(",")); - BinningValue bv = - Acts::detail::GeoModelBinningHelper::toBinningValue(sbTokens[0]); + AxisDirection bv = + Acts::detail::GeoModelBinningHelper::toAxisDirection(sbTokens[0]); if (sbTokens.size() > 1u) { std::vector valueTokens = {sbTokens.begin() + 1, sbTokens.end()}; @@ -103,12 +103,12 @@ Acts::detail::GeoModelExentHelper::extentFromTable( "least 4 entries (rmin, rmax, zmin, zmax)"); } // Raw database values to extent entries - constexpr std::array bvCyl = { - BinningValue::binR, BinningValue::binR, BinningValue::binZ, - BinningValue::binZ, BinningValue::binPhi, BinningValue::binPhi}; + constexpr std::array bvCyl = { + AxisDirection::AxisR, AxisDirection::AxisR, AxisDirection::AxisZ, + AxisDirection::AxisZ, AxisDirection::AxisPhi, AxisDirection::AxisPhi}; for (auto [iv, value] : enumerate(valuesEntry)) { // Get the binning value - BinningValue bValue = bvCyl.at(iv); + AxisDirection bValue = bvCyl.at(iv); double val = std::numeric_limits::max(); bool isMin = (iv % 2 == 0); // Case "e" : external extent @@ -149,7 +149,7 @@ Acts::detail::GeoModelExentHelper::extentFromTable( } // Round up / down if configured if (roundInternalExtent) { - for (const auto& bv : allBinningValues()) { + for (const auto& bv : allAxisDirections()) { if (internalExtent.constrains(bv)) { extent.setMin(bv, std::floor(extent.min(bv))); extent.setMax(bv, std::ceil(extent.max(bv))); diff --git a/Plugins/Json/CMakeLists.txt b/Plugins/Json/CMakeLists.txt index 20634d2bfe5..3ec47a181e4 100644 --- a/Plugins/Json/CMakeLists.txt +++ b/Plugins/Json/CMakeLists.txt @@ -15,6 +15,7 @@ add_library( src/MaterialJsonConverter.cpp src/PortalJsonConverter.cpp src/ProtoDetectorJsonConverter.cpp + src/ProtoAxisJsonConverter.cpp src/SurfaceBoundsJsonConverter.cpp src/SurfaceJsonConverter.cpp src/UtilitiesJsonConverter.cpp diff --git a/Plugins/Json/include/Acts/Plugins/Json/DetectorVolumeFinderJsonConverter.hpp b/Plugins/Json/include/Acts/Plugins/Json/DetectorVolumeFinderJsonConverter.hpp index 7b391a53fb5..dbf348bdd8f 100644 --- a/Plugins/Json/include/Acts/Plugins/Json/DetectorVolumeFinderJsonConverter.hpp +++ b/Plugins/Json/include/Acts/Plugins/Json/DetectorVolumeFinderJsonConverter.hpp @@ -13,7 +13,7 @@ #include "Acts/Navigation/PortalNavigation.hpp" #include "Acts/Plugins/Json/DetrayJsonHelper.hpp" #include "Acts/Plugins/Json/IndexedGridJsonHelper.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Grid.hpp" #include diff --git a/Plugins/Json/include/Acts/Plugins/Json/DetrayJsonHelper.hpp b/Plugins/Json/include/Acts/Plugins/Json/DetrayJsonHelper.hpp index d80b5cbfdde..92db94bdb32 100644 --- a/Plugins/Json/include/Acts/Plugins/Json/DetrayJsonHelper.hpp +++ b/Plugins/Json/include/Acts/Plugins/Json/DetrayJsonHelper.hpp @@ -9,7 +9,7 @@ #pragma once #include "Acts/Surfaces/SurfaceBounds.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include #include @@ -62,6 +62,6 @@ void addVolumeLink(nlohmann::json& jSurface, int vLink); /// @param casts are the grid axes cast types /// /// @return the acceleration link idnetifier -std::size_t accelerationLink(std::span casts); +std::size_t accelerationLink(std::span casts); } // namespace Acts::DetrayJsonHelper diff --git a/Plugins/Json/include/Acts/Plugins/Json/GridJsonConverter.hpp b/Plugins/Json/include/Acts/Plugins/Json/GridJsonConverter.hpp index 3215bd66eae..086ec7b0c03 100644 --- a/Plugins/Json/include/Acts/Plugins/Json/GridJsonConverter.hpp +++ b/Plugins/Json/include/Acts/Plugins/Json/GridJsonConverter.hpp @@ -10,7 +10,7 @@ #include "Acts/Plugins/Json/ActsJson.hpp" #include "Acts/Plugins/Json/TrackParametersJsonConverter.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/GridAccessHelpers.hpp" #include "Acts/Utilities/IAxis.hpp" diff --git a/Plugins/Json/include/Acts/Plugins/Json/IndexedGridJsonHelper.hpp b/Plugins/Json/include/Acts/Plugins/Json/IndexedGridJsonHelper.hpp index 3a3ab6b829f..ae4dd431a1c 100644 --- a/Plugins/Json/include/Acts/Plugins/Json/IndexedGridJsonHelper.hpp +++ b/Plugins/Json/include/Acts/Plugins/Json/IndexedGridJsonHelper.hpp @@ -11,7 +11,7 @@ #include "Acts/Plugins/Json/AlgebraJsonConverter.hpp" #include "Acts/Plugins/Json/GridJsonConverter.hpp" #include "Acts/Plugins/Json/UtilitiesJsonConverter.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Grid.hpp" #include "Acts/Utilities/GridAxisGenerators.hpp" @@ -46,8 +46,8 @@ nlohmann::json convertImpl(const index_grid& indexGrid, bool detray = false, jCasts.push_back(indexGrid.casts[0u]); jCasts.push_back(indexGrid.casts[1u]); // Check for axis swap (detray version) - swapAxes = checkSwap && (indexGrid.casts[0u] == BinningValue::binZ && - indexGrid.casts[1u] == BinningValue::binPhi); + swapAxes = checkSwap && (indexGrid.casts[0u] == AxisDirection::AxisZ && + indexGrid.casts[1u] == AxisDirection::AxisPhi); } jIndexedGrid["casts"] = jCasts; jIndexedGrid["transform"] = @@ -99,12 +99,12 @@ updator_type generateFromJson(const nlohmann::json& jUpdater, Transform3 transform = Transform3JsonConverter::fromJson(jUpdater["transform"]); auto jGrid = jUpdater["grid"]; - auto jCasts = jUpdater["casts"].get>(); + auto jCasts = jUpdater["casts"].get>(); auto jAxes = jGrid["axes"]; // 1D cases if (jAxes.size() == 1u) { - BinningValue bValue = jCasts[0u]; + AxisDirection bValue = jCasts[0u]; auto jAxis = jAxes[0u]; AxisType axisType = jAxis["type"]; @@ -146,8 +146,8 @@ updator_type generateFromJson(const nlohmann::json& jUpdater, // This currently writes out only the main options of 2D grids // nota bene: it assumes if one axis is closed, it is axis B - BinningValue bValueA = jCasts[0u]; - BinningValue bValueB = jCasts[1u]; + AxisDirection bValueA = jCasts[0u]; + AxisDirection bValueB = jCasts[1u]; auto jAxisA = jAxes[0u]; auto jAxisB = jAxes[1u]; diff --git a/Plugins/Json/include/Acts/Plugins/Json/IndexedSurfacesJsonConverter.hpp b/Plugins/Json/include/Acts/Plugins/Json/IndexedSurfacesJsonConverter.hpp index 4e0b8982a62..2511218af3f 100644 --- a/Plugins/Json/include/Acts/Plugins/Json/IndexedSurfacesJsonConverter.hpp +++ b/Plugins/Json/include/Acts/Plugins/Json/IndexedSurfacesJsonConverter.hpp @@ -17,7 +17,7 @@ #include "Acts/Plugins/Json/DetrayJsonHelper.hpp" #include "Acts/Plugins/Json/GridJsonConverter.hpp" #include "Acts/Plugins/Json/IndexedGridJsonHelper.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Enumerate.hpp" #include "Acts/Utilities/Grid.hpp" #include "Acts/Utilities/GridAxisGenerators.hpp" diff --git a/Plugins/Json/include/Acts/Plugins/Json/ProtoAxisJsonConverter.hpp b/Plugins/Json/include/Acts/Plugins/Json/ProtoAxisJsonConverter.hpp new file mode 100644 index 00000000000..9ba4ad53dd5 --- /dev/null +++ b/Plugins/Json/include/Acts/Plugins/Json/ProtoAxisJsonConverter.hpp @@ -0,0 +1,34 @@ +// 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/Plugins/Json/ActsJson.hpp" +#include "Acts/Utilities/ProtoAxis.hpp" + +#include + +/// Custom Json encoder/decoders. Naming is mandated by nlohmann::json and thus +/// can not match our naming guidelines. +/// +/// This uses a custom API and nomenclature as it would +/// otherwise require the ProtoAxis to have a default +/// constructor which is deleted +namespace Acts::ProtoAxisJsonConverter { + +/// Write the ProtoAxis to a json object +/// +/// @param pa the proto axis to be written out +nlohmann::json toJson(const ProtoAxis& pa); + +/// Create a ProtoAxis from a json object +/// +/// @param j the json object to be read from +Acts::ProtoAxis fromJson(const nlohmann::json& j); + +} // namespace Acts::ProtoAxisJsonConverter diff --git a/Plugins/Json/include/Acts/Plugins/Json/UtilitiesJsonConverter.hpp b/Plugins/Json/include/Acts/Plugins/Json/UtilitiesJsonConverter.hpp index 4874f7b49ad..ef7207af333 100644 --- a/Plugins/Json/include/Acts/Plugins/Json/UtilitiesJsonConverter.hpp +++ b/Plugins/Json/include/Acts/Plugins/Json/UtilitiesJsonConverter.hpp @@ -42,14 +42,15 @@ void from_json(const nlohmann::json& j, Range1D& r) { r.setMax(static_cast(j["max"])); } -NLOHMANN_JSON_SERIALIZE_ENUM(BinningValue, {{BinningValue::binX, "binX"}, - {BinningValue::binY, "binY"}, - {BinningValue::binZ, "binZ"}, - {BinningValue::binR, "binR"}, - {BinningValue::binPhi, "binPhi"}, - {BinningValue::binRPhi, "binRPhi"}, - {BinningValue::binH, "binH"}, - {BinningValue::binEta, "binEta"}, - {BinningValue::binMag, "binMag"}}) +NLOHMANN_JSON_SERIALIZE_ENUM(AxisDirection, + {{AxisDirection::AxisX, "AxisX"}, + {AxisDirection::AxisY, "AxisY"}, + {AxisDirection::AxisZ, "AxisZ"}, + {AxisDirection::AxisR, "AxisR"}, + {AxisDirection::AxisPhi, "AxisPhi"}, + {AxisDirection::AxisRPhi, "AxisRPhi"}, + {AxisDirection::AxisTheta, "AxisTheta"}, + {AxisDirection::AxisEta, "AxisEta"}, + {AxisDirection::AxisMag, "AxisMag"}}) } // namespace Acts diff --git a/Plugins/Json/src/DetectorVolumeFinderJsonConverter.cpp b/Plugins/Json/src/DetectorVolumeFinderJsonConverter.cpp index 8defd1ef5da..a71af293237 100644 --- a/Plugins/Json/src/DetectorVolumeFinderJsonConverter.cpp +++ b/Plugins/Json/src/DetectorVolumeFinderJsonConverter.cpp @@ -37,7 +37,7 @@ struct IndexedVolumesGenerator { template Acts::Experimental::ExternalNavigationDelegate createUpdater( grid_type&& grid, - const std::array& bv, + const std::array& bv, const Acts::Transform3& transform) { using IndexedDetectorVolumesImpl = Acts::Experimental::IndexedGridNavigation< diff --git a/Plugins/Json/src/DetrayJsonHelper.cpp b/Plugins/Json/src/DetrayJsonHelper.cpp index d17e6cee1d5..9accb3d9f2b 100644 --- a/Plugins/Json/src/DetrayJsonHelper.cpp +++ b/Plugins/Json/src/DetrayJsonHelper.cpp @@ -64,29 +64,25 @@ void addVolumeLink(nlohmann::json& jSurface, int vLink) { jSurface["volume_link"] = vLink; } -std::size_t accelerationLink(std::span casts) { +std::size_t accelerationLink(std::span casts) { // Default is `brute_force` + using enum AxisDirection; std::size_t accLink = 0u; if (casts.size() == 2u) { - if (casts[0u] == BinningValue::binX && casts[1u] == BinningValue::binY) { + if (casts[0u] == AxisX && casts[1u] == AxisY) { accLink = 1u; - } else if (casts[0u] == BinningValue::binR && - casts[1u] == BinningValue::binPhi) { + } else if (casts[0u] == AxisR && casts[1u] == AxisPhi) { accLink = 3u; - } else if (casts[0u] == BinningValue::binZ && - casts[1u] == BinningValue::binPhi) { + } else if (casts[0u] == AxisZ && casts[1u] == AxisPhi) { accLink = 4u; - } else if (casts[0u] == BinningValue::binZ && - casts[1u] == BinningValue::binR) { + } else if (casts[0u] == AxisZ && casts[1u] == AxisR) { accLink = 5u; } } else if (casts.size() == 3u) { - if (casts[0u] == BinningValue::binX && casts[1u] == BinningValue::binY && - casts[2u] == BinningValue::binZ) { + if (casts[0u] == AxisX && casts[1u] == AxisY && casts[2u] == AxisZ) { accLink = 2u; - } else if (casts[0u] == BinningValue::binZ && - casts[1u] == BinningValue::binPhi && - casts[2u] == BinningValue::binR) { + } else if (casts[0u] == AxisZ && casts[1u] == AxisPhi && + casts[2u] == AxisR) { accLink = 5u; } } diff --git a/Plugins/Json/src/ExtentJsonConverter.cpp b/Plugins/Json/src/ExtentJsonConverter.cpp index 67b501c79f4..3dfba75f2c1 100644 --- a/Plugins/Json/src/ExtentJsonConverter.cpp +++ b/Plugins/Json/src/ExtentJsonConverter.cpp @@ -22,9 +22,9 @@ void Acts::to_json(nlohmann::json& j, const Acts::Extent& e) { { nlohmann::json jrange; const auto& xrange = e.range(); - for (auto ibv : allBinningValues()) { + for (auto ibv : allAxisDirections()) { if (e.constrains(ibv)) { - jrange[binningValueName(ibv)] = xrange[toUnderlying(ibv)]; + jrange[axisDirectionName(ibv)] = xrange[toUnderlying(ibv)]; } } j["range"] = jrange; @@ -33,9 +33,9 @@ void Acts::to_json(nlohmann::json& j, const Acts::Extent& e) { { nlohmann::json jenvelope; const auto& envelope = e.envelope(); - for (auto ibv : allBinningValues()) { + for (auto ibv : allAxisDirections()) { if (envelope[ibv] != zeroEnvelope) { - jenvelope[binningValueName(ibv)] = + jenvelope[axisDirectionName(ibv)] = Range1D(envelope[ibv][0], envelope[ibv][1]); } } @@ -49,7 +49,7 @@ void Acts::from_json(const nlohmann::json& j, Acts::Extent& e) { const auto& jrange = j["range"]; for (const auto& [key, value] : jrange.items()) { - BinningValue bval = binningValueFromName(key); + AxisDirection bval = axisDirectionFromName(key); e.set(bval, value["min"], value["max"]); } @@ -58,7 +58,7 @@ void Acts::from_json(const nlohmann::json& j, Acts::Extent& e) { ExtentEnvelope envelope; for (const auto& [key, value] : jenvelope.items()) { - BinningValue bval = binningValueFromName(key); + AxisDirection bval = axisDirectionFromName(key); envelope[bval] = {value["min"], value["max"]}; } diff --git a/Plugins/Json/src/GridJsonConverter.cpp b/Plugins/Json/src/GridJsonConverter.cpp index 478224bc163..082b7002a0c 100644 --- a/Plugins/Json/src/GridJsonConverter.cpp +++ b/Plugins/Json/src/GridJsonConverter.cpp @@ -55,7 +55,7 @@ void encodeSubspace( const Subspace* subspace = dynamic_cast(&globalToGridLocal); if (subspace != nullptr) { jGlobalToGridLocal["type"] = "subspace"; - jGlobalToGridLocal["accessors"] = subspace->bValues; + jGlobalToGridLocal["accessors"] = subspace->axisDirs; } } @@ -96,13 +96,13 @@ void encodeSubspaces( } } -template +template std::unique_ptr> decodeSubspace( const nlohmann::json& /*j*/) { return std::make_unique>(); } -template +template std::unique_ptr>> decodeTransformedSubspace(const nlohmann::json& jGlobalToGridLocal) { @@ -114,7 +114,7 @@ decodeTransformedSubspace(const nlohmann::json& jGlobalToGridLocal) { transform); } -template +template std::unique_ptr decodeGeneralSubspace(const nlohmann::json& jGlobalToGridLocal) { if (jGlobalToGridLocal.find("transform") != jGlobalToGridLocal.end()) { @@ -123,7 +123,7 @@ decodeGeneralSubspace(const nlohmann::json& jGlobalToGridLocal) { return decodeSubspace(jGlobalToGridLocal); } -template +template void decorateGlobalDelegate(Delegate& delegate, const nlohmann::json& jGlobalToGridLocal) { // The delegate has already been connected @@ -136,8 +136,9 @@ void decorateGlobalDelegate(Delegate& delegate, jGlobalToGridLocal.find("transform") != jGlobalToGridLocal.end(); // Get the accessors - std::vector accessors = - jGlobalToGridLocal.at("accessors").get>(); + std::vector accessors = + jGlobalToGridLocal.at("accessors") + .get>(); // One dimensional setting if constexpr (sizeof...(Args) == 1u) { @@ -179,7 +180,7 @@ void decorateGlobalDelegate(Delegate& delegate, } } -template +template void decorateGlobal1DimDelegate( Acts::GridAccess::GlobalToGridLocal1DimDelegate& delegate, const nlohmann::json& jGlobalToGridLocal) { @@ -197,12 +198,12 @@ nlohmann::json Acts::GridAccessJsonConverter::toJson( std::array transformOptions = {false, true}; // One dimensional sub spaces - const std::tuple, - GridAccess::GlobalSubspace, - GridAccess::GlobalSubspace, - GridAccess::GlobalSubspace, - GridAccess::GlobalSubspace, - GridAccess::GlobalSubspace> + const std::tuple, + GridAccess::GlobalSubspace, + GridAccess::GlobalSubspace, + GridAccess::GlobalSubspace, + GridAccess::GlobalSubspace, + GridAccess::GlobalSubspace> oneDimSubspaces = {}; for (bool transform : transformOptions) { @@ -215,16 +216,16 @@ nlohmann::json Acts::GridAccessJsonConverter::toJson( // Useful two dimensional sub spaces const std::tuple< - GridAccess::GlobalSubspace, - GridAccess::GlobalSubspace, - GridAccess::GlobalSubspace, - GridAccess::GlobalSubspace, - GridAccess::GlobalSubspace, - GridAccess::GlobalSubspace, - GridAccess::GlobalSubspace, - GridAccess::GlobalSubspace, - GridAccess::GlobalSubspace, - GridAccess::GlobalSubspace> + GridAccess::GlobalSubspace, + GridAccess::GlobalSubspace, + GridAccess::GlobalSubspace, + GridAccess::GlobalSubspace, + GridAccess::GlobalSubspace, + GridAccess::GlobalSubspace, + GridAccess::GlobalSubspace, + GridAccess::GlobalSubspace, + GridAccess::GlobalSubspace, + GridAccess::GlobalSubspace> twoDimSubspaces = {}; for (bool transform : transformOptions) { @@ -243,35 +244,35 @@ Acts::GridAccessJsonConverter::globalToGridLocalFromJson( std::unique_ptr globalToGridLocal = nullptr; - std::vector accessors = - jGlobalToGridLocal.at("accessors").get>(); + std::vector accessors = + jGlobalToGridLocal.at("accessors").get>(); // Switch and fill for 1D if (accessors.size() == 1u) { switch (accessors[0]) { - case BinningValue::binX: + case AxisDirection::AxisX: globalToGridLocal = - decodeGeneralSubspace(jGlobalToGridLocal); + decodeGeneralSubspace(jGlobalToGridLocal); break; - case BinningValue::binY: + case AxisDirection::AxisY: globalToGridLocal = - decodeGeneralSubspace(jGlobalToGridLocal); + decodeGeneralSubspace(jGlobalToGridLocal); break; - case BinningValue::binZ: + case AxisDirection::AxisZ: globalToGridLocal = - decodeGeneralSubspace(jGlobalToGridLocal); + decodeGeneralSubspace(jGlobalToGridLocal); break; - case BinningValue::binR: + case AxisDirection::AxisR: globalToGridLocal = - decodeGeneralSubspace(jGlobalToGridLocal); + decodeGeneralSubspace(jGlobalToGridLocal); break; - case BinningValue::binPhi: + case AxisDirection::AxisPhi: globalToGridLocal = - decodeGeneralSubspace(jGlobalToGridLocal); + decodeGeneralSubspace(jGlobalToGridLocal); break; - case BinningValue::binEta: + case AxisDirection::AxisEta: globalToGridLocal = - decodeGeneralSubspace(jGlobalToGridLocal); + decodeGeneralSubspace(jGlobalToGridLocal); break; default: // globalToGridLocal = nullptr; @@ -281,55 +282,55 @@ Acts::GridAccessJsonConverter::globalToGridLocalFromJson( // Switch and fill for 2D if (accessors.size() == 2u) { - if (accessors == - std::vector{BinningValue::binX, BinningValue::binY}) { + if (accessors == std::vector{AxisDirection::AxisX, + AxisDirection::AxisY}) { globalToGridLocal = - decodeGeneralSubspace( + decodeGeneralSubspace( jGlobalToGridLocal); - } else if (accessors == std::vector{BinningValue::binY, - BinningValue::binX}) { + } else if (accessors == std::vector{AxisDirection::AxisY, + AxisDirection::AxisX}) { globalToGridLocal = - decodeGeneralSubspace( + decodeGeneralSubspace( jGlobalToGridLocal); - } else if (accessors == std::vector{BinningValue::binX, - BinningValue::binZ}) { + } else if (accessors == std::vector{AxisDirection::AxisX, + AxisDirection::AxisZ}) { globalToGridLocal = - decodeGeneralSubspace( + decodeGeneralSubspace( jGlobalToGridLocal); - } else if (accessors == std::vector{BinningValue::binZ, - BinningValue::binX}) { + } else if (accessors == std::vector{AxisDirection::AxisZ, + AxisDirection::AxisX}) { globalToGridLocal = - decodeGeneralSubspace( + decodeGeneralSubspace( jGlobalToGridLocal); - } else if (accessors == std::vector{BinningValue::binY, - BinningValue::binZ}) { + } else if (accessors == std::vector{AxisDirection::AxisY, + AxisDirection::AxisZ}) { globalToGridLocal = - decodeGeneralSubspace( + decodeGeneralSubspace( jGlobalToGridLocal); - } else if (accessors == std::vector{BinningValue::binZ, - BinningValue::binY}) { + } else if (accessors == std::vector{AxisDirection::AxisZ, + AxisDirection::AxisY}) { globalToGridLocal = - decodeGeneralSubspace( + decodeGeneralSubspace( jGlobalToGridLocal); - } else if (accessors == std::vector{BinningValue::binR, - BinningValue::binPhi}) { + } else if (accessors == std::vector{ + AxisDirection::AxisR, AxisDirection::AxisPhi}) { globalToGridLocal = - decodeGeneralSubspace( + decodeGeneralSubspace( jGlobalToGridLocal); - } else if (accessors == std::vector{BinningValue::binPhi, - BinningValue::binR}) { + } else if (accessors == std::vector{AxisDirection::AxisPhi, + AxisDirection::AxisR}) { globalToGridLocal = - decodeGeneralSubspace( + decodeGeneralSubspace( jGlobalToGridLocal); - } else if (accessors == std::vector{BinningValue::binZ, - BinningValue::binPhi}) { + } else if (accessors == std::vector{ + AxisDirection::AxisZ, AxisDirection::AxisPhi}) { globalToGridLocal = - decodeGeneralSubspace( + decodeGeneralSubspace( jGlobalToGridLocal); - } else if (accessors == std::vector{BinningValue::binPhi, - BinningValue::binZ}) { + } else if (accessors == std::vector{AxisDirection::AxisPhi, + AxisDirection::AxisZ}) { globalToGridLocal = - decodeGeneralSubspace( + decodeGeneralSubspace( jGlobalToGridLocal); } // else globalToGridLocal = nullptr; @@ -347,9 +348,9 @@ Acts::GridAccessJsonConverter::globalToGridLocal1DimDelegateFromJson( } // Unroll the decoration Acts::GridAccess::GlobalToGridLocal1DimDelegate delegate; - decorateGlobal1DimDelegate( + decorateGlobal1DimDelegate( delegate, jGlobalToGridLocal); return delegate; } @@ -367,34 +368,34 @@ Acts::GridAccessJsonConverter::globalToGridLocal2DimDelegateFromJson( // Only the matching one will be applied, matching condition is checked inside // the call - may unroll this es well decorateGlobalDelegate( + AxisDirection::AxisX, AxisDirection::AxisY>( delegate, jGlobalToGridLocal); decorateGlobalDelegate( + AxisDirection::AxisY, AxisDirection::AxisX>( delegate, jGlobalToGridLocal); decorateGlobalDelegate( + AxisDirection::AxisX, AxisDirection::AxisZ>( delegate, jGlobalToGridLocal); decorateGlobalDelegate( + AxisDirection::AxisZ, AxisDirection::AxisX>( delegate, jGlobalToGridLocal); decorateGlobalDelegate( + AxisDirection::AxisY, AxisDirection::AxisZ>( delegate, jGlobalToGridLocal); decorateGlobalDelegate( + AxisDirection::AxisZ, AxisDirection::AxisY>( delegate, jGlobalToGridLocal); decorateGlobalDelegate( + AxisDirection::AxisR, AxisDirection::AxisPhi>( delegate, jGlobalToGridLocal); decorateGlobalDelegate( + AxisDirection::AxisPhi, AxisDirection::AxisR>( delegate, jGlobalToGridLocal); decorateGlobalDelegate( + AxisDirection::AxisZ, AxisDirection::AxisPhi>( delegate, jGlobalToGridLocal); decorateGlobalDelegate( + AxisDirection::AxisPhi, AxisDirection::AxisZ>( delegate, jGlobalToGridLocal); return delegate; } diff --git a/Plugins/Json/src/IndexedSurfacesJsonConverter.cpp b/Plugins/Json/src/IndexedSurfacesJsonConverter.cpp index 40548ede336..9e2930eef1b 100644 --- a/Plugins/Json/src/IndexedSurfacesJsonConverter.cpp +++ b/Plugins/Json/src/IndexedSurfacesJsonConverter.cpp @@ -37,7 +37,7 @@ struct IndexedSurfacesGenerator { template Acts::Experimental::InternalNavigationDelegate createUpdater( grid_type&& grid, - const std::array& bv, + const std::array& bv, const Acts::Transform3& transform) { Acts::Experimental::IndexedSurfacesNavigation indexedSurfaces( std::forward(grid), bv, transform); diff --git a/Plugins/Json/src/MaterialJsonConverter.cpp b/Plugins/Json/src/MaterialJsonConverter.cpp index ce582850e3c..f6f722ef826 100644 --- a/Plugins/Json/src/MaterialJsonConverter.cpp +++ b/Plugins/Json/src/MaterialJsonConverter.cpp @@ -686,14 +686,14 @@ nlohmann::json Acts::MaterialJsonConverter::toJsonDetray( BinUtility bUtility = binnedMaterial->binUtility(); // Turn the bin value into a 2D grid if (bUtility.dimensions() == 1u) { - if (bUtility.binningData()[0u].binvalue == BinningValue::binR) { + if (bUtility.binningData()[0u].binvalue == AxisDirection::AxisR) { // Turn to R-Phi bUtility += BinUtility(1u, -std::numbers::pi, std::numbers::pi, closed, - BinningValue::binPhi); - } else if (bUtility.binningData()[0u].binvalue == BinningValue::binZ) { + AxisDirection::AxisPhi); + } else if (bUtility.binningData()[0u].binvalue == AxisDirection::AxisZ) { // Turn to Phi-Z - swap needed BinUtility nbUtility(1u, -std::numbers::pi, std::numbers::pi, closed, - BinningValue::binPhi); + AxisDirection::AxisPhi); nbUtility += bUtility; bUtility = std::move(nbUtility); swapped = true; @@ -701,24 +701,25 @@ nlohmann::json Acts::MaterialJsonConverter::toJsonDetray( std::runtime_error("Unsupported binning for Detray"); } } else if (bUtility.dimensions() == 2u && - bUtility.binningData()[0u].binvalue == BinningValue::binZ && - bUtility.binningData()[1u].binvalue == BinningValue::binPhi) { + bUtility.binningData()[0u].binvalue == AxisDirection::AxisZ && + bUtility.binningData()[1u].binvalue == AxisDirection::AxisPhi) { BinUtility nbUtility(bUtility.binningData()[1u]); - nbUtility += bUtility.binningData()[0u]; + nbUtility += BinUtility{bUtility.binningData()[0u]}; bUtility = std::move(nbUtility); swapped = true; } - BinningValue bVal0 = bUtility.binningData()[0u].binvalue; - BinningValue bVal1 = bUtility.binningData()[1u].binvalue; + AxisDirection bVal0 = bUtility.binningData()[0u].binvalue; + AxisDirection bVal1 = bUtility.binningData()[1u].binvalue; // Translate into grid index type int gridIndexType = 0; - if (bVal0 == BinningValue::binR && bVal1 == BinningValue::binPhi) { + if (bVal0 == AxisDirection::AxisR && bVal1 == AxisDirection::AxisPhi) { gridIndexType = 0; - } else if (bVal0 == BinningValue::binPhi && bVal1 == BinningValue::binZ) { + } else if (bVal0 == AxisDirection::AxisPhi && + bVal1 == AxisDirection::AxisZ) { gridIndexType = 3; - } else if (bVal0 == BinningValue::binX && bVal1 == BinningValue::binY) { + } else if (bVal0 == AxisDirection::AxisX && bVal1 == AxisDirection::AxisY) { gridIndexType = 2; } else { std::runtime_error("Unsupported binning for Detray"); @@ -801,7 +802,7 @@ nlohmann::json Acts::MaterialJsonConverter::toJsonDetray( jAxis["label"] = ib; jAxis["bins"] = bData.bins(); double offset = 0; - if (bData.binvalue == BinningValue::binZ) { + if (bData.binvalue == AxisDirection::AxisZ) { offset = surface.center(Acts::GeometryContext{}).z(); } jAxis["edges"] = diff --git a/Plugins/Json/src/MaterialMapJsonConverter.cpp b/Plugins/Json/src/MaterialMapJsonConverter.cpp index dc423ecc50b..51211ac2386 100644 --- a/Plugins/Json/src/MaterialMapJsonConverter.cpp +++ b/Plugins/Json/src/MaterialMapJsonConverter.cpp @@ -119,9 +119,9 @@ Acts::SurfaceAndMaterialWithContext defaultSurfaceMaterial( std::numbers::pi) < Acts::s_epsilon ? Acts::closed : Acts::open, - Acts::BinningValue::binPhi); + Acts::AxisDirection::AxisPhi); bUtility += Acts::BinUtility(1, radialBounds->rMin(), radialBounds->rMax(), - Acts::open, Acts::BinningValue::binR); + Acts::open, Acts::AxisDirection::AxisR); } if (cylinderBounds != nullptr) { bUtility += Acts::BinUtility( @@ -134,41 +134,41 @@ Acts::SurfaceAndMaterialWithContext defaultSurfaceMaterial( std::numbers::pi) < Acts::s_epsilon ? Acts::closed : Acts::open, - Acts::BinningValue::binPhi); + Acts::AxisDirection::AxisPhi); bUtility += Acts::BinUtility( 1, -1 * cylinderBounds->get(Acts::CylinderBounds::eHalfLengthZ), cylinderBounds->get(Acts::CylinderBounds::eHalfLengthZ), Acts::open, - Acts::BinningValue::binZ); + Acts::AxisDirection::AxisZ); } if (annulusBounds != nullptr) { bUtility += Acts::BinUtility(1, annulusBounds->get(Acts::AnnulusBounds::eMinPhiRel), annulusBounds->get(Acts::AnnulusBounds::eMaxPhiRel), - Acts::open, Acts::BinningValue::binPhi); + Acts::open, Acts::AxisDirection::AxisPhi); bUtility += Acts::BinUtility(1, static_cast(annulusBounds->rMin()), static_cast(annulusBounds->rMax()), - Acts::open, Acts::BinningValue::binR); + Acts::open, Acts::AxisDirection::AxisR); } if (rectangleBounds != nullptr) { bUtility += Acts::BinUtility(1, rectangleBounds->get(Acts::RectangleBounds::eMinX), rectangleBounds->get(Acts::RectangleBounds::eMaxX), - Acts::open, Acts::BinningValue::binX); + Acts::open, Acts::AxisDirection::AxisX); bUtility += Acts::BinUtility(1, rectangleBounds->get(Acts::RectangleBounds::eMinY), rectangleBounds->get(Acts::RectangleBounds::eMaxY), - Acts::open, Acts::BinningValue::binY); + Acts::open, Acts::AxisDirection::AxisY); } if (trapezoidBounds != nullptr) { double halfLengthX = std::max(trapezoidBounds->get(Acts::TrapezoidBounds::eHalfLengthXnegY), trapezoidBounds->get(Acts::TrapezoidBounds::eHalfLengthXposY)); bUtility += Acts::BinUtility(1, -1 * halfLengthX, halfLengthX, Acts::open, - Acts::BinningValue::binX); + Acts::AxisDirection::AxisX); bUtility += Acts::BinUtility( 1, -1 * trapezoidBounds->get(Acts::TrapezoidBounds::eHalfLengthY), trapezoidBounds->get(Acts::TrapezoidBounds::eHalfLengthY), Acts::open, - Acts::BinningValue::binY); + Acts::AxisDirection::AxisY); } return {surface, std::make_shared(bUtility), context}; @@ -192,7 +192,7 @@ Acts::TrackingVolumeAndMaterial defaultVolumeMaterial( bUtility += Acts::BinUtility(1, cyBounds->get(Acts::CylinderVolumeBounds::eMinR), cyBounds->get(Acts::CylinderVolumeBounds::eMaxR), - Acts::open, Acts::BinningValue::binR); + Acts::open, Acts::AxisDirection::AxisR); bUtility += Acts::BinUtility( 1, -cyBounds->get(Acts::CylinderVolumeBounds::eHalfPhiSector), cyBounds->get(Acts::CylinderVolumeBounds::eHalfPhiSector), @@ -200,37 +200,37 @@ Acts::TrackingVolumeAndMaterial defaultVolumeMaterial( std::numbers::pi) < Acts::s_epsilon ? Acts::closed : Acts::open, - Acts::BinningValue::binPhi); + Acts::AxisDirection::AxisPhi); bUtility += Acts::BinUtility( 1, -cyBounds->get(Acts::CylinderVolumeBounds::eHalfLengthZ), cyBounds->get(Acts::CylinderVolumeBounds::eHalfLengthZ), Acts::open, - Acts::BinningValue::binZ); + Acts::AxisDirection::AxisZ); } if (cutcylBounds != nullptr) { bUtility += Acts::BinUtility( 1, cutcylBounds->get(Acts::CutoutCylinderVolumeBounds::eMinR), cutcylBounds->get(Acts::CutoutCylinderVolumeBounds::eMaxR), Acts::open, - Acts::BinningValue::binR); + Acts::AxisDirection::AxisR); bUtility += Acts::BinUtility(1, -std::numbers::pi_v, std::numbers::pi_v, Acts::closed, - Acts::BinningValue::binPhi); + Acts::AxisDirection::AxisPhi); bUtility += Acts::BinUtility( 1, -cutcylBounds->get(Acts::CutoutCylinderVolumeBounds::eHalfLengthZ), cutcylBounds->get(Acts::CutoutCylinderVolumeBounds::eHalfLengthZ), - Acts::open, Acts::BinningValue::binZ); + Acts::open, Acts::AxisDirection::AxisZ); } else if (cuBounds != nullptr) { bUtility += Acts::BinUtility( 1, -cuBounds->get(Acts::CuboidVolumeBounds::eHalfLengthX), cuBounds->get(Acts::CuboidVolumeBounds::eHalfLengthX), Acts::open, - Acts::BinningValue::binX); + Acts::AxisDirection::AxisX); bUtility += Acts::BinUtility( 1, -cuBounds->get(Acts::CuboidVolumeBounds::eHalfLengthY), cuBounds->get(Acts::CuboidVolumeBounds::eHalfLengthY), Acts::open, - Acts::BinningValue::binY); + Acts::AxisDirection::AxisY); bUtility += Acts::BinUtility( 1, -cuBounds->get(Acts::CuboidVolumeBounds::eHalfLengthZ), cuBounds->get(Acts::CuboidVolumeBounds::eHalfLengthZ), Acts::open, - Acts::BinningValue::binZ); + Acts::AxisDirection::AxisZ); } return {volume, std::make_shared(bUtility)}; } diff --git a/Plugins/Json/src/PortalJsonConverter.cpp b/Plugins/Json/src/PortalJsonConverter.cpp index 3fb7e4865a3..0178bc71234 100644 --- a/Plugins/Json/src/PortalJsonConverter.cpp +++ b/Plugins/Json/src/PortalJsonConverter.cpp @@ -157,13 +157,13 @@ Acts::PortalJsonConverter::toJsonDetray( std::array clipRange = {0., 0.}; std::vector boundValues = surfaceAdjusted->bounds().values(); if (surfaceType == Surface::SurfaceType::Cylinder && - cast == BinningValue::binZ) { + cast == AxisDirection::AxisZ) { double zPosition = surfaceAdjusted->center(gctx).z(); clipRange = { zPosition - boundValues[CylinderBounds::BoundValues::eHalfLengthZ], zPosition + boundValues[CylinderBounds::BoundValues::eHalfLengthZ]}; } else if (surfaceType == Surface::SurfaceType::Disc && - cast == BinningValue::binR) { + cast == AxisDirection::AxisR) { clipRange = {boundValues[RadialBounds::BoundValues::eMinR], boundValues[RadialBounds::BoundValues::eMaxR]}; } else { @@ -319,8 +319,8 @@ std::shared_ptr Acts::PortalJsonConverter::fromJson( } auto portal = std::make_shared(regSurface); - std::array normalDirs = {Direction::Backward, - Direction::Forward}; + std::array normalDirs = {Direction::Backward(), + Direction::Forward()}; // re-create the volume links auto jLinks = jPortal["volume_links"]; for (auto [ivl, vl] : enumerate(jLinks)) { @@ -332,7 +332,7 @@ std::shared_ptr Acts::PortalJsonConverter::fromJson( // Resolve the multi link 1D auto jMultiLink = vl["multi_1D"]; auto boundaries = jMultiLink["boundaries"].get>(); - auto binning = jMultiLink["binning"].get(); + auto binning = jMultiLink["binning"].get(); auto targets = jMultiLink["targets"].get>(); std::vector> targetVolumes; for (const auto t : targets) { diff --git a/Plugins/Json/src/ProtoAxisJsonConverter.cpp b/Plugins/Json/src/ProtoAxisJsonConverter.cpp new file mode 100644 index 00000000000..3a47450be0a --- /dev/null +++ b/Plugins/Json/src/ProtoAxisJsonConverter.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 "Acts/Plugins/Json/ProtoAxisJsonConverter.hpp" + +#include "Acts/Plugins/Json/GridJsonConverter.hpp" +#include "Acts/Plugins/Json/UtilitiesJsonConverter.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" + +nlohmann::json Acts::ProtoAxisJsonConverter::toJson(const Acts::ProtoAxis& pa) { + nlohmann::json j; + j["axis_dir"] = pa.getAxisDirection(); + j["axis"] = AxisJsonConverter::toJson(pa.getAxis()); + j["autorange"] = pa.isAutorange(); + return j; +} + +Acts::ProtoAxis Acts::ProtoAxisJsonConverter::fromJson( + const nlohmann::json& j) { + auto axisDir = j.at("axis_dir").get(); + auto axisBoundaryType = + j.at("axis").at("boundary_type").get(); + if (auto axisType = j.at("axis").at("type").get(); + axisType == AxisType::Equidistant) { + auto nbins = j.at("axis").at("bins").get(); + if (nbins == 0) { + throw std::invalid_argument("Number of bins must be positive"); + } + + if (j.at("autorange").get()) { + return ProtoAxis(axisDir, axisBoundaryType, nbins); + } + auto min = j.at("axis").at("range").at(0).get(); + auto max = j.at("axis").at("range").at(1).get(); + if (min >= max) { + throw std::invalid_argument("Invalid range: min must be less than max"); + } + return ProtoAxis(axisDir, axisBoundaryType, min, max, nbins); + } + auto binEdges = j.at("axis").at("boundaries").get>(); + if (binEdges.size() < 2) { + throw std::invalid_argument("At least two bin edges required"); + } + if (!std::ranges::is_sorted(binEdges)) { + throw std::invalid_argument("Bin edges must be sorted in ascending order"); + } + return ProtoAxis(axisDir, axisBoundaryType, binEdges); +} diff --git a/Plugins/Json/src/UtilitiesJsonConverter.cpp b/Plugins/Json/src/UtilitiesJsonConverter.cpp index 558bb8aa048..6bb186b120b 100644 --- a/Plugins/Json/src/UtilitiesJsonConverter.cpp +++ b/Plugins/Json/src/UtilitiesJsonConverter.cpp @@ -54,7 +54,37 @@ void Acts::from_json(const nlohmann::json& j, BinningData& bd) { float min = j["min"]; float max = j["max"]; int bins = j["bins"]; - auto bValue = j["value"].get(); + + // Support legacy format with BinningValue instead of AxisDirection, + // this will anyway disappear with the removal of BinUtility + AxisDirection bValue = AxisDirection::AxisX; + if (j["value"].get().substr(0, 3) == "bin") { + std::string bValueStr = j["value"]; + if (bValueStr == "binX") { + bValue = AxisDirection::AxisX; + } else if (bValueStr == "binY") { + bValue = AxisDirection::AxisY; + } else if (bValueStr == "binZ") { + bValue = AxisDirection::AxisZ; + } else if (bValueStr == "binR") { + bValue = AxisDirection::AxisR; + } else if (bValueStr == "binPhi") { + bValue = AxisDirection::AxisPhi; + } else if (bValueStr == "binRPhi") { + bValue = AxisDirection::AxisRPhi; + } else if (bValueStr == "binH") { + bValue = AxisDirection::AxisTheta; + } else if (bValueStr == "binEta") { + bValue = AxisDirection::AxisEta; + } else if (bValueStr == "binMag") { + bValue = AxisDirection::AxisMag; + } else { + throw std::invalid_argument("Unknown binning value name: " + bValueStr); + } + } else { + bValue = j["value"].get(); + } + if (bins == 1 && !(j["type"] == "arbitrary")) { bd = BinningData(bValue, min, max); return; diff --git a/Plugins/Podio/include/Acts/Plugins/Podio/PodioTrackStateContainer.hpp b/Plugins/Podio/include/Acts/Plugins/Podio/PodioTrackStateContainer.hpp index 53eebf0e9b4..2a5d1b799bf 100644 --- a/Plugins/Podio/include/Acts/Plugins/Podio/PodioTrackStateContainer.hpp +++ b/Plugins/Podio/include/Acts/Plugins/Podio/PodioTrackStateContainer.hpp @@ -619,13 +619,11 @@ class MutablePodioTrackStateContainer final void allocateCalibrated_impl(IndexType istate, const Eigen::DenseBase& val, const Eigen::DenseBase& cov) - - requires(Eigen::PlainObjectBase::RowsAtCompileTime > 0 && - Eigen::PlainObjectBase::RowsAtCompileTime <= eBoundSize && - Eigen::PlainObjectBase::RowsAtCompileTime == - Eigen::PlainObjectBase::RowsAtCompileTime && - Eigen::PlainObjectBase::RowsAtCompileTime == - Eigen::PlainObjectBase::ColsAtCompileTime) + requires(Concepts::eigen_base_is_fixed_size && + Eigen::PlainObjectBase::RowsAtCompileTime <= + toUnderlying(eBoundSize) && + Concepts::eigen_bases_have_same_num_rows && + Concepts::eigen_base_is_square) { constexpr std::size_t measdim = val_t::RowsAtCompileTime; diff --git a/Plugins/TGeo/include/Acts/Plugins/TGeo/TGeoLayerBuilder.hpp b/Plugins/TGeo/include/Acts/Plugins/TGeo/TGeoLayerBuilder.hpp index 8bd87122332..bf2eb7e9916 100644 --- a/Plugins/TGeo/include/Acts/Plugins/TGeo/TGeoLayerBuilder.hpp +++ b/Plugins/TGeo/include/Acts/Plugins/TGeo/TGeoLayerBuilder.hpp @@ -58,9 +58,9 @@ class TGeoLayerBuilder : public ILayerBuilder { /// Helper config structs for volume parsing struct LayerConfig { public: - using RangeConfig = std::pair>; + using RangeConfig = std::pair>; - using SplitConfig = std::pair; + using SplitConfig = std::pair; /// Identify the search volume by name std::string volumeName = ""; diff --git a/Plugins/TGeo/include/Acts/Plugins/TGeo/TGeoParser.hpp b/Plugins/TGeo/include/Acts/Plugins/TGeo/TGeoParser.hpp index 3a99a008819..a59743a5b46 100644 --- a/Plugins/TGeo/include/Acts/Plugins/TGeo/TGeoParser.hpp +++ b/Plugins/TGeo/include/Acts/Plugins/TGeo/TGeoParser.hpp @@ -10,7 +10,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/Units.hpp" -#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include #include @@ -69,7 +69,7 @@ struct TGeoParser { /// Scaling from TGeo to ROOT double unit = 1 * UnitConstants::cm; /// Parse restrictions, several can apply - std::vector > parseRanges = {}; + std::vector > parseRanges = {}; }; /// The parsing module, it takes the top Volume and recursively steps down diff --git a/Plugins/TGeo/src/TGeoLayerBuilder.cpp b/Plugins/TGeo/src/TGeoLayerBuilder.cpp index 73cd8bb25ec..3cbce625c7c 100644 --- a/Plugins/TGeo/src/TGeoLayerBuilder.cpp +++ b/Plugins/TGeo/src/TGeoLayerBuilder.cpp @@ -150,12 +150,12 @@ void Acts::TGeoLayerBuilder::buildLayers(const GeometryContext& gctx, ProtoLayer pl(gctx, lSurfaces); ACTS_DEBUG("- creating CylinderLayer with " << lSurfaces.size() - << " surfaces at r = " << pl.medium(BinningValue::binR)); + << " surfaces at r = " << pl.medium(AxisDirection::AxisR)); - pl.envelope[Acts::BinningValue::binR] = {lCfg.envelope.first, - lCfg.envelope.second}; - pl.envelope[Acts::BinningValue::binZ] = {lCfg.envelope.second, - lCfg.envelope.second}; + pl.envelope[Acts::AxisDirection::AxisR] = {lCfg.envelope.first, + lCfg.envelope.second}; + pl.envelope[Acts::AxisDirection::AxisZ] = {lCfg.envelope.second, + lCfg.envelope.second}; if (nb0 >= 0 && nb1 >= 0) { layers.push_back( m_cfg.layerCreator->cylinderLayer(gctx, lSurfaces, nb0, nb1, pl)); @@ -167,12 +167,12 @@ void Acts::TGeoLayerBuilder::buildLayers(const GeometryContext& gctx, ProtoLayer pl(gctx, lSurfaces); ACTS_DEBUG("- creating DiscLayer with " << lSurfaces.size() - << " surfaces at z = " << pl.medium(BinningValue::binZ)); + << " surfaces at z = " << pl.medium(AxisDirection::AxisZ)); - pl.envelope[Acts::BinningValue::binR] = {lCfg.envelope.first, - lCfg.envelope.second}; - pl.envelope[Acts::BinningValue::binZ] = {lCfg.envelope.second, - lCfg.envelope.second}; + pl.envelope[Acts::AxisDirection::AxisR] = {lCfg.envelope.first, + lCfg.envelope.second}; + pl.envelope[Acts::AxisDirection::AxisZ] = {lCfg.envelope.second, + lCfg.envelope.second}; if (nb0 >= 0 && nb1 >= 0) { layers.push_back( m_cfg.layerCreator->discLayer(gctx, lSurfaces, nb0, nb1, pl)); @@ -192,7 +192,7 @@ void Acts::TGeoLayerBuilder::buildLayers(const GeometryContext& gctx, if (!layerCfg.parseRanges.empty()) { for (const auto& pRange : layerCfg.parseRanges) { ACTS_DEBUG("- layer parsing restricted in " - << binningValueName(pRange.first) << " to [" + << axisDirectionName(pRange.first) << " to [" << pRange.second.first << "/" << pRange.second.second << "]."); } @@ -200,7 +200,7 @@ void Acts::TGeoLayerBuilder::buildLayers(const GeometryContext& gctx, if (!layerCfg.splitConfigs.empty()) { for (const auto& sConfig : layerCfg.splitConfigs) { ACTS_DEBUG("- layer splitting attempt in " - << binningValueName(sConfig.first) << " with tolerance " + << axisDirectionName(sConfig.first) << " with tolerance " << sConfig.second << "."); } } @@ -240,7 +240,7 @@ void Acts::TGeoLayerBuilder::buildLayers(const GeometryContext& gctx, ACTS_DEBUG("- applying " << layerCfg.parseRanges.size() << " search restrictions."); for (const auto& prange : layerCfg.parseRanges) { - ACTS_VERBOSE(" - range " << binningValueName(prange.first) + ACTS_VERBOSE(" - range " << axisDirectionName(prange.first) << " within [ " << prange.second.first << ", " << prange.second.second << "]"); } diff --git a/Tests/Benchmarks/AnnulusBoundsBenchmark.cpp b/Tests/Benchmarks/AnnulusBoundsBenchmark.cpp index 4d89df9bb41..c700c3d08d5 100644 --- a/Tests/Benchmarks/AnnulusBoundsBenchmark.cpp +++ b/Tests/Benchmarks/AnnulusBoundsBenchmark.cpp @@ -56,10 +56,10 @@ int main(int /*argc*/, char** /*argv[]*/) { cov << 1.0, 0, 0, 0.05; BoundaryTolerance bcAbs = BoundaryTolerance::None(); - BoundaryTolerance bcTol0 = BoundaryTolerance::AbsoluteBound{1.0, 0}; - BoundaryTolerance bcTol1 = BoundaryTolerance::AbsoluteBound{0, 0.2}; - BoundaryTolerance bcTol01 = BoundaryTolerance::AbsoluteBound{1.0, 0.2}; - BoundaryTolerance bcCov = BoundaryTolerance::Chi2Bound{cov, 1}; + BoundaryTolerance bcTol0 = BoundaryTolerance::AbsoluteBound(1.0, 0.0); + BoundaryTolerance bcTol1 = BoundaryTolerance::AbsoluteBound(0.0, 0.2); + BoundaryTolerance bcTol01 = BoundaryTolerance::AbsoluteBound(1.0, 0.2); + BoundaryTolerance bcCov = BoundaryTolerance::Chi2Bound(cov, 1.0); // visualization to make sense of things for (std::size_t i = 0; i < 10000; i++) { diff --git a/Tests/Benchmarks/BinUtilityBenchmark.cpp b/Tests/Benchmarks/BinUtilityBenchmark.cpp index 251503e2f73..0fcf652ecdf 100644 --- a/Tests/Benchmarks/BinUtilityBenchmark.cpp +++ b/Tests/Benchmarks/BinUtilityBenchmark.cpp @@ -50,14 +50,14 @@ int main(int argc, char* argv[]) { for (unsigned int ib = 0; ib < 6; ++ib) { fewBins.push_back(ib * 6. / 5.); } - Acts::BinUtility small(fewBins, Acts::open, Acts::BinningValue::binX); + Acts::BinUtility small(fewBins, Acts::open, Acts::AxisDirection::AxisX); std::vector mediumBins; mediumBins.reserve(21); for (unsigned int ib = 0; ib < 21; ++ib) { mediumBins.push_back(ib * 6. / 20.); } - Acts::BinUtility medium(mediumBins, Acts::open, Acts::BinningValue::binX); + Acts::BinUtility medium(mediumBins, Acts::open, Acts::AxisDirection::AxisX); std::vector manyBins; manyBins.reserve(101); @@ -65,7 +65,7 @@ int main(int argc, char* argv[]) { manyBins.push_back(ib * 6. / 100.); } - Acts::BinUtility many(manyBins, Acts::open, Acts::BinningValue::binX); + Acts::BinUtility many(manyBins, Acts::open, Acts::AxisDirection::AxisX); Acts::Vector3 low = Acts::Vector3(1.5, 0., 0.); Acts::Vector3 high = Acts::Vector3(4.5, 0., 0.); @@ -125,7 +125,7 @@ int main(int argc, char* argv[]) { ACTS_INFO("Fraction is: " << st << " vs. " << gt); Acts::BinUtility equidistant(100, 0., 6., Acts::open, - Acts::BinningValue::binX); + Acts::AxisDirection::AxisX); st = 0; gt = 0; num_iters = 0; diff --git a/Tests/CommonHelpers/Acts/Tests/CommonHelpers/CubicTrackingGeometry.hpp b/Tests/CommonHelpers/Acts/Tests/CommonHelpers/CubicTrackingGeometry.hpp index 55793113d99..9967d1b9750 100644 --- a/Tests/CommonHelpers/Acts/Tests/CommonHelpers/CubicTrackingGeometry.hpp +++ b/Tests/CommonHelpers/Acts/Tests/CommonHelpers/CubicTrackingGeometry.hpp @@ -134,7 +134,7 @@ struct CubicTrackingGeometry { layVec.push_back(layers[1]); std::unique_ptr layArr1(layArrCreator.layerArray( geoContext, layVec, -2_m - 1._mm, -1._m + 1._mm, BinningType::arbitrary, - BinningValue::binX)); + AxisDirection::AxisX)); auto trackVolume1 = std::make_shared( trafoVol1, boundsVol, nullptr, std::move(layArr1), nullptr, @@ -150,7 +150,7 @@ struct CubicTrackingGeometry { } std::unique_ptr layArr2( layArrCreator.layerArray(geoContext, layVec, 1._m - 2._mm, 2._m + 2._mm, - BinningType::arbitrary, BinningValue::binX)); + BinningType::arbitrary, AxisDirection::AxisX)); auto trackVolume2 = std::make_shared( trafoVol2, boundsVol, nullptr, std::move(layArr2), nullptr, @@ -178,7 +178,8 @@ struct CubicTrackingGeometry { std::vector binBoundaries = {-3._m, 0., 3._m}; - BinningData binData(BinningOption::open, BinningValue::binX, binBoundaries); + BinningData binData(BinningOption::open, AxisDirection::AxisX, + binBoundaries); std::unique_ptr bu(new BinUtility(binData)); std::shared_ptr trVolArr( diff --git a/Tests/CommonHelpers/Acts/Tests/CommonHelpers/CylindricalDetector.cpp b/Tests/CommonHelpers/Acts/Tests/CommonHelpers/CylindricalDetector.cpp index 7ab854d4e65..5ec9a806005 100644 --- a/Tests/CommonHelpers/Acts/Tests/CommonHelpers/CylindricalDetector.cpp +++ b/Tests/CommonHelpers/Acts/Tests/CommonHelpers/CylindricalDetector.cpp @@ -73,7 +73,7 @@ std::shared_ptr Acts::Test::buildCylindricalDetector( // Create the barrel container builder CylindricalContainerBuilder::Config barrelRCfg; barrelRCfg.builders = {barrel0, barrel1, barrel2}; - barrelRCfg.binning = {BinningValue::binR}; + barrelRCfg.binning = {AxisDirection::AxisR}; auto barrel = std::make_shared( barrelRCfg, getDefaultLogger("BarrelBuilderR", Logging::INFO)); @@ -88,7 +88,7 @@ std::shared_ptr Acts::Test::buildCylindricalDetector( // Create the barrel container builder CylindricalContainerBuilder::Config barrelEndcapCfg; barrelEndcapCfg.builders = {endcapN, barrel, endcapP}; - barrelEndcapCfg.binning = {BinningValue::binZ}; + barrelEndcapCfg.binning = {AxisDirection::AxisZ}; auto barrelEndcap = std::make_shared( barrelEndcapCfg, getDefaultLogger("BarrelEndcapBuilder", Logging::INFO)); @@ -96,7 +96,7 @@ std::shared_ptr Acts::Test::buildCylindricalDetector( // Create the barrel container builder CylindricalContainerBuilder::Config detectorCfg; detectorCfg.builders = {beampipe, barrelEndcap}; - detectorCfg.binning = {BinningValue::binR}; + detectorCfg.binning = {AxisDirection::AxisR}; auto containerBuilder = std::make_shared( detectorCfg, getDefaultLogger("DetectorBuilder", Logging::INFO)); diff --git a/Tests/CommonHelpers/Acts/Tests/CommonHelpers/CylindricalTrackingGeometry.hpp b/Tests/CommonHelpers/Acts/Tests/CommonHelpers/CylindricalTrackingGeometry.hpp index a37bbcb1e8f..84e51027a6e 100644 --- a/Tests/CommonHelpers/Acts/Tests/CommonHelpers/CylindricalTrackingGeometry.hpp +++ b/Tests/CommonHelpers/Acts/Tests/CommonHelpers/CylindricalTrackingGeometry.hpp @@ -304,7 +304,7 @@ struct CylindricalTrackingGeometry { // create the layer and store it ProtoLayer protoLayer(geoContext, layerSurfaces); - protoLayer.envelope[BinningValue::binR] = {0.5, 0.5}; + protoLayer.envelope[AxisDirection::AxisR] = {0.5, 0.5}; auto pLayer = layerCreator->cylinderLayer( geoContext, std::move(layerSurfacePtrs), pLayerBinning[ilp].first, pLayerBinning[ilp].second, protoLayer); @@ -319,7 +319,7 @@ struct CylindricalTrackingGeometry { // layer array auto pLayerArray = layerArrayCreator->layerArray( - geoContext, pLayers, 25., 300., arbitrary, BinningValue::binR); + geoContext, pLayers, 25., 300., arbitrary, AxisDirection::AxisR); auto pVolumeBounds = std::make_shared(25., 300., 1100.); // create the Tracking volume diff --git a/Tests/Data/material-map.json b/Tests/Data/material-map.json index a59a29a7d17..447fad8f872 100644 --- a/Tests/Data/material-map.json +++ b/Tests/Data/material-map.json @@ -17,7 +17,7 @@ "min": 0.0, "option": "open", "type": "equidistant", - "value": "binR" + "value": "AxisR" }, { "bins": 2, @@ -25,7 +25,7 @@ "min": -3.1415927410125732, "option": "closed", "type": "equidistant", - "value": "binPhi" + "value": "AxisPhi" }, { "bins": 2, @@ -33,7 +33,7 @@ "min": -4002.0, "option": "open", "type": "equidistant", - "value": "binZ" + "value": "AxisZ" } ] }, @@ -154,7 +154,7 @@ "min": -3.1415927410125732, "option": "open", "type": "equidistant", - "value": "binPhi" + "value": "AxisPhi" }, { "bins": 2, @@ -162,7 +162,7 @@ "min": -524.0, "option": "open", "type": "equidistant", - "value": "binZ" + "value": "AxisZ" } ] }, @@ -212,7 +212,7 @@ "min": -3.1415927410125732, "option": "open", "type": "equidistant", - "value": "binPhi" + "value": "AxisPhi" }, { "bins": 2, @@ -220,7 +220,7 @@ "min": -524.0, "option": "open", "type": "equidistant", - "value": "binZ" + "value": "AxisZ" } ] }, @@ -269,7 +269,7 @@ "min": -3.1415927410125732, "option": "open", "type": "equidistant", - "value": "binPhi" + "value": "AxisPhi" }, { "bins": 3, @@ -277,7 +277,7 @@ "min": 27.0, "option": "open", "type": "equidistant", - "value": "binR" + "value": "AxisR" } ] }, @@ -338,7 +338,7 @@ "min": -3.1415927410125732, "option": "closed", "type": "equidistant", - "value": "binPhi" + "value": "AxisPhi" }, { "bins": 3, @@ -346,7 +346,7 @@ "min": -1154.0, "option": "open", "type": "equidistant", - "value": "binZ" + "value": "AxisZ" } ] }, diff --git a/Tests/IntegrationTests/Fatras/FatrasSimulationTests.cpp b/Tests/IntegrationTests/Fatras/FatrasSimulationTests.cpp index f459feb0f24..941423f6a74 100644 --- a/Tests/IntegrationTests/Fatras/FatrasSimulationTests.cpp +++ b/Tests/IntegrationTests/Fatras/FatrasSimulationTests.cpp @@ -10,10 +10,10 @@ #include #include "Acts/Definitions/ParticleData.hpp" -#include "Acts/EventData/TrackParameters.hpp" #include "Acts/MagneticField/ConstantBField.hpp" #include "Acts/Propagator/EigenStepper.hpp" #include "Acts/Propagator/Navigator.hpp" +#include "Acts/Propagator/Propagator.hpp" #include "Acts/Propagator/StraightLineStepper.hpp" #include "Acts/Tests/CommonHelpers/CylindricalTrackingGeometry.hpp" #include "Acts/Utilities/Logger.hpp" diff --git a/Tests/IntegrationTests/NavigatorConsistency.cpp b/Tests/IntegrationTests/NavigatorConsistency.cpp index ea74491a1c0..1e997f5290b 100644 --- a/Tests/IntegrationTests/NavigatorConsistency.cpp +++ b/Tests/IntegrationTests/NavigatorConsistency.cpp @@ -11,6 +11,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/Units.hpp" +#include "Acts/EventData/TrackParameters.hpp" #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/MagneticField/ConstantBField.hpp" #include "Acts/Propagator/EigenStepper.hpp" @@ -21,6 +22,7 @@ #include "Acts/Propagator/TryAllNavigator.hpp" #include "Acts/Surfaces/BoundaryTolerance.hpp" #include "Acts/Tests/CommonHelpers/CylindricalTrackingGeometry.hpp" +#include "Acts/Utilities/Logger.hpp" #include "Acts/Utilities/VectorHelpers.hpp" #include @@ -42,8 +44,6 @@ auto tGeometry = cGeometry(); const double Bz = 2_T; auto bField = std::make_shared(Vector3{0, 0, Bz}); -Acts::Logging::Level logLevel = Acts::Logging::INFO; - using SurfaceCollector = SurfaceCollector; std::vector collectRelevantGeoIds( @@ -103,7 +103,7 @@ void runSelfConsistencyTest(const propagator_t& prop, // backward surface test Options bwdOptions(tgContext, mfContext); bwdOptions.pathLimit = 25_cm; - bwdOptions.direction = Direction::Backward; + bwdOptions.direction = Direction::Backward(); // get the surface collector and configure it auto& bwdMSurfaceCollector = @@ -189,7 +189,7 @@ void runSelfConsistencyTest(const propagator_t& prop, // stepping from one surface to the next : backwards // now go from surface to surface and check Options bwdStepOptions(tgContext, mfContext); - bwdStepOptions.direction = Direction::Backward; + bwdStepOptions.direction = Direction::Backward(); // get the surface collector and configure it auto& bwdStepSurfaceCollector = @@ -300,45 +300,46 @@ void runConsistencyTest(const propagator_probe_t& propProbe, refSurfaces.begin(), refSurfaces.end()); } +Acts::Logging::Level logLevel = Acts::Logging::INFO; + const int nTestsSelfConsistency = 500; const int nTestsRefConsistency = 500; -int skip = 0; +using StraightLinePropagator = Propagator; using EigenStepper = Acts::EigenStepper<>; using EigenPropagator = Propagator; -using StraightLinePropagator = Propagator; -using Reference1EigenPropagator = Propagator; using Reference1StraightLinePropagator = Propagator; -using Reference2EigenPropagator = - Propagator; +using Reference1EigenPropagator = Propagator; using Reference2StraightLinePropagator = Propagator; +using Reference2EigenPropagator = + Propagator; -EigenStepper estepper(bField); StraightLineStepper slstepper; +EigenStepper estepper(bField); -EigenPropagator epropagator(estepper, - Navigator({tGeometry, true, true, false}, - getDefaultLogger("e_nav", Logging::INFO)), - getDefaultLogger("e_prop", Logging::INFO)); StraightLinePropagator slpropagator(slstepper, Navigator({tGeometry, true, true, false}, getDefaultLogger("sl_nav", Logging::INFO)), getDefaultLogger("sl_prop", Logging::INFO)); +EigenPropagator epropagator(estepper, + Navigator({tGeometry, true, true, false}, + getDefaultLogger("e_nav", Logging::INFO)), + getDefaultLogger("e_prop", Logging::INFO)); +Reference1StraightLinePropagator refslpropagator1( + slstepper, + TryAllNavigator({tGeometry, true, true, false}, + getDefaultLogger("ref1_sl_nav", Logging::INFO)), + getDefaultLogger("ref1_sl_prop", Logging::INFO)); Reference1EigenPropagator refepropagator1( estepper, TryAllNavigator({tGeometry, true, true, false, BoundaryTolerance::Infinite()}, getDefaultLogger("ref1_e_nav", Logging::INFO)), getDefaultLogger("ref1_e_prop", Logging::INFO)); -Reference1StraightLinePropagator refslpropagator1( - slstepper, - TryAllNavigator({tGeometry, true, true, false}, - getDefaultLogger("ref1_sl_nav", Logging::INFO)), - getDefaultLogger("ref1_sl_prop", Logging::INFO)); Reference2EigenPropagator refepropagator2( estepper, @@ -366,19 +367,37 @@ auto eventGen = (bdata::engine = std::mt19937(), bdata::seed = 23, bdata::distribution = std::uniform_int_distribution(0, 1))); -BOOST_DATA_TEST_CASE(NavigatorSelfConsistency, +CurvilinearTrackParameters createStartParameters(double pT, double phi, + double theta, int charge) { + double p = pT / std::sin(theta); + double q = -1 + 2 * charge; + return CurvilinearTrackParameters(Vector4(0, 0, 0, 0), phi, theta, q / p, + std::nullopt, ParticleHypothesis::pion()); +} + +BOOST_DATA_TEST_CASE(NavigatorStraightLineSelfConsistency, eventGen ^ bdata::xrange(nTestsSelfConsistency), pT, phi, theta, charge, index) { - ACTS_LOCAL_LOGGER(Acts::getDefaultLogger("NavigatorTest", logLevel)) + ACTS_LOCAL_LOGGER(Acts::getDefaultLogger("NavigatorTest", logLevel)); - if (index < skip) { - return; - } + CurvilinearTrackParameters start = + createStartParameters(pT, phi, theta, charge); - double p = pT / std::sin(theta); - double q = -1 + 2 * charge; - CurvilinearTrackParameters start(Vector4(0, 0, 0, 0), phi, theta, q / p, - std::nullopt, ParticleHypothesis::pion()); + ACTS_DEBUG(">>> Run navigation tests with:\n pT = " + << pT << "\n phi = " << phi << "\n theta = " << theta + << "\n charge = " << charge << "\n index = " << index); + + ACTS_DEBUG(">>> Test self consistency slpropagator"); + runSelfConsistencyTest(slpropagator, start, logger()); +} + +BOOST_DATA_TEST_CASE(NavigatorEigenSelfConsistency, + eventGen ^ bdata::xrange(nTestsSelfConsistency), pT, phi, + theta, charge, index) { + ACTS_LOCAL_LOGGER(Acts::getDefaultLogger("NavigatorTest", logLevel)); + + CurvilinearTrackParameters start = + createStartParameters(pT, phi, theta, charge); ACTS_DEBUG(">>> Run navigation tests with:\n pT = " << pT << "\n phi = " << phi << "\n theta = " << theta @@ -386,49 +405,31 @@ BOOST_DATA_TEST_CASE(NavigatorSelfConsistency, ACTS_DEBUG(">>> Test self consistency epropagator"); runSelfConsistencyTest(epropagator, start, logger()); - - ACTS_DEBUG(">>> Test self consistency slpropagator"); - runSelfConsistencyTest(slpropagator, start, logger()); } -BOOST_DATA_TEST_CASE(NavigatorRef1Consistency, +BOOST_DATA_TEST_CASE(NavigatorRef1StraightLineConsistency, eventGen ^ bdata::xrange(nTestsRefConsistency), pT, phi, theta, charge, index) { - ACTS_LOCAL_LOGGER(Acts::getDefaultLogger("NavigatorTest", logLevel)) - - if (index < skip) { - return; - } + ACTS_LOCAL_LOGGER(Acts::getDefaultLogger("NavigatorTest", logLevel)); - double p = pT / std::sin(theta); - double q = -1 + 2 * charge; - CurvilinearTrackParameters start(Vector4(0, 0, 0, 0), phi, theta, q / p, - std::nullopt, ParticleHypothesis::pion()); + CurvilinearTrackParameters start = + createStartParameters(pT, phi, theta, charge); ACTS_DEBUG(">>> Run navigation tests with:\n pT = " << pT << "\n phi = " << phi << "\n theta = " << theta << "\n charge = " << charge << "\n index = " << index); - ACTS_DEBUG(">>> Test reference 1 consistency epropagator"); - runConsistencyTest(epropagator, refepropagator1, start, logger()); - ACTS_DEBUG(">>> Test reference 1 consistency slpropagator"); runConsistencyTest(slpropagator, refslpropagator1, start, logger()); } -BOOST_DATA_TEST_CASE(NavigatorRef2Consistency, +BOOST_DATA_TEST_CASE(NavigatorRef1EigenConsistency, eventGen ^ bdata::xrange(nTestsRefConsistency), pT, phi, theta, charge, index) { - ACTS_LOCAL_LOGGER(Acts::getDefaultLogger("NavigatorTest", logLevel)) + ACTS_LOCAL_LOGGER(Acts::getDefaultLogger("NavigatorTest", logLevel)); - if (index < skip) { - return; - } - - double p = pT / std::sin(theta); - double q = -1 + 2 * charge; - CurvilinearTrackParameters start(Vector4(0, 0, 0, 0), phi, theta, q / p, - std::nullopt, ParticleHypothesis::pion()); + CurvilinearTrackParameters start = + createStartParameters(pT, phi, theta, charge); ACTS_DEBUG(">>> Run navigation tests with:\n pT = " << pT << "\n phi = " << phi << "\n theta = " << theta @@ -436,15 +437,38 @@ BOOST_DATA_TEST_CASE(NavigatorRef2Consistency, ACTS_DEBUG(">>> Test reference 1 consistency epropagator"); runConsistencyTest(epropagator, refepropagator1, start, logger()); +} - ACTS_DEBUG(">>> Test reference 1 consistency slpropagator"); - runConsistencyTest(slpropagator, refslpropagator1, start, logger()); +BOOST_DATA_TEST_CASE(NavigatorRef2StraightLineConsistency, + eventGen ^ bdata::xrange(nTestsRefConsistency), pT, phi, + theta, charge, index) { + ACTS_LOCAL_LOGGER(Acts::getDefaultLogger("NavigatorTest", logLevel)); - ACTS_DEBUG(">>> Test reference 2 consistency epropagator"); - runConsistencyTest(epropagator, refepropagator2, start, logger()); + CurvilinearTrackParameters start = + createStartParameters(pT, phi, theta, charge); + + ACTS_DEBUG(">>> Run navigation tests with:\n pT = " + << pT << "\n phi = " << phi << "\n theta = " << theta + << "\n charge = " << charge << "\n index = " << index); ACTS_DEBUG(">>> Test reference 2 consistency slpropagator"); runConsistencyTest(slpropagator, refslpropagator2, start, logger()); } +BOOST_DATA_TEST_CASE(NavigatorRef2EigenConsistency, + eventGen ^ bdata::xrange(nTestsRefConsistency), pT, phi, + theta, charge, index) { + ACTS_LOCAL_LOGGER(Acts::getDefaultLogger("NavigatorTest", logLevel)); + + CurvilinearTrackParameters start = + createStartParameters(pT, phi, theta, charge); + + ACTS_DEBUG(">>> Run navigation tests with:\n pT = " + << pT << "\n phi = " << phi << "\n theta = " << theta + << "\n charge = " << charge << "\n index = " << index); + + ACTS_DEBUG(">>> Test reference 2 consistency epropagator"); + runConsistencyTest(epropagator, refepropagator2, start, logger()); +} + } // namespace Acts::Test diff --git a/Tests/IntegrationTests/PropagationTests.hpp b/Tests/IntegrationTests/PropagationTests.hpp index b7b40c66e0c..56722d8462f 100644 --- a/Tests/IntegrationTests/PropagationTests.hpp +++ b/Tests/IntegrationTests/PropagationTests.hpp @@ -269,7 +269,7 @@ inline std::pair transportToSurface( // setup propagation options options_t options(geoCtx, magCtx); - options.direction = Acts::Direction::Forward; + options.direction = Acts::Direction::Forward(); options.pathLimit = pathLimit; options.surfaceTolerance = 1_nm; options.stepping.stepTolerance = 1_nm; @@ -293,7 +293,7 @@ inline void runForwardBackwardTest( const Acts::MagneticFieldContext& magCtx, const Acts::CurvilinearTrackParameters& initialParams, double pathLength, double epsPos, double epsDir, double epsMom) { - // propagate parameters Acts::Direction::Forward + // propagate parameters Acts::Direction::Forward() auto [fwdParams, fwdPathLength] = transportFreely( propagator, geoCtx, magCtx, initialParams, pathLength); CHECK_CLOSE_ABS(fwdPathLength, pathLength, epsPos); diff --git a/Tests/UnitTests/Alignment/Kernel/AlignmentTests.cpp b/Tests/UnitTests/Alignment/Kernel/AlignmentTests.cpp index e6bbad83f4b..86d668b5beb 100644 --- a/Tests/UnitTests/Alignment/Kernel/AlignmentTests.cpp +++ b/Tests/UnitTests/Alignment/Kernel/AlignmentTests.cpp @@ -158,7 +158,7 @@ struct TelescopeDetector { // Create the layer array std::unique_ptr layArr(layArrCreator.layerArray( geoContext, layVec, positions.front() - 2._mm, positions.back() + 2._mm, - BinningType::arbitrary, BinningValue::binX)); + BinningType::arbitrary, AxisDirection::AxisX)); // Build the tracking volume auto trackVolume = std::make_shared( diff --git a/Tests/UnitTests/Core/Definitions/DirectionTests.cpp b/Tests/UnitTests/Core/Definitions/DirectionTests.cpp index 0badd75c66a..4eb5603d1fc 100644 --- a/Tests/UnitTests/Core/Definitions/DirectionTests.cpp +++ b/Tests/UnitTests/Core/Definitions/DirectionTests.cpp @@ -18,11 +18,11 @@ using namespace Acts; BOOST_AUTO_TEST_SUITE(DefinitionsDirection) BOOST_AUTO_TEST_CASE(DirectionTests) { - constexpr Direction bwd = Direction::Backward; - constexpr Direction fwd = Direction::Forward; + constexpr Direction bwd = Direction::Backward(); + constexpr Direction fwd = Direction::Forward(); - BOOST_CHECK_EQUAL(bwd, Direction::Negative); - BOOST_CHECK_EQUAL(fwd, Direction::Positive); + BOOST_CHECK_EQUAL(bwd, Direction::Negative()); + BOOST_CHECK_EQUAL(fwd, Direction::Positive()); BOOST_CHECK_EQUAL(Direction::fromScalar(-1.), bwd); BOOST_CHECK_EQUAL(Direction::fromScalar(1.), fwd); diff --git a/Tests/UnitTests/Core/Detector/BlueprintHelperTests.cpp b/Tests/UnitTests/Core/Detector/BlueprintHelperTests.cpp index a8876bbd8f3..b10042791cf 100644 --- a/Tests/UnitTests/Core/Detector/BlueprintHelperTests.cpp +++ b/Tests/UnitTests/Core/Detector/BlueprintHelperTests.cpp @@ -23,7 +23,8 @@ BOOST_AUTO_TEST_SUITE(Experimental) BOOST_AUTO_TEST_CASE(BlueprintHelperSorting) { // Create root node - std::vector detectorBinning = {Acts::BinningValue::binR}; + std::vector detectorBinning = { + Acts::AxisDirection::AxisR}; std::vector detectorBoundaries = {0., 50., 100.}; auto detector = std::make_unique( "detector", Acts::Transform3::Identity(), Acts::VolumeBounds::eCylinder, @@ -33,7 +34,7 @@ BOOST_AUTO_TEST_CASE(BlueprintHelperSorting) { BOOST_CHECK(detector->children.empty()); BOOST_CHECK_EQUAL(detector->name, "detector"); - std::vector pixelsBinning = {Acts::BinningValue::binZ}; + std::vector pixelsBinning = {Acts::AxisDirection::AxisZ}; std::vector pixelsBoundaries = {20., 50., 100.}; auto pixels = std::make_unique( @@ -105,7 +106,8 @@ BOOST_AUTO_TEST_CASE(BlueprintCylindricalGapFilling) { std::make_shared(); // Create root node - std::vector detectorBinning = {Acts::BinningValue::binR}; + std::vector detectorBinning = { + Acts::AxisDirection::AxisR}; std::vector detectorBoundaries = {detectorIr, detectorOr, detectorHz}; // The root node - detector @@ -122,14 +124,15 @@ BOOST_AUTO_TEST_CASE(BlueprintCylindricalGapFilling) { // A pixel system std::vector pixelBoundaries = {pixelIr, pixelOr, detectorHz}; - std::vector pixelBinning = {Acts::BinningValue::binZ}; + std::vector pixelBinning = {Acts::AxisDirection::AxisZ}; auto pixel = std::make_unique( "pixel", Acts::Transform3::Identity(), Acts::VolumeBounds::eCylinder, pixelBoundaries, pixelBinning); // Nec: Small differences to check if the adjustments are made std::vector pixelEcBoundaries = {pixelIr, pixelOr - 5., pixelEcHz}; - std::vector pixelEcBinning = {Acts::BinningValue::binZ}; + std::vector pixelEcBinning = { + Acts::AxisDirection::AxisZ}; auto pixelNec = std::make_unique( "pixelNec", @@ -150,8 +153,8 @@ BOOST_AUTO_TEST_CASE(BlueprintCylindricalGapFilling) { // Barrel std::vector pixelBarrelBoundaries = {pixelIr + 1, pixelOr - 1., detectorHz - 2 * pixelEcHz}; - std::vector pixelBarrelBinning = { - Acts::BinningValue::binR}; + std::vector pixelBarrelBinning = { + Acts::AxisDirection::AxisR}; auto pixelBarrel = std::make_unique( "pixelBarrel", Acts::Transform3::Identity(), @@ -260,7 +263,8 @@ BOOST_AUTO_TEST_CASE(BlueprintCylindricalGapException) { // The root node - detector std::vector detectorBoundaries = {0., 50., 100.}; - std::vector detectorBinning = {Acts::BinningValue::binX}; + std::vector detectorBinning = { + Acts::AxisDirection::AxisX}; auto detector = std::make_unique( "detector", Acts::Transform3::Identity(), Acts::VolumeBounds::eCylinder, detectorBoundaries, detectorBinning); diff --git a/Tests/UnitTests/Core/Detector/BlueprintTests.cpp b/Tests/UnitTests/Core/Detector/BlueprintTests.cpp index 72be3a15c77..2c4a090d24f 100644 --- a/Tests/UnitTests/Core/Detector/BlueprintTests.cpp +++ b/Tests/UnitTests/Core/Detector/BlueprintTests.cpp @@ -23,7 +23,7 @@ BOOST_AUTO_TEST_CASE(BlueprintTest) { std::vector bValues = {0., 10., 100.}; // Create root node - std::vector binning = {Acts::BinningValue::binR}; + std::vector binning = {Acts::AxisDirection::AxisR}; auto root = std::make_unique( "detector", Acts::Transform3::Identity(), Acts::VolumeBounds::eOther, bValues, binning); diff --git a/Tests/UnitTests/Core/Detector/CuboidalContainerBuilderTests.cpp b/Tests/UnitTests/Core/Detector/CuboidalContainerBuilderTests.cpp index 8578b282a76..bc803685b2c 100644 --- a/Tests/UnitTests/Core/Detector/CuboidalContainerBuilderTests.cpp +++ b/Tests/UnitTests/Core/Detector/CuboidalContainerBuilderTests.cpp @@ -125,15 +125,15 @@ BOOST_AUTO_TEST_CASE(CuboidalContainerBuilder_Misconfiguration) { std::invalid_argument); // misconfiguration - 1D binning not in x, y, z misCfg.builders = {nullptr}; - misCfg.binning = Acts::BinningValue::binR; + misCfg.binning = Acts::AxisDirection::AxisR; BOOST_CHECK_THROW(auto b = CuboidalContainerBuilder(misCfg), std::invalid_argument); } BOOST_AUTO_TEST_CASE(CuboidalContainerBuildingXYZVolumes) { - std::array binningValues = {Acts::BinningValue::binX, - Acts::BinningValue::binY, - Acts::BinningValue::binZ}; + std::array binningValues = { + Acts::AxisDirection::AxisX, Acts::AxisDirection::AxisY, + Acts::AxisDirection::AxisZ}; for (auto bVal : binningValues) { // A perfect box shape auto box = Acts::CuboidVolumeBounds(10, 10, 10); diff --git a/Tests/UnitTests/Core/Detector/CuboidalDetectorFromBlueprintTests.cpp b/Tests/UnitTests/Core/Detector/CuboidalDetectorFromBlueprintTests.cpp index 8711a2847ab..e5259d79587 100644 --- a/Tests/UnitTests/Core/Detector/CuboidalDetectorFromBlueprintTests.cpp +++ b/Tests/UnitTests/Core/Detector/CuboidalDetectorFromBlueprintTests.cpp @@ -95,7 +95,7 @@ BOOST_AUTO_TEST_CASE(CuboidalDetectorFromBlueprintTest) { double pixelZ = 10; // Create root node - std::vector detectorBins = {Acts::BinningValue::binX}; + std::vector detectorBins = {Acts::AxisDirection::AxisX}; std::vector detectorBounds = {detectorX, detectorY, detectorZ}; // The root node - detector @@ -106,7 +106,7 @@ BOOST_AUTO_TEST_CASE(CuboidalDetectorFromBlueprintTest) { // Left arm std::vector leftArmBounds = {detectorX * 0.5, detectorY, detectorZ}; - std::vector leftArmBins = {Acts::BinningValue::binZ}; + std::vector leftArmBins = {Acts::AxisDirection::AxisZ}; Acts::Transform3 leftArmTransform = Acts::Transform3::Identity() * @@ -153,7 +153,7 @@ BOOST_AUTO_TEST_CASE(CuboidalDetectorFromBlueprintTest) { // Right arm std::vector rightArmBounds = {detectorX * 0.5, detectorY, detectorZ}; - std::vector rightArmBins = {Acts::BinningValue::binZ}; + std::vector rightArmBins = {Acts::AxisDirection::AxisZ}; Acts::Transform3 rightArmTransform = Acts::Transform3::Identity() * Acts::Translation3(detectorX * 0.5, 0., 0); @@ -258,76 +258,76 @@ BOOST_AUTO_TEST_CASE(CuboidalDetectorFromBlueprintTest) { double internalStretchLeftZ = detector->volumes()[0] ->volumeBounds() - .values()[toUnderlying(Acts::BinningValue::binZ)] + + .values()[toUnderlying(Acts::AxisDirection::AxisZ)] + detector->volumes()[1] ->volumeBounds() - .values()[toUnderlying(Acts::BinningValue::binZ)] + + .values()[toUnderlying(Acts::AxisDirection::AxisZ)] + detector->volumes()[2] ->volumeBounds() - .values()[toUnderlying(Acts::BinningValue::binZ)] + + .values()[toUnderlying(Acts::AxisDirection::AxisZ)] + detector->volumes()[3] ->volumeBounds() - .values()[toUnderlying(Acts::BinningValue::binZ)] + + .values()[toUnderlying(Acts::AxisDirection::AxisZ)] + detector->volumes()[4] ->volumeBounds() - .values()[toUnderlying(Acts::BinningValue::binZ)]; + .values()[toUnderlying(Acts::AxisDirection::AxisZ)]; double internalStretchRightZ = detector->volumes()[5] ->volumeBounds() - .values()[toUnderlying(Acts::BinningValue::binZ)] + + .values()[toUnderlying(Acts::AxisDirection::AxisZ)] + detector->volumes()[6] ->volumeBounds() - .values()[toUnderlying(Acts::BinningValue::binZ)] + + .values()[toUnderlying(Acts::AxisDirection::AxisZ)] + detector->volumes()[7] ->volumeBounds() - .values()[toUnderlying(Acts::BinningValue::binZ)] + + .values()[toUnderlying(Acts::AxisDirection::AxisZ)] + detector->volumes()[8] ->volumeBounds() - .values()[toUnderlying(Acts::BinningValue::binZ)] + + .values()[toUnderlying(Acts::AxisDirection::AxisZ)] + detector->volumes()[9] ->volumeBounds() - .values()[toUnderlying(Acts::BinningValue::binZ)]; + .values()[toUnderlying(Acts::AxisDirection::AxisZ)]; double internalStretchX1 = detector->volumes()[0] ->volumeBounds() - .values()[toUnderlying(Acts::BinningValue::binX)] + + .values()[toUnderlying(Acts::AxisDirection::AxisX)] + detector->volumes()[5] ->volumeBounds() - .values()[toUnderlying(Acts::BinningValue::binX)]; + .values()[toUnderlying(Acts::AxisDirection::AxisX)]; double internalStretchX2 = detector->volumes()[1] ->volumeBounds() - .values()[toUnderlying(Acts::BinningValue::binX)] + + .values()[toUnderlying(Acts::AxisDirection::AxisX)] + detector->volumes()[6] ->volumeBounds() - .values()[toUnderlying(Acts::BinningValue::binX)]; + .values()[toUnderlying(Acts::AxisDirection::AxisX)]; double internalStretchX3 = detector->volumes()[2] ->volumeBounds() - .values()[toUnderlying(Acts::BinningValue::binX)] + + .values()[toUnderlying(Acts::AxisDirection::AxisX)] + detector->volumes()[7] ->volumeBounds() - .values()[toUnderlying(Acts::BinningValue::binX)]; + .values()[toUnderlying(Acts::AxisDirection::AxisX)]; double internalStretchX4 = detector->volumes()[3] ->volumeBounds() - .values()[toUnderlying(Acts::BinningValue::binX)] + + .values()[toUnderlying(Acts::AxisDirection::AxisX)] + detector->volumes()[8] ->volumeBounds() - .values()[toUnderlying(Acts::BinningValue::binX)]; + .values()[toUnderlying(Acts::AxisDirection::AxisX)]; double internalStretchX5 = detector->volumes()[4] ->volumeBounds() - .values()[toUnderlying(Acts::BinningValue::binX)] + + .values()[toUnderlying(Acts::AxisDirection::AxisX)] + detector->volumes()[9] ->volumeBounds() - .values()[toUnderlying(Acts::BinningValue::binX)]; + .values()[toUnderlying(Acts::AxisDirection::AxisX)]; BOOST_CHECK_EQUAL(internalStretchLeftZ, detectorZ); BOOST_CHECK_EQUAL(internalStretchRightZ, detectorZ); @@ -338,9 +338,9 @@ BOOST_AUTO_TEST_CASE(CuboidalDetectorFromBlueprintTest) { BOOST_CHECK_EQUAL(internalStretchX5, detectorX); for (auto& volume : detector->volumes()) { - BOOST_CHECK_EQUAL( - volume->volumeBounds().values()[toUnderlying(Acts::BinningValue::binY)], - detectorY); + BOOST_CHECK_EQUAL(volume->volumeBounds() + .values()[toUnderlying(Acts::AxisDirection::AxisY)], + detectorY); } // There should be surfaces inside the pixel diff --git a/Tests/UnitTests/Core/Detector/CuboidalDetectorHelperTests.cpp b/Tests/UnitTests/Core/Detector/CuboidalDetectorHelperTests.cpp index 0f7e453ef35..388b9410d69 100644 --- a/Tests/UnitTests/Core/Detector/CuboidalDetectorHelperTests.cpp +++ b/Tests/UnitTests/Core/Detector/CuboidalDetectorHelperTests.cpp @@ -50,15 +50,15 @@ BOOST_AUTO_TEST_CASE(CubicVolumeExceptions) { volumeA, volumeB}; BOOST_CHECK_THROW(Acts::Experimental::detail::CuboidalDetectorHelper::connect( - tContext, volumes, Acts::BinningValue::binX, {}, + tContext, volumes, Acts::AxisDirection::AxisX, {}, Acts::Logging::VERBOSE), std::invalid_argument); } BOOST_AUTO_TEST_CASE(SimpleBoxConnection) { - std::array binningValues = {Acts::BinningValue::binX, - Acts::BinningValue::binY, - Acts::BinningValue::binZ}; + std::array binningValues = { + Acts::AxisDirection::AxisX, Acts::AxisDirection::AxisY, + Acts::AxisDirection::AxisZ}; for (auto bVal : binningValues) { // A perfect box shape auto box = std::make_shared(10, 10, 10); @@ -91,15 +91,15 @@ BOOST_AUTO_TEST_CASE(SimpleBoxConnection) { Acts::ObjVisualization3D obj; Acts::GeometryView3D::drawDetectorVolume(obj, *volumeA, tContext); Acts::GeometryView3D::drawDetectorVolume(obj, *volumeB, tContext); - obj.write("ConnectectBoxesRegular_" + Acts::binningValueName(bVal) + + obj.write("ConnectectBoxesRegular_" + Acts::axisDirectionName(bVal) + ".obj"); } } BOOST_AUTO_TEST_CASE(IrregularBoxConnectionInZ) { - std::vector binningValues = {Acts::BinningValue::binX, - Acts::BinningValue::binY, - Acts::BinningValue::binZ}; + std::vector binningValues = {Acts::AxisDirection::AxisX, + Acts::AxisDirection::AxisY, + Acts::AxisDirection::AxisZ}; using HlPos = std::array; using VolHlPos = std::array; @@ -170,7 +170,7 @@ BOOST_AUTO_TEST_CASE(IrregularBoxConnectionInZ) { Acts::GeometryView3D::drawDetectorVolume(obj, *volumeA, tContext); Acts::GeometryView3D::drawDetectorVolume(obj, *volumeB, tContext); Acts::GeometryView3D::drawDetectorVolume(obj, *volumeC, tContext); - obj.write("ConnectectBoxesIrregular_" + Acts::binningValueName(bVal) + + obj.write("ConnectectBoxesIrregular_" + Acts::axisDirectionName(bVal) + trstr + ".obj"); } } @@ -190,7 +190,7 @@ BOOST_AUTO_TEST_CASE(ContainerConnection) { // Move it into the bval direction auto transformB = Acts::Transform3::Identity(); Acts::Vector3 translationB = Acts::Vector3::Zero(); - translationB[toUnderlying(Acts::BinningValue::binX)] = 20; + translationB[toUnderlying(Acts::AxisDirection::AxisX)] = 20; transformB.pretranslate(translationB); // Create volume B auto volumeB = Acts::Experimental::DetectorVolumeFactory::construct( @@ -201,14 +201,14 @@ BOOST_AUTO_TEST_CASE(ContainerConnection) { volumeA, volumeB}; auto containerAB = Acts::Experimental::detail::CuboidalDetectorHelper::connect( - tContext, volumes, Acts::BinningValue::binX, {}, + tContext, volumes, Acts::AxisDirection::AxisX, {}, Acts::Logging::VERBOSE); // Create a CD container auto transformC = Acts::Transform3::Identity(); Acts::Vector3 translationC = Acts::Vector3::Zero(); - translationC[toUnderlying(Acts::BinningValue::binY)] = 20; + translationC[toUnderlying(Acts::AxisDirection::AxisY)] = 20; transformC.pretranslate(translationC); auto volumeC = Acts::Experimental::DetectorVolumeFactory::construct( @@ -217,8 +217,8 @@ BOOST_AUTO_TEST_CASE(ContainerConnection) { auto transformD = Acts::Transform3::Identity(); Acts::Vector3 translationD = Acts::Vector3::Zero(); - translationD[toUnderlying(Acts::BinningValue::binX)] = 20; - translationD[toUnderlying(Acts::BinningValue::binY)] = 20; + translationD[toUnderlying(Acts::AxisDirection::AxisX)] = 20; + translationD[toUnderlying(Acts::AxisDirection::AxisY)] = 20; transformD.pretranslate(translationD); auto volumeD = Acts::Experimental::DetectorVolumeFactory::construct( @@ -228,12 +228,12 @@ BOOST_AUTO_TEST_CASE(ContainerConnection) { volumes = {volumeC, volumeD}; auto containerCD = Acts::Experimental::detail::CuboidalDetectorHelper::connect( - tContext, volumes, Acts::BinningValue::binX, {}, + tContext, volumes, Acts::AxisDirection::AxisX, {}, Acts::Logging::VERBOSE); auto containerABCD = Acts::Experimental::detail::CuboidalDetectorHelper::connect( - tContext, {containerAB, containerCD}, Acts::BinningValue::binY, {}, + tContext, {containerAB, containerCD}, Acts::AxisDirection::AxisY, {}, Acts::Logging::VERBOSE); // Check the container is constructed diff --git a/Tests/UnitTests/Core/Detector/CylindricalContainerBuilderTests.cpp b/Tests/UnitTests/Core/Detector/CylindricalContainerBuilderTests.cpp index 3ee5c24cda3..52a93cfc0ea 100644 --- a/Tests/UnitTests/Core/Detector/CylindricalContainerBuilderTests.cpp +++ b/Tests/UnitTests/Core/Detector/CylindricalContainerBuilderTests.cpp @@ -84,19 +84,19 @@ BOOST_AUTO_TEST_CASE(CylindricaContainerBuilder_Misconfiguration) { std::invalid_argument); // misconfiguration - 1D binning not in z, r, phi misCfg.builders = {nullptr}; - misCfg.binning = {Acts::BinningValue::binX}; + misCfg.binning = {Acts::AxisDirection::AxisX}; BOOST_CHECK_THROW(auto b = CylindricalContainerBuilder(misCfg), std::invalid_argument); // misconfiguration - 2D binning not in z, r, misCfg.builders = {nullptr, nullptr}; - misCfg.binning = {Acts::BinningValue::binZ, Acts::BinningValue::binPhi}; + misCfg.binning = {Acts::AxisDirection::AxisZ, Acts::AxisDirection::AxisPhi}; BOOST_CHECK_THROW(auto c = CylindricalContainerBuilder(misCfg), std::invalid_argument); // misconfiguration - 2D binning in z, r, but not exactly 2 builders misCfg.builders = {nullptr, nullptr, nullptr}; - misCfg.binning = {Acts::BinningValue::binZ, Acts::BinningValue::binR}; + misCfg.binning = {Acts::AxisDirection::AxisZ, Acts::AxisDirection::AxisR}; BOOST_CHECK_THROW(auto d = CylindricalContainerBuilder(misCfg), std::invalid_argument); } @@ -127,12 +127,12 @@ BOOST_AUTO_TEST_CASE(CylindricaContainerBuildingZ) { CylindricalContainerBuilder::Config tripleZCfg; tripleZCfg.auxiliary = "*** Test 0 - Build triple in Z ***"; tripleZCfg.builders = {negDisc, barrel, posDisc}; - tripleZCfg.binning = {BinningValue::binZ}; + tripleZCfg.binning = {AxisDirection::AxisZ}; tripleZCfg.geoIdGenerator = std::make_shared(); // Create a materialBinning tripleZCfg.portalMaterialBinning[2u] = BinningDescription{ - {ProtoBinning(BinningValue::binZ, Acts::AxisBoundaryType::Bound, 50), - ProtoBinning(BinningValue::binPhi, Acts::AxisBoundaryType::Closed, + {ProtoBinning(AxisDirection::AxisZ, Acts::AxisBoundaryType::Bound, 50), + ProtoBinning(AxisDirection::AxisPhi, Acts::AxisBoundaryType::Closed, -std::numbers::pi, std::numbers::pi, 12)}}; // Let's test the reverse generation @@ -180,7 +180,7 @@ BOOST_AUTO_TEST_CASE(CylindricaContainerBuildingR) { CylindricalContainerBuilder::Config barrelRCfg; barrelRCfg.auxiliary = "*** Test 1 - Build multilayer barrel ***"; barrelRCfg.builders = {barrel0, barrel1, barrel2}; - barrelRCfg.binning = {BinningValue::binR}; + barrelRCfg.binning = {AxisDirection::AxisR}; barrelRCfg.geoIdGenerator = std::make_shared(); auto barrelR = std::make_shared( @@ -199,7 +199,7 @@ BOOST_AUTO_TEST_CASE(CylindricaContainerBuildingPhi) { // Create the container builder CylindricalContainerBuilder::Config barrelPhiCfg; barrelPhiCfg.auxiliary = "*** Test 2 - Build segmented phi barrel ***"; - barrelPhiCfg.binning = {BinningValue::binPhi}; + barrelPhiCfg.binning = {AxisDirection::AxisPhi}; unsigned int phiSectors = 5; double phiHalfSector = std::numbers::pi / phiSectors; @@ -267,7 +267,7 @@ BOOST_AUTO_TEST_CASE(CylindricalContainerBuilderDetector) { // Create the barrel container builder CylindricalContainerBuilder::Config barrelRCfg; barrelRCfg.builders = {barrel0, barrel1, barrel2}; - barrelRCfg.binning = {BinningValue::binR}; + barrelRCfg.binning = {AxisDirection::AxisR}; auto barrel = std::make_shared( barrelRCfg, getDefaultLogger("BarrelBuilderR", Logging::VERBOSE)); @@ -282,7 +282,7 @@ BOOST_AUTO_TEST_CASE(CylindricalContainerBuilderDetector) { // Create the barrel container builder CylindricalContainerBuilder::Config barrelEndcapCfg; barrelEndcapCfg.builders = {endcapN, barrel, endcapP}; - barrelEndcapCfg.binning = {BinningValue::binZ}; + barrelEndcapCfg.binning = {AxisDirection::AxisZ}; auto barrelEndcap = std::make_shared( barrelEndcapCfg, @@ -291,7 +291,7 @@ BOOST_AUTO_TEST_CASE(CylindricalContainerBuilderDetector) { // Create the barrel container builder CylindricalContainerBuilder::Config detectorCfg; detectorCfg.builders = {beampipe, barrelEndcap}; - detectorCfg.binning = {BinningValue::binR}; + detectorCfg.binning = {AxisDirection::AxisR}; auto detector = std::make_shared( detectorCfg, getDefaultLogger("DetectorBuilder", Logging::VERBOSE)); diff --git a/Tests/UnitTests/Core/Detector/CylindricalDetectorFromBlueprintTests.cpp b/Tests/UnitTests/Core/Detector/CylindricalDetectorFromBlueprintTests.cpp index 2a3a45518ee..0323b844921 100644 --- a/Tests/UnitTests/Core/Detector/CylindricalDetectorFromBlueprintTests.cpp +++ b/Tests/UnitTests/Core/Detector/CylindricalDetectorFromBlueprintTests.cpp @@ -91,7 +91,8 @@ BOOST_AUTO_TEST_CASE(CylindricalDetectorFromBlueprintTest) { double pixelEcLayerHz = 10; // Create root node - std::vector detectorBinning = {Acts::BinningValue::binR}; + std::vector detectorBinning = { + Acts::AxisDirection::AxisR}; std::vector detectorBoundaries = {detectorIr, detectorOr, detectorHz}; // The root node - detector @@ -112,14 +113,15 @@ BOOST_AUTO_TEST_CASE(CylindricalDetectorFromBlueprintTest) { // A pixel system std::vector pixelBoundaries = {pixelIr, pixelOr, detectorHz}; - std::vector pixelBinning = {Acts::BinningValue::binZ}; + std::vector pixelBinning = {Acts::AxisDirection::AxisZ}; auto pixel = std::make_unique( "pixel", Acts::Transform3::Identity(), Acts::VolumeBounds::eCylinder, pixelBoundaries, pixelBinning); // Nec: Small differences to check if the adjustments are made std::vector pixelEcBoundaries = {pixelIr, pixelOr - 5., pixelEcHz}; - std::vector pixelEcBinning = {Acts::BinningValue::binZ}; + std::vector pixelEcBinning = { + Acts::AxisDirection::AxisZ}; Acts::Transform3 pixelNecTransform = Acts::Transform3::Identity() * @@ -146,8 +148,8 @@ BOOST_AUTO_TEST_CASE(CylindricalDetectorFromBlueprintTest) { // Barrel std::vector pixelBarrelBoundaries = {pixelIr + 1, pixelOr - 1., detectorHz - 2 * pixelEcHz}; - std::vector pixelBarrelBinning = { - Acts::BinningValue::binR}; + std::vector pixelBarrelBinning = { + Acts::AxisDirection::AxisR}; auto pixelBarrel = std::make_unique( "pixel_barrel", Acts::Transform3::Identity(), @@ -205,8 +207,8 @@ BOOST_AUTO_TEST_CASE(CylindricalDetectorFromBlueprintTest) { detectorBpr->add(std::move(pixel)); // An Indexed volume finder will be attached - std::vector rootVolumeBinning = { - Acts::BinningValue::binZ, Acts::BinningValue::binR}; + std::vector rootVolumeBinning = { + Acts::AxisDirection::AxisZ, Acts::AxisDirection::AxisR}; detectorBpr->rootVolumeFinderBuilder = std::make_shared( rootVolumeBinning); diff --git a/Tests/UnitTests/Core/Detector/DetectorVolumeBuilderTests.cpp b/Tests/UnitTests/Core/Detector/DetectorVolumeBuilderTests.cpp index 7b0a551f36e..c23abf8339e 100644 --- a/Tests/UnitTests/Core/Detector/DetectorVolumeBuilderTests.cpp +++ b/Tests/UnitTests/Core/Detector/DetectorVolumeBuilderTests.cpp @@ -161,8 +161,8 @@ BOOST_AUTO_TEST_CASE(DetectorVolumeBuilder_EmptyVolume) { // Assign proto material to dvCfg.portalMaterialBinning[2u] = BinningDescription{ - {ProtoBinning(BinningValue::binZ, Acts::AxisBoundaryType::Bound, 50), - ProtoBinning(BinningValue::binPhi, Acts::AxisBoundaryType::Closed, + {ProtoBinning(AxisDirection::AxisZ, Acts::AxisBoundaryType::Bound, 50), + ProtoBinning(AxisDirection::AxisPhi, Acts::AxisBoundaryType::Closed, -std::numbers::pi, std::numbers::pi, 12)}}; auto dvBuilder = std::make_shared( diff --git a/Tests/UnitTests/Core/Detector/DetectorVolumeConsistencyTests.cpp b/Tests/UnitTests/Core/Detector/DetectorVolumeConsistencyTests.cpp index d46133b4760..f96ce7ab4a0 100644 --- a/Tests/UnitTests/Core/Detector/DetectorVolumeConsistencyTests.cpp +++ b/Tests/UnitTests/Core/Detector/DetectorVolumeConsistencyTests.cpp @@ -33,8 +33,8 @@ BOOST_AUTO_TEST_CASE(DetectorVolumeConsistencyFail) { // Move it into the bval direction auto transformB = Acts::Transform3::Identity(); Acts::Vector3 translationB = Acts::Vector3::Zero(); - translationB[toUnderlying(Acts::BinningValue::binX)] = 20; - translationB[toUnderlying(Acts::BinningValue::binY)] = 5; + translationB[toUnderlying(Acts::AxisDirection::AxisX)] = 20; + translationB[toUnderlying(Acts::AxisDirection::AxisY)] = 5; transformB.pretranslate(translationB); // Create volume B auto volumeB = Acts::Experimental::DetectorVolumeFactory::construct( @@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE(DetectorVolumeConsistencyFail) { BOOST_CHECK_THROW(Acts::Experimental::detail::DetectorVolumeConsistency:: checkCenterAlignment(tContext, {volumeA, volumeB}, - Acts::BinningValue::binX), + Acts::AxisDirection::AxisX), std::invalid_argument); } @@ -62,7 +62,7 @@ BOOST_AUTO_TEST_CASE(DetectorVolumeConsistencyPass) { // Move it into the bval direction auto transformB = Acts::Transform3::Identity(); Acts::Vector3 translationB = Acts::Vector3::Zero(); - translationB[toUnderlying(Acts::BinningValue::binX)] = 20; + translationB[toUnderlying(Acts::AxisDirection::AxisX)] = 20; transformB.pretranslate(translationB); // Create volume B auto volumeB = Acts::Experimental::DetectorVolumeFactory::construct( @@ -74,7 +74,7 @@ BOOST_AUTO_TEST_CASE(DetectorVolumeConsistencyPass) { BOOST_CHECK_NO_THROW(Acts::Experimental::detail::DetectorVolumeConsistency:: checkCenterAlignment(tContext, {volumeA, volumeB}, - Acts::BinningValue::binX)); + Acts::AxisDirection::AxisX)); } BOOST_AUTO_TEST_SUITE_END() diff --git a/Tests/UnitTests/Core/Detector/DetectorVolumeTests.cpp b/Tests/UnitTests/Core/Detector/DetectorVolumeTests.cpp index 7c050c564bc..35f398b184b 100644 --- a/Tests/UnitTests/Core/Detector/DetectorVolumeTests.cpp +++ b/Tests/UnitTests/Core/Detector/DetectorVolumeTests.cpp @@ -185,10 +185,10 @@ BOOST_AUTO_TEST_CASE(CylindricalDetectorVolumePortals) { // Check the extent auto volumeExtent = tubeCylinderVolume->extent(tContext, 1); - CHECK_CLOSE_ABS(volumeExtent.min(Acts::BinningValue::binR), 10., 10e-5); - CHECK_CLOSE_ABS(volumeExtent.max(Acts::BinningValue::binR), 100., 10e-5); - CHECK_CLOSE_ABS(volumeExtent.min(Acts::BinningValue::binZ), -200., 10e-5); - CHECK_CLOSE_ABS(volumeExtent.max(Acts::BinningValue::binZ), 200., 10e-5); + CHECK_CLOSE_ABS(volumeExtent.min(Acts::AxisDirection::AxisR), 10., 10e-5); + CHECK_CLOSE_ABS(volumeExtent.max(Acts::AxisDirection::AxisR), 100., 10e-5); + CHECK_CLOSE_ABS(volumeExtent.min(Acts::AxisDirection::AxisZ), -200., 10e-5); + CHECK_CLOSE_ABS(volumeExtent.max(Acts::AxisDirection::AxisZ), 200., 10e-5); } BOOST_AUTO_TEST_CASE(UpdatePortal) { diff --git a/Tests/UnitTests/Core/Detector/IndexedRootVolumeFinderBuilderTests.cpp b/Tests/UnitTests/Core/Detector/IndexedRootVolumeFinderBuilderTests.cpp index f505e901236..30c9a1f9ce5 100644 --- a/Tests/UnitTests/Core/Detector/IndexedRootVolumeFinderBuilderTests.cpp +++ b/Tests/UnitTests/Core/Detector/IndexedRootVolumeFinderBuilderTests.cpp @@ -69,7 +69,7 @@ BOOST_AUTO_TEST_CASE(IndexedRootVolumeFinderBuilderCylindrical) { innerV, middleLV, middleDV, middleUV, middleRV, outerV}; IndexedRootVolumeFinderBuilder builder( - {Acts::BinningValue::binZ, Acts::BinningValue::binR}); + {Acts::AxisDirection::AxisZ, Acts::AxisDirection::AxisR}); // Let's construct a detector auto rootVolumeFinder = builder.construct(tContext, rootVolumes); diff --git a/Tests/UnitTests/Core/Detector/IndexedSurfaceGridFillerTests.cpp b/Tests/UnitTests/Core/Detector/IndexedSurfaceGridFillerTests.cpp index ffe66a708c6..62a25480ef2 100644 --- a/Tests/UnitTests/Core/Detector/IndexedSurfaceGridFillerTests.cpp +++ b/Tests/UnitTests/Core/Detector/IndexedSurfaceGridFillerTests.cpp @@ -20,7 +20,7 @@ #include "Acts/Surfaces/RectangleBounds.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Utilities/Axis.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/BinningType.hpp" #include "Acts/Utilities/Enumerate.hpp" #include "Acts/Utilities/Grid.hpp" @@ -127,7 +127,7 @@ BOOST_AUTO_TEST_CASE(IndexGridXYOneSurfaceCenter) { // Indexed Surface grid IndexedSurfacesNavigation indexedGridXY( - std::move(gridXY), {BinningValue::binX, BinningValue::binY}); + std::move(gridXY), {AxisDirection::AxisX, AxisDirection::AxisY}); // Create a single surface in the center auto rBounds = std::make_shared(4., 4.); @@ -163,7 +163,7 @@ BOOST_AUTO_TEST_CASE(IndexGridXYOneSurfaceBinValue) { // Indexed Surface grid IndexedSurfacesNavigation indexedGridXY( - std::move(gridXY), {BinningValue::binX, BinningValue::binY}); + std::move(gridXY), {AxisDirection::AxisX, AxisDirection::AxisY}); // Create a single surface in the center auto rBounds = std::make_shared(4., 4.); @@ -174,7 +174,7 @@ BOOST_AUTO_TEST_CASE(IndexGridXYOneSurfaceBinValue) { IndexedGridFiller filler{{}}; filler.oLogger = getDefaultLogger("IndexGridFiller", Logging::VERBOSE); - BinningValueReferenceGenerator generator; + AxisDirectionReferenceGenerator generator; std::vector> surfaces = {pSurface}; // Fill the surface @@ -200,7 +200,7 @@ BOOST_AUTO_TEST_CASE(IndexGridXYOneSurfacePolyhedron) { // Indexed Surface grid IndexedSurfacesNavigation indexedGridXY( - std::move(gridXY), {BinningValue::binX, BinningValue::binY}); + std::move(gridXY), {AxisDirection::AxisX, AxisDirection::AxisY}); // Create a single surface in the center auto rBounds = std::make_shared(4., 4.); @@ -237,7 +237,7 @@ BOOST_AUTO_TEST_CASE(IndexGridXYOneSurfacePolyhedronBinExpansion) { // Indexed Surface grid IndexedSurfacesNavigation indexedGridXY( - std::move(gridXY), {BinningValue::binX, BinningValue::binY}); + std::move(gridXY), {AxisDirection::AxisX, AxisDirection::AxisY}); // Create a single surface in the center auto rBounds = std::make_shared(4., 4.); @@ -274,7 +274,7 @@ BOOST_AUTO_TEST_CASE(IndexGridZPhiYOneSurfacePolyhedronBinExpansion) { // Indexed Surface grid IndexedSurfacesNavigation indexedGridZPhi( - std::move(gridZPhi), {BinningValue::binZ, BinningValue::binPhi}); + std::move(gridZPhi), {AxisDirection::AxisZ, AxisDirection::AxisPhi}); auto cBounds = std::make_shared(10, 2., std::numbers::pi / 30, 0.); @@ -312,7 +312,7 @@ BOOST_AUTO_TEST_CASE(IndexGridZPhiYOneSurfaceMPIPolyhedronBinExpansion) { // Indexed Surface grid IndexedSurfacesNavigation indexedGridZPhi( - std::move(gridZPhi), {BinningValue::binZ, BinningValue::binPhi}); + std::move(gridZPhi), {AxisDirection::AxisZ, AxisDirection::AxisPhi}); auto cBounds = std::make_shared(10, 2., std::numbers::pi / 10, 0.); diff --git a/Tests/UnitTests/Core/Detector/IndexedSurfacesGeneratorTests.cpp b/Tests/UnitTests/Core/Detector/IndexedSurfacesGeneratorTests.cpp index f95adbdcb3b..4d0bbe9634e 100644 --- a/Tests/UnitTests/Core/Detector/IndexedSurfacesGeneratorTests.cpp +++ b/Tests/UnitTests/Core/Detector/IndexedSurfacesGeneratorTests.cpp @@ -20,7 +20,7 @@ #include "Acts/Surfaces/RadialBounds.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Tests/CommonHelpers/CylindricalTrackingGeometry.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/BinningType.hpp" #include "Acts/Utilities/Delegate.hpp" #include "Acts/Utilities/Enumerate.hpp" @@ -54,7 +54,7 @@ BOOST_AUTO_TEST_CASE(RingDisc1D) { 55., 0., 2., 22u); IndexedSurfacesGenerator - irSurfaces{rSurfaces, {}, {BinningValue::binPhi}}; + irSurfaces{rSurfaces, {}, {AxisDirection::AxisPhi}}; GridAxisGenerators::EqClosed aGenerator{{-std::numbers::pi, std::numbers::pi}, 44u}; @@ -100,7 +100,7 @@ BOOST_AUTO_TEST_CASE(RingDisc1DWithSupport) { rSurfaces.push_back(dSurface.get()); IndexedSurfacesGenerator - irSurfaces{rSurfaces, {rSurfaces.size() - 1u}, {BinningValue::binPhi}}; + irSurfaces{rSurfaces, {rSurfaces.size() - 1u}, {AxisDirection::AxisPhi}}; GridAxisGenerators::EqClosed aGenerator{{-std::numbers::pi, std::numbers::pi}, 44u}; @@ -148,7 +148,7 @@ BOOST_AUTO_TEST_CASE(RingDisc2D) { rSurfaces.insert(rSurfaces.end(), rSurfacesR1.begin(), rSurfacesR1.end()); IndexedSurfacesGenerator - irSurfaces{rSurfaces, {}, {BinningValue::binR, BinningValue::binPhi}}; + irSurfaces{rSurfaces, {}, {AxisDirection::AxisR, AxisDirection::AxisPhi}}; GridAxisGenerators::VarBoundEqClosed aGenerator{ {24., 74., 110.}, {-std::numbers::pi, std::numbers::pi}, 44u}; @@ -194,7 +194,7 @@ BOOST_AUTO_TEST_CASE(RingDisc2DFine) { rSurfaces.insert(rSurfaces.end(), rSurfacesR2.begin(), rSurfacesR2.end()); IndexedSurfacesGenerator - irSurfaces{rSurfaces, {}, {BinningValue::binR, BinningValue::binPhi}}; + irSurfaces{rSurfaces, {}, {AxisDirection::AxisR, AxisDirection::AxisPhi}}; GridAxisGenerators::EqBoundEqClosed aGenerator{ {24., 152}, 8u, {-std::numbers::pi, std::numbers::pi}, 88u}; @@ -241,8 +241,10 @@ BOOST_AUTO_TEST_CASE(RingDisc2DFineExpanded) { rSurfaces.insert(rSurfaces.end(), rSurfacesR2.begin(), rSurfacesR2.end()); IndexedSurfacesGenerator - irSurfaces{ - rSurfaces, {}, {BinningValue::binR, BinningValue::binPhi}, {2u, 4u}}; + irSurfaces{rSurfaces, + {}, + {AxisDirection::AxisR, AxisDirection::AxisPhi}, + {2u, 4u}}; GridAxisGenerators::EqBoundEqClosed aGenerator{ {24., 152}, 8u, {-std::numbers::pi, std::numbers::pi}, 88u}; @@ -276,8 +278,10 @@ BOOST_AUTO_TEST_CASE(Cylinder2D) { 116., 3., 2., {52, 14}); IndexedSurfacesGenerator - icSurfaces{ - surfaces, {}, {BinningValue::binZ, BinningValue::binPhi}, {1u, 1u}}; + icSurfaces{surfaces, + {}, + {AxisDirection::AxisZ, AxisDirection::AxisPhi}, + {1u, 1u}}; GridAxisGenerators::EqBoundEqClosed aGenerator{ {-500., 500}, 28, {-std::numbers::pi, std::numbers::pi}, 52u}; diff --git a/Tests/UnitTests/Core/Detector/KdtSurfacesProviderTests.cpp b/Tests/UnitTests/Core/Detector/KdtSurfacesProviderTests.cpp index 254ded41d52..d12f0874a6c 100644 --- a/Tests/UnitTests/Core/Detector/KdtSurfacesProviderTests.cpp +++ b/Tests/UnitTests/Core/Detector/KdtSurfacesProviderTests.cpp @@ -99,12 +99,12 @@ BOOST_AUTO_TEST_CASE(KdtSurfacesProvider) { using KDTS = Acts::Experimental::KdtSurfaces<>; auto skdt = std::make_shared( - KDTS(tContext, pSurfaces, {BinningValue::binZ, BinningValue::binR})); + KDTS(tContext, pSurfaces, {AxisDirection::AxisZ, AxisDirection::AxisR})); // query: Negative disc 3, it should yield 22 surfaces Acts::Extent regionND3; - regionND3.set(BinningValue::binZ, -820, -780); - regionND3.set(BinningValue::binR, 0., 200.); + regionND3.set(AxisDirection::AxisZ, -820, -780); + regionND3.set(AxisDirection::AxisR, 0., 200.); Acts::Experimental::KdtSurfacesProvider<> end3(skdt, regionND3); auto nd3 = end3.surfaces(tContext); @@ -112,8 +112,8 @@ BOOST_AUTO_TEST_CASE(KdtSurfacesProvider) { // query: 2nd Pixel barrel Acts::Extent regionB1; - regionB1.set(BinningValue::binZ, -580, 580); - regionB1.set(BinningValue::binR, 60., 80.); + regionB1.set(AxisDirection::AxisZ, -580, 580); + regionB1.set(AxisDirection::AxisR, 60., 80.); Acts::Experimental::KdtSurfacesProvider<> ba1(skdt, regionB1); diff --git a/Tests/UnitTests/Core/Detector/LayerStructureBuilderTests.cpp b/Tests/UnitTests/Core/Detector/LayerStructureBuilderTests.cpp index bf4009335c6..cb36e6cf99f 100644 --- a/Tests/UnitTests/Core/Detector/LayerStructureBuilderTests.cpp +++ b/Tests/UnitTests/Core/Detector/LayerStructureBuilderTests.cpp @@ -68,7 +68,7 @@ BOOST_AUTO_TEST_CASE(LayerStructureBuilder_creationRing) { lsConfig.auxiliary = "*** Endcap with 22 surfaces ***"; lsConfig.surfacesProvider = endcapSurfaces; lsConfig.binnings = { - ProtoBinning(Acts::BinningValue::binPhi, Acts::AxisBoundaryType::Closed, + ProtoBinning(Acts::AxisDirection::AxisPhi, Acts::AxisBoundaryType::Closed, -std::numbers::pi, std::numbers::pi, 22u, 1u)}; auto endcapBuilder = Acts::Experimental::LayerStructureBuilder( @@ -89,8 +89,8 @@ BOOST_AUTO_TEST_CASE(LayerStructureBuilder_creationRing) { LayerSupport supportDisc; supportDisc.type = Acts::Surface::SurfaceType::Disc; supportDisc.offset = 15.; - supportDisc.internalConstraints = {Acts::BinningValue::binZ, - Acts::BinningValue::binR}; + supportDisc.internalConstraints = {Acts::AxisDirection::AxisZ, + Acts::AxisDirection::AxisR}; lsConfig.auxiliary = "*** Endcap with 22 surfaces + 1 support disc, " @@ -118,9 +118,9 @@ BOOST_AUTO_TEST_CASE(LayerStructureBuilder_creationRing) { // clearance: z is still from internals, but r is from the volume/external // // Second test with one support disc, but external constraint - supportDisc.internalConstraints = {Acts::BinningValue::binZ}; - supportDisc.volumeExtent.set(Acts::BinningValue::binR, 10., 120.); - supportDisc.volumeClearance[Acts::BinningValue::binR] = {2., 1.}; + supportDisc.internalConstraints = {Acts::AxisDirection::AxisZ}; + supportDisc.volumeExtent.set(Acts::AxisDirection::AxisR, 10., 120.); + supportDisc.volumeClearance[Acts::AxisDirection::AxisR] = {2., 1.}; lsConfig.supports = {supportDisc}; @@ -187,11 +187,11 @@ BOOST_AUTO_TEST_CASE(LayerStructureBuilder_creationCylinder) { lsConfig.auxiliary = "*** Barrel with 448 surfaces ***"; lsConfig.surfacesProvider = barrelSurfaces; lsConfig.binnings = { - Acts::Experimental::ProtoBinning{Acts::BinningValue::binZ, + Acts::Experimental::ProtoBinning{Acts::AxisDirection::AxisZ, Acts::AxisBoundaryType::Bound, -480., 480., 14u, 1u}, Acts::Experimental::ProtoBinning( - Acts::BinningValue::binPhi, Acts::AxisBoundaryType::Closed, + Acts::AxisDirection::AxisPhi, Acts::AxisBoundaryType::Closed, -std::numbers::pi, std::numbers::pi, 32u, 1u)}; auto barrelBuilder = Acts::Experimental::LayerStructureBuilder( @@ -211,8 +211,8 @@ BOOST_AUTO_TEST_CASE(LayerStructureBuilder_creationCylinder) { LayerSupport supportCylinder; supportCylinder.type = Acts::Surface::SurfaceType::Cylinder; supportCylinder.offset = 15.; - supportCylinder.internalConstraints = {Acts::BinningValue::binZ, - Acts::BinningValue::binR}; + supportCylinder.internalConstraints = {Acts::AxisDirection::AxisZ, + Acts::AxisDirection::AxisR}; lsConfig.supports = {supportCylinder}; lsConfig.auxiliary = "*** Barrel with 448 surfaces + 1 support cylinder, r/z evaluated ***"; @@ -229,9 +229,9 @@ BOOST_AUTO_TEST_CASE(LayerStructureBuilder_creationCylinder) { BOOST_CHECK(volumeUpdater1.connected()); // Second test: z-range externally given - supportCylinder.internalConstraints = {Acts::BinningValue::binR}; - supportCylinder.volumeExtent.set(Acts::BinningValue::binZ, -600., 600.); - supportCylinder.volumeClearance[Acts::BinningValue::binZ] = {2., 2.}; + supportCylinder.internalConstraints = {Acts::AxisDirection::AxisR}; + supportCylinder.volumeExtent.set(Acts::AxisDirection::AxisZ, -600., 600.); + supportCylinder.volumeClearance[Acts::AxisDirection::AxisZ] = {2., 2.}; lsConfig.supports = {supportCylinder}; lsConfig.auxiliary = "*** Barrel with 448 surfaces + 1 support cylinder, r evaluated, z given " diff --git a/Tests/UnitTests/Core/Detector/MultiWireStructureBuilderTests.cpp b/Tests/UnitTests/Core/Detector/MultiWireStructureBuilderTests.cpp index e9daba0e0a0..3939908064b 100644 --- a/Tests/UnitTests/Core/Detector/MultiWireStructureBuilderTests.cpp +++ b/Tests/UnitTests/Core/Detector/MultiWireStructureBuilderTests.cpp @@ -72,9 +72,9 @@ BOOST_AUTO_TEST_CASE(Multi_Wire_Structure_Builder_StrawSurfacesCreation) { mlCfg.mlSurfaces = strawSurfaces; mlCfg.mlBounds = vBounds; mlCfg.mlBinning = { - ProtoBinning(Acts::BinningValue::binX, Acts::AxisBoundaryType::Bound, + ProtoBinning(Acts::AxisDirection::AxisX, Acts::AxisBoundaryType::Bound, -vBounds[0], vBounds[0], nSurfacesX, 1u), - ProtoBinning(Acts::BinningValue::binY, Acts::AxisBoundaryType::Bound, + ProtoBinning(Acts::AxisDirection::AxisY, Acts::AxisBoundaryType::Bound, -vBounds[1], vBounds[1], nSurfacesY, 0u)}; MultiWireStructureBuilder mlBuilder(mlCfg); diff --git a/Tests/UnitTests/Core/Detector/PortalTests.cpp b/Tests/UnitTests/Core/Detector/PortalTests.cpp index 46d6b32b94c..46a0558db9d 100644 --- a/Tests/UnitTests/Core/Detector/PortalTests.cpp +++ b/Tests/UnitTests/Core/Detector/PortalTests.cpp @@ -88,8 +88,8 @@ BOOST_AUTO_TEST_CASE(PortalTest) { auto linkToAImpl = std::make_unique(volumeA); ExternalNavigationDelegate linkToA; linkToA.connect<&LinkToVolumeImpl::link>(std::move(linkToAImpl)); - portalA->assignPortalNavigation(Acts::Direction::Positive, std::move(linkToA), - {volumeA}); + portalA->assignPortalNavigation(Acts::Direction::Positive(), + std::move(linkToA), {volumeA}); auto attachedDetectorVolumes = portalA->attachedDetectorVolumes(); BOOST_CHECK(attachedDetectorVolumes[0u].empty()); @@ -111,8 +111,8 @@ BOOST_AUTO_TEST_CASE(PortalTest) { ExternalNavigationDelegate linkToB; auto linkToBImpl = std::make_unique(volumeB); linkToB.connect<&LinkToVolumeImpl::link>(std::move(linkToBImpl)); - portalB->assignPortalNavigation(Acts::Direction::Negative, std::move(linkToB), - {volumeB}); + portalB->assignPortalNavigation(Acts::Direction::Negative(), + std::move(linkToB), {volumeB}); // Reverse: positive volume nullptr, negative volume volumeB nState.direction = Acts::Vector3(0., 0., 1.); @@ -206,8 +206,8 @@ BOOST_AUTO_TEST_CASE(PortalMaterialTest) { ExternalNavigationDelegate linkToA; auto linkToAImpl = std::make_unique(volumeA); linkToA.connect<&LinkToVolumeImpl::link>(std::move(linkToAImpl)); - portalA->assignPortalNavigation(Acts::Direction::Positive, std::move(linkToA), - {volumeA}); + portalA->assignPortalNavigation(Acts::Direction::Positive(), + std::move(linkToA), {volumeA}); auto surfaceB = Acts::Surface::makeShared( Acts::Transform3::Identity(), rectangle); @@ -215,8 +215,8 @@ BOOST_AUTO_TEST_CASE(PortalMaterialTest) { ExternalNavigationDelegate linkToB; auto linkToBImpl = std::make_unique(volumeB); linkToB.connect<&LinkToVolumeImpl::link>(std::move(linkToBImpl)); - portalB->assignPortalNavigation(Acts::Direction::Negative, std::move(linkToB), - {volumeB}); + portalB->assignPortalNavigation(Acts::Direction::Negative(), + std::move(linkToB), {volumeB}); // Portal A fuses with B // - has material and keeps it @@ -228,7 +228,7 @@ BOOST_AUTO_TEST_CASE(PortalMaterialTest) { ExternalNavigationDelegate linkToB2; auto linkToB2Impl = std::make_unique(volumeB); linkToB2.connect<&LinkToVolumeImpl::link>(std::move(linkToB2Impl)); - portalB->assignPortalNavigation(Acts::Direction::Negative, + portalB->assignPortalNavigation(Acts::Direction::Negative(), std::move(linkToB2), {volumeB}); // Portal B fuses with A @@ -238,7 +238,7 @@ BOOST_AUTO_TEST_CASE(PortalMaterialTest) { // This fails because A has accumulated volumes on both sides through fusing BOOST_CHECK_THROW(Portal::fuse(portalB, portalA), std::invalid_argument); // Remove Negative volume on A - portalA->assignPortalNavigation(Acts::Direction::Negative, + portalA->assignPortalNavigation(Acts::Direction::Negative(), ExternalNavigationDelegate{}, {}); portalB = Portal::fuse(portalB, portalA); @@ -249,7 +249,7 @@ BOOST_AUTO_TEST_CASE(PortalMaterialTest) { ExternalNavigationDelegate linkToA2; auto linkToA2Impl = std::make_unique(volumeA); linkToA2.connect<&LinkToVolumeImpl::link>(std::move(linkToA2Impl)); - portalA->assignPortalNavigation(Acts::Direction::Positive, + portalA->assignPortalNavigation(Acts::Direction::Positive(), std::move(linkToA2), {volumeA}); surfaceB->assignSurfaceMaterial(materialB); @@ -257,7 +257,7 @@ BOOST_AUTO_TEST_CASE(PortalMaterialTest) { ExternalNavigationDelegate linkToB3; auto linkToB3Impl = std::make_unique(volumeB); linkToB3.connect<&LinkToVolumeImpl::link>(std::move(linkToB3Impl)); - portalB->assignPortalNavigation(Acts::Direction::Negative, + portalB->assignPortalNavigation(Acts::Direction::Negative(), std::move(linkToB3), {volumeB}); // Portal A fuses with B - both have material, throw exception diff --git a/Tests/UnitTests/Core/Detector/ProtoBinningTests.cpp b/Tests/UnitTests/Core/Detector/ProtoBinningTests.cpp index 46492d9f27c..269292acd2d 100644 --- a/Tests/UnitTests/Core/Detector/ProtoBinningTests.cpp +++ b/Tests/UnitTests/Core/Detector/ProtoBinningTests.cpp @@ -20,29 +20,29 @@ BOOST_AUTO_TEST_SUITE(Detector) BOOST_AUTO_TEST_CASE(ProtoBinningPlaceHolderEquidistant) { // A valid placeholder binning - auto peq = - ProtoBinning(Acts::BinningValue::binX, Acts::AxisBoundaryType::Bound, 5u); + auto peq = ProtoBinning(Acts::AxisDirection::AxisX, + Acts::AxisBoundaryType::Bound, 5u); BOOST_CHECK_EQUAL(peq.bins(), 5u); } BOOST_AUTO_TEST_CASE(ProtoBinningEquidistant) { // An invalid binning, 0 bins given - BOOST_CHECK_THROW(ProtoBinning(Acts::BinningValue::binX, + BOOST_CHECK_THROW(ProtoBinning(Acts::AxisDirection::AxisX, Acts::AxisBoundaryType::Bound, 15., 20., 0), std::invalid_argument); // Another invalid binning, min/max swapped - BOOST_CHECK_THROW(ProtoBinning(Acts::BinningValue::binX, + BOOST_CHECK_THROW(ProtoBinning(Acts::AxisDirection::AxisX, Acts::AxisBoundaryType::Bound, 150., 20., 10), std::invalid_argument); // A valid binning - auto eq = ProtoBinning(Acts::BinningValue::binX, + auto eq = ProtoBinning(Acts::AxisDirection::AxisX, Acts::AxisBoundaryType::Bound, 0., 10., 5u); std::vector reference = {0., 2., 4., 6., 8., 10.}; BOOST_CHECK_EQUAL(eq.bins(), 5u); - BOOST_CHECK_EQUAL(eq.binValue, Acts::BinningValue::binX); + BOOST_CHECK_EQUAL(eq.axisDir, Acts::AxisDirection::AxisX); BOOST_CHECK(eq.axisType == Acts::AxisType::Equidistant); BOOST_CHECK(eq.boundaryType == Acts::AxisBoundaryType::Bound); BOOST_CHECK_EQUAL_COLLECTIONS(eq.edges.begin(), eq.edges.end(), @@ -52,17 +52,17 @@ BOOST_AUTO_TEST_CASE(ProtoBinningEquidistant) { BOOST_AUTO_TEST_CASE(ProtoBinningVariable) { // An invalid binning, edge size < 2u std::vector iedges = {12.}; - BOOST_CHECK_THROW(ProtoBinning(Acts::BinningValue::binX, + BOOST_CHECK_THROW(ProtoBinning(Acts::AxisDirection::AxisX, Acts::AxisBoundaryType::Bound, iedges), std::invalid_argument); // A valid binning std::vector varEdges = {0., 12., 13., 15., 20.}; - auto var = ProtoBinning(Acts::BinningValue::binX, + auto var = ProtoBinning(Acts::AxisDirection::AxisX, Acts::AxisBoundaryType::Bound, varEdges); BOOST_CHECK_EQUAL(var.bins(), 4u); - BOOST_CHECK_EQUAL(var.binValue, Acts::BinningValue::binX); + BOOST_CHECK_EQUAL(var.axisDir, Acts::AxisDirection::AxisX); BOOST_CHECK(var.axisType == Acts::AxisType::Variable); BOOST_CHECK(var.boundaryType == Acts::AxisBoundaryType::Bound); BOOST_CHECK_EQUAL_COLLECTIONS(var.edges.begin(), var.edges.end(), @@ -71,9 +71,11 @@ BOOST_AUTO_TEST_CASE(ProtoBinningVariable) { BOOST_AUTO_TEST_CASE(BinningDescriptionFromAndToBinUtility) { // A valid binning - Acts::BinUtility bUtility(5u, 0., 10., Acts::open, Acts::BinningValue::binR); + Acts::BinUtility bUtility(5u, 0., 10., Acts::open, + Acts::AxisDirection::AxisR); std::vector edges = {-std::numbers::pi, 0.1, std::numbers::pi}; - bUtility += Acts::BinUtility(edges, Acts::closed, Acts::BinningValue::binPhi); + bUtility += + Acts::BinUtility(edges, Acts::closed, Acts::AxisDirection::AxisPhi); auto bDescription = BinningDescription::fromBinUtility(bUtility); @@ -81,7 +83,8 @@ BOOST_AUTO_TEST_CASE(BinningDescriptionFromAndToBinUtility) { // Test the first entry BOOST_CHECK_EQUAL(bDescription.binning[0].bins(), 5u); - BOOST_CHECK_EQUAL(bDescription.binning[0].binValue, Acts::BinningValue::binR); + BOOST_CHECK_EQUAL(bDescription.binning[0].axisDir, + Acts::AxisDirection::AxisR); BOOST_CHECK(bDescription.binning[0].axisType == Acts::AxisType::Equidistant); BOOST_CHECK(bDescription.binning[0].boundaryType == Acts::AxisBoundaryType::Bound); @@ -89,8 +92,8 @@ BOOST_AUTO_TEST_CASE(BinningDescriptionFromAndToBinUtility) { // Check the second entry BOOST_CHECK_EQUAL(bDescription.binning[1].bins(), 2u); - BOOST_CHECK_EQUAL(bDescription.binning[1].binValue, - Acts::BinningValue::binPhi); + BOOST_CHECK_EQUAL(bDescription.binning[1].axisDir, + Acts::AxisDirection::AxisPhi); BOOST_CHECK(bDescription.binning[1].axisType == Acts::AxisType::Variable); BOOST_CHECK(bDescription.binning[1].boundaryType == Acts::AxisBoundaryType::Closed); diff --git a/Tests/UnitTests/Core/Detector/ProtoDetectorTests.cpp b/Tests/UnitTests/Core/Detector/ProtoDetectorTests.cpp index 71d571eda37..a8d7ee5cd55 100644 --- a/Tests/UnitTests/Core/Detector/ProtoDetectorTests.cpp +++ b/Tests/UnitTests/Core/Detector/ProtoDetectorTests.cpp @@ -35,56 +35,56 @@ Acts::ProtoDetector createProtoDetector() { // Container Acts::ProtoVolume detectorVolume; detectorVolume.name = "detector-container"; - detectorVolume.extent.set(Acts::BinningValue::binZ, -2000., 2000); + detectorVolume.extent.set(Acts::AxisDirection::AxisZ, -2000., 2000); // Beam Pipe volume Acts::ProtoVolume beamPipe; beamPipe.name = "beam-pipe"; - beamPipe.extent.set(Acts::BinningValue::binR, 0., 30.); + beamPipe.extent.set(Acts::AxisDirection::AxisR, 0., 30.); // Pixel section Acts::ProtoVolume pixelContainer; pixelContainer.name = "pixel-container"; - pixelContainer.extent.set(Acts::BinningValue::binR, 40., 200); + pixelContainer.extent.set(Acts::AxisDirection::AxisR, 40., 200); // Pixel volume sub structure Acts::ProtoVolume pixelNec; pixelNec.name = "pixel-nec"; - pixelNec.extent.set(Acts::BinningValue::binZ, -1900., -600); + pixelNec.extent.set(Acts::AxisDirection::AxisZ, -1900., -600); Acts::ProtoVolume pixelBarrel; pixelBarrel.name = "pixel-barrel"; - pixelBarrel.extent.set(Acts::BinningValue::binR, 41., 199.); - pixelBarrel.extent.set(Acts::BinningValue::binZ, -550., 550.); + pixelBarrel.extent.set(Acts::AxisDirection::AxisR, 41., 199.); + pixelBarrel.extent.set(Acts::AxisDirection::AxisZ, -550., 550.); Acts::ProtoVolume pixelBarrelL0; pixelBarrelL0.name = "pixel-barrel-l0"; - pixelBarrelL0.extent.set(Acts::BinningValue::binR, 45., 50.); + pixelBarrelL0.extent.set(Acts::AxisDirection::AxisR, 45., 50.); pixelBarrelL0.internal = Acts::ProtoVolume::InternalStructure{ Acts::Surface::SurfaceType::Cylinder}; Acts::ProtoVolume pixelBarrelL1; pixelBarrelL1.name = "pixel-barrel-l1"; - pixelBarrelL1.extent.set(Acts::BinningValue::binR, 70., 80.); + pixelBarrelL1.extent.set(Acts::AxisDirection::AxisR, 70., 80.); pixelBarrelL1.internal = Acts::ProtoVolume::InternalStructure{ Acts::Surface::SurfaceType::Cylinder}; pixelBarrel.container = Acts::ProtoVolume::ContainerStructure{ {pixelBarrelL0, pixelBarrelL1}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binR, {0., 1.})}, + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisR, {0., 1.})}, true}; Acts::ProtoVolume pixelPec; pixelPec.name = "pixel-pec"; - pixelPec.extent.set(Acts::BinningValue::binZ, 600., 1900.); + pixelPec.extent.set(Acts::AxisDirection::AxisZ, 600., 1900.); pixelContainer.container = Acts::ProtoVolume::ContainerStructure{ {pixelNec, pixelBarrel, pixelPec}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binZ, {0., 1})}}; + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisZ, {0., 1})}}; detectorVolume.container = Acts::ProtoVolume::ContainerStructure{ {beamPipe, pixelContainer}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binR, {0., 1})}}; + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisR, {0., 1})}}; Acts::ProtoDetector detector; detector.name = "detector"; @@ -108,10 +108,10 @@ BOOST_AUTO_TEST_CASE(ProtoTrackingGeometryTests) { auto& detectorVolume = detector.worldVolume; // The detector volume should have received maximum dimensions - CHECK_CLOSE_ABS(detectorVolume.extent.min(Acts::BinningValue::binR), 0, + CHECK_CLOSE_ABS(detectorVolume.extent.min(Acts::AxisDirection::AxisR), 0, std::numeric_limits::epsilon()); - CHECK_CLOSE_ABS(detectorVolume.extent.max(Acts::BinningValue::binR), 200., + CHECK_CLOSE_ABS(detectorVolume.extent.max(Acts::AxisDirection::AxisR), 200., std::numeric_limits::epsilon()); // The detector container should have binning in R @@ -123,7 +123,7 @@ BOOST_AUTO_TEST_CASE(ProtoTrackingGeometryTests) { BOOST_CHECK_EQUAL(cts.constituentBinning.size(), 1u); BOOST_CHECK_EQUAL(cts.constituentBinning[0].type, Acts::arbitrary); BOOST_CHECK_EQUAL(cts.constituentBinning[0].binvalue, - Acts::BinningValue::binR); + Acts::AxisDirection::AxisR); const auto& binBoundaries = cts.constituentBinning[0].boundaries(); BOOST_CHECK_EQUAL(binBoundaries.size(), 3u); @@ -139,14 +139,14 @@ BOOST_AUTO_TEST_CASE(ProtoTrackingGeometryTests) { auto& beamPipe = cts.constituentVolumes[0u]; BOOST_CHECK_EQUAL(beamPipe.name, "beam-pipe"); - CHECK_CLOSE_ABS(beamPipe.extent.min(Acts::BinningValue::binZ), -2000., + CHECK_CLOSE_ABS(beamPipe.extent.min(Acts::AxisDirection::AxisZ), -2000., std::numeric_limits::epsilon()); - CHECK_CLOSE_ABS(beamPipe.extent.max(Acts::BinningValue::binZ), 2000., + CHECK_CLOSE_ABS(beamPipe.extent.max(Acts::AxisDirection::AxisZ), 2000., std::numeric_limits::epsilon()); // The new beam pipe radius should have been applied - CHECK_CLOSE_ABS(beamPipe.extent.max(Acts::BinningValue::binR), 35., + CHECK_CLOSE_ABS(beamPipe.extent.max(Acts::AxisDirection::AxisR), 35., std::numeric_limits::epsilon()); // The second volume is the pixel detector @@ -154,13 +154,13 @@ BOOST_AUTO_TEST_CASE(ProtoTrackingGeometryTests) { BOOST_CHECK_EQUAL(pixelContainer.name, "pixel-container"); // Pixel container should have fitting boundaries - CHECK_CLOSE_ABS(pixelContainer.extent.min(Acts::BinningValue::binR), 35., + CHECK_CLOSE_ABS(pixelContainer.extent.min(Acts::AxisDirection::AxisR), 35., std::numeric_limits::epsilon()); - CHECK_CLOSE_ABS(pixelContainer.extent.max(Acts::BinningValue::binR), 200., + CHECK_CLOSE_ABS(pixelContainer.extent.max(Acts::AxisDirection::AxisR), 200., std::numeric_limits::epsilon()); - CHECK_CLOSE_ABS(pixelContainer.extent.min(Acts::BinningValue::binZ), -2000., + CHECK_CLOSE_ABS(pixelContainer.extent.min(Acts::AxisDirection::AxisZ), -2000., std::numeric_limits::epsilon()); - CHECK_CLOSE_ABS(pixelContainer.extent.max(Acts::BinningValue::binZ), 2000., + CHECK_CLOSE_ABS(pixelContainer.extent.max(Acts::AxisDirection::AxisZ), 2000., std::numeric_limits::epsilon()); // The Pixel container has constituents @@ -170,10 +170,10 @@ BOOST_AUTO_TEST_CASE(ProtoTrackingGeometryTests) { // All of the internal containers should now have synchronized // inner & outer boundaries for (auto& pv : cts1.constituentVolumes) { - CHECK_CLOSE_ABS(pv.extent.min(Acts::BinningValue::binR), 35., + CHECK_CLOSE_ABS(pv.extent.min(Acts::AxisDirection::AxisR), 35., std::numeric_limits::epsilon()); - CHECK_CLOSE_ABS(pv.extent.max(Acts::BinningValue::binR), 200., + CHECK_CLOSE_ABS(pv.extent.max(Acts::AxisDirection::AxisR), 200., std::numeric_limits::epsilon()); } @@ -181,7 +181,7 @@ BOOST_AUTO_TEST_CASE(ProtoTrackingGeometryTests) { BOOST_CHECK_EQUAL(cts1.constituentBinning.size(), 1u); BOOST_CHECK_EQUAL(cts1.constituentBinning[0].type, Acts::arbitrary); BOOST_CHECK_EQUAL(cts1.constituentBinning[0].binvalue, - Acts::BinningValue::binZ); + Acts::AxisDirection::AxisZ); const auto& binBoundariesZ = cts1.constituentBinning[0].boundaries(); BOOST_CHECK_EQUAL(binBoundariesZ.size(), 4u); diff --git a/Tests/UnitTests/Core/Detector/ReferenceGeneratorsTests.cpp b/Tests/UnitTests/Core/Detector/ReferenceGeneratorsTests.cpp index 662119ab3a1..c623bc23fa0 100644 --- a/Tests/UnitTests/Core/Detector/ReferenceGeneratorsTests.cpp +++ b/Tests/UnitTests/Core/Detector/ReferenceGeneratorsTests.cpp @@ -41,10 +41,10 @@ BOOST_AUTO_TEST_CASE(CenterReference) { BOOST_AUTO_TEST_CASE(BinningPositionReference) { // Simply return binning position, we test only the behavior of the generator // not the output - auto binningPosition = - BinningValueReferenceGenerator{}.references( + auto referencePosition = + AxisDirectionReferenceGenerator{}.references( tContext, *pSurface); - BOOST_CHECK_EQUAL(binningPosition.size(), 1u); + BOOST_CHECK_EQUAL(referencePosition.size(), 1u); } BOOST_AUTO_TEST_CASE(PolyhedronReference) { diff --git a/Tests/UnitTests/Core/Detector/SupportSurfacesHelperTests.cpp b/Tests/UnitTests/Core/Detector/SupportSurfacesHelperTests.cpp index c93f529db78..d76b90be92b 100644 --- a/Tests/UnitTests/Core/Detector/SupportSurfacesHelperTests.cpp +++ b/Tests/UnitTests/Core/Detector/SupportSurfacesHelperTests.cpp @@ -43,8 +43,8 @@ BOOST_AUTO_TEST_CASE(CylindricalSupportCase) { // phi max = 2pi Acts::Extent lExtent; - lExtent.set(Acts::BinningValue::binR, 100., 110.); - lExtent.set(Acts::BinningValue::binZ, -400., 400.); + lExtent.set(Acts::AxisDirection::AxisR, 100., 110.); + lExtent.set(Acts::AxisDirection::AxisZ, -400., 400.); // Test creation of surface components CylindricalSupport csCreator{10., {1., 1.}}; @@ -101,8 +101,8 @@ BOOST_AUTO_TEST_CASE(DiscSupportCase) { // phi min = 0 // phi max = 2pi Acts::Extent lExtent; - lExtent.set(Acts::BinningValue::binR, 100., 400.); - lExtent.set(Acts::BinningValue::binZ, -405., -395.); + lExtent.set(Acts::AxisDirection::AxisR, 100., 400.); + lExtent.set(Acts::AxisDirection::AxisZ, -405., -395.); // Test creation of surface components DiscSupport dsCreator{0., {1., 1.}}; @@ -162,14 +162,14 @@ BOOST_AUTO_TEST_CASE(RectangularSupportCase) { // dy = [-200,200] // dz = [-50, -60] Acts::Extent lExtent; - lExtent.set(Acts::BinningValue::binX, -100., 100.); - lExtent.set(Acts::BinningValue::binY, -200., 200.); - lExtent.set(Acts::BinningValue::binZ, -60., -50.); + lExtent.set(Acts::AxisDirection::AxisX, -100., 100.); + lExtent.set(Acts::AxisDirection::AxisY, -200., 200.); + lExtent.set(Acts::AxisDirection::AxisZ, -60., -50.); // place in Z with offset 2_mm // Asymmetric clearances in x an y for testing RectangularSupport rsCreator{ - Acts::BinningValue::binZ, 2., {1., 2.}, {3., 4.}}; + Acts::AxisDirection::AxisZ, 2., {1., 2.}, {3., 4.}}; auto rsComponents = rsCreator(lExtent); auto& [rsType, rsValues, rsTransform] = rsComponents; @@ -192,8 +192,8 @@ BOOST_AUTO_TEST_CASE(RectangularSupportCase) { // Invalid / runtime checks Acts::Extent invalid; - invalid.set(Acts::BinningValue::binX, -100., 100.); - invalid.set(Acts::BinningValue::binY, -200., 200.); + invalid.set(Acts::AxisDirection::AxisX, -100., 100.); + invalid.set(Acts::AxisDirection::AxisY, -200., 200.); BOOST_CHECK_THROW(rsCreator(invalid), std::invalid_argument); } @@ -209,8 +209,8 @@ BOOST_AUTO_TEST_CASE(addCylinderSupportCase) { // -> did yield and extend of 100 < r 110 // The volume would give an extend of -400 < z < 400 Acts::Extent lExtent; - lExtent.set(Acts::BinningValue::binR, 100., 110.); - lExtent.set(Acts::BinningValue::binZ, -400., 400.); + lExtent.set(Acts::AxisDirection::AxisR, 100., 110.); + lExtent.set(Acts::AxisDirection::AxisZ, -400., 400.); // Cylinder support CylindricalSupport csCreator{10., {1., 1.}}; @@ -249,8 +249,8 @@ BOOST_AUTO_TEST_CASE(addDiscSupportCase) { // The Extent Acts::Extent lExtent; - lExtent.set(Acts::BinningValue::binR, 100., 400.); - lExtent.set(Acts::BinningValue::binZ, -110., -100.); + lExtent.set(Acts::AxisDirection::AxisR, 100., 400.); + lExtent.set(Acts::AxisDirection::AxisZ, -110., -100.); // Disc support: this would set the disc at the center DiscSupport dsCreator{0., {1., 1.}}; @@ -291,14 +291,14 @@ BOOST_AUTO_TEST_CASE(addRectangularSupportCase) { // dy = [-200,200] // dz = [-50, -60] Acts::Extent lExtent; - lExtent.set(Acts::BinningValue::binX, -100., 100.); - lExtent.set(Acts::BinningValue::binY, -200., 200.); - lExtent.set(Acts::BinningValue::binZ, -60., -50.); + lExtent.set(Acts::AxisDirection::AxisX, -100., 100.); + lExtent.set(Acts::AxisDirection::AxisY, -200., 200.); + lExtent.set(Acts::AxisDirection::AxisZ, -60., -50.); // place in Z with offset 2_mm // Asymmetric clearances in x an y for testing RectangularSupport rsCreator{ - Acts::BinningValue::binZ, 2., {1., 2.}, {3., 4.}}; + Acts::AxisDirection::AxisZ, 2., {1., 2.}, {3., 4.}}; // Add a single disc as a support surface Acts::Experimental::detail::SupportSurfacesHelper::addSupport( @@ -337,8 +337,8 @@ BOOST_AUTO_TEST_CASE(addMisconfiguredSupportCase) { std::invalid_argument); // The Extent - lExtent.set(Acts::BinningValue::binR, 100., 400.); - lExtent.set(Acts::BinningValue::binZ, -110., -100.); + lExtent.set(Acts::AxisDirection::AxisR, 100., 400.); + lExtent.set(Acts::AxisDirection::AxisZ, -110., -100.); // Wrong surface type struct InvalidCreator { diff --git a/Tests/UnitTests/Core/Detector/VolumeStructureBuilderTests.cpp b/Tests/UnitTests/Core/Detector/VolumeStructureBuilderTests.cpp index 9d7064a52a4..fb50110efd6 100644 --- a/Tests/UnitTests/Core/Detector/VolumeStructureBuilderTests.cpp +++ b/Tests/UnitTests/Core/Detector/VolumeStructureBuilderTests.cpp @@ -107,9 +107,9 @@ BOOST_AUTO_TEST_CASE(VolumeStructureBuilderCuboid) { // Cuboid volume from extent Extent cuboidExtent; - cuboidExtent.set(BinningValue::binX, -100, 100); - cuboidExtent.set(BinningValue::binY, -200, 200); - cuboidExtent.set(BinningValue::binZ, -300, 300); + cuboidExtent.set(AxisDirection::AxisX, -100, 100); + cuboidExtent.set(AxisDirection::AxisY, -200, 200); + cuboidExtent.set(AxisDirection::AxisZ, -300, 300); VolumeStructureBuilder::Config cuboidExtentConfig; cuboidExtentConfig.boundsType = VolumeBounds::BoundsType::eCuboid; @@ -224,8 +224,8 @@ BOOST_AUTO_TEST_CASE(VolumeStructureBuilderCylinder) { // Cylinder volume from extent Extent cylinderExtent; - cylinderExtent.set(BinningValue::binR, 100., 200.); - cylinderExtent.set(BinningValue::binZ, -800., 0.); + cylinderExtent.set(AxisDirection::AxisR, 100., 200.); + cylinderExtent.set(AxisDirection::AxisZ, -800., 0.); VolumeStructureBuilder::Config cylExtentConfig; cylExtentConfig.extent = cylinderExtent; diff --git a/Tests/UnitTests/Core/Geometry/BlueprintApiTests.cpp b/Tests/UnitTests/Core/Geometry/BlueprintApiTests.cpp index 737f410e24b..e3f748a07e8 100644 --- a/Tests/UnitTests/Core/Geometry/BlueprintApiTests.cpp +++ b/Tests/UnitTests/Core/Geometry/BlueprintApiTests.cpp @@ -23,6 +23,8 @@ #include "Acts/Geometry/MaterialDesignatorBlueprintNode.hpp" #include "Acts/Geometry/TrackingGeometry.hpp" #include "Acts/Geometry/TrackingVolume.hpp" +#include "Acts/Geometry/VolumeAttachmentStrategy.hpp" +#include "Acts/Geometry/VolumeResizeStrategy.hpp" #include "Acts/Navigation/INavigationPolicy.hpp" #include "Acts/Navigation/NavigationStream.hpp" #include "Acts/Surfaces/RectangleBounds.hpp" @@ -254,30 +256,29 @@ BOOST_AUTO_TEST_CASE(NodeApiTestContainers) { }; Blueprint::Config cfg; - cfg.envelope[BinningValue::binZ] = {20_mm, 20_mm}; - cfg.envelope[BinningValue::binR] = {0_mm, 20_mm}; + cfg.envelope[AxisDirection::AxisZ] = {20_mm, 20_mm}; + cfg.envelope[AxisDirection::AxisR] = {0_mm, 20_mm}; auto root = std::make_unique(cfg); root->addMaterial("GlobalMaterial", [&](MaterialDesignatorBlueprintNode& mat) { - Experimental::ProtoBinning zBinning{BinningValue::binZ, + Experimental::ProtoBinning zBinning{AxisDirection::AxisZ, AxisBoundaryType::Bound, 20}; - Experimental::ProtoBinning rPhiBinning{BinningValue::binRPhi, + Experimental::ProtoBinning rPhiBinning{AxisDirection::AxisRPhi, AxisBoundaryType::Bound, 20}; mat.setBinning(std::vector{std::tuple{ CylinderVolumeBounds::Face::OuterCylinder, rPhiBinning, zBinning}}); - mat.addCylinderContainer("Detector", BinningValue::binR, [&](auto& det) { - det.addCylinderContainer("Pixel", BinningValue::binZ, [&](auto& cyl) { - cyl.setAttachmentStrategy(CylinderVolumeStack::AttachmentStrategy::Gap) - .setResizeStrategy(CylinderVolumeStack::ResizeStrategy::Gap); + mat.addCylinderContainer("Detector", AxisDirection::AxisR, [&](auto& det) { + det.addCylinderContainer("Pixel", AxisDirection::AxisZ, [&](auto& cyl) { + cyl.setAttachmentStrategy(VolumeAttachmentStrategy::Gap) + .setResizeStrategy(VolumeResizeStrategy::Gap); cyl.addCylinderContainer( - "PixelNegativeEndcap", BinningValue::binZ, [&](auto& ec) { - ec.setAttachmentStrategy( - CylinderVolumeStack::AttachmentStrategy::Gap); + "PixelNegativeEndcap", AxisDirection::AxisZ, [&](auto& ec) { + ec.setAttachmentStrategy(VolumeAttachmentStrategy::Gap); auto makeLayer = [&](const Transform3& trf, auto& layer) { std::vector> surfaces; @@ -307,10 +308,9 @@ BOOST_AUTO_TEST_CASE(NodeApiTestContainers) { }); cyl.addCylinderContainer( - "PixelBarrel", BinningValue::binR, [&](auto& brl) { - brl.setAttachmentStrategy( - CylinderVolumeStack::AttachmentStrategy::Gap) - .setResizeStrategy(CylinderVolumeStack::ResizeStrategy::Gap); + "PixelBarrel", AxisDirection::AxisR, [&](auto& brl) { + brl.setAttachmentStrategy(VolumeAttachmentStrategy::Gap) + .setResizeStrategy(VolumeResizeStrategy::Gap); auto makeLayer = [&](const std::string& name, double r, std::size_t nStaves, int nSensorsPerStave) { @@ -342,8 +342,8 @@ BOOST_AUTO_TEST_CASE(NodeApiTestContainers) { }); auto& ec = - cyl.addCylinderContainer("PixelPosWrapper", BinningValue::binR); - ec.setResizeStrategy(CylinderVolumeStack::ResizeStrategy::Gap); + cyl.addCylinderContainer("PixelPosWrapper", AxisDirection::AxisR); + ec.setResizeStrategy(VolumeResizeStrategy::Gap); ec.addStaticVolume(std::make_unique( base * Translation3{Vector3{0, 0, 600_mm}}, std::make_shared(150_mm, 390_mm, 200_mm), diff --git a/Tests/UnitTests/Core/Geometry/BlueprintTests.cpp b/Tests/UnitTests/Core/Geometry/BlueprintTests.cpp index c3a0ecc028f..15a6263b8c7 100644 --- a/Tests/UnitTests/Core/Geometry/BlueprintTests.cpp +++ b/Tests/UnitTests/Core/Geometry/BlueprintTests.cpp @@ -22,6 +22,7 @@ #include "Acts/Geometry/MaterialDesignatorBlueprintNode.hpp" #include "Acts/Geometry/StaticBlueprintNode.hpp" #include "Acts/Geometry/TrackingVolume.hpp" +#include "Acts/Geometry/VolumeAttachmentStrategy.hpp" #include "Acts/Material/BinnedSurfaceMaterial.hpp" #include "Acts/Material/ProtoSurfaceMaterial.hpp" #include "Acts/Surfaces/RectangleBounds.hpp" @@ -168,8 +169,8 @@ BOOST_AUTO_TEST_CASE(Depth) { BOOST_AUTO_TEST_CASE(Static) { Blueprint::Config cfg; - cfg.envelope[BinningValue::binZ] = {20_mm, 20_mm}; - cfg.envelope[BinningValue::binR] = {1_mm, 2_mm}; + cfg.envelope[AxisDirection::AxisZ] = {20_mm, 20_mm}; + cfg.envelope[AxisDirection::AxisR] = {1_mm, 2_mm}; Blueprint root{cfg}; double hlZ = 30_mm; @@ -209,12 +210,12 @@ BOOST_AUTO_TEST_CASE(Static) { BOOST_AUTO_TEST_CASE(CylinderContainer) { Blueprint::Config cfg; - cfg.envelope[BinningValue::binZ] = {20_mm, 20_mm}; - cfg.envelope[BinningValue::binR] = {2_mm, 20_mm}; + cfg.envelope[AxisDirection::AxisZ] = {20_mm, 20_mm}; + cfg.envelope[AxisDirection::AxisR] = {2_mm, 20_mm}; auto root = std::make_unique(cfg); - auto& cyl = root->addCylinderContainer("Container", BinningValue::binZ); - cyl.setAttachmentStrategy(CylinderVolumeStack::AttachmentStrategy::Gap); + auto& cyl = root->addCylinderContainer("Container", AxisDirection::AxisZ); + cyl.setAttachmentStrategy(VolumeAttachmentStrategy::Gap); double z0 = -200_mm; double hlZ = 30_mm; @@ -262,8 +263,8 @@ BOOST_AUTO_TEST_CASE(Confined) { Transform3 base{Transform3::Identity()}; Blueprint::Config cfg; - cfg.envelope[BinningValue::binZ] = {20_mm, 20_mm}; - cfg.envelope[BinningValue::binR] = {2_mm, 20_mm}; + cfg.envelope[AxisDirection::AxisZ] = {20_mm, 20_mm}; + cfg.envelope[AxisDirection::AxisR] = {2_mm, 20_mm}; auto root = std::make_unique(cfg); root->addStaticVolume( @@ -472,8 +473,8 @@ BOOST_AUTO_TEST_CASE(CylinderLayer) { BOOST_AUTO_TEST_CASE(Material) { Blueprint::Config cfg; - cfg.envelope[BinningValue::binZ] = {20_mm, 20_mm}; - cfg.envelope[BinningValue::binR] = {1_mm, 2_mm}; + cfg.envelope[AxisDirection::AxisZ] = {20_mm, 20_mm}; + cfg.envelope[AxisDirection::AxisR] = {1_mm, 2_mm}; Blueprint root{cfg}; double hlZ = 30_mm; @@ -481,17 +482,17 @@ BOOST_AUTO_TEST_CASE(Material) { auto cyl = std::make_unique(Transform3::Identity(), cylBounds, "child"); - using enum BinningValue; + using enum AxisDirection; using enum CylinderVolumeBounds::Face; using enum AxisBoundaryType; root.addMaterial("Material", [&](auto& mat) { // @TODO: This API is not great mat.setBinning(std::vector{ - std::tuple{NegativeDisc, Experimental::ProtoBinning{binR, Bound, 5}, - Experimental::ProtoBinning{binPhi, Bound, 10}}, - std::tuple{PositiveDisc, Experimental::ProtoBinning{binR, Bound, 15}, - Experimental::ProtoBinning{binPhi, Bound, 20}}, + std::tuple{NegativeDisc, Experimental::ProtoBinning{AxisR, Bound, 5}, + Experimental::ProtoBinning{AxisPhi, Bound, 10}}, + std::tuple{PositiveDisc, Experimental::ProtoBinning{AxisR, Bound, 15}, + Experimental::ProtoBinning{AxisPhi, Bound, 20}}, }); mat.addStaticVolume(std::move(cyl)); diff --git a/Tests/UnitTests/Core/Geometry/CMakeLists.txt b/Tests/UnitTests/Core/Geometry/CMakeLists.txt index 41c218129fe..89b54d8972c 100644 --- a/Tests/UnitTests/Core/Geometry/CMakeLists.txt +++ b/Tests/UnitTests/Core/Geometry/CMakeLists.txt @@ -32,6 +32,7 @@ add_unittest(TrapezoidVolumeBounds TrapezoidVolumeBoundsTests.cpp) add_unittest(VolumeBounds VolumeBoundsTests.cpp) add_unittest(Volume VolumeTests.cpp) add_unittest(CylinderVolumeStack CylinderVolumeStackTests.cpp) +add_unittest(CuboidVolumeStack CuboidVolumeStackTests.cpp) add_unittest(PortalLink PortalLinkTests.cpp) add_unittest(Portal PortalTests.cpp) add_unittest(PortalShell PortalShellTests.cpp) diff --git a/Tests/UnitTests/Core/Geometry/CuboidVolumeBoundsTests.cpp b/Tests/UnitTests/Core/Geometry/CuboidVolumeBoundsTests.cpp index a4c18aa3609..126a803ca73 100644 --- a/Tests/UnitTests/Core/Geometry/CuboidVolumeBoundsTests.cpp +++ b/Tests/UnitTests/Core/Geometry/CuboidVolumeBoundsTests.cpp @@ -38,6 +38,12 @@ BOOST_AUTO_TEST_CASE(CuboidVolumeConstruction) { // Test Construction CuboidVolumeBounds box(hx, hy, hz); + // Test initilizer list construction + CuboidVolumeBounds init( + {{CuboidVolumeBounds::BoundValues::eHalfLengthX, hx}, + {CuboidVolumeBounds::BoundValues::eHalfLengthY, hy}, + {CuboidVolumeBounds::BoundValues::eHalfLengthZ, hz}}); + // Test copy construction CuboidVolumeBounds copied(box); BOOST_CHECK_EQUAL(box, copied); @@ -71,6 +77,11 @@ BOOST_AUTO_TEST_CASE(CuboidVolumeException) { BOOST_CHECK_THROW(CuboidVolumeBounds(hx, -hy, -hz), std::logic_error); // Other iterations : all BOOST_CHECK_THROW(CuboidVolumeBounds(-hx, -hy, -hz), std::logic_error); + // Initilizer list with missing bound values + BOOST_CHECK_THROW( + CuboidVolumeBounds({{CuboidVolumeBounds::BoundValues::eHalfLengthX, hx}, + {CuboidVolumeBounds::BoundValues::eHalfLengthZ, hz}}), + std::logic_error); } BOOST_AUTO_TEST_CASE(CuboidVolumeProperties) { @@ -104,10 +115,13 @@ BOOST_AUTO_TEST_CASE(CuboidVolumeProperties) { } // Check the binning value positions - CHECK_CLOSE_ABS(box.binningBorder(Acts::BinningValue::binX), hx, s_epsilon); - CHECK_CLOSE_ABS(box.binningBorder(Acts::BinningValue::binY), hy, s_epsilon); - CHECK_CLOSE_ABS(box.binningBorder(Acts::BinningValue::binZ), hz, s_epsilon); - CHECK_CLOSE_ABS(box.binningBorder(Acts::BinningValue::binR), + CHECK_CLOSE_ABS(box.referenceBorder(Acts::AxisDirection::AxisX), hx, + s_epsilon); + CHECK_CLOSE_ABS(box.referenceBorder(Acts::AxisDirection::AxisY), hy, + s_epsilon); + CHECK_CLOSE_ABS(box.referenceBorder(Acts::AxisDirection::AxisZ), hz, + s_epsilon); + CHECK_CLOSE_ABS(box.referenceBorder(Acts::AxisDirection::AxisR), std::sqrt(hx * hx + hy * hy), s_epsilon); } diff --git a/Tests/UnitTests/Core/Geometry/CuboidVolumeStackTests.cpp b/Tests/UnitTests/Core/Geometry/CuboidVolumeStackTests.cpp new file mode 100644 index 00000000000..ca35feb302a --- /dev/null +++ b/Tests/UnitTests/Core/Geometry/CuboidVolumeStackTests.cpp @@ -0,0 +1,1128 @@ +// 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 +#include +#include +#include +#include +#include +#include + +#include "Acts/Definitions/Algebra.hpp" +#include "Acts/Definitions/Units.hpp" +#include "Acts/Geometry/CuboidVolumeBounds.hpp" +#include "Acts/Geometry/CuboidVolumeStack.hpp" +#include "Acts/Geometry/VolumeAttachmentStrategy.hpp" +#include "Acts/Geometry/VolumeResizeStrategy.hpp" +#include "Acts/Tests/CommonHelpers/FloatComparisons.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" +#include "Acts/Utilities/Logger.hpp" +#include "Acts/Utilities/ThrowAssert.hpp" +#include "Acts/Utilities/Zip.hpp" + +#include +#include +#include +#include + +using namespace Acts::UnitLiterals; + +namespace Acts::Test { + +auto logger = Acts::getDefaultLogger("UnitTests", Acts::Logging::VERBOSE); + +struct Fixture { + Logging::Level m_level; + Fixture() { + m_level = Acts::Logging::getFailureThreshold(); + Acts::Logging::setFailureThreshold(Acts::Logging::FATAL); + } + + ~Fixture() { Acts::Logging::setFailureThreshold(m_level); } +}; + +BOOST_FIXTURE_TEST_SUITE(Geometry, Fixture) + +static const std::vector strategies = { + VolumeAttachmentStrategy::Gap, + VolumeAttachmentStrategy::First, + VolumeAttachmentStrategy::Second, + VolumeAttachmentStrategy::Midpoint, +}; + +static const std::vector resizeStrategies = { + VolumeResizeStrategy::Expand, + VolumeResizeStrategy::Gap, +}; + +BOOST_AUTO_TEST_SUITE(CuboidVolumeStackTest) + +BOOST_DATA_TEST_CASE(BaselineLocal, + (boost::unit_test::data::xrange(-135, 180, 45) * + boost::unit_test::data::xrange(0, 2, 1) * + boost::unit_test::data::make(0.8, 1.0, 1.2) * + boost::unit_test::data::make(Vector3{0_mm, 0_mm, 0_mm}, + Vector3{20_mm, 0_mm, 0_mm}, + Vector3{0_mm, 20_mm, 0_mm}, + Vector3{20_mm, 20_mm, 0_mm}, + Vector3{0_mm, 0_mm, 20_mm}) * + boost::unit_test::data::make(strategies) * + boost::unit_test::data::make(Acts::AxisDirection::AxisX, + Acts::AxisDirection::AxisY, + Acts::AxisDirection::AxisZ)), + angle, rotate, shift, offset, strategy, dir) { + double halfDir = 400_mm; + + auto [dirOrth1, dirOrth2] = CuboidVolumeStack::getOrthogonalAxes(dir); + + auto dirIdx = CuboidVolumeStack::axisToIndex(dir); + auto dirOrth1Idx = CuboidVolumeStack::axisToIndex(dirOrth1); + + auto boundDir = CuboidVolumeBounds::fromAxisDirection(dir); + auto boundDirOrth1 = CuboidVolumeBounds::fromAxisDirection(dirOrth1); + auto boundDirOrth2 = CuboidVolumeBounds::fromAxisDirection(dirOrth2); + + auto bounds1 = std::make_shared( + std::initializer_list>{ + {boundDir, halfDir}, + {boundDirOrth1, 100_mm}, + {boundDirOrth2, 400_mm}}); + + auto bounds2 = std::make_shared( + std::initializer_list>{ + {boundDir, halfDir}, + {boundDirOrth1, 200_mm}, + {boundDirOrth2, 600_mm}}); + + auto bounds3 = std::make_shared( + std::initializer_list>{ + {boundDir, halfDir}, + {boundDirOrth1, 300_mm}, + {boundDirOrth2, 500_mm}}); + + Transform3 base = AngleAxis3(angle * 1_degree, Vector3::Unit(dirOrth1Idx)) * + Translation3(offset); + + Translation3 translation1(Vector3::Unit(dirIdx) * (-2 * halfDir * shift)); + Transform3 transform1 = base * translation1; + auto vol1 = std::make_shared(transform1, bounds1); + + Transform3 transform2 = base; + auto vol2 = std::make_shared(transform2, bounds2); + + Translation3 translation3(Vector3::Unit(dirIdx) * (2 * halfDir * shift)); + Transform3 transform3 = base * translation3; + auto vol3 = std::make_shared(transform3, bounds3); + + std::vector volumes = {vol1.get(), vol2.get(), vol3.get()}; + // Rotate to simulate unsorted volumes: all results should be the same! + std::rotate(volumes.begin(), volumes.begin() + rotate, volumes.end()); + + auto origVolumes = volumes; + + std::vector originalBounds; + std::transform(volumes.begin(), volumes.end(), + std::back_inserter(originalBounds), [](const auto& vol) { + const auto* res = + dynamic_cast(&vol->volumeBounds()); + throw_assert(res != nullptr, ""); + return *res; + }); + + if (shift < 1.0) { + BOOST_CHECK_THROW(CuboidVolumeStack(volumes, dir, strategy, + VolumeResizeStrategy::Gap, *logger), + std::invalid_argument); + return; + } + CuboidVolumeStack stack(volumes, dir, strategy, VolumeResizeStrategy::Gap, + *logger); + + auto stackBounds = + dynamic_cast(&stack.volumeBounds()); + BOOST_REQUIRE(stackBounds != nullptr); + + BOOST_CHECK_CLOSE(stackBounds->get(boundDirOrth1), 300_mm, 1e-6); + BOOST_CHECK_CLOSE(stackBounds->get(boundDirOrth2), 600_mm, 1e-6); + BOOST_CHECK_CLOSE(stackBounds->get(boundDir), halfDir + 2 * halfDir * shift, + 1e-6); + CHECK_CLOSE_OR_SMALL(stack.transform().matrix(), base.matrix(), 1e-10, 1e-12); + + // All volumes (including gaps) are cuboids and have the same orthogonal + // bounds + for (const auto& volume : volumes) { + const auto* cuboidBounds = + dynamic_cast(&volume->volumeBounds()); + BOOST_REQUIRE(cuboidBounds != nullptr); + BOOST_CHECK_CLOSE(cuboidBounds->get(boundDirOrth1), 300_mm, 1e-6); + BOOST_CHECK_CLOSE(cuboidBounds->get(boundDirOrth2), 600_mm, 1e-6); + } + + // Volumes are sorted in (local) stacking direction + for (std::size_t i = 0; i < volumes.size() - 1; ++i) { + const auto& a = volumes.at(i); + const auto& b = volumes.at(i + 1); + + BOOST_CHECK_LT((base.inverse() * a->center())[dirIdx], + (base.inverse() * b->center())[dirIdx]); + } + + if (shift <= 1.0) { + // No gap volumes were added + BOOST_CHECK_EQUAL(volumes.size(), 3); + + // No expansion, original volumes did not move + BOOST_CHECK_EQUAL(vol1->transform().matrix(), transform1.matrix()); + BOOST_CHECK_EQUAL(vol2->transform().matrix(), transform2.matrix()); + BOOST_CHECK_EQUAL(vol3->transform().matrix(), transform3.matrix()); + + for (const auto& [volume, bounds] : zip(origVolumes, originalBounds)) { + const auto* newBounds = + dynamic_cast(&volume->volumeBounds()); + BOOST_CHECK_CLOSE(newBounds->get(boundDir), bounds.get(boundDir), 1e-6); + } + } else { + if (strategy == VolumeAttachmentStrategy::Gap) { + // Gap volumes were added + BOOST_CHECK_EQUAL(volumes.size(), 5); + auto gap1 = volumes.at(1); + auto gap2 = volumes.at(3); + + BOOST_TEST_MESSAGE("Gap 1: " << gap1->transform().matrix()); + BOOST_TEST_MESSAGE("Gap 2: " << gap2->transform().matrix()); + + const auto* gapBounds1 = + dynamic_cast(&gap1->volumeBounds()); + const auto* gapBounds2 = + dynamic_cast(&gap2->volumeBounds()); + + double gapHlDir = (shift - 1.0) * halfDir; + + BOOST_CHECK(std::abs(gapBounds1->get(boundDir) - gapHlDir) < 1e-12); + BOOST_CHECK(std::abs(gapBounds2->get(boundDir) - gapHlDir) < 1e-12); + + double gap1Dir = (-2 * halfDir * shift) + halfDir + gapHlDir; + double gap2Dir = (2 * halfDir * shift) - halfDir - gapHlDir; + + Translation3 gap1Translation(Vector3::Unit(dirIdx) * gap1Dir); + Translation3 gap2Translation(Vector3::Unit(dirIdx) * gap2Dir); + + Transform3 gap1Transform = base * gap1Translation; + Transform3 gap2Transform = base * gap2Translation; + + CHECK_CLOSE_OR_SMALL(gap1->transform().matrix(), gap1Transform.matrix(), + 1e-10, 1e-12); + CHECK_CLOSE_OR_SMALL(gap2->transform().matrix(), gap2Transform.matrix(), + 1e-10, 1e-12); + + // Original volumes did not changes bounds + for (const auto& [volume, bounds] : zip(origVolumes, originalBounds)) { + const auto* newBounds = + dynamic_cast(&volume->volumeBounds()); + BOOST_CHECK_CLOSE(newBounds->get(boundDir), bounds.get(boundDir), 1e-6); + } + + // No expansion, original volumes did not move + BOOST_CHECK_EQUAL(vol1->transform().matrix(), transform1.matrix()); + BOOST_CHECK_EQUAL(vol2->transform().matrix(), transform2.matrix()); + BOOST_CHECK_EQUAL(vol3->transform().matrix(), transform3.matrix()); + } else if (strategy == VolumeAttachmentStrategy::First) { + // No gap volumes were added + BOOST_CHECK_EQUAL(volumes.size(), 3); + + double wGap = (shift - 1.0) * halfDir * 2; + + // Volume 1 got bigger and shifted right + auto newBounds1 = + dynamic_cast(&vol1->volumeBounds()); + BOOST_CHECK_CLOSE(newBounds1->get(boundDir), halfDir + wGap / 2.0, 1e-6); + double pDir1 = -2 * halfDir * shift + wGap / 2.0; + Translation3 expectedTranslation1(Vector3::Unit(dirIdx) * pDir1); + Transform3 expectedTransform1 = base * expectedTranslation1; + CHECK_CLOSE_OR_SMALL(vol1->transform().matrix(), + expectedTransform1.matrix(), 1e-10, 1e-12); + + // Volume 2 got bigger and shifted left + auto newBounds2 = + dynamic_cast(&vol2->volumeBounds()); + BOOST_CHECK_CLOSE(newBounds2->get(boundDir), halfDir + wGap / 2.0, 1e-6); + double pDir2 = wGap / 2.0; + Translation3 expectedTranslation2(Vector3::Unit(dirIdx) * pDir2); + Transform3 expectedTransform2 = base * expectedTranslation2; + CHECK_CLOSE_OR_SMALL(vol2->transform().matrix(), + expectedTransform2.matrix(), 1e-10, 1e-12); + + // Volume 3 stayed the same + auto newBounds3 = + dynamic_cast(&vol3->volumeBounds()); + BOOST_CHECK_CLOSE(newBounds3->get(boundDir), halfDir, 1e-6); + double pDir3 = 2 * halfDir * shift; + Translation3 expectedTranslation3(Vector3::Unit(dirIdx) * pDir3); + Transform3 expectedTransform3 = base * expectedTranslation3; + CHECK_CLOSE_OR_SMALL(vol3->transform().matrix(), + expectedTransform3.matrix(), 1e-10, 1e-12); + } else if (strategy == VolumeAttachmentStrategy::Second) { + // No gap volumes were added + BOOST_CHECK_EQUAL(volumes.size(), 3); + + double wGap = (shift - 1.0) * halfDir * 2; + + // Volume 1 stayed the same + auto newBounds1 = + dynamic_cast(&vol1->volumeBounds()); + BOOST_CHECK_CLOSE(newBounds1->get(boundDir), halfDir, 1e-6); + double pDir1 = -2 * halfDir * shift; + Translation3 expectedTranslation1(Vector3::Unit(dirIdx) * pDir1); + Transform3 expectedTransform1 = base * expectedTranslation1; + CHECK_CLOSE_OR_SMALL(vol1->transform().matrix(), + expectedTransform1.matrix(), 1e-10, 1e-12); + + // Volume 2 got bigger and shifted left + auto newBounds2 = + dynamic_cast(&vol2->volumeBounds()); + BOOST_CHECK_CLOSE(newBounds2->get(boundDir), halfDir + wGap / 2.0, 1e-6); + double pDir2 = -wGap / 2.0; + Translation3 expectedTranslation2(Vector3::Unit(dirIdx) * pDir2); + Transform3 expectedTransform2 = base * expectedTranslation2; + CHECK_CLOSE_OR_SMALL(vol2->transform().matrix(), + expectedTransform2.matrix(), 1e-10, 1e-12); + + // Volume 3 got bigger and shifted left + auto newBounds3 = + dynamic_cast(&vol3->volumeBounds()); + BOOST_CHECK_CLOSE(newBounds3->get(boundDir), halfDir + wGap / 2.0, 1e-6); + double pDir3 = 2 * halfDir * shift - wGap / 2.0; + Translation3 expectedTranslation3(Vector3::Unit(dirIdx) * pDir3); + Transform3 expectedTransform3 = base * expectedTranslation3; + CHECK_CLOSE_OR_SMALL(vol3->transform().matrix(), + expectedTransform3.matrix(), 1e-10, 1e-12); + } else if (strategy == VolumeAttachmentStrategy::Midpoint) { + // No gap volumes were added + BOOST_CHECK_EQUAL(volumes.size(), 3); + + double wGap = (shift - 1.0) * halfDir * 2; + + // Volume 1 got bigger and shifted right + auto newBounds1 = + dynamic_cast(&vol1->volumeBounds()); + BOOST_CHECK_CLOSE(newBounds1->get(boundDir), halfDir + wGap / 4.0, 1e-6); + double pDir1 = -2 * halfDir * shift + wGap / 4.0; + Translation3 expectedTranslation1(Vector3::Unit(dirIdx) * pDir1); + Transform3 expectedTransform1 = base * expectedTranslation1; + CHECK_CLOSE_OR_SMALL(vol1->transform().matrix(), + expectedTransform1.matrix(), 1e-10, 1e-12); + + // Volume 2 got bigger but didn't move + auto newBounds2 = + dynamic_cast(&vol2->volumeBounds()); + BOOST_CHECK_CLOSE(newBounds2->get(boundDir), halfDir + wGap / 2.0, 1e-6); + CHECK_CLOSE_OR_SMALL(vol2->transform().matrix(), base.matrix(), 1e-10, + 1e-12); + + // Volume 3 got bigger and shifted left + auto newBounds3 = + dynamic_cast(&vol3->volumeBounds()); + BOOST_CHECK_CLOSE(newBounds3->get(boundDir), halfDir + wGap / 4.0, 1e-6); + double pDir3 = 2 * halfDir * shift - wGap / 4.0; + Translation3 expectedTranslation3(Vector3::Unit(dirIdx) * pDir3); + Transform3 expectedTransform3 = base * expectedTranslation3; + CHECK_CLOSE_OR_SMALL(vol3->transform().matrix(), + expectedTransform3.matrix(), 1e-10, 1e-12); + } + } +} + +BOOST_DATA_TEST_CASE(BaselineGlobal, + (boost::unit_test::data::xrange(-135, 180, 45) * + boost::unit_test::data::xrange(0, 2, 1) * + boost::unit_test::data::make(1.0, 1.2) * + boost::unit_test::data::make(Vector3{0_mm, 0_mm, 0_mm}, + Vector3{20_mm, 0_mm, 0_mm}, + Vector3{0_mm, 20_mm, 0_mm}, + Vector3{20_mm, 20_mm, 0_mm}, + Vector3{0_mm, 0_mm, 20_mm}) * + boost::unit_test::data::make(strategies)), + angle, rotate, shift, offset, strategy) { + double halfDir = 400_mm; + + auto bounds1 = std::make_shared(100_mm, 400_mm, halfDir); + auto bounds2 = std::make_shared(200_mm, 600_mm, halfDir); + auto bounds3 = std::make_shared(300_mm, 500_mm, halfDir); + + AngleAxis3 baseRotation = AngleAxis3(angle, Vector3::UnitX()); + Transform3 base = baseRotation * Translation3(offset); + + Vector3 orientation = baseRotation * Vector3::UnitZ(); + + Translation3 translation1(Vector3::UnitZ() * (-2 * halfDir * shift)); + Transform3 transform1 = base * translation1; + auto vol1Orientation = std::make_shared(transform1, bounds1); + auto vol1AxisDirection = std::make_shared(transform1, bounds1); + + Transform3 transform2 = base; + auto vol2Orientation = std::make_shared(transform2, bounds2); + auto vol2AxisDirection = std::make_shared(transform2, bounds2); + + Translation3 translation3(Vector3::UnitZ() * (2 * halfDir * shift)); + Transform3 transform3 = base * translation3; + auto vol3Orientation = std::make_shared(transform3, bounds3); + auto vol3AxisDirection = std::make_shared(transform3, bounds3); + + std::vector volumesOrientation = { + vol1Orientation.get(), vol2Orientation.get(), vol3Orientation.get()}; + std::vector volumesAxisDirection = {vol1AxisDirection.get(), + vol2AxisDirection.get(), + vol3AxisDirection.get()}; + + // Rotate to simulate unsorted volumes: all results should be the same! + std::rotate(volumesOrientation.begin(), volumesOrientation.begin() + rotate, + volumesOrientation.end()); + std::rotate(volumesAxisDirection.begin(), + volumesAxisDirection.begin() + rotate, + volumesAxisDirection.end()); + + CuboidVolumeStack stackOrientation(volumesOrientation, orientation, strategy, + VolumeResizeStrategy::Gap, *logger); + CuboidVolumeStack stackAxisDirection(volumesAxisDirection, + AxisDirection::AxisZ, strategy, + VolumeResizeStrategy::Gap, *logger); + + auto stackBoundsOrientation = + dynamic_cast(&stackOrientation.volumeBounds()); + auto stackBoundsAxisDirection = dynamic_cast( + &stackAxisDirection.volumeBounds()); + + // Global vector direction and local axis direction should + // produce the same results + BOOST_CHECK_NE(stackBoundsOrientation, nullptr); + BOOST_CHECK_NE(stackBoundsAxisDirection, nullptr); + BOOST_CHECK_EQUAL(*stackBoundsOrientation, *stackBoundsAxisDirection); + CHECK_CLOSE_OR_SMALL(stackOrientation.transform().matrix(), + stackAxisDirection.transform().matrix(), 1e-10, 1e-12); +} + +BOOST_DATA_TEST_CASE(Asymmetric, + boost::unit_test::data::make(Acts::AxisDirection::AxisX, + Acts::AxisDirection::AxisY, + Acts::AxisDirection::AxisZ), + dir) { + double halfDir1 = 200_mm; + double pDir1 = -1100_mm; + double halfDir2 = 600_mm; + double pDir2 = -200_mm; + double halfDir3 = 400_mm; + double pDir3 = 850_mm; + + auto [dirOrth1, dirOrth2] = CuboidVolumeStack::getOrthogonalAxes(dir); + + auto dirIdx = CuboidVolumeStack::axisToIndex(dir); + + auto boundDir = CuboidVolumeBounds::fromAxisDirection(dir); + auto boundDirOrth1 = CuboidVolumeBounds::fromAxisDirection(dirOrth1); + auto boundDirOrth2 = CuboidVolumeBounds::fromAxisDirection(dirOrth2); + + auto bounds1 = std::make_shared( + std::initializer_list>{ + {boundDir, halfDir1}, + {boundDirOrth1, 100_mm}, + {boundDirOrth2, 400_mm}}); + + auto bounds2 = std::make_shared( + std::initializer_list>{ + {boundDir, halfDir2}, + {boundDirOrth1, 200_mm}, + {boundDirOrth2, 600_mm}}); + + auto bounds3 = std::make_shared( + std::initializer_list>{ + {boundDir, halfDir3}, + {boundDirOrth1, 300_mm}, + {boundDirOrth2, 500_mm}}); + + Translation3 translation1(Vector3::Unit(dirIdx) * pDir1); + Transform3 transform1(translation1); + auto vol1 = std::make_shared(transform1, bounds1); + + Translation3 translation2(Vector3::Unit(dirIdx) * pDir2); + Transform3 transform2(translation2); + auto vol2 = std::make_shared(transform2, bounds2); + + Translation3 translation3(Vector3::Unit(dirIdx) * pDir3); + Transform3 transform3(translation3); + auto vol3 = std::make_shared(transform3, bounds3); + + std::vector volumes = {vol2.get(), vol1.get(), vol3.get()}; + + CuboidVolumeStack stack(volumes, dir, VolumeAttachmentStrategy::Gap, + VolumeResizeStrategy::Gap, *logger); + BOOST_CHECK_EQUAL(volumes.size(), 5); + + auto stackBounds = + dynamic_cast(&stack.volumeBounds()); + BOOST_REQUIRE(stackBounds != nullptr); + + BOOST_CHECK_CLOSE(stackBounds->get(boundDirOrth1), 300_mm, 1e-6); + BOOST_CHECK_CLOSE(stackBounds->get(boundDirOrth2), 600_mm, 1e-6); + BOOST_CHECK_CLOSE(stackBounds->get(boundDir), + (std::abs(pDir1 - halfDir1) + pDir3 + halfDir3) / 2.0, + 1e-6); + + double midDir = (pDir1 - halfDir1 + pDir3 + halfDir3) / 2.0; + Translation3 expectedTranslation(Vector3::Unit(dirIdx) * midDir); + Transform3 expectedTransform = Transform3::Identity() * expectedTranslation; + CHECK_CLOSE_OR_SMALL(stack.transform().matrix(), expectedTransform.matrix(), + 1e-10, 1e-12); +} + +BOOST_DATA_TEST_CASE(UpdateStack, + (boost::unit_test::data::xrange(-135, 180, 45) * + boost::unit_test::data::make(Vector3{0_mm, 0_mm, 0_mm}, + Vector3{20_mm, 0_mm, 0_mm}, + Vector3{0_mm, 20_mm, 0_mm}, + Vector3{20_mm, 20_mm, 0_mm}, + Vector3{0_mm, 0_mm, 20_mm}) * + boost::unit_test::data::make(-100_mm, 0_mm, 100_mm) * + boost::unit_test::data::make(resizeStrategies) * + boost::unit_test::data::make(Acts::AxisDirection::AxisX, + Acts::AxisDirection::AxisY, + Acts::AxisDirection::AxisZ)), + angle, offset, zshift, strategy, dir) { + double halfDir = 400_mm; + + auto [dirOrth1, dirOrth2] = CuboidVolumeStack::getOrthogonalAxes(dir); + + auto dirIdx = CuboidVolumeStack::axisToIndex(dir); + auto dirOrth1Idx = CuboidVolumeStack::axisToIndex(dirOrth1); + + auto boundDir = CuboidVolumeBounds::fromAxisDirection(dir); + auto boundDirOrth1 = CuboidVolumeBounds::fromAxisDirection(dirOrth1); + auto boundDirOrth2 = CuboidVolumeBounds::fromAxisDirection(dirOrth2); + + auto bounds1 = std::make_shared( + std::initializer_list>{ + {boundDir, halfDir}, + {boundDirOrth1, 100_mm}, + {boundDirOrth2, 600_mm}}); + + auto bounds2 = std::make_shared( + std::initializer_list>{ + {boundDir, halfDir}, + {boundDirOrth1, 100_mm}, + {boundDirOrth2, 600_mm}}); + + auto bounds3 = std::make_shared( + std::initializer_list>{ + {boundDir, halfDir}, + {boundDirOrth1, 100_mm}, + {boundDirOrth2, 600_mm}}); + + Vector3 shift = Vector3::Unit(dirIdx) * zshift; + Transform3 base = AngleAxis3(angle * 1_degree, Vector3::Unit(dirOrth1Idx)) * + Translation3(offset + shift); + + Translation3 translation1(Vector3::Unit(dirIdx) * -2 * halfDir); + Transform3 transform1 = base * translation1; + auto vol1 = std::make_shared(transform1, bounds1); + + Transform3 transform2 = base; + auto vol2 = std::make_shared(transform2, bounds2); + + Translation3 translation3(Vector3::Unit(dirIdx) * 2 * halfDir); + Transform3 transform3 = base * translation3; + auto vol3 = std::make_shared(transform3, bounds3); + + std::vector volumes = {vol1.get(), vol2.get(), vol3.get()}; + std::vector originalVolumes = volumes; + + std::vector originalTransforms = {transform1, transform2, + transform3}; + + CuboidVolumeStack stack(volumes, dir, + VolumeAttachmentStrategy::Gap, // should not make a + // difference + strategy, *logger); + + const auto* originalBounds = + dynamic_cast(&stack.volumeBounds()); + + auto assertOriginalBounds = [&]() { + const auto* bounds = + dynamic_cast(&stack.volumeBounds()); + BOOST_REQUIRE(bounds != nullptr); + BOOST_CHECK_EQUAL(bounds, originalBounds); + BOOST_CHECK_CLOSE(bounds->get(boundDirOrth1), 100_mm, 1e-6); + BOOST_CHECK_CLOSE(bounds->get(boundDirOrth2), 600_mm, 1e-6); + BOOST_CHECK_CLOSE(bounds->get(boundDir), 3 * halfDir, 1e-6); + }; + + assertOriginalBounds(); + + { + // Assign a copy of the identical bounds gives identical bounds + auto bounds = std::make_shared( + dynamic_cast(stack.volumeBounds())); + stack.update(bounds, std::nullopt, *logger); + assertOriginalBounds(); + } + + { + // Cannot decrease half length + auto bounds = std::make_shared( + dynamic_cast(stack.volumeBounds())); + bounds->set(boundDirOrth1, 20_mm); + BOOST_CHECK_THROW(stack.update(bounds, std::nullopt, *logger), + std::invalid_argument); + assertOriginalBounds(); + } + + { + // Cannot decrease half length + auto bounds = std::make_shared( + dynamic_cast(stack.volumeBounds())); + bounds->set(boundDirOrth2, 200_mm); + BOOST_CHECK_THROW(stack.update(bounds, std::nullopt, *logger), + std::invalid_argument); + assertOriginalBounds(); + } + + { + // Cannot decrease half length + auto bounds = std::make_shared( + dynamic_cast(stack.volumeBounds())); + bounds->set(boundDir, 2 * halfDir); + BOOST_CHECK_THROW(stack.update(bounds, std::nullopt, *logger), + std::invalid_argument); + assertOriginalBounds(); + } + + { + // Increase half length + auto bounds = std::make_shared( + dynamic_cast(stack.volumeBounds())); + bounds->set(boundDirOrth1, 700_mm); + stack.update(bounds, std::nullopt, *logger); + const auto* updatedBounds = + dynamic_cast(&stack.volumeBounds()); + BOOST_REQUIRE(updatedBounds != nullptr); + BOOST_CHECK_CLOSE(updatedBounds->get(boundDirOrth1), 700_mm, 1e-6); + BOOST_CHECK_CLOSE(updatedBounds->get(boundDirOrth2), 600_mm, 1e-6); + BOOST_CHECK_CLOSE(updatedBounds->get(boundDir), 3 * halfDir, 1e-6); + + // No gap volumes were added + BOOST_CHECK_EQUAL(volumes.size(), 3); + + // All volumes increase half x to accommodate + for (const auto& [volume, origTransform] : + zip(volumes, originalTransforms)) { + const auto* newBounds = + dynamic_cast(&volume->volumeBounds()); + BOOST_CHECK_CLOSE(newBounds->get(boundDirOrth1), 700_mm, 1e-6); + BOOST_CHECK_CLOSE(newBounds->get(boundDirOrth2), 600_mm, 1e-6); + BOOST_CHECK_CLOSE(newBounds->get(boundDir), halfDir, 1e-6); + + // Position stayed the same + BOOST_CHECK_EQUAL(volume->transform().matrix(), origTransform.matrix()); + } + } + { + // Increase half length + auto bounds = std::make_shared( + dynamic_cast(stack.volumeBounds())); + bounds->set(boundDirOrth2, 700_mm); + stack.update(bounds, std::nullopt, *logger); + const auto* updatedBounds = + dynamic_cast(&stack.volumeBounds()); + BOOST_REQUIRE(updatedBounds != nullptr); + BOOST_CHECK_CLOSE(updatedBounds->get(boundDirOrth1), 700_mm, 1e-6); + BOOST_CHECK_CLOSE(updatedBounds->get(boundDirOrth2), 700_mm, 1e-6); + BOOST_CHECK_CLOSE(updatedBounds->get(boundDir), 3 * halfDir, 1e-6); + + // No gap volumes were added + BOOST_CHECK_EQUAL(volumes.size(), 3); + + // All volumes increase half y to accommodate + for (const auto& [volume, origTransform] : + zip(volumes, originalTransforms)) { + const auto* newBounds = + dynamic_cast(&volume->volumeBounds()); + BOOST_CHECK_CLOSE(newBounds->get(boundDirOrth1), 700_mm, 1e-6); + BOOST_CHECK_CLOSE(newBounds->get(boundDirOrth2), 700_mm, 1e-6); + BOOST_CHECK_CLOSE(newBounds->get(boundDir), halfDir, 1e-6); + + // Position stayed the same + BOOST_CHECK_EQUAL(volume->transform().matrix(), origTransform.matrix()); + } + } + + { + // Increase half length + auto bounds = std::make_shared( + dynamic_cast(stack.volumeBounds())); + bounds->set(boundDir, 4 * halfDir); + stack.update(bounds, std::nullopt, *logger); + const auto* updatedBounds = + dynamic_cast(&stack.volumeBounds()); + BOOST_REQUIRE(updatedBounds != nullptr); + BOOST_CHECK_CLOSE(updatedBounds->get(boundDir), 4 * halfDir, 1e-6); + BOOST_CHECK_CLOSE(updatedBounds->get(boundDirOrth1), 700_mm, 1e-6); + BOOST_CHECK_CLOSE(updatedBounds->get(boundDirOrth2), 700_mm, 1e-6); + + if (strategy == VolumeResizeStrategy::Expand) { + // No gap volumes were added + BOOST_CHECK_EQUAL(volumes.size(), 3); + + // Volume 1 got bigger and shifted left + auto newBounds1 = + dynamic_cast(&vol1->volumeBounds()); + BOOST_CHECK_CLOSE(newBounds1->get(boundDir), halfDir + halfDir / 2.0, + 1e-6); + auto expectedTranslation1 = + Translation3(Vector3::Unit(dirIdx) * (-2 * halfDir - halfDir / 2.0)); + Transform3 expectedTransform1 = base * expectedTranslation1; + CHECK_CLOSE_OR_SMALL(vol1->transform().matrix(), + expectedTransform1.matrix(), 1e-10, 1e-12); + + // Volume 2 stayed the same + auto newBounds2 = + dynamic_cast(&vol2->volumeBounds()); + BOOST_CHECK_CLOSE(newBounds2->get(boundDir), halfDir, 1e-6); + CHECK_CLOSE_OR_SMALL(vol2->transform().matrix(), transform2.matrix(), + 1e-10, 1e-12); + + // Volume 3 got bigger and shifted right + auto newBounds3 = + dynamic_cast(&vol3->volumeBounds()); + BOOST_CHECK_CLOSE(newBounds3->get(boundDir), halfDir + halfDir / 2.0, + 1e-6); + auto expectedTranslation3 = + Translation3(Vector3::Unit(dirIdx) * (2 * halfDir + halfDir / 2.0)); + Transform3 expectedTransform3 = base * expectedTranslation3; + CHECK_CLOSE_OR_SMALL(vol3->transform().matrix(), + expectedTransform3.matrix(), 1e-10, 1e-12); + } else if (strategy == VolumeResizeStrategy::Gap) { + // Gap volumes were added + BOOST_CHECK_EQUAL(volumes.size(), 5); + + for (const auto& [volume, origTransform] : + zip(originalVolumes, originalTransforms)) { + const auto* newBounds = + dynamic_cast(&volume->volumeBounds()); + BOOST_CHECK_CLOSE(newBounds->get(boundDirOrth1), 700_mm, 1e-6); + BOOST_CHECK_CLOSE(newBounds->get(boundDirOrth2), 700_mm, 1e-6); + BOOST_CHECK_CLOSE(newBounds->get(boundDir), halfDir, 1e-6); + // Position stayed the same + CHECK_CLOSE_OR_SMALL(volume->transform().matrix(), + origTransform.matrix(), 1e-10, 1e-12); + } + + auto gap1 = volumes.front(); + auto gap2 = volumes.back(); + + const auto* gapBounds1 = + dynamic_cast(&gap1->volumeBounds()); + const auto* gapBounds2 = + dynamic_cast(&gap2->volumeBounds()); + + BOOST_CHECK_CLOSE(gapBounds1->get(boundDir), halfDir / 2.0, 1e-6); + BOOST_CHECK_CLOSE(gapBounds2->get(boundDir), halfDir / 2.0, 1e-6); + auto gap1Translation = + Translation3(Vector3::Unit(dirIdx) * (-3 * halfDir - halfDir / 2.0)); + Transform3 gap1Transform = base * gap1Translation; + + auto gap2Translation = + Translation3(Vector3::Unit(dirIdx) * (3 * halfDir + halfDir / 2.0)); + Transform3 gap2Transform = base * gap2Translation; + CHECK_CLOSE_OR_SMALL(gap1->transform().matrix(), gap1Transform.matrix(), + 1e-10, 1e-12); + CHECK_CLOSE_OR_SMALL(gap2->transform().matrix(), gap2Transform.matrix(), + 1e-10, 1e-12); + } + } +} + +BOOST_DATA_TEST_CASE( + UpdateStackOneSided, + ((boost::unit_test::data::make(-1.0, 1.0) ^ + boost::unit_test::data::make(VolumeResizeStrategy::Gap, + VolumeResizeStrategy::Expand)) * + boost::unit_test::data::make(Acts::AxisDirection::AxisX, + Acts::AxisDirection::AxisY, + Acts::AxisDirection::AxisZ)), + f, strategy, dir) { + auto [dirOrth1, dirOrth2] = CuboidVolumeStack::getOrthogonalAxes(dir); + + auto dirIdx = CuboidVolumeStack::axisToIndex(dir); + auto dirOrth1Idx = CuboidVolumeStack::axisToIndex(dirOrth1); + auto dirOrth2Idx = CuboidVolumeStack::axisToIndex(dirOrth2); + + auto boundDir = CuboidVolumeBounds::fromAxisDirection(dir); + auto boundDirOrth1 = CuboidVolumeBounds::fromAxisDirection(dirOrth1); + auto boundDirOrth2 = CuboidVolumeBounds::fromAxisDirection(dirOrth2); + + auto bounds1 = std::make_shared( + std::initializer_list>{ + {boundDir, 400_mm}, + {boundDirOrth1, 100_mm}, + {boundDirOrth2, 300_mm}}); + + auto bounds2 = std::make_shared( + std::initializer_list>{ + {boundDir, 400_mm}, + {boundDirOrth1, 100_mm}, + {boundDirOrth2, 300_mm}}); + + auto trf = Transform3::Identity(); + + auto translation1 = Translation3(Vector3::Unit(dirIdx) * -500_mm); + auto trf1 = trf * translation1; + auto vol1 = std::make_shared(trf1, bounds1); + + auto translation2 = Translation3(Vector3::Unit(dirIdx) * 500_mm); + auto trf2 = trf * translation2; + auto vol2 = std::make_shared(trf2, bounds2); + + std::vector volumes = {vol1.get(), vol2.get()}; + + CuboidVolumeStack stack{volumes, dir, VolumeAttachmentStrategy::Gap, strategy, + *logger}; + const auto* originalBounds = + dynamic_cast(&stack.volumeBounds()); + + // Increase half length by 50mm + auto newBounds = std::make_shared( + dynamic_cast(stack.volumeBounds())); + newBounds->set(boundDir, 950_mm); + // Shift to +stacking direction by 50mm + auto delta = Translation3(Vector3::Unit(dirIdx) * f * 50_mm); + trf *= delta; + // -> left edge should stay at -400mm, right edge should be at 500mm or the + // other direction + auto checkUnchanged = [&]() { + const auto* bounds = + dynamic_cast(&stack.volumeBounds()); + BOOST_REQUIRE(bounds != nullptr); + BOOST_CHECK_EQUAL(*bounds, *originalBounds); + }; + + // Invalid: shift too far in merging direction + BOOST_CHECK_THROW( + auto errDelta = Translation3(Vector3::Unit(dirIdx) * f * 20_mm); + stack.update(newBounds, trf * errDelta, *logger), std::invalid_argument); + checkUnchanged(); + + // Invalid: shift in orthogonal direction + BOOST_CHECK_THROW( + auto errDelta = Translation3(Vector3::Unit(dirOrth1Idx) * 10_mm); + stack.update(newBounds, trf * errDelta, *logger), std::invalid_argument); + checkUnchanged(); + + // Invalid: shift in orthogonal direction + BOOST_CHECK_THROW( + auto errDelta = Translation3(Vector3::Unit(dirOrth2Idx) * 10_mm); + stack.update(newBounds, trf * errDelta, *logger), std::invalid_argument); + checkUnchanged(); + + // Invalid: rotation + BOOST_CHECK_THROW( + stack.update(newBounds, + trf * AngleAxis3{10_degree, Vector3::Unit(dirOrth1Idx)}, + *logger), + std::invalid_argument); + checkUnchanged(); + + stack.update(newBounds, trf, *logger); + + CHECK_CLOSE_OR_SMALL(stack.transform().matrix(), trf.matrix(), 1e-10, 1e-12); + const auto* bounds = + dynamic_cast(&stack.volumeBounds()); + BOOST_REQUIRE(bounds != nullptr); + BOOST_CHECK_CLOSE(bounds->get(boundDir), 950_mm, 1e-6); + + // All volumes including gaps should have same size in orthogonal plane + for (const auto* vol : volumes) { + const auto* volBounds = + dynamic_cast(&vol->volumeBounds()); + BOOST_REQUIRE(volBounds != nullptr); + BOOST_CHECK_CLOSE(volBounds->get(boundDirOrth1), 100_mm, 1e-6); + BOOST_CHECK_CLOSE(volBounds->get(boundDirOrth2), 300_mm, 1e-6); + } + + if (strategy == VolumeResizeStrategy::Expand) { + // No gaps were added, there was one gap initially + BOOST_CHECK_EQUAL(volumes.size(), 3); + const Volume* vol = nullptr; + if (f < 0.0) { + // first volume should have gotten bigger + vol = volumes.front(); + } else { + // last volume should have gotten bigger + vol = volumes.back(); + } + + const auto* volBounds = + dynamic_cast(&vol->volumeBounds()); + BOOST_REQUIRE(volBounds != nullptr); + BOOST_CHECK_CLOSE(volBounds->get(boundDir), 450_mm, 1e-6); + BOOST_CHECK_EQUAL(vol->center()[dirIdx], f * 550_mm); + } else if (strategy == VolumeResizeStrategy::Gap) { + // One gap volume was added + BOOST_CHECK_EQUAL(volumes.size(), 4); + + const Volume* gap = nullptr; + if (f < 0.0) { + gap = volumes.front(); + } else { + gap = volumes.back(); + } + const auto* gapBounds = + dynamic_cast(&gap->volumeBounds()); + BOOST_REQUIRE(gapBounds != nullptr); + + BOOST_CHECK_CLOSE(gapBounds->get(boundDir), 50_mm, 1e-6); + BOOST_CHECK_EQUAL(gap->center()[dirIdx], f * 950_mm); + } +} + +// original size +// <---------------> +// +---------------+ +// | | +// | | +// | Volume 1 | +// | | +// | | +// +---------------+ +// first resize +// <--------------------------> +// +---------------+----------+ +// | | | +// | | | +// | Volume 1 | Gap | +// | | | Gap is +// | | | reused!--+ +// +---------------+----------+ | +// second resize | +// <-----------------------------------> | +// +---------------+-------------------+ | +// | | | | +// | | | | +// | Volume 1 | Gap |<-----+ +// | | | +// | | | +// +---------------+-------------------+ +// +BOOST_DATA_TEST_CASE(ResizeGapMultiple, + boost::unit_test::data::make(Acts::AxisDirection::AxisX, + Acts::AxisDirection::AxisY, + Acts::AxisDirection::AxisZ), + dir) { + auto [dirOrth1, dirOrth2] = CuboidVolumeStack::getOrthogonalAxes(dir); + + auto dirIdx = CuboidVolumeStack::axisToIndex(dir); + + auto boundDir = CuboidVolumeBounds::fromAxisDirection(dir); + auto boundDirOrth1 = CuboidVolumeBounds::fromAxisDirection(dirOrth1); + auto boundDirOrth2 = CuboidVolumeBounds::fromAxisDirection(dirOrth2); + + auto bounds = std::make_shared( + std::initializer_list>{ + {boundDir, 100}, {boundDirOrth1, 70}, {boundDirOrth2, 100}}); + Transform3 trf = Transform3::Identity(); + Volume vol{trf, bounds}; + + BOOST_TEST_CONTEXT("Positive") { + std::vector volumes = {&vol}; + CuboidVolumeStack stack(volumes, dir, VolumeAttachmentStrategy::Gap, + VolumeResizeStrategy::Gap, *logger); + + BOOST_CHECK_EQUAL(volumes.size(), 1); + BOOST_CHECK(stack.gaps().empty()); + + auto newBounds1 = std::make_shared( + std::initializer_list< + std::pair>{ + {boundDir, 200}, {boundDirOrth1, 70}, {boundDirOrth2, 100}}); + stack.update(newBounds1, trf * Translation3{Vector3::Unit(dirIdx) * 100}, + *logger); + BOOST_CHECK_EQUAL(volumes.size(), 2); + BOOST_CHECK_EQUAL(stack.gaps().size(), 1); + + BOOST_CHECK_EQUAL(stack.gaps().front()->center()[dirIdx], 200.0); + const auto* updatedBounds = dynamic_cast( + &stack.gaps().front()->volumeBounds()); + BOOST_REQUIRE_NE(updatedBounds, nullptr); + BOOST_CHECK_CLOSE(updatedBounds->get(boundDir), 100.0, 1e-6); + + auto newBounds2 = std::make_shared( + std::initializer_list< + std::pair>{ + {boundDir, 300}, {boundDirOrth1, 70}, {boundDirOrth2, 100}}); + stack.update(newBounds2, trf * Translation3{Vector3::Unit(dirIdx) * 200}, + *logger); + + BOOST_CHECK_EQUAL(volumes.size(), 2); + // No additional gap volume was added! + BOOST_CHECK_EQUAL(stack.gaps().size(), 1); + + BOOST_CHECK_EQUAL(stack.gaps().front()->center()[dirIdx], 300.0); + updatedBounds = dynamic_cast( + &stack.gaps().front()->volumeBounds()); + BOOST_REQUIRE_NE(updatedBounds, nullptr); + BOOST_CHECK_CLOSE(updatedBounds->get(boundDir), 200.0, 1e-6); + } + + BOOST_TEST_CONTEXT("Negative") { + std::vector volumes = {&vol}; + CuboidVolumeStack stack(volumes, dir, VolumeAttachmentStrategy::Gap, + VolumeResizeStrategy::Gap, *logger); + + BOOST_CHECK_EQUAL(volumes.size(), 1); + BOOST_CHECK(stack.gaps().empty()); + + auto newBounds1 = std::make_shared( + std::initializer_list< + std::pair>{ + {boundDir, 200}, {boundDirOrth1, 70}, {boundDirOrth2, 100}}); + stack.update(newBounds1, trf * Translation3{Vector3::Unit(dirIdx) * -100}, + *logger); + BOOST_CHECK_EQUAL(volumes.size(), 2); + BOOST_CHECK_EQUAL(stack.gaps().size(), 1); + + BOOST_CHECK_EQUAL(stack.gaps().front()->center()[dirIdx], -200.0); + const auto* updatedBounds = dynamic_cast( + &stack.gaps().front()->volumeBounds()); + BOOST_REQUIRE_NE(updatedBounds, nullptr); + BOOST_CHECK_CLOSE(updatedBounds->get(boundDir), 100.0, 1e-6); + + auto newBounds2 = std::make_shared( + std::initializer_list< + std::pair>{ + {boundDir, 300}, {boundDirOrth1, 70}, {boundDirOrth2, 100}}); + stack.update(newBounds2, trf * Translation3{Vector3::Unit(dirIdx) * -200}, + *logger); + + BOOST_CHECK_EQUAL(volumes.size(), 2); + // No additional gap volume was added! + BOOST_CHECK_EQUAL(stack.gaps().size(), 1); + + BOOST_CHECK_EQUAL(stack.gaps().front()->center()[dirIdx], -300.0); + updatedBounds = dynamic_cast( + &stack.gaps().front()->volumeBounds()); + BOOST_REQUIRE_NE(updatedBounds, nullptr); + BOOST_CHECK_CLOSE(updatedBounds->get(boundDir), 200.0, 1e-6); + } +} + +BOOST_DATA_TEST_CASE(InvalidDirection, boost::unit_test::data::make(strategies), + strategy) { + std::vector volumes; + auto vol1 = std::make_shared( + Transform3::Identity(), + std::make_shared(100_mm, 400_mm, 400_mm)); + volumes.push_back(vol1.get()); + + // Single volume invalid direction still gives an error + BOOST_CHECK_THROW(CuboidVolumeStack(volumes, AxisDirection::AxisR, strategy), + std::invalid_argument); + + auto vol2 = std::make_shared( + Transform3::Identity(), + std::make_shared(100_mm, 400_mm, 400_mm)); + volumes.push_back(vol2.get()); + + BOOST_CHECK_THROW(CuboidVolumeStack(volumes, AxisDirection::AxisR, strategy), + std::invalid_argument); +} + +BOOST_DATA_TEST_CASE(InvalidInput, + (boost::unit_test::data::make(strategies) * + boost::unit_test::data::make(Acts::AxisDirection::AxisX, + Acts::AxisDirection::AxisY, + Acts::AxisDirection::AxisZ)), + strategy, direction) { + BOOST_TEST_CONTEXT("Empty Volume") { + std::vector volumes; + BOOST_CHECK_THROW(CuboidVolumeStack(volumes, direction, strategy), + std::invalid_argument); + } + + BOOST_TEST_CONTEXT("Volumes rotated relative to each other") { + // At this time, all rotations are considered invalid, even around + // orientation + for (const Vector3 axis : {Vector3::UnitX(), Vector3::UnitY()}) { + std::vector volumes; + auto vol1 = std::make_shared( + Transform3{Translation3{Vector3{0_mm, 0_mm, -500_mm}}}, + std::make_shared(100_mm, 400_mm, 400_mm)); + volumes.push_back(vol1.get()); + + BOOST_TEST_MESSAGE("Axis: " << axis); + auto vol2 = std::make_shared( + Transform3{Translation3{Vector3{0_mm, 0_mm, 500_mm}} * + AngleAxis3(1_degree, axis)}, + std::make_shared(100_mm, 400_mm, 400_mm)); + volumes.push_back(vol2.get()); + + BOOST_CHECK_THROW(CuboidVolumeStack(volumes, direction, strategy, + VolumeResizeStrategy::Gap, *logger), + std::invalid_argument); + } + } + + BOOST_TEST_CONTEXT( + "Volumes shifted in the orthogonal plane relative to each other") { + for (const Vector3& shift : + {Vector3{5_mm, 0, 0}, Vector3{0, -5_mm, 0}, Vector3{2_mm, -2_mm, 0}}) { + std::vector volumes; + auto vol1 = std::make_shared( + Transform3{Translation3{Vector3{0_mm, 0_mm, -500_mm}}}, + std::make_shared(100_mm, 400_mm, 400_mm)); + volumes.push_back(vol1.get()); + + auto vol2 = std::make_shared( + Transform3{Translation3{Vector3{0_mm, 0_mm, 500_mm} + shift}}, + std::make_shared(100_mm, 400_mm, 400_mm)); + volumes.push_back(vol2.get()); + + BOOST_CHECK_THROW(CuboidVolumeStack(volumes, direction, strategy, + VolumeResizeStrategy::Gap, *logger), + std::invalid_argument); + } + } +} + +BOOST_DATA_TEST_CASE(JoinCuboidVolumeSingle, + (boost::unit_test::data::make(Acts::AxisDirection::AxisX, + Acts::AxisDirection::AxisY, + Acts::AxisDirection::AxisZ) * + boost::unit_test::data::make(strategies)), + direction, strategy) { + auto vol = std::make_shared( + Transform3::Identity() * Translation3{14_mm, 24_mm, 0_mm} * + AngleAxis3(73_degree, Vector3::UnitX()), + std::make_shared(100_mm, 400_mm, 400_mm)); + + std::vector volumes{vol.get()}; + + CuboidVolumeStack stack(volumes, direction, strategy, + VolumeResizeStrategy::Gap, *logger); + + // Cuboid stack has the same transform as bounds as the single input + // volume + BOOST_CHECK_EQUAL(volumes.size(), 1); + BOOST_CHECK_EQUAL(volumes.at(0), vol.get()); + BOOST_CHECK_EQUAL(vol->transform().matrix(), stack.transform().matrix()); + BOOST_CHECK_EQUAL(vol->volumeBounds(), stack.volumeBounds()); +} + +BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END() + +} // namespace Acts::Test diff --git a/Tests/UnitTests/Core/Geometry/CutoutCylinderVolumeBoundsTests.cpp b/Tests/UnitTests/Core/Geometry/CutoutCylinderVolumeBoundsTests.cpp index 7518ad5489a..90a455ebc81 100644 --- a/Tests/UnitTests/Core/Geometry/CutoutCylinderVolumeBoundsTests.cpp +++ b/Tests/UnitTests/Core/Geometry/CutoutCylinderVolumeBoundsTests.cpp @@ -194,7 +194,8 @@ BOOST_AUTO_TEST_CASE(CutoutCylinderVolumeOrientedBoundaries) { Vector3 zaxis(0., 0., 1.); for (auto& os : ccvbOrientedSurfaces) { - auto onSurface = os.surface->binningPosition(geoCtx, BinningValue::binR); + auto onSurface = + os.surface->referencePosition(geoCtx, AxisDirection::AxisR); auto locPos = os.surface->globalToLocal(geoCtx, onSurface, Vector3::Zero()).value(); auto osNormal = os.surface->normal(geoCtx, locPos); diff --git a/Tests/UnitTests/Core/Geometry/CylinderVolumeBoundsTests.cpp b/Tests/UnitTests/Core/Geometry/CylinderVolumeBoundsTests.cpp index 9de254dfb68..9c7ce9ac061 100644 --- a/Tests/UnitTests/Core/Geometry/CylinderVolumeBoundsTests.cpp +++ b/Tests/UnitTests/Core/Geometry/CylinderVolumeBoundsTests.cpp @@ -311,7 +311,8 @@ BOOST_AUTO_TEST_CASE(CylinderVolumeOrientedBoundaries) { Vector3 zaxis(0., 0., 1.); for (auto& os : cvbOrientedSurfaces) { - auto onSurface = os.surface->binningPosition(geoCtx, BinningValue::binR); + auto onSurface = + os.surface->referencePosition(geoCtx, AxisDirection::AxisR); auto locPos = os.surface->globalToLocal(geoCtx, onSurface, Vector3::Zero()).value(); auto osNormal = os.surface->normal(geoCtx, locPos); diff --git a/Tests/UnitTests/Core/Geometry/CylinderVolumeStackTests.cpp b/Tests/UnitTests/Core/Geometry/CylinderVolumeStackTests.cpp index 4ed2d419c49..08523bd2b75 100644 --- a/Tests/UnitTests/Core/Geometry/CylinderVolumeStackTests.cpp +++ b/Tests/UnitTests/Core/Geometry/CylinderVolumeStackTests.cpp @@ -19,6 +19,8 @@ #include "Acts/Definitions/Units.hpp" #include "Acts/Geometry/CylinderVolumeBounds.hpp" #include "Acts/Geometry/CylinderVolumeStack.hpp" +#include "Acts/Geometry/VolumeAttachmentStrategy.hpp" +#include "Acts/Geometry/VolumeResizeStrategy.hpp" #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp" #include "Acts/Utilities/BinningType.hpp" #include "Acts/Utilities/Logger.hpp" @@ -44,17 +46,16 @@ struct Fixture { BOOST_FIXTURE_TEST_SUITE(Geometry, Fixture) -static const std::vector strategies = { - CylinderVolumeStack::AttachmentStrategy::Gap, - CylinderVolumeStack::AttachmentStrategy::First, - CylinderVolumeStack::AttachmentStrategy::Second, - CylinderVolumeStack::AttachmentStrategy::Midpoint, +static const std::vector strategies = { + VolumeAttachmentStrategy::Gap, + VolumeAttachmentStrategy::First, + VolumeAttachmentStrategy::Second, + VolumeAttachmentStrategy::Midpoint, }; -static const std::vector resizeStrategies = - { - CylinderVolumeStack::ResizeStrategy::Expand, - CylinderVolumeStack::ResizeStrategy::Gap, +static const std::vector resizeStrategies = { + VolumeResizeStrategy::Expand, + VolumeResizeStrategy::Gap, }; BOOST_AUTO_TEST_SUITE(CylinderVolumeStackTest) @@ -108,14 +109,13 @@ BOOST_DATA_TEST_CASE(Baseline, if (shift < 1.0) { BOOST_CHECK_THROW( - CylinderVolumeStack(volumes, BinningValue::binZ, strategy, - CylinderVolumeStack::ResizeStrategy::Gap, *logger), + CylinderVolumeStack(volumes, AxisDirection::AxisZ, strategy, + VolumeResizeStrategy::Gap, *logger), std::invalid_argument); return; } - CylinderVolumeStack cylStack(volumes, BinningValue::binZ, strategy, - CylinderVolumeStack::ResizeStrategy::Gap, - *logger); + CylinderVolumeStack cylStack(volumes, AxisDirection::AxisZ, strategy, + VolumeResizeStrategy::Gap, *logger); auto stackBounds = dynamic_cast(&cylStack.volumeBounds()); @@ -162,7 +162,7 @@ BOOST_DATA_TEST_CASE(Baseline, bounds.get(CylinderVolumeBounds::eHalfLengthZ)); } } else { - if (strategy == CylinderVolumeStack::AttachmentStrategy::Gap) { + if (strategy == VolumeAttachmentStrategy::Gap) { // Gap volumes were added BOOST_CHECK_EQUAL(volumes.size(), 5); auto gap1 = volumes.at(1); @@ -207,7 +207,7 @@ BOOST_DATA_TEST_CASE(Baseline, BOOST_CHECK_EQUAL(vol2->transform().matrix(), transform2.matrix()); BOOST_CHECK_EQUAL(vol3->transform().matrix(), transform3.matrix()); - } else if (strategy == CylinderVolumeStack::AttachmentStrategy::First) { + } else if (strategy == VolumeAttachmentStrategy::First) { // No gap volumes were added BOOST_CHECK_EQUAL(volumes.size(), 3); @@ -242,7 +242,7 @@ BOOST_DATA_TEST_CASE(Baseline, Transform3 expectedTransform3 = base * Translation3{0_mm, 0_mm, pZ3}; CHECK_CLOSE_OR_SMALL(vol3->transform().matrix(), expectedTransform3.matrix(), 1e-10, 1e-14); - } else if (strategy == CylinderVolumeStack::AttachmentStrategy::Second) { + } else if (strategy == VolumeAttachmentStrategy::Second) { // No gap volumes were added BOOST_CHECK_EQUAL(volumes.size(), 3); @@ -277,7 +277,7 @@ BOOST_DATA_TEST_CASE(Baseline, Transform3 expectedTransform3 = base * Translation3{0_mm, 0_mm, pZ3}; CHECK_CLOSE_OR_SMALL(vol3->transform().matrix(), expectedTransform3.matrix(), 1e-10, 1e-14); - } else if (strategy == CylinderVolumeStack::AttachmentStrategy::Midpoint) { + } else if (strategy == VolumeAttachmentStrategy::Midpoint) { // No gap volumes were added BOOST_CHECK_EQUAL(volumes.size(), 3); @@ -341,9 +341,9 @@ BOOST_AUTO_TEST_CASE(Asymmetric) { std::vector volumes = {vol2.get(), vol1.get(), vol3.get()}; - CylinderVolumeStack cylStack( - volumes, BinningValue::binZ, CylinderVolumeStack::AttachmentStrategy::Gap, - CylinderVolumeStack::ResizeStrategy::Gap, *logger); + CylinderVolumeStack cylStack(volumes, AxisDirection::AxisZ, + VolumeAttachmentStrategy::Gap, + VolumeResizeStrategy::Gap, *logger); BOOST_CHECK_EQUAL(volumes.size(), 5); auto stackBounds = @@ -383,9 +383,8 @@ BOOST_DATA_TEST_CASE(RotationInZ, boost::unit_test::data::make(strategies), std::vector volumes = {vol1.get(), vol2.get()}; - CylinderVolumeStack cylStack(volumes, BinningValue::binZ, strategy, - CylinderVolumeStack::ResizeStrategy::Gap, - *logger); + CylinderVolumeStack cylStack(volumes, AxisDirection::AxisZ, strategy, + VolumeResizeStrategy::Gap, *logger); auto stackBounds = dynamic_cast(&cylStack.volumeBounds()); @@ -405,13 +404,13 @@ BOOST_DATA_TEST_CASE(RotationInZ, boost::unit_test::data::make(strategies), BOOST_CHECK_EQUAL(bounds->get(CylinderVolumeBounds::eMaxR), 400_mm); } - if (strategy == CylinderVolumeStack::AttachmentStrategy::Gap) { + if (strategy == VolumeAttachmentStrategy::Gap) { // Volumes stayed at the same position, not resized BOOST_CHECK_EQUAL(vol1->center()[eZ], -hlZ - gap / 2.0 + shift); BOOST_CHECK_EQUAL(vol2->center()[eZ], hlZ + gap / 2.0 + shift); BOOST_CHECK_EQUAL(newBounds1->get(CylinderVolumeBounds::eHalfLengthZ), hlZ); BOOST_CHECK_EQUAL(newBounds2->get(CylinderVolumeBounds::eHalfLengthZ), hlZ); - } else if (strategy == CylinderVolumeStack::AttachmentStrategy::First) { + } else if (strategy == VolumeAttachmentStrategy::First) { // Left volume moved, got resized BOOST_CHECK_EQUAL(vol1->center()[eZ], -hlZ + shift); BOOST_CHECK_EQUAL(newBounds1->get(CylinderVolumeBounds::eHalfLengthZ), @@ -419,7 +418,7 @@ BOOST_DATA_TEST_CASE(RotationInZ, boost::unit_test::data::make(strategies), // Right volume stayed the same BOOST_CHECK_EQUAL(vol2->center()[eZ], hlZ + gap / 2.0 + shift); BOOST_CHECK_EQUAL(newBounds2->get(CylinderVolumeBounds::eHalfLengthZ), hlZ); - } else if (strategy == CylinderVolumeStack::AttachmentStrategy::Second) { + } else if (strategy == VolumeAttachmentStrategy::Second) { // Left volume stayed the same BOOST_CHECK_EQUAL(vol1->center()[eZ], -hlZ - gap / 2.0 + shift); BOOST_CHECK_EQUAL(newBounds1->get(CylinderVolumeBounds::eHalfLengthZ), hlZ); @@ -427,7 +426,7 @@ BOOST_DATA_TEST_CASE(RotationInZ, boost::unit_test::data::make(strategies), BOOST_CHECK_EQUAL(vol2->center()[eZ], hlZ + shift); BOOST_CHECK_EQUAL(newBounds2->get(CylinderVolumeBounds::eHalfLengthZ), hlZ + gap / 2.0); - } else if (strategy == CylinderVolumeStack::AttachmentStrategy::Midpoint) { + } else if (strategy == VolumeAttachmentStrategy::Midpoint) { // Left volume moved, got resized BOOST_CHECK_EQUAL(vol1->center()[eZ], -hlZ - gap / 4.0 + shift); BOOST_CHECK_EQUAL(newBounds1->get(CylinderVolumeBounds::eHalfLengthZ), @@ -479,9 +478,9 @@ BOOST_DATA_TEST_CASE(UpdateStack, transform3}; CylinderVolumeStack cylStack( - volumes, BinningValue::binZ, - CylinderVolumeStack::AttachmentStrategy::Gap, // should not make a - // difference + volumes, AxisDirection::AxisZ, + VolumeAttachmentStrategy::Gap, // should not make a + // difference strategy, *logger); const auto* originalBounds = @@ -620,7 +619,7 @@ BOOST_DATA_TEST_CASE(UpdateStack, BOOST_CHECK_EQUAL(cylBounds->get(CylinderVolumeBounds::eMinR), 50_mm); BOOST_CHECK_EQUAL(cylBounds->get(CylinderVolumeBounds::eMaxR), 700_mm); - if (strategy == CylinderVolumeStack::ResizeStrategy::Expand) { + if (strategy == VolumeResizeStrategy::Expand) { // No gap volumes were added BOOST_CHECK_EQUAL(volumes.size(), 3); @@ -650,7 +649,7 @@ BOOST_DATA_TEST_CASE(UpdateStack, base * Translation3{0_mm, 0_mm, 2 * hlZ + hlZ / 2.0}; BOOST_CHECK_EQUAL(vol3->transform().matrix(), expectedTransform3.matrix()); - } else if (strategy == CylinderVolumeStack::ResizeStrategy::Gap) { + } else if (strategy == VolumeResizeStrategy::Gap) { // Gap volumes were added BOOST_CHECK_EQUAL(volumes.size(), 5); @@ -695,8 +694,8 @@ BOOST_DATA_TEST_CASE(UpdateStack, BOOST_DATA_TEST_CASE( UpdateStackOneSided, (boost::unit_test::data::make(-1.0, 1.0) ^ - boost::unit_test::data::make(CylinderVolumeStack::ResizeStrategy::Gap, - CylinderVolumeStack::ResizeStrategy::Expand)), + boost::unit_test::data::make(VolumeResizeStrategy::Gap, + VolumeResizeStrategy::Expand)), f, strategy) { auto trf = Transform3::Identity(); @@ -710,9 +709,9 @@ BOOST_DATA_TEST_CASE( std::vector volumes = {vol1.get(), vol2.get()}; - CylinderVolumeStack cylStack{volumes, BinningValue::binZ, - CylinderVolumeStack::AttachmentStrategy::Gap, - strategy, *logger}; + CylinderVolumeStack cylStack{volumes, AxisDirection::AxisZ, + VolumeAttachmentStrategy::Gap, strategy, + *logger}; const auto* originalBounds = dynamic_cast(&cylStack.volumeBounds()); @@ -777,7 +776,7 @@ BOOST_DATA_TEST_CASE( BOOST_CHECK_EQUAL(volBounds->get(CylinderVolumeBounds::eMaxR), 300_mm); } - if (strategy == CylinderVolumeStack::ResizeStrategy::Expand) { + if (strategy == VolumeResizeStrategy::Expand) { // No gaps were added, there was one gap initially BOOST_CHECK_EQUAL(volumes.size(), 3); const Volume* vol = nullptr; @@ -795,7 +794,7 @@ BOOST_DATA_TEST_CASE( BOOST_CHECK_EQUAL(volBounds->get(CylinderVolumeBounds::eHalfLengthZ), 450_mm); BOOST_CHECK_EQUAL(vol->center()[eZ], f * 550_mm); - } else if (strategy == CylinderVolumeStack::ResizeStrategy::Gap) { + } else if (strategy == VolumeResizeStrategy::Gap) { // One gap volume was added BOOST_CHECK_EQUAL(volumes.size(), 4); @@ -822,9 +821,9 @@ BOOST_AUTO_TEST_CASE(ResizeReproduction1) { Volume vol1{trf1, bounds1}; std::vector volumes = {&vol1}; - CylinderVolumeStack stack(volumes, BinningValue::binZ, - CylinderVolumeStack::AttachmentStrategy::Gap, - CylinderVolumeStack::ResizeStrategy::Gap, *logger); + CylinderVolumeStack stack(volumes, AxisDirection::AxisZ, + VolumeAttachmentStrategy::Gap, + VolumeResizeStrategy::Gap, *logger); Transform3 trf2 = Transform3::Identity() * Translation3{Vector3::UnitZ() * -1500}; @@ -848,9 +847,9 @@ BOOST_AUTO_TEST_CASE(ResizeReproduction2) { Volume vol1{trf1, bounds1}; std::vector volumes = {&vol1}; - CylinderVolumeStack stack(volumes, BinningValue::binZ, - CylinderVolumeStack::AttachmentStrategy::Gap, - CylinderVolumeStack::ResizeStrategy::Gap, *logger); + CylinderVolumeStack stack(volumes, AxisDirection::AxisZ, + VolumeAttachmentStrategy::Gap, + VolumeResizeStrategy::Gap, *logger); Transform3 trf2 = Transform3::Identity() * Translation3{Vector3::UnitZ() * 260.843}; @@ -901,10 +900,9 @@ BOOST_AUTO_TEST_CASE(ResizeGapMultiple) { BOOST_TEST_CONTEXT("Positive") { std::vector volumes = {&vol}; - CylinderVolumeStack stack(volumes, BinningValue::binZ, - CylinderVolumeStack::AttachmentStrategy::Gap, - CylinderVolumeStack::ResizeStrategy::Gap, - *logger); + CylinderVolumeStack stack(volumes, AxisDirection::AxisZ, + VolumeAttachmentStrategy::Gap, + VolumeResizeStrategy::Gap, *logger); BOOST_CHECK_EQUAL(volumes.size(), 1); BOOST_CHECK(stack.gaps().empty()); @@ -938,10 +936,9 @@ BOOST_AUTO_TEST_CASE(ResizeGapMultiple) { BOOST_TEST_CONTEXT("Negative") { std::vector volumes = {&vol}; - CylinderVolumeStack stack(volumes, BinningValue::binZ, - CylinderVolumeStack::AttachmentStrategy::Gap, - CylinderVolumeStack::ResizeStrategy::Gap, - *logger); + CylinderVolumeStack stack(volumes, AxisDirection::AxisZ, + VolumeAttachmentStrategy::Gap, + VolumeResizeStrategy::Gap, *logger); BOOST_CHECK_EQUAL(volumes.size(), 1); BOOST_CHECK(stack.gaps().empty()); @@ -1034,15 +1031,14 @@ BOOST_DATA_TEST_CASE(Baseline, if (f < 0.0) { BOOST_CHECK_THROW( - CylinderVolumeStack(volumes, BinningValue::binR, strategy, - CylinderVolumeStack::ResizeStrategy::Gap, *logger), + CylinderVolumeStack(volumes, AxisDirection::AxisR, strategy, + VolumeResizeStrategy::Gap, *logger), std::invalid_argument); return; } - CylinderVolumeStack cylStack(volumes, BinningValue::binR, strategy, - CylinderVolumeStack::ResizeStrategy::Gap, - *logger); + CylinderVolumeStack cylStack(volumes, AxisDirection::AxisR, strategy, + VolumeResizeStrategy::Gap, *logger); auto stackBounds = dynamic_cast(&cylStack.volumeBounds()); @@ -1124,7 +1120,7 @@ BOOST_DATA_TEST_CASE(Baseline, dynamic_cast(&vol2->volumeBounds()); const auto* newBounds3 = dynamic_cast(&vol3->volumeBounds()); - if (strategy == CylinderVolumeStack::AttachmentStrategy::Gap) { + if (strategy == VolumeAttachmentStrategy::Gap) { // Two gap volumes were added BOOST_CHECK_EQUAL(volumes.size(), 5); @@ -1159,7 +1155,7 @@ BOOST_DATA_TEST_CASE(Baseline, BOOST_CHECK_EQUAL(gapBounds2->get(CylinderVolumeBounds::eMaxR), fInner * 600_mm); - } else if (strategy == CylinderVolumeStack::AttachmentStrategy::First) { + } else if (strategy == VolumeAttachmentStrategy::First) { // No gap volumes were added BOOST_CHECK_EQUAL(volumes.size(), 3); @@ -1181,7 +1177,7 @@ BOOST_DATA_TEST_CASE(Baseline, BOOST_CHECK_EQUAL(newBounds3->get(CylinderVolumeBounds::eMaxR), fOuter * 900_mm); - } else if (strategy == CylinderVolumeStack::AttachmentStrategy::Second) { + } else if (strategy == VolumeAttachmentStrategy::Second) { // No gap volumes were added BOOST_CHECK_EQUAL(volumes.size(), 3); @@ -1202,7 +1198,7 @@ BOOST_DATA_TEST_CASE(Baseline, fOuter * 600_mm); BOOST_CHECK_EQUAL(newBounds3->get(CylinderVolumeBounds::eMaxR), fOuter * 900_mm); - } else if (strategy == CylinderVolumeStack::AttachmentStrategy::Midpoint) { + } else if (strategy == VolumeAttachmentStrategy::Midpoint) { // No gap volumes were added BOOST_CHECK_EQUAL(volumes.size(), 3); @@ -1276,9 +1272,9 @@ BOOST_DATA_TEST_CASE(UpdateStack, } cylStack = std::make_unique( - volumes, BinningValue::binR, - CylinderVolumeStack::AttachmentStrategy::Gap, // should not make a - // difference + volumes, AxisDirection::AxisR, + VolumeAttachmentStrategy::Gap, // should not make a + // difference strategy, *logger); originalOuterBounds = @@ -1366,7 +1362,7 @@ BOOST_DATA_TEST_CASE(UpdateStack, BOOST_CHECK_EQUAL(cylBounds->get(CylinderVolumeBounds::eMaxR), 900_mm); BOOST_CHECK_EQUAL(cylBounds->get(CylinderVolumeBounds::eHalfLengthZ), hlZ); - if (strategy == CylinderVolumeStack::ResizeStrategy::Expand) { + if (strategy == VolumeResizeStrategy::Expand) { // No gap volumes were added BOOST_CHECK_EQUAL(volumes.size(), 3); @@ -1388,7 +1384,7 @@ BOOST_DATA_TEST_CASE(UpdateStack, BOOST_CHECK_EQUAL(*newBounds3, originalBounds[2]); BOOST_CHECK_EQUAL(vol3->transform().matrix(), base.matrix()); - } else if (strategy == CylinderVolumeStack::ResizeStrategy::Gap) { + } else if (strategy == VolumeResizeStrategy::Gap) { // One gap volume was added BOOST_CHECK_EQUAL(volumes.size(), 4); @@ -1423,7 +1419,7 @@ BOOST_DATA_TEST_CASE(UpdateStack, BOOST_CHECK_EQUAL(cylBounds->get(CylinderVolumeBounds::eMinR), 100_mm); BOOST_CHECK_EQUAL(cylBounds->get(CylinderVolumeBounds::eHalfLengthZ), hlZ); - if (strategy == CylinderVolumeStack::ResizeStrategy::Expand) { + if (strategy == VolumeResizeStrategy::Expand) { // No gap volumes were added BOOST_CHECK_EQUAL(volumes.size(), 3); @@ -1445,7 +1441,7 @@ BOOST_DATA_TEST_CASE(UpdateStack, BOOST_CHECK_EQUAL(*newBounds2, originalBounds[1]); BOOST_CHECK_EQUAL(vol2->transform().matrix(), base.matrix()); - } else if (strategy == CylinderVolumeStack::ResizeStrategy::Gap) { + } else if (strategy == VolumeResizeStrategy::Gap) { // One gap volume was added BOOST_CHECK_EQUAL(volumes.size(), 4); @@ -1484,7 +1480,7 @@ BOOST_DATA_TEST_CASE(UpdateStack, BOOST_CHECK_EQUAL(cylBounds->get(CylinderVolumeBounds::eMinR), 0_mm); BOOST_CHECK_EQUAL(cylBounds->get(CylinderVolumeBounds::eHalfLengthZ), hlZ); - if (strategy == CylinderVolumeStack::ResizeStrategy::Expand) { + if (strategy == VolumeResizeStrategy::Expand) { // No gap volumes were added BOOST_CHECK_EQUAL(volumes.size(), 3); @@ -1508,7 +1504,7 @@ BOOST_DATA_TEST_CASE(UpdateStack, // Position stayed the same BOOST_CHECK_EQUAL(vol3->transform().matrix(), base.matrix()); - } else if (strategy == CylinderVolumeStack::ResizeStrategy::Gap) { + } else if (strategy == VolumeResizeStrategy::Gap) { // One gap volume was added BOOST_CHECK_EQUAL(volumes.size(), 5); @@ -1580,8 +1576,8 @@ BOOST_DATA_TEST_CASE(UpdateStack, BOOST_DATA_TEST_CASE( UpdateStackOneSided, (boost::unit_test::data::make(-1.0, 1.0) ^ - boost::unit_test::data::make(CylinderVolumeStack::ResizeStrategy::Gap, - CylinderVolumeStack::ResizeStrategy::Expand)), + boost::unit_test::data::make(VolumeResizeStrategy::Gap, + VolumeResizeStrategy::Expand)), f, strategy) { // Strategy should not affect the sizing here at all @@ -1595,9 +1591,9 @@ BOOST_DATA_TEST_CASE( std::vector volumes = {vol1.get(), vol2.get()}; - CylinderVolumeStack cylStack{volumes, BinningValue::binR, - CylinderVolumeStack::AttachmentStrategy::Gap, - strategy, *logger}; + CylinderVolumeStack cylStack{volumes, AxisDirection::AxisR, + VolumeAttachmentStrategy::Gap, strategy, + *logger}; const auto* originalBounds = dynamic_cast(&cylStack.volumeBounds()); @@ -1671,10 +1667,9 @@ BOOST_AUTO_TEST_CASE(ResizeGapMultiple) { BOOST_TEST_CONTEXT("Outer") { std::vector volumes = {&vol}; - CylinderVolumeStack stack(volumes, BinningValue::binR, - CylinderVolumeStack::AttachmentStrategy::Gap, - CylinderVolumeStack::ResizeStrategy::Gap, - *logger); + CylinderVolumeStack stack(volumes, AxisDirection::AxisR, + VolumeAttachmentStrategy::Gap, + VolumeResizeStrategy::Gap, *logger); BOOST_CHECK_EQUAL(volumes.size(), 1); BOOST_CHECK(stack.gaps().empty()); @@ -1706,10 +1701,9 @@ BOOST_AUTO_TEST_CASE(ResizeGapMultiple) { BOOST_TEST_CONTEXT("Inner") { std::vector volumes = {&vol}; - CylinderVolumeStack stack(volumes, BinningValue::binR, - CylinderVolumeStack::AttachmentStrategy::Gap, - CylinderVolumeStack::ResizeStrategy::Gap, - *logger); + CylinderVolumeStack stack(volumes, AxisDirection::AxisR, + VolumeAttachmentStrategy::Gap, + VolumeResizeStrategy::Gap, *logger); BOOST_CHECK_EQUAL(volumes.size(), 1); BOOST_CHECK(stack.gaps().empty()); @@ -1753,22 +1747,24 @@ BOOST_DATA_TEST_CASE(JoinCylinderVolumesInvalidDirection, volumes.push_back(vol1.get()); // Single volume invalid direction still gives an error - BOOST_CHECK_THROW(CylinderVolumeStack(volumes, BinningValue::binY, strategy), - std::invalid_argument); + BOOST_CHECK_THROW( + CylinderVolumeStack(volumes, AxisDirection::AxisY, strategy), + std::invalid_argument); auto vol2 = std::make_shared( Transform3::Identity(), std::make_shared(100_mm, 400_mm, 400_mm)); volumes.push_back(vol2.get()); - BOOST_CHECK_THROW(CylinderVolumeStack(volumes, BinningValue::binY, strategy), - std::invalid_argument); + BOOST_CHECK_THROW( + CylinderVolumeStack(volumes, AxisDirection::AxisY, strategy), + std::invalid_argument); } BOOST_DATA_TEST_CASE(JoinCylinderVolumesInvalidInput, (boost::unit_test::data::make(strategies) * - boost::unit_test::data::make(Acts::BinningValue::binZ, - Acts::BinningValue::binR)), + boost::unit_test::data::make(Acts::AxisDirection::AxisZ, + Acts::AxisDirection::AxisR)), strategy, direction) { BOOST_TEST_CONTEXT("Empty Volume") { std::vector volumes; @@ -1792,9 +1788,8 @@ BOOST_DATA_TEST_CASE(JoinCylinderVolumesInvalidInput, std::make_shared(100_mm, 400_mm, 400_mm)); volumes.push_back(vol2.get()); - BOOST_CHECK_THROW(CylinderVolumeStack( - volumes, direction, strategy, - CylinderVolumeStack::ResizeStrategy::Gap, *logger), + BOOST_CHECK_THROW(CylinderVolumeStack(volumes, direction, strategy, + VolumeResizeStrategy::Gap, *logger), std::invalid_argument); } } @@ -1813,9 +1808,8 @@ BOOST_DATA_TEST_CASE(JoinCylinderVolumesInvalidInput, std::make_shared(100_mm, 400_mm, 400_mm)); volumes.push_back(vol2.get()); - BOOST_CHECK_THROW(CylinderVolumeStack( - volumes, direction, strategy, - CylinderVolumeStack::ResizeStrategy::Gap, *logger), + BOOST_CHECK_THROW(CylinderVolumeStack(volumes, direction, strategy, + VolumeResizeStrategy::Gap, *logger), std::invalid_argument); } } @@ -1849,15 +1843,14 @@ BOOST_DATA_TEST_CASE(JoinCylinderVolumesInvalidInput, { // have valid stack, try to assign extra CylinderVolumeStack cylStack(volumes, direction, strategy, - CylinderVolumeStack::ResizeStrategy::Gap, - *logger); + VolumeResizeStrategy::Gap, *logger); BOOST_CHECK_THROW(cylStack.update(invalid, std::nullopt, *logger), std::invalid_argument); } { std::shared_ptr vol; - if (direction == BinningValue::binZ) { + if (direction == AxisDirection::AxisZ) { vol = std::make_shared( Transform3{Translation3{Vector3{0_mm, 0_mm, 500_mm}}}, invalid); } else { @@ -1871,8 +1864,7 @@ BOOST_DATA_TEST_CASE(JoinCylinderVolumesInvalidInput, volumes.push_back(vol.get()); BOOST_CHECK_THROW( CylinderVolumeStack(volumes, direction, strategy, - CylinderVolumeStack::ResizeStrategy::Gap, - *logger), + VolumeResizeStrategy::Gap, *logger), std::invalid_argument); } } @@ -1881,8 +1873,8 @@ BOOST_DATA_TEST_CASE(JoinCylinderVolumesInvalidInput, } BOOST_DATA_TEST_CASE(JoinCylinderVolumeSingle, - (boost::unit_test::data::make(Acts::BinningValue::binZ, - Acts::BinningValue::binR) * + (boost::unit_test::data::make(Acts::AxisDirection::AxisZ, + Acts::AxisDirection::AxisR) * boost::unit_test::data::make(strategies)), direction, strategy) { auto vol = std::make_shared( @@ -1893,8 +1885,7 @@ BOOST_DATA_TEST_CASE(JoinCylinderVolumeSingle, std::vector volumes{vol.get()}; CylinderVolumeStack cylStack(volumes, direction, strategy, - CylinderVolumeStack::ResizeStrategy::Gap, - *logger); + VolumeResizeStrategy::Gap, *logger); // Cylinder stack has the same transform as bounds as the single input // volume diff --git a/Tests/UnitTests/Core/Geometry/ExtentTests.cpp b/Tests/UnitTests/Core/Geometry/ExtentTests.cpp index 3d0595f807d..2b0f4d5ad95 100644 --- a/Tests/UnitTests/Core/Geometry/ExtentTests.cpp +++ b/Tests/UnitTests/Core/Geometry/ExtentTests.cpp @@ -42,24 +42,24 @@ BOOST_AUTO_TEST_CASE(ExtentTest) { double phiMax = std::atan2(3_mm, 15_mm); double rMin = std::hypot(15_mm, 3_mm); - CHECK_CLOSE_ABS(gExt.min(BinningValue::binX), 15_mm, 1e-6); - CHECK_CLOSE_ABS(gExt.max(BinningValue::binX), 18_mm, 1e-6); - CHECK_CLOSE_ABS(gExt.min(BinningValue::binY), -3_mm, 1e-6); - CHECK_CLOSE_ABS(gExt.max(BinningValue::binY), 3_mm, 1e-6); - CHECK_CLOSE_ABS(gExt.min(BinningValue::binZ), -10_mm, 1e-6); - CHECK_CLOSE_ABS(gExt.max(BinningValue::binZ), 10_mm, 1e-6); - CHECK_CLOSE_ABS(gExt.min(BinningValue::binR), rMin, 1e-6); - CHECK_CLOSE_ABS(gExt.max(BinningValue::binR), 18_mm, 1e-6); - CHECK_CLOSE_ABS(gExt.min(BinningValue::binPhi), phiMin, 1e-6); - CHECK_CLOSE_ABS(gExt.max(BinningValue::binPhi), phiMax, 1e-6); + CHECK_CLOSE_ABS(gExt.min(AxisDirection::AxisX), 15_mm, 1e-6); + CHECK_CLOSE_ABS(gExt.max(AxisDirection::AxisX), 18_mm, 1e-6); + CHECK_CLOSE_ABS(gExt.min(AxisDirection::AxisY), -3_mm, 1e-6); + CHECK_CLOSE_ABS(gExt.max(AxisDirection::AxisY), 3_mm, 1e-6); + CHECK_CLOSE_ABS(gExt.min(AxisDirection::AxisZ), -10_mm, 1e-6); + CHECK_CLOSE_ABS(gExt.max(AxisDirection::AxisZ), 10_mm, 1e-6); + CHECK_CLOSE_ABS(gExt.min(AxisDirection::AxisR), rMin, 1e-6); + CHECK_CLOSE_ABS(gExt.max(AxisDirection::AxisR), 18_mm, 1e-6); + CHECK_CLOSE_ABS(gExt.min(AxisDirection::AxisPhi), phiMin, 1e-6); + CHECK_CLOSE_ABS(gExt.max(AxisDirection::AxisPhi), phiMax, 1e-6); // Call with histogram filling Extent gExtHist; for (const auto& v : vertices) { - gExtHist.extend(v, {BinningValue::binX}, false, true); + gExtHist.extend(v, {AxisDirection::AxisX}, false, true); } const auto& vHist = gExtHist.valueHistograms(); - auto xVals = vHist[toUnderlying(BinningValue::binX)]; + auto xVals = vHist[toUnderlying(AxisDirection::AxisX)]; BOOST_CHECK_EQUAL(xVals.size(), 6u); std::vector reference = {15_mm, 18_mm, 15_mm, 15_mm, 18_mm, 15_mm}; @@ -68,31 +68,31 @@ BOOST_AUTO_TEST_CASE(ExtentTest) { // Call with ieterator range Extent gExtItr; gExtItr.extend(vertices.begin(), vertices.end()); - CHECK_CLOSE_ABS(gExtItr.min(BinningValue::binX), 15_mm, 1e-6); - CHECK_CLOSE_ABS(gExtItr.max(BinningValue::binX), 18_mm, 1e-6); - CHECK_CLOSE_ABS(gExtItr.min(BinningValue::binY), -3_mm, 1e-6); - CHECK_CLOSE_ABS(gExtItr.max(BinningValue::binY), 3_mm, 1e-6); - CHECK_CLOSE_ABS(gExtItr.min(BinningValue::binZ), -10_mm, 1e-6); - CHECK_CLOSE_ABS(gExtItr.max(BinningValue::binZ), 10_mm, 1e-6); - CHECK_CLOSE_ABS(gExtItr.min(BinningValue::binR), rMin, 1e-6); - CHECK_CLOSE_ABS(gExtItr.max(BinningValue::binR), 18_mm, 1e-6); - CHECK_CLOSE_ABS(gExtItr.min(BinningValue::binPhi), phiMin, 1e-6); - CHECK_CLOSE_ABS(gExtItr.max(BinningValue::binPhi), phiMax, 1e-6); + CHECK_CLOSE_ABS(gExtItr.min(AxisDirection::AxisX), 15_mm, 1e-6); + CHECK_CLOSE_ABS(gExtItr.max(AxisDirection::AxisX), 18_mm, 1e-6); + CHECK_CLOSE_ABS(gExtItr.min(AxisDirection::AxisY), -3_mm, 1e-6); + CHECK_CLOSE_ABS(gExtItr.max(AxisDirection::AxisY), 3_mm, 1e-6); + CHECK_CLOSE_ABS(gExtItr.min(AxisDirection::AxisZ), -10_mm, 1e-6); + CHECK_CLOSE_ABS(gExtItr.max(AxisDirection::AxisZ), 10_mm, 1e-6); + CHECK_CLOSE_ABS(gExtItr.min(AxisDirection::AxisR), rMin, 1e-6); + CHECK_CLOSE_ABS(gExtItr.max(AxisDirection::AxisR), 18_mm, 1e-6); + CHECK_CLOSE_ABS(gExtItr.min(AxisDirection::AxisPhi), phiMin, 1e-6); + CHECK_CLOSE_ABS(gExtItr.max(AxisDirection::AxisPhi), phiMax, 1e-6); // Create a second Extent Extent gExtCopy; gExtCopy.extend(gExt); - CHECK_CLOSE_ABS(gExtCopy.min(BinningValue::binX), 15_mm, 1e-6); - CHECK_CLOSE_ABS(gExtCopy.max(BinningValue::binX), 18_mm, 1e-6); - CHECK_CLOSE_ABS(gExtCopy.min(BinningValue::binY), -3_mm, 1e-6); - CHECK_CLOSE_ABS(gExtCopy.max(BinningValue::binY), 3_mm, 1e-6); - CHECK_CLOSE_ABS(gExtCopy.min(BinningValue::binZ), -10_mm, 1e-6); - CHECK_CLOSE_ABS(gExtCopy.max(BinningValue::binZ), 10_mm, 1e-6); - CHECK_CLOSE_ABS(gExtCopy.min(BinningValue::binR), rMin, 1e-6); - CHECK_CLOSE_ABS(gExtCopy.max(BinningValue::binR), 18_mm, 1e-6); - CHECK_CLOSE_ABS(gExtCopy.min(BinningValue::binPhi), phiMin, 1e-6); - CHECK_CLOSE_ABS(gExtCopy.max(BinningValue::binPhi), phiMax, 1e-6); + CHECK_CLOSE_ABS(gExtCopy.min(AxisDirection::AxisX), 15_mm, 1e-6); + CHECK_CLOSE_ABS(gExtCopy.max(AxisDirection::AxisX), 18_mm, 1e-6); + CHECK_CLOSE_ABS(gExtCopy.min(AxisDirection::AxisY), -3_mm, 1e-6); + CHECK_CLOSE_ABS(gExtCopy.max(AxisDirection::AxisY), 3_mm, 1e-6); + CHECK_CLOSE_ABS(gExtCopy.min(AxisDirection::AxisZ), -10_mm, 1e-6); + CHECK_CLOSE_ABS(gExtCopy.max(AxisDirection::AxisZ), 10_mm, 1e-6); + CHECK_CLOSE_ABS(gExtCopy.min(AxisDirection::AxisR), rMin, 1e-6); + CHECK_CLOSE_ABS(gExtCopy.max(AxisDirection::AxisR), 18_mm, 1e-6); + CHECK_CLOSE_ABS(gExtCopy.min(AxisDirection::AxisPhi), phiMin, 1e-6); + CHECK_CLOSE_ABS(gExtCopy.max(AxisDirection::AxisPhi), phiMax, 1e-6); // Check containment Extent unbound; @@ -101,55 +101,55 @@ BOOST_AUTO_TEST_CASE(ExtentTest) { // Check application of an envelope on it ExtentEnvelope xEnvelopes = ExtentEnvelope::Zero(); - xEnvelopes[BinningValue::binX] = {1., 2.}; + xEnvelopes[AxisDirection::AxisX] = {1., 2.}; // Take the extent and extend by an envelope Extent envelope(xEnvelopes); gExt.extend(envelope); // Changed ones - CHECK_CLOSE_ABS(gExt.min(BinningValue::binX), 14_mm, 1e-6); - CHECK_CLOSE_ABS(gExt.max(BinningValue::binX), 20_mm, 1e-6); + CHECK_CLOSE_ABS(gExt.min(AxisDirection::AxisX), 14_mm, 1e-6); + CHECK_CLOSE_ABS(gExt.max(AxisDirection::AxisX), 20_mm, 1e-6); // Unchanged ones - CHECK_CLOSE_ABS(gExt.min(BinningValue::binY), -3_mm, 1e-6); - CHECK_CLOSE_ABS(gExt.max(BinningValue::binY), 3_mm, 1e-6); - CHECK_CLOSE_ABS(gExt.min(BinningValue::binZ), -10_mm, 1e-6); - CHECK_CLOSE_ABS(gExt.max(BinningValue::binZ), 10_mm, 1e-6); - CHECK_CLOSE_ABS(gExt.min(BinningValue::binR), rMin, 1e-6); - CHECK_CLOSE_ABS(gExt.max(BinningValue::binR), 18_mm, 1e-6); - CHECK_CLOSE_ABS(gExt.min(BinningValue::binPhi), phiMin, 1e-6); - CHECK_CLOSE_ABS(gExt.max(BinningValue::binPhi), phiMax, 1e-6); + CHECK_CLOSE_ABS(gExt.min(AxisDirection::AxisY), -3_mm, 1e-6); + CHECK_CLOSE_ABS(gExt.max(AxisDirection::AxisY), 3_mm, 1e-6); + CHECK_CLOSE_ABS(gExt.min(AxisDirection::AxisZ), -10_mm, 1e-6); + CHECK_CLOSE_ABS(gExt.max(AxisDirection::AxisZ), 10_mm, 1e-6); + CHECK_CLOSE_ABS(gExt.min(AxisDirection::AxisR), rMin, 1e-6); + CHECK_CLOSE_ABS(gExt.max(AxisDirection::AxisR), 18_mm, 1e-6); + CHECK_CLOSE_ABS(gExt.min(AxisDirection::AxisPhi), phiMin, 1e-6); + CHECK_CLOSE_ABS(gExt.max(AxisDirection::AxisPhi), phiMax, 1e-6); // Fill it with envelope Extent gExtEnv(envelope); gExtEnv.extend(vertices.begin(), vertices.end()); // Changed ones - CHECK_CLOSE_ABS(gExtEnv.min(BinningValue::binX), 14_mm, 1e-6); - CHECK_CLOSE_ABS(gExtEnv.max(BinningValue::binX), 20_mm, 1e-6); + CHECK_CLOSE_ABS(gExtEnv.min(AxisDirection::AxisX), 14_mm, 1e-6); + CHECK_CLOSE_ABS(gExtEnv.max(AxisDirection::AxisX), 20_mm, 1e-6); // Check the set method - gExt.set(BinningValue::binX, 2_mm, 8_mm); - CHECK_CLOSE_ABS(gExt.min(BinningValue::binX), 2_mm, 1e-6); - CHECK_CLOSE_ABS(gExt.max(BinningValue::binX), 8_mm, 1e-6); + gExt.set(AxisDirection::AxisX, 2_mm, 8_mm); + CHECK_CLOSE_ABS(gExt.min(AxisDirection::AxisX), 2_mm, 1e-6); + CHECK_CLOSE_ABS(gExt.max(AxisDirection::AxisX), 8_mm, 1e-6); // Radius can not go below 0 - gExt.set(BinningValue::binR, -2_mm, 18_mm); - CHECK_CLOSE_ABS(gExt.min(BinningValue::binR), 0_mm, 1e-6); - CHECK_CLOSE_ABS(gExt.max(BinningValue::binR), 18_mm, 1e-6); + gExt.set(AxisDirection::AxisR, -2_mm, 18_mm); + CHECK_CLOSE_ABS(gExt.min(AxisDirection::AxisR), 0_mm, 1e-6); + CHECK_CLOSE_ABS(gExt.max(AxisDirection::AxisR), 18_mm, 1e-6); // Take an Extent and add a constraint Extent gExtConst; - gExtConst.set(BinningValue::binR, 0., 5.); + gExtConst.set(AxisDirection::AxisR, 0., 5.); Extent gExtNonConst; - BOOST_CHECK(!gExtNonConst.constrains(BinningValue::binR)); + BOOST_CHECK(!gExtNonConst.constrains(AxisDirection::AxisR)); gExtNonConst.addConstrain(gExtConst); - BOOST_CHECK(gExtNonConst.constrains(BinningValue::binR)); + BOOST_CHECK(gExtNonConst.constrains(AxisDirection::AxisR)); std::string tString = gExtConst.toString(); BOOST_CHECK(!tString.empty()); // Check single vertex containment Extent gExtVertexCheck; - gExtVertexCheck.set(BinningValue::binR, 0., 5.); + gExtVertexCheck.set(AxisDirection::AxisR, 0., 5.); BOOST_CHECK(gExtVertexCheck.contains(Vector3(1., 0., 0.))); BOOST_CHECK(!gExtVertexCheck.contains(Vector3(6., 0., 0.))); } @@ -163,23 +163,23 @@ BOOST_AUTO_TEST_CASE(ProtoSupportCaseTests) { Vector3(18_mm, 0_mm, 10_mm), Vector3(15_mm, 3_mm, 10_mm)}; Extent volumeExtent; - volumeExtent.set(BinningValue::binZ, -300_mm, 300_mm); + volumeExtent.set(AxisDirection::AxisZ, -300_mm, 300_mm); - BOOST_CHECK(volumeExtent.constrains(BinningValue::binZ)); - BOOST_CHECK(!volumeExtent.constrains(BinningValue::binR)); + BOOST_CHECK(volumeExtent.constrains(AxisDirection::AxisZ)); + BOOST_CHECK(!volumeExtent.constrains(AxisDirection::AxisR)); for (const auto& v : vertices) { - volumeExtent.extend(v, {BinningValue::binR}); + volumeExtent.extend(v, {AxisDirection::AxisR}); } - BOOST_CHECK(volumeExtent.constrains(BinningValue::binR)); + BOOST_CHECK(volumeExtent.constrains(AxisDirection::AxisR)); } BOOST_AUTO_TEST_CASE(DesignatedInitializers) { - using enum BinningValue; + using enum AxisDirection; ExtentEnvelope exp; - exp[binX] = {1., 2.}; - exp[binEta] = {-1., 1.}; + exp[AxisX] = {1., 2.}; + exp[AxisEta] = {-1., 1.}; ExtentEnvelope act{{.x = {1., 2.}, .eta = {-1., 1.}}}; diff --git a/Tests/UnitTests/Core/Geometry/KDTreeTrackingGeometryBuilderTests.cpp b/Tests/UnitTests/Core/Geometry/KDTreeTrackingGeometryBuilderTests.cpp index f30bd15c6cb..87fd7a9b4cd 100644 --- a/Tests/UnitTests/Core/Geometry/KDTreeTrackingGeometryBuilderTests.cpp +++ b/Tests/UnitTests/Core/Geometry/KDTreeTrackingGeometryBuilderTests.cpp @@ -100,35 +100,35 @@ BOOST_AUTO_TEST_CASE(KDTreeTrackingGeometryBuilder_simple) { // Make a proto detectpr description Acts::ProtoVolume beamPipeContainer; beamPipeContainer.name = "odd-beam-pipe"; - beamPipeContainer.extent.set(Acts::BinningValue::binR, 0., 17); + beamPipeContainer.extent.set(Acts::AxisDirection::AxisR, 0., 17); Acts::ProtoVolume beamPipe; beamPipe.name = "odd-beam-pipe-l"; - beamPipe.extent.set(Acts::BinningValue::binR, 2., 16.); + beamPipe.extent.set(Acts::AxisDirection::AxisR, 2., 16.); beamPipe.internal = Acts::ProtoVolume::InternalStructure{ Acts::Surface::SurfaceType::Cylinder}; beamPipeContainer.container = Acts::ProtoVolume::ContainerStructure{ {beamPipe}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binR, {0., 1.})}, + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisR, {0., 1.})}, true}; // Pixel section Acts::ProtoVolume pixelContainer; pixelContainer.name = "odd-pixel"; - pixelContainer.extent.set(Acts::BinningValue::binR, 18., 200); + pixelContainer.extent.set(Acts::AxisDirection::AxisR, 18., 200); Acts::ProtoVolume pixelNec; pixelNec.name = "odd-pixel-nec"; - pixelNec.extent.set(Acts::BinningValue::binZ, -1000., -580); + pixelNec.extent.set(Acts::AxisDirection::AxisZ, -1000., -580); Acts::ProtoVolume pixNecD1; pixNecD1.name = "odd-pixel-nec-d1"; - pixNecD1.extent.set(Acts::BinningValue::binZ, -720., -680); + pixNecD1.extent.set(Acts::AxisDirection::AxisZ, -720., -680); Acts::ProtoVolume pixNecD0; pixNecD0.name = "odd-pixel-nec-d0"; - pixNecD0.extent.set(Acts::BinningValue::binZ, -620., -580); + pixNecD0.extent.set(Acts::AxisDirection::AxisZ, -620., -580); pixelNec.container = Acts::ProtoVolume::ContainerStructure{ {pixNecD1, pixNecD0}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binZ, {0., 1.})}, + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisZ, {0., 1.})}, true}; for (auto& cv : pixelNec.container.value().constituentVolumes) { cv.internal = @@ -137,52 +137,52 @@ BOOST_AUTO_TEST_CASE(KDTreeTrackingGeometryBuilder_simple) { Acts::ProtoVolume pixelBarrel; pixelBarrel.name = "odd-pixel-barrel"; - pixelBarrel.extent.set(Acts::BinningValue::binZ, -580., 580); + pixelBarrel.extent.set(Acts::AxisDirection::AxisZ, -580., 580); Acts::ProtoVolume pixBarrelL0; pixBarrelL0.name = "odd-pixel-barrel-l0"; - pixBarrelL0.extent.set(Acts::BinningValue::binR, 28., 48.); - pixBarrelL0.extent.set(Acts::BinningValue::binZ, -580., 580); + pixBarrelL0.extent.set(Acts::AxisDirection::AxisR, 28., 48.); + pixBarrelL0.extent.set(Acts::AxisDirection::AxisZ, -580., 580); pixBarrelL0.internal = Acts::ProtoVolume::InternalStructure{ Acts::Surface::SurfaceType::Cylinder}; Acts::ProtoVolume pixBarrelL1; pixBarrelL1.name = "odd-pixel-barrel-l1"; - pixBarrelL1.extent.set(Acts::BinningValue::binR, 62., 76); - pixBarrelL1.extent.set(Acts::BinningValue::binZ, -580., 580); + pixBarrelL1.extent.set(Acts::AxisDirection::AxisR, 62., 76); + pixBarrelL1.extent.set(Acts::AxisDirection::AxisZ, -580., 580); pixBarrelL1.internal = Acts::ProtoVolume::InternalStructure{ Acts::Surface::SurfaceType::Cylinder}; Acts::ProtoVolume pixBarrelL2; pixBarrelL2.name = "odd-pixel-barrel-l2"; - pixBarrelL2.extent.set(Acts::BinningValue::binR, 100., 120.); - pixBarrelL2.extent.set(Acts::BinningValue::binZ, -580., 580); + pixBarrelL2.extent.set(Acts::AxisDirection::AxisR, 100., 120.); + pixBarrelL2.extent.set(Acts::AxisDirection::AxisZ, -580., 580); pixBarrelL2.internal = Acts::ProtoVolume::InternalStructure{ Acts::Surface::SurfaceType::Cylinder}; Acts::ProtoVolume pixBarrelL3; pixBarrelL3.name = "odd-pixel-barrel-l3"; - pixBarrelL3.extent.set(Acts::BinningValue::binR, 160., 180.); - pixBarrelL3.extent.set(Acts::BinningValue::binZ, -580., 580); + pixBarrelL3.extent.set(Acts::AxisDirection::AxisR, 160., 180.); + pixBarrelL3.extent.set(Acts::AxisDirection::AxisZ, -580., 580); pixBarrelL3.internal = Acts::ProtoVolume::InternalStructure{ Acts::Surface::SurfaceType::Cylinder}; pixelBarrel.container = Acts::ProtoVolume::ContainerStructure{ {pixBarrelL0, pixBarrelL1, pixBarrelL2, pixBarrelL3}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binR, {0., 1})}, + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisR, {0., 1})}, true}; Acts::ProtoVolume pixelPec; pixelPec.name = "odd-pixel-pec"; - pixelPec.extent.set(Acts::BinningValue::binZ, 580., 1000.); + pixelPec.extent.set(Acts::AxisDirection::AxisZ, 580., 1000.); Acts::ProtoVolume pixPecD0; pixPecD0.name = "odd-pixel-pec-d0"; - pixPecD0.extent.set(Acts::BinningValue::binZ, 580., 620); + pixPecD0.extent.set(Acts::AxisDirection::AxisZ, 580., 620); Acts::ProtoVolume pixPecD1; pixPecD1.name = "odd-pixel-pec-d1"; - pixPecD1.extent.set(Acts::BinningValue::binZ, 680., 720); + pixPecD1.extent.set(Acts::AxisDirection::AxisZ, 680., 720); pixelPec.container = Acts::ProtoVolume::ContainerStructure{ {pixPecD0, pixPecD1}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binZ, {0., 1})}, + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisZ, {0., 1})}, true}; for (auto& cv : pixelPec.container.value().constituentVolumes) { cv.internal = @@ -191,15 +191,15 @@ BOOST_AUTO_TEST_CASE(KDTreeTrackingGeometryBuilder_simple) { pixelContainer.container = Acts::ProtoVolume::ContainerStructure{ {pixelNec, pixelBarrel, pixelPec}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binZ, + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisZ, {-1000., -580., 580., 1000.})}}; Acts::ProtoVolume detectorContainer; detectorContainer.name = "odd-detector"; - detectorContainer.extent.set(Acts::BinningValue::binR, 0., 200); + detectorContainer.extent.set(Acts::AxisDirection::AxisR, 0., 200); detectorContainer.container = Acts::ProtoVolume::ContainerStructure{ {beamPipeContainer, pixelContainer}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binR, + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisR, {0., 17.5, 200.})}}; Acts::ProtoDetector detector; diff --git a/Tests/UnitTests/Core/Geometry/LayerCreatorTests.cpp b/Tests/UnitTests/Core/Geometry/LayerCreatorTests.cpp index 20f43a3b68e..adf80a20880 100644 --- a/Tests/UnitTests/Core/Geometry/LayerCreatorTests.cpp +++ b/Tests/UnitTests/Core/Geometry/LayerCreatorTests.cpp @@ -245,8 +245,8 @@ BOOST_FIXTURE_TEST_CASE(LayerCreator_createCylinderLayer, LayerCreatorFixture) { // CASE I double envR = 0.1, envZ = 0.5; ProtoLayer pl(tgContext, srf); - pl.envelope[Acts::BinningValue::binR] = {envR, envR}; - pl.envelope[Acts::BinningValue::binZ] = {envZ, envZ}; + pl.envelope[Acts::AxisDirection::AxisR] = {envR, envR}; + pl.envelope[Acts::AxisDirection::AxisZ] = {envZ, envZ}; std::shared_ptr layer = std::dynamic_pointer_cast( p_LC->cylinderLayer(tgContext, srf, equidistant, equidistant, pl)); @@ -270,8 +270,8 @@ BOOST_FIXTURE_TEST_CASE(LayerCreator_createCylinderLayer, LayerCreatorFixture) { // CASE II ProtoLayer pl2(tgContext, srf); - pl2.envelope[Acts::BinningValue::binR] = {envR, envR}; - pl2.envelope[Acts::BinningValue::binZ] = {envZ, envZ}; + pl2.envelope[Acts::AxisDirection::AxisR] = {envR, envR}; + pl2.envelope[Acts::AxisDirection::AxisZ] = {envZ, envZ}; layer = std::dynamic_pointer_cast( p_LC->cylinderLayer(tgContext, srf, 30, 7, pl2)); CHECK_CLOSE_REL(layer->thickness(), (rMax - rMin) + 2 * envR, 1e-3); @@ -306,8 +306,8 @@ BOOST_FIXTURE_TEST_CASE(LayerCreator_createCylinderLayer, LayerCreatorFixture) { // CASE III ProtoLayer pl3; - pl3.extent.range(Acts::BinningValue::binR).set(1, 20); - pl3.extent.range(Acts::BinningValue::binZ).set(-25, 25); + pl3.extent.range(Acts::AxisDirection::AxisR).set(1, 20); + pl3.extent.range(Acts::AxisDirection::AxisZ).set(-25, 25); layer = std::dynamic_pointer_cast( p_LC->cylinderLayer(tgContext, srf, equidistant, equidistant, pl3)); CHECK_CLOSE_REL(layer->thickness(), 19, 1e-3); @@ -340,8 +340,8 @@ BOOST_FIXTURE_TEST_CASE(LayerCreator_createDiscLayer, LayerCreatorFixture) { draw_surfaces(surfaces, "LayerCreator_createDiscLayer_EC_1.obj"); ProtoLayer pl(tgContext, surfaces); - pl.extent.range(BinningValue::binZ).set(-10, 10); - pl.extent.range(BinningValue::binR).set(5., 25.); + pl.extent.range(AxisDirection::AxisZ).set(-10, 10); + pl.extent.range(AxisDirection::AxisR).set(5., 25.); std::shared_ptr layer = std::dynamic_pointer_cast( p_LC->discLayer(tgContext, surfaces, equidistant, equidistant, pl)); CHECK_CLOSE_REL(layer->thickness(), 20, 1e-3); @@ -368,8 +368,8 @@ BOOST_FIXTURE_TEST_CASE(LayerCreator_createDiscLayer, LayerCreatorFixture) { double envMinR = 1, envMaxR = 1, envZ = 5; std::size_t nBinsR = 3, nBinsPhi = 30; ProtoLayer pl2(tgContext, surfaces); - pl2.envelope[BinningValue::binR] = {envMinR, envMaxR}; - pl2.envelope[BinningValue::binZ] = {envZ, envZ}; + pl2.envelope[AxisDirection::AxisR] = {envMinR, envMaxR}; + pl2.envelope[AxisDirection::AxisZ] = {envZ, envZ}; layer = std::dynamic_pointer_cast( p_LC->discLayer(tgContext, surfaces, nBinsR, nBinsPhi, pl2)); @@ -424,8 +424,8 @@ BOOST_FIXTURE_TEST_CASE(LayerCreator_barrelStagger, LayerCreatorFixture) { double envR = 0, envZ = 0; ProtoLayer pl(tgContext, brl); - pl.envelope[BinningValue::binR] = {envR, envR}; - pl.envelope[BinningValue::binZ] = {envZ, envZ}; + pl.envelope[AxisDirection::AxisR] = {envR, envR}; + pl.envelope[AxisDirection::AxisZ] = {envZ, envZ}; std::shared_ptr layer = std::dynamic_pointer_cast( p_LC->cylinderLayer(tgContext, brl, equidistant, equidistant, pl)); @@ -444,7 +444,7 @@ BOOST_FIXTURE_TEST_CASE(LayerCreator_barrelStagger, LayerCreatorFixture) { // std::cout << "dPHi = " << A->center().phi() - B->center().phi() << // std::endl; - Vector3 ctr = A->binningPosition(tgContext, BinningValue::binR); + Vector3 ctr = A->referencePosition(tgContext, AxisDirection::AxisR); auto binContent = layer->surfaceArray()->at(ctr); BOOST_CHECK_EQUAL(binContent.size(), 2u); std::set act; diff --git a/Tests/UnitTests/Core/Geometry/NavigationLayerTests.cpp b/Tests/UnitTests/Core/Geometry/NavigationLayerTests.cpp index 32406c3a288..6e606e3e03c 100644 --- a/Tests/UnitTests/Core/Geometry/NavigationLayerTests.cpp +++ b/Tests/UnitTests/Core/Geometry/NavigationLayerTests.cpp @@ -51,10 +51,10 @@ BOOST_AUTO_TEST_CASE(NavigationLayerProperties) { auto rawSurfacePtr = pSurface.get(); auto pNavigationLayer = NavigationLayer::create(std::move(pSurface), thickness); - BinningValue b{BinningValue::binZ}; + AxisDirection b{AxisDirection::AxisZ}; Vector3 origin{0., 0., 0.}; - // binningPosition(), needs a better test - BOOST_CHECK_EQUAL(pNavigationLayer->binningPosition(tgContext, b), origin); + // referencePosition(), needs a better test + BOOST_CHECK_EQUAL(pNavigationLayer->referencePosition(tgContext, b), origin); // surfaceRepresentation() [looks dangerous] BOOST_CHECK_EQUAL(rawSurfacePtr, &(pNavigationLayer->surfaceRepresentation())); diff --git a/Tests/UnitTests/Core/Geometry/PlaneLayerTests.cpp b/Tests/UnitTests/Core/Geometry/PlaneLayerTests.cpp index b3d96a56943..229ce3fbe8e 100644 --- a/Tests/UnitTests/Core/Geometry/PlaneLayerTests.cpp +++ b/Tests/UnitTests/Core/Geometry/PlaneLayerTests.cpp @@ -58,7 +58,7 @@ BOOST_AUTO_TEST_CASE(PlaneLayerConstruction) { SurfaceArrayCreator sac; std::size_t binsX(2), binsY(4); auto pSurfaceArray = sac.surfaceArrayOnPlane(tgContext, aSurfaces, binsX, - binsY, BinningValue::binZ); + binsY, AxisDirection::AxisZ); auto pPlaneLayerFromSurfaces = PlaneLayer::create(pTransform, pRectangle, std::move(pSurfaceArray)); BOOST_CHECK_EQUAL(pPlaneLayerFromSurfaces->layerType(), LayerType::active); diff --git a/Tests/UnitTests/Core/Geometry/PolyhedronTests.cpp b/Tests/UnitTests/Core/Geometry/PolyhedronTests.cpp index d087c6485cf..6b6e8548d0c 100644 --- a/Tests/UnitTests/Core/Geometry/PolyhedronTests.cpp +++ b/Tests/UnitTests/Core/Geometry/PolyhedronTests.cpp @@ -83,18 +83,18 @@ BOOST_AUTO_TEST_CASE(PolyhedronExtent) { Polyhedron rectangle(rvertices, rfaces, rmesh); auto rExtent = rectangle.extent(); - CHECK_CLOSE_ABS(rExtent.min(BinningValue::binX), -1., 1e-6); - CHECK_CLOSE_ABS(rExtent.max(BinningValue::binX), 1., 1e-6); - CHECK_CLOSE_ABS(rExtent.min(BinningValue::binY), -2., 1e-6); - CHECK_CLOSE_ABS(rExtent.max(BinningValue::binY), -1., 1e-6); - CHECK_CLOSE_ABS(rExtent.min(BinningValue::binZ), 0., 1e-6); - CHECK_CLOSE_ABS(rExtent.max(BinningValue::binZ), 0., 1e-6); - CHECK_CLOSE_ABS(rExtent.min(BinningValue::binR), 1., 1e-6); - CHECK_CLOSE_ABS(rExtent.max(BinningValue::binR), + CHECK_CLOSE_ABS(rExtent.min(AxisDirection::AxisX), -1., 1e-6); + CHECK_CLOSE_ABS(rExtent.max(AxisDirection::AxisX), 1., 1e-6); + CHECK_CLOSE_ABS(rExtent.min(AxisDirection::AxisY), -2., 1e-6); + CHECK_CLOSE_ABS(rExtent.max(AxisDirection::AxisY), -1., 1e-6); + CHECK_CLOSE_ABS(rExtent.min(AxisDirection::AxisZ), 0., 1e-6); + CHECK_CLOSE_ABS(rExtent.max(AxisDirection::AxisZ), 0., 1e-6); + CHECK_CLOSE_ABS(rExtent.min(AxisDirection::AxisR), 1., 1e-6); + CHECK_CLOSE_ABS(rExtent.max(AxisDirection::AxisR), VectorHelpers::perp(rvertices[0]), 1e-6); - CHECK_CLOSE_ABS(rExtent.min(BinningValue::binPhi), + CHECK_CLOSE_ABS(rExtent.min(AxisDirection::AxisPhi), VectorHelpers::phi(rvertices[3]), 1e-6); - CHECK_CLOSE_ABS(rExtent.max(BinningValue::binPhi), + CHECK_CLOSE_ABS(rExtent.max(AxisDirection::AxisPhi), VectorHelpers::phi(rvertices[2]), 1e-6); // Now shift the Extent @@ -102,12 +102,12 @@ BOOST_AUTO_TEST_CASE(PolyhedronExtent) { Transform3 shiftedTransform = Transform3::Identity(); shiftedTransform.pretranslate(shift); rExtent = rectangle.extent(shiftedTransform); - CHECK_CLOSE_ABS(rExtent.min(BinningValue::binX), -2., 1e-6); - CHECK_CLOSE_ABS(rExtent.max(BinningValue::binX), 0., 1e-6); - CHECK_CLOSE_ABS(rExtent.min(BinningValue::binY), -2., 1e-6); - CHECK_CLOSE_ABS(rExtent.max(BinningValue::binY), -1., 1e-6); - CHECK_CLOSE_ABS(rExtent.min(BinningValue::binZ), 1., 1e-6); - CHECK_CLOSE_ABS(rExtent.max(BinningValue::binZ), 1., 1e-6); + CHECK_CLOSE_ABS(rExtent.min(AxisDirection::AxisX), -2., 1e-6); + CHECK_CLOSE_ABS(rExtent.max(AxisDirection::AxisX), 0., 1e-6); + CHECK_CLOSE_ABS(rExtent.min(AxisDirection::AxisY), -2., 1e-6); + CHECK_CLOSE_ABS(rExtent.max(AxisDirection::AxisY), -1., 1e-6); + CHECK_CLOSE_ABS(rExtent.min(AxisDirection::AxisZ), 1., 1e-6); + CHECK_CLOSE_ABS(rExtent.max(AxisDirection::AxisZ), 1., 1e-6); // Test a rectangle in yz - pane (at x == 3) rvertices = {Vector3(3_mm, -5_mm, -10_mm), Vector3(3_mm, 5_mm, -10_mm), @@ -115,14 +115,14 @@ BOOST_AUTO_TEST_CASE(PolyhedronExtent) { rectangle = Polyhedron(rvertices, rfaces, rmesh); rExtent = rectangle.extent(); - CHECK_CLOSE_ABS(rExtent.min(BinningValue::binX), 3., 1e-6); - CHECK_CLOSE_ABS(rExtent.max(BinningValue::binX), 3., 1e-6); - CHECK_CLOSE_ABS(rExtent.min(BinningValue::binY), -5., 1e-6); - CHECK_CLOSE_ABS(rExtent.max(BinningValue::binY), 5., 1e-6); - CHECK_CLOSE_ABS(rExtent.min(BinningValue::binZ), -10., 1e-6); - CHECK_CLOSE_ABS(rExtent.max(BinningValue::binZ), 10., 1e-6); - CHECK_CLOSE_ABS(rExtent.min(BinningValue::binR), 3., 1e-6); - CHECK_CLOSE_ABS(rExtent.max(BinningValue::binR), std::sqrt(9. + 25.), 1e-6); + CHECK_CLOSE_ABS(rExtent.min(AxisDirection::AxisX), 3., 1e-6); + CHECK_CLOSE_ABS(rExtent.max(AxisDirection::AxisX), 3., 1e-6); + CHECK_CLOSE_ABS(rExtent.min(AxisDirection::AxisY), -5., 1e-6); + CHECK_CLOSE_ABS(rExtent.max(AxisDirection::AxisY), 5., 1e-6); + CHECK_CLOSE_ABS(rExtent.min(AxisDirection::AxisZ), -10., 1e-6); + CHECK_CLOSE_ABS(rExtent.max(AxisDirection::AxisZ), 10., 1e-6); + CHECK_CLOSE_ABS(rExtent.min(AxisDirection::AxisR), 3., 1e-6); + CHECK_CLOSE_ABS(rExtent.max(AxisDirection::AxisR), std::sqrt(9. + 25.), 1e-6); } BOOST_AUTO_TEST_SUITE_END() diff --git a/Tests/UnitTests/Core/Geometry/PortalLinkTests.cpp b/Tests/UnitTests/Core/Geometry/PortalLinkTests.cpp index fd87545d4f0..14f6ee23d33 100644 --- a/Tests/UnitTests/Core/Geometry/PortalLinkTests.cpp +++ b/Tests/UnitTests/Core/Geometry/PortalLinkTests.cpp @@ -15,15 +15,17 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/Units.hpp" #include "Acts/Geometry/CompositePortalLink.hpp" +#include "Acts/Geometry/CuboidVolumeBounds.hpp" #include "Acts/Geometry/CylinderVolumeBounds.hpp" #include "Acts/Geometry/GridPortalLink.hpp" #include "Acts/Geometry/TrackingVolume.hpp" #include "Acts/Geometry/TrivialPortalLink.hpp" #include "Acts/Surfaces/CylinderSurface.hpp" #include "Acts/Surfaces/RadialBounds.hpp" +#include "Acts/Surfaces/RectangleBounds.hpp" #include "Acts/Surfaces/SurfaceMergingException.hpp" #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/ThrowAssert.hpp" #include @@ -94,23 +96,23 @@ BOOST_AUTO_TEST_CASE(Cylinder) { std::make_shared(30_mm, 40_mm, 100_mm)); // Incompatible binning - BOOST_CHECK_THROW( - GridPortalLink::make(cyl, BinningValue::binZ, Axis{AxisBound, 0, 5, 5}), - std::invalid_argument); + BOOST_CHECK_THROW(GridPortalLink::make(cyl, AxisDirection::AxisZ, + Axis{AxisBound, 0, 5, 5}), + std::invalid_argument); - auto grid1dCyl = GridPortalLink::make(cyl, BinningValue::binZ, + auto grid1dCyl = GridPortalLink::make(cyl, AxisDirection::AxisZ, Axis{AxisBound, -100_mm, 100_mm, 10}); BOOST_REQUIRE(grid1dCyl); grid1dCyl->setVolume(vol.get()); // Throws because non-closed axis - BOOST_CHECK_THROW(GridPortalLink::make(cyl, BinningValue::binRPhi, + BOOST_CHECK_THROW(GridPortalLink::make(cyl, AxisDirection::AxisRPhi, Axis{AxisBound, -180_degree * 30_mm, 180_degree * 30_mm, 10}), std::invalid_argument); auto grid1dCylRPhi = GridPortalLink::make( - cyl, BinningValue::binRPhi, + cyl, AxisDirection::AxisRPhi, Axis{AxisClosed, -180_degree * 30_mm, 180_degree * 30_mm, 10}); BOOST_REQUIRE_NE(grid1dCylRPhi, nullptr); grid1dCylRPhi->setVolume(vol.get()); @@ -124,14 +126,14 @@ BOOST_AUTO_TEST_CASE(Cylinder) { auto cyl2 = Surface::makeShared( Transform3{Translation3{Vector3::UnitZ() * 150_mm}}, 30_mm, 50_mm); - auto grid1dCyl2 = GridPortalLink::make(cyl2, BinningValue::binZ, + auto grid1dCyl2 = GridPortalLink::make(cyl2, AxisDirection::AxisZ, Axis{AxisBound, -50_mm, 50_mm, 5}); // Test exception on cylinder with non-zero average phi auto cylNonZeroAverage = Surface::makeShared( Transform3::Identity(), 30_mm, 100_mm, 20_degree, 45_degree); BOOST_CHECK_THROW( - GridPortalLink::make(cylNonZeroAverage, BinningValue::binZ, + GridPortalLink::make(cylNonZeroAverage, AxisDirection::AxisZ, Axis{AxisBound, -100_mm, 100_mm, 10}), std::invalid_argument); @@ -185,12 +187,12 @@ BOOST_AUTO_TEST_CASE(Cylinder) { auto cylPhi = Surface::makeShared( Transform3::Identity(), 30_mm, 100_mm, 45_degree); std::unique_ptr grid1dCylPhi = GridPortalLink::make( - cylPhi, BinningValue::binZ, Axis{AxisBound, -100_mm, 100_mm, 10}); + cylPhi, AxisDirection::AxisZ, Axis{AxisBound, -100_mm, 100_mm, 10}); grid1dCylPhi->setVolume(vol.get()); // Check that phi sector portal does not accept closed axis - BOOST_CHECK_THROW(GridPortalLink::make(cylPhi, BinningValue::binRPhi, + BOOST_CHECK_THROW(GridPortalLink::make(cylPhi, AxisDirection::AxisRPhi, Axis{AxisClosed, -45_degree * 30_mm, 45_degree * 30_mm, 10}), std::invalid_argument); @@ -290,17 +292,17 @@ BOOST_AUTO_TEST_CASE(Disc) { Transform3::Identity(), std::make_shared(30_mm, 40_mm, 100_mm)); - BOOST_CHECK_THROW(GridPortalLink::make(disc1, BinningValue::binZ, + BOOST_CHECK_THROW(GridPortalLink::make(disc1, AxisDirection::AxisZ, Axis{AxisBound, 30_mm, 100_mm, 3}), std::invalid_argument); // Check exception for full disc and non-closed phi axis BOOST_CHECK_THROW( - GridPortalLink::make(disc1, BinningValue::binPhi, + GridPortalLink::make(disc1, AxisDirection::AxisPhi, Axis{AxisBound, -180_degree, 180_degree, 3}), std::invalid_argument); - auto grid1 = GridPortalLink::make(disc1, BinningValue::binR, + auto grid1 = GridPortalLink::make(disc1, AxisDirection::AxisR, Axis{AxisBound, 30_mm, 100_mm, 3}); BOOST_REQUIRE_NE(grid1, nullptr); BOOST_CHECK_EQUAL(grid1->grid().axes().size(), 1); @@ -315,12 +317,12 @@ BOOST_AUTO_TEST_CASE(Disc) { // Check thet disc with phi sector does not accept closed axis BOOST_CHECK_THROW( - GridPortalLink::make(discPhi, BinningValue::binPhi, + GridPortalLink::make(discPhi, AxisDirection::AxisPhi, Axis{AxisClosed, -45_degree, 45_degree, 3}), std::invalid_argument); auto gridPhi = - GridPortalLink::make(discPhi, BinningValue::binPhi, + GridPortalLink::make(discPhi, AxisDirection::AxisPhi, Axis{AxisBound, -45_degree, 45_degree, 3}); BOOST_REQUIRE_NE(gridPhi, nullptr); gridPhi->setVolume(vol.get()); @@ -330,7 +332,7 @@ BOOST_AUTO_TEST_CASE(Disc) { Transform3::Identity(), std::make_shared(30_mm, 100_mm, 45_degree, 75_degree)); BOOST_CHECK_THROW( - GridPortalLink::make(discNonZeroAverage, BinningValue::binR, + GridPortalLink::make(discNonZeroAverage, AxisDirection::AxisR, Axis{AxisBound, 30_mm, 100_mm, 3}), std::invalid_argument); @@ -379,7 +381,7 @@ BOOST_AUTO_TEST_CASE(Disc) { *grid2dExplicit)); auto gridPhiBinnedInR = GridPortalLink::make( - discPhi, BinningValue::binR, Axis{AxisBound, 30_mm, 100_mm, 3}); + discPhi, AxisDirection::AxisR, Axis{AxisBound, 30_mm, 100_mm, 3}); gridPhiBinnedInR->setVolume(vol.get()); auto grid2dPhiNonClosed = gridPhiBinnedInR->extendTo2d(nullptr); BOOST_REQUIRE(grid2dPhiNonClosed); @@ -465,7 +467,124 @@ BOOST_AUTO_TEST_CASE(Disc) { } BOOST_AUTO_TEST_CASE(Plane) { - // @TODO: Add plane tests + using enum AxisType; + using enum AxisBoundaryType; + BOOST_TEST_CONTEXT("1D") { + // Initialize surfaces + auto rBounds = std::make_shared(30_mm, 100_mm); + auto planeX = + Surface::makeShared(Transform3::Identity(), rBounds); + auto planeY = + Surface::makeShared(Transform3::Identity(), rBounds); + + // Volume for bin testing + auto vol = std::make_shared( + Transform3::Identity(), + std::make_shared(30_mm, 40_mm, 100_mm)); + + // Initialize grids + auto gridX = GridPortalLink::make(planeX, AxisDirection::AxisX, + Axis{AxisBound, -30_mm, 30_mm, 3}); + auto gridY = GridPortalLink::make(planeY, AxisDirection::AxisY, + Axis{AxisBound, -100_mm, 100_mm, 3}); + + // Check grid X + BOOST_REQUIRE_NE(gridX, nullptr); + BOOST_CHECK_EQUAL(gridX->grid().axes().size(), 1); + const auto& axisX = *gridX->grid().axes().front(); + Axis axisXExpected{AxisBound, -30_mm, 30_mm, 3}; + BOOST_CHECK_EQUAL(axisX, axisXExpected); + + // Check grid Y + BOOST_REQUIRE_NE(gridY, nullptr); + BOOST_CHECK_EQUAL(gridY->grid().axes().size(), 1); + const auto& axisY = *gridY->grid().axes().front(); + Axis axisYExpected{AxisBound, -100_mm, 100_mm, 3}; + BOOST_CHECK_EQUAL(axisY, axisYExpected); + + // Check gridX/gridX bin content + auto checkAllBins = [&](const auto& grid) { + visitBins(grid, [&](const TrackingVolume* content) { + BOOST_CHECK_EQUAL(content, vol.get()); + }); + }; + + gridX->setVolume(vol.get()); + checkAllBins(*gridX); + + gridY->setVolume(vol.get()); + checkAllBins(*gridY); + + // Test making 2D grids from the 1D ones + + // Test grid X + auto gridX2d = gridX->extendTo2d(nullptr); + BOOST_REQUIRE(gridX2d); + BOOST_CHECK_EQUAL(gridX2d->grid().axes().size(), 2); + const auto* axisX1 = gridX2d->grid().axes().front(); + BOOST_CHECK_EQUAL(*axisX1, axisXExpected); + const auto* axisX2 = gridX2d->grid().axes().back(); + BOOST_CHECK_EQUAL(axisX2->getMin(), -100_mm); + BOOST_CHECK_EQUAL(axisX2->getMax(), 100_mm); + BOOST_CHECK_EQUAL(axisX2->getNBins(), 1); + BOOST_CHECK_EQUAL(axisX2->getType(), AxisType::Equidistant); + BOOST_CHECK_EQUAL(axisX2->getBoundaryType(), AxisBoundaryType::Bound); + + // Test grid X explicit + Axis axisYExplicit{AxisClosed, -100_mm, 100_mm, 3}; + auto gridX2dExplicit = gridX->extendTo2d(&axisYExplicit); + BOOST_REQUIRE(gridX2dExplicit); + BOOST_CHECK_EQUAL(gridX2dExplicit->grid().axes().size(), 2); + axisX1 = gridX2dExplicit->grid().axes().front(); + axisX2 = gridX2dExplicit->grid().axes().back(); + BOOST_CHECK_EQUAL(*axisX1, axisXExpected); + BOOST_CHECK_EQUAL(*axisX2, axisYExplicit); + + checkAllBins( + dynamic_cast< + GridPortalLinkT&>( + *gridX2dExplicit)); + + // Test grid Y + auto gridY2d = gridY->extendTo2d(nullptr); + BOOST_REQUIRE(gridY2d); + BOOST_CHECK_EQUAL(gridY2d->grid().axes().size(), 2); + const auto* axisY1 = gridY2d->grid().axes().front(); + BOOST_CHECK_EQUAL(axisY1->getMin(), -30_mm); + BOOST_CHECK_EQUAL(axisY1->getMax(), 30_mm); + BOOST_CHECK_EQUAL(axisY1->getNBins(), 1); + BOOST_CHECK_EQUAL(axisY1->getType(), AxisType::Equidistant); + BOOST_CHECK_EQUAL(axisY1->getBoundaryType(), AxisBoundaryType::Bound); + const auto* axisY2 = gridY2d->grid().axes().back(); + BOOST_CHECK_EQUAL(*axisY2, axisYExpected); + + // Test grid Y explicit + Axis axisXExplicit{AxisClosed, -30_mm, 30_mm, 3}; + auto gridY2dExplicit = gridY->extendTo2d(&axisXExplicit); + BOOST_REQUIRE(gridY2dExplicit); + BOOST_CHECK_EQUAL(gridY2dExplicit->grid().axes().size(), 2); + axisY1 = gridY2dExplicit->grid().axes().front(); + axisY2 = gridY2dExplicit->grid().axes().back(); + BOOST_CHECK_EQUAL(*axisY1, axisXExplicit); + BOOST_CHECK_EQUAL(*axisY2, axisYExpected); + + checkAllBins( + dynamic_cast< + GridPortalLinkT&>( + *gridY2dExplicit)); + } + BOOST_TEST_CONTEXT("2D") { + auto rBounds = std::make_shared(30_mm, 100_mm); + + auto plane = + Surface::makeShared(Transform3::Identity(), rBounds); + + Axis xAxis{AxisBound, -30_mm, 30_mm, 5}; + Axis yAxis{AxisBound, -100_mm, 100_mm, 5}; + + auto grid = GridPortalLink::make(plane, xAxis, yAxis); + BOOST_REQUIRE_NE(grid, nullptr); + } } BOOST_AUTO_TEST_CASE(FromTrivial) { @@ -483,7 +602,7 @@ BOOST_AUTO_TEST_CASE(FromTrivial) { BOOST_CHECK_EQUAL(trivial->resolveVolume(gctx, Vector2{1, 2}).value(), vol.get()); - auto gridZ = trivial->makeGrid(BinningValue::binZ); + auto gridZ = trivial->makeGrid(AxisDirection::AxisZ); BOOST_REQUIRE(gridZ); BOOST_CHECK_EQUAL(gridZ->grid().axes().size(), 1); @@ -495,7 +614,7 @@ BOOST_AUTO_TEST_CASE(FromTrivial) { gridZ->resolveVolume(gctx, Vector2{20_degree * 30_mm, 90_mm}).value(), vol.get()); - auto gridRPhi = trivial->makeGrid(BinningValue::binRPhi); + auto gridRPhi = trivial->makeGrid(AxisDirection::AxisRPhi); BOOST_REQUIRE(gridRPhi); BOOST_CHECK_EQUAL(gridRPhi->grid().axes().size(), 1); @@ -513,7 +632,7 @@ BOOST_AUTO_TEST_CASE(FromTrivial) { BOOST_CHECK_EQUAL(trivialPhi->resolveVolume(gctx, Vector2{1, 2}).value(), vol.get()); - auto gridRPhiSector = trivialPhi->makeGrid(BinningValue::binRPhi); + auto gridRPhiSector = trivialPhi->makeGrid(AxisDirection::AxisRPhi); BOOST_REQUIRE(gridRPhiSector); BOOST_CHECK_EQUAL( @@ -543,7 +662,7 @@ BOOST_AUTO_TEST_CASE(FromTrivial) { BOOST_CHECK_EQUAL(trivial->resolveVolume(gctx, Vector2{1, 2}).value(), vol.get()); - auto gridR = trivial->makeGrid(BinningValue::binR); + auto gridR = trivial->makeGrid(AxisDirection::AxisR); BOOST_REQUIRE(gridR); BOOST_CHECK_EQUAL(gridR->grid().axes().size(), 1); @@ -555,7 +674,7 @@ BOOST_AUTO_TEST_CASE(FromTrivial) { gridR->resolveVolume(gctx, Vector2{90_mm, 10_degree}).value(), vol.get()); - auto gridPhi = trivial->makeGrid(BinningValue::binPhi); + auto gridPhi = trivial->makeGrid(AxisDirection::AxisPhi); BOOST_REQUIRE(gridPhi); BOOST_CHECK_EQUAL(gridPhi->grid().axes().size(), 1); @@ -567,6 +686,45 @@ BOOST_AUTO_TEST_CASE(FromTrivial) { gridPhi->resolveVolume(gctx, Vector2{90_mm, 10_degree}).value(), vol.get()); } + BOOST_TEST_CONTEXT("Plane") { + auto rBounds = std::make_shared(30_mm, 100_mm); + + auto plane = + Surface::makeShared(Transform3::Identity(), rBounds); + + auto vol = std::make_shared( + Transform3::Identity(), + std::make_shared(30_mm, 40_mm, 100_mm)); + + auto trivial = std::make_unique(plane, *vol); + BOOST_REQUIRE(trivial); + + // Doesn't matter which position + BOOST_CHECK_EQUAL( + trivial->resolveVolume(gctx, Vector2{10_mm, 20_mm}).value(), vol.get()); + + auto gridX = trivial->makeGrid(AxisDirection::AxisX); + BOOST_REQUIRE(gridX); + + BOOST_CHECK_EQUAL(gridX->grid().axes().size(), 1); + BOOST_CHECK_EQUAL(gridX->surface().bounds(), plane->bounds()); + Axis axisXExpected{AxisBound, -30_mm, 30_mm, 1}; + BOOST_CHECK_EQUAL(*gridX->grid().axes().front(), axisXExpected); + + BOOST_CHECK_EQUAL(gridX->resolveVolume(gctx, Vector2{20_mm, 10_mm}).value(), + vol.get()); + + auto gridY = trivial->makeGrid(AxisDirection::AxisY); + BOOST_REQUIRE(gridY); + + BOOST_CHECK_EQUAL(gridY->grid().axes().size(), 1); + BOOST_CHECK_EQUAL(gridY->surface().bounds(), plane->bounds()); + Axis axisYExpected{AxisBound, -100_mm, 100_mm, 1}; + BOOST_CHECK_EQUAL(*gridY->grid().axes().front(), axisYExpected); + + BOOST_CHECK_EQUAL(gridY->resolveVolume(gctx, Vector2{15_mm, 20_mm}).value(), + vol.get()); + } } BOOST_AUTO_TEST_SUITE_END() // GridConstruction @@ -584,7 +742,7 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { auto cyl = Surface::makeShared(Transform3::Identity(), 30_mm, 100_mm); - auto grid1dCyl = GridPortalLink::make(cyl, BinningValue::binZ, + auto grid1dCyl = GridPortalLink::make(cyl, AxisDirection::AxisZ, Axis{AxisBound, -100_mm, 100_mm, 10}); grid1dCyl->setVolume(vol1.get()); @@ -592,24 +750,24 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { auto cyl2 = Surface::makeShared( Transform3{Translation3{Vector3::UnitZ() * 150_mm}}, 30_mm, 50_mm); - auto grid1dCyl2 = GridPortalLink::make(cyl2, BinningValue::binZ, + auto grid1dCyl2 = GridPortalLink::make(cyl2, AxisDirection::AxisZ, Axis{AxisBound, -50_mm, 50_mm, 5}); grid1dCyl2->setVolume(vol2.get()); // Completely invalid BOOST_CHECK_THROW(GridPortalLink::merge(*grid1dCyl, *grid1dCyl2, - BinningValue::binPhi, *logger), + AxisDirection::AxisPhi, *logger), AssertionFailureException); // Invalid direction, as the cylinders are shifted in z, and can't be merged // in r x phi BOOST_CHECK_THROW(GridPortalLink::merge(*grid1dCyl, *grid1dCyl2, - BinningValue::binRPhi, *logger), + AxisDirection::AxisRPhi, *logger), SurfaceMergingException); BOOST_TEST_CONTEXT("Consistent equidistant") { auto mergedPtr = GridPortalLink::merge(*grid1dCyl, *grid1dCyl2, - BinningValue::binZ, *logger); + AxisDirection::AxisZ, *logger); BOOST_REQUIRE_NE(mergedPtr, nullptr); const auto* merged = dynamic_cast(mergedPtr.get()); BOOST_REQUIRE_NE(merged, nullptr); @@ -624,10 +782,10 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { BOOST_TEST_CONTEXT("Inconsistent equidistant") { auto grid1dCyl2BinWidthChanged = GridPortalLink::make( - cyl2, BinningValue::binZ, Axis{AxisBound, -50_mm, 50_mm, 6}); + cyl2, AxisDirection::AxisZ, Axis{AxisBound, -50_mm, 50_mm, 6}); auto mergedPtr = GridPortalLink::merge( - *grid1dCyl, *grid1dCyl2BinWidthChanged, BinningValue::binZ, *logger); + *grid1dCyl, *grid1dCyl2BinWidthChanged, AxisDirection::AxisZ, *logger); BOOST_REQUIRE_NE(mergedPtr, nullptr); const auto* merged = dynamic_cast(mergedPtr.get()); BOOST_REQUIRE_NE(merged, nullptr); @@ -641,15 +799,15 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { } BOOST_TEST_CONTEXT("Right Variable") { - auto gridLeft = GridPortalLink::make(cyl, BinningValue::binZ, + auto gridLeft = GridPortalLink::make(cyl, AxisDirection::AxisZ, Axis{AxisBound, -100_mm, 100_mm, 10}); auto gridRight = - GridPortalLink::make(cyl2, BinningValue::binZ, + GridPortalLink::make(cyl2, AxisDirection::AxisZ, Axis{AxisBound, {-50_mm, -10_mm, 10_mm, 50_mm}}); auto mergedPtr = GridPortalLink::merge(*gridLeft, *gridRight, - BinningValue::binZ, *logger); + AxisDirection::AxisZ, *logger); BOOST_REQUIRE_NE(mergedPtr, nullptr); const auto* merged = dynamic_cast(mergedPtr.get()); BOOST_REQUIRE_NE(merged, nullptr); @@ -664,14 +822,14 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { BOOST_TEST_CONTEXT("Left Variable") { auto gridLeft = - GridPortalLink::make(cyl, BinningValue::binZ, + GridPortalLink::make(cyl, AxisDirection::AxisZ, Axis{AxisBound, {-100_mm, -80_mm, 10_mm, 100_mm}}); - auto gridRight = GridPortalLink::make(cyl2, BinningValue::binZ, + auto gridRight = GridPortalLink::make(cyl2, AxisDirection::AxisZ, Axis{AxisBound, -50_mm, 50_mm, 8}); auto mergedPtr = GridPortalLink::merge(*gridLeft, *gridRight, - BinningValue::binZ, *logger); + AxisDirection::AxisZ, *logger); BOOST_REQUIRE_NE(mergedPtr, nullptr); const auto* merged = dynamic_cast(mergedPtr.get()); BOOST_REQUIRE_NE(merged, nullptr); @@ -686,15 +844,15 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { BOOST_TEST_CONTEXT("Both Variable") { auto gridLeft = - GridPortalLink::make(cyl, BinningValue::binZ, + GridPortalLink::make(cyl, AxisDirection::AxisZ, Axis{AxisBound, {-100_mm, -80_mm, 10_mm, 100_mm}}); auto gridRight = - GridPortalLink::make(cyl2, BinningValue::binZ, + GridPortalLink::make(cyl2, AxisDirection::AxisZ, Axis{AxisBound, {-50_mm, -10_mm, 10_mm, 50_mm}}); auto mergedPtr = GridPortalLink::merge(*gridLeft, *gridRight, - BinningValue::binZ, *logger); + AxisDirection::AxisZ, *logger); BOOST_REQUIRE_NE(mergedPtr, nullptr); const auto* merged = dynamic_cast(mergedPtr.get()); BOOST_REQUIRE_NE(merged, nullptr); @@ -709,21 +867,21 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { BOOST_TEST_CONTEXT("Non bound axis") { std::unique_ptr gridLeft = - GridPortalLink::make(cyl, BinningValue::binZ, + GridPortalLink::make(cyl, AxisDirection::AxisZ, Axis{AxisBound, {-100_mm, -80_mm, 10_mm, 100_mm}}); std::unique_ptr gridRightClosed = - GridPortalLink::make(cyl2, BinningValue::binZ, + GridPortalLink::make(cyl2, AxisDirection::AxisZ, Axis{AxisClosed, {-50_mm, -10_mm, 10_mm, 50_mm}}); std::unique_ptr gridRightOpen = - GridPortalLink::make(cyl2, BinningValue::binZ, + GridPortalLink::make(cyl2, AxisDirection::AxisZ, Axis{AxisOpen, {-50_mm, -10_mm, 10_mm, 50_mm}}); auto compositeLR = PortalLinkBase::merge( - copy(gridLeft), copy(gridRightClosed), BinningValue::binZ, *logger); + copy(gridLeft), copy(gridRightClosed), AxisDirection::AxisZ, *logger); BOOST_CHECK_NE(dynamic_cast(compositeLR.get()), nullptr); auto compositeRL = PortalLinkBase::merge( - copy(gridLeft), copy(gridRightOpen), BinningValue::binZ, *logger); + copy(gridLeft), copy(gridRightOpen), AxisDirection::AxisZ, *logger); BOOST_CHECK_NE(dynamic_cast(compositeRL.get()), nullptr); } @@ -735,7 +893,7 @@ BOOST_AUTO_TEST_CASE(ParallelMerge) { 30_mm, 100_mm, 35_degree); auto grid1 = GridPortalLink::make( - cyl1, BinningValue::binRPhi, + cyl1, AxisDirection::AxisRPhi, Axis{AxisBound, -35_degree * 30_mm, 35_degree * 30_mm, 3}); auto cyl2 = Surface::makeShared( @@ -743,11 +901,11 @@ BOOST_AUTO_TEST_CASE(ParallelMerge) { 35_degree); auto grid2 = GridPortalLink::make( - cyl2, BinningValue::binRPhi, + cyl2, AxisDirection::AxisRPhi, Axis{AxisBound, -35_degree * 30_mm, 35_degree * 30_mm, 3}); auto merged12Ptr = - GridPortalLink::merge(*grid1, *grid2, BinningValue::binZ, *logger); + GridPortalLink::merge(*grid1, *grid2, AxisDirection::AxisZ, *logger); BOOST_REQUIRE_NE(merged12Ptr, nullptr); auto merged12 = dynamic_cast(merged12Ptr.get()); BOOST_REQUIRE_NE(merged12, nullptr); @@ -769,7 +927,7 @@ BOOST_AUTO_TEST_SUITE(RPhiDirection) BOOST_AUTO_TEST_CASE(ColinearMerge) { auto cyl = Surface::makeShared(Transform3::Identity(), 30_mm, 100_mm); - BOOST_CHECK_THROW(GridPortalLink::make(cyl, BinningValue::binRPhi, + BOOST_CHECK_THROW(GridPortalLink::make(cyl, AxisDirection::AxisRPhi, Axis{AxisBound, 0, 5, 5}), std::invalid_argument); @@ -778,7 +936,7 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { BOOST_CHECK_THROW( GridPortalLink::make( - cylNonZeroAverage, BinningValue::binRPhi, + cylNonZeroAverage, AxisDirection::AxisRPhi, Axis{AxisBound, -20_degree * 30_mm, 20_degree * 30_mm, 5}), std::invalid_argument); @@ -792,11 +950,11 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { 30_mm, 100_mm, 40_degree, 0_degree); auto portalPhi1 = GridPortalLink::make( - cylPhi1, BinningValue::binRPhi, + cylPhi1, AxisDirection::AxisRPhi, Axis{AxisBound, -20_degree * 30_mm, 20_degree * 30_mm, 5}); auto portalPhi2 = GridPortalLink::make( - cylPhi2, BinningValue::binRPhi, + cylPhi2, AxisDirection::AxisRPhi, Axis{AxisBound, -40_degree * 30_mm, 40_degree * 30_mm, 10}); auto cylPhi3 = Surface::makeShared( @@ -808,16 +966,16 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { 30_mm, 100_mm, 90_degree, 0_degree); auto portalPhi3 = GridPortalLink::make( - cylPhi3, BinningValue::binRPhi, + cylPhi3, AxisDirection::AxisRPhi, Axis{AxisBound, -90_degree * 30_mm, 90_degree * 30_mm, 2}); auto portalPhi4 = GridPortalLink::make( - cylPhi4, BinningValue::binRPhi, + cylPhi4, AxisDirection::AxisRPhi, Axis{AxisBound, -90_degree * 30_mm, 90_degree * 30_mm, 2}); BOOST_TEST_CONTEXT("Consistent equidistant") { - auto portalMerged = GridPortalLink::merge(*portalPhi1, *portalPhi2, - BinningValue::binRPhi, *logger); + auto portalMerged = GridPortalLink::merge( + *portalPhi1, *portalPhi2, AxisDirection::AxisRPhi, *logger); BOOST_REQUIRE_NE(portalMerged, nullptr); const auto* merged = @@ -833,7 +991,7 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { // Test that if you merge half-circles, we get a closed axis auto portalMerged34 = GridPortalLink::merge( - *portalPhi3, *portalPhi4, BinningValue::binRPhi, *logger); + *portalPhi3, *portalPhi4, AxisDirection::AxisRPhi, *logger); BOOST_REQUIRE_NE(portalMerged34, nullptr); const auto* merged34 = @@ -850,11 +1008,11 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { BOOST_TEST_CONTEXT("Inconsistent equidistant") { auto portalPhi2Mod = GridPortalLink::make( - cylPhi2, BinningValue::binRPhi, + cylPhi2, AxisDirection::AxisRPhi, Axis{AxisBound, -40_degree * 30_mm, 40_degree * 30_mm, 3}); auto portalMergedMod = GridPortalLink::merge( - *portalPhi1, *portalPhi2Mod, BinningValue::binRPhi, *logger); + *portalPhi1, *portalPhi2Mod, AxisDirection::AxisRPhi, *logger); BOOST_REQUIRE_NE(portalMergedMod, nullptr); const auto* merged12 = @@ -874,11 +1032,11 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { CHECK_CLOSE_OR_SMALL(axis12.getBinEdges(), expected12, 1e-4, 10e-10); auto portalPhi4Mod = GridPortalLink::make( - cylPhi4, BinningValue::binRPhi, + cylPhi4, AxisDirection::AxisRPhi, Axis{AxisBound, -90_degree * 30_mm, 90_degree * 30_mm, 1}); auto portalMerged34 = GridPortalLink::merge( - *portalPhi3, *portalPhi4Mod, BinningValue::binRPhi, *logger); + *portalPhi3, *portalPhi4Mod, AxisDirection::AxisRPhi, *logger); BOOST_REQUIRE_NE(portalMerged34, nullptr); const auto* merged34 = @@ -901,16 +1059,16 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { BOOST_TEST_CONTEXT("Left variable") { BOOST_TEST_CONTEXT("Non-closed") { auto gridLeft = - GridPortalLink::make(cylPhi1, BinningValue::binRPhi, + GridPortalLink::make(cylPhi1, AxisDirection::AxisRPhi, Axis{AxisBound, {-20_degree * 30_mm, -10_degree * 30_mm, 10_degree * 30_mm, 20_degree * 30_mm}}); auto gridRight = GridPortalLink::make( - cylPhi2, BinningValue::binRPhi, + cylPhi2, AxisDirection::AxisRPhi, Axis{AxisBound, -40_degree * 30_mm, 40_degree * 30_mm, 3}); - auto mergedPtr = GridPortalLink::merge(*gridLeft, *gridRight, - BinningValue::binRPhi, *logger); + auto mergedPtr = GridPortalLink::merge( + *gridLeft, *gridRight, AxisDirection::AxisRPhi, *logger); BOOST_REQUIRE_NE(mergedPtr, nullptr); const auto* merged = @@ -931,16 +1089,16 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { BOOST_TEST_CONTEXT("Closed") { auto gridLeft = GridPortalLink::make( - cylPhi4, BinningValue::binRPhi, + cylPhi4, AxisDirection::AxisRPhi, Axis{AxisBound, {-90_degree * 30_mm, 25_degree * 30_mm, 90_degree * 30_mm}}); auto gridRight = GridPortalLink::make( - cylPhi3, BinningValue::binRPhi, + cylPhi3, AxisDirection::AxisRPhi, Axis{AxisBound, -90_degree * 30_mm, 90_degree * 30_mm, 3}); - auto mergedPtr = GridPortalLink::merge(*gridLeft, *gridRight, - BinningValue::binRPhi, *logger); + auto mergedPtr = GridPortalLink::merge( + *gridLeft, *gridRight, AxisDirection::AxisRPhi, *logger); BOOST_REQUIRE_NE(mergedPtr, nullptr); const auto* merged = @@ -965,16 +1123,16 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { BOOST_TEST_CONTEXT("Right variable") { BOOST_TEST_CONTEXT("Non-closed") { auto gridLeft = GridPortalLink::make( - cylPhi1, BinningValue::binRPhi, + cylPhi1, AxisDirection::AxisRPhi, Axis{AxisBound, -20_degree * 30_mm, 20_degree * 30_mm, 3}); auto gridRight = - GridPortalLink::make(cylPhi2, BinningValue::binRPhi, + GridPortalLink::make(cylPhi2, AxisDirection::AxisRPhi, Axis{AxisBound, {-40_degree * 30_mm, -10_degree * 30_mm, 10_degree * 30_mm, 40_degree * 30_mm}}); - auto mergedPtr = GridPortalLink::merge(*gridLeft, *gridRight, - BinningValue::binRPhi, *logger); + auto mergedPtr = GridPortalLink::merge( + *gridLeft, *gridRight, AxisDirection::AxisRPhi, *logger); BOOST_REQUIRE_NE(mergedPtr, nullptr); const auto* merged = @@ -995,16 +1153,16 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { BOOST_TEST_CONTEXT("Closed") { auto gridLeft = GridPortalLink::make( - cylPhi4, BinningValue::binRPhi, + cylPhi4, AxisDirection::AxisRPhi, Axis{AxisBound, -90_degree * 30_mm, 90_degree * 30_mm, 3}); auto gridRight = GridPortalLink::make( - cylPhi3, BinningValue::binRPhi, + cylPhi3, AxisDirection::AxisRPhi, Axis{AxisBound, {-90_degree * 30_mm, 25_degree * 30_mm, 90_degree * 30_mm}}); - auto mergedPtr = GridPortalLink::merge(*gridLeft, *gridRight, - BinningValue::binRPhi, *logger); + auto mergedPtr = GridPortalLink::merge( + *gridLeft, *gridRight, AxisDirection::AxisRPhi, *logger); BOOST_REQUIRE_NE(mergedPtr, nullptr); const auto* merged = @@ -1029,17 +1187,17 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { BOOST_TEST_CONTEXT("Both variable") { BOOST_TEST_CONTEXT("Non-closed") { auto gridLeft = - GridPortalLink::make(cylPhi1, BinningValue::binRPhi, + GridPortalLink::make(cylPhi1, AxisDirection::AxisRPhi, Axis{AxisBound, {-20_degree * 30_mm, -10_degree * 30_mm, 10_degree * 30_mm, 20_degree * 30_mm}}); auto gridRight = GridPortalLink::make( - cylPhi2, BinningValue::binRPhi, + cylPhi2, AxisDirection::AxisRPhi, Axis{AxisBound, {-40_degree * 30_mm, -5_degree * 30_mm, 40_degree * 30_mm}}); - auto mergedPtr = GridPortalLink::merge(*gridLeft, *gridRight, - BinningValue::binRPhi, *logger); + auto mergedPtr = GridPortalLink::merge( + *gridLeft, *gridRight, AxisDirection::AxisRPhi, *logger); BOOST_REQUIRE_NE(mergedPtr, nullptr); const auto* merged = @@ -1060,18 +1218,18 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { BOOST_TEST_CONTEXT("Closed") { auto gridLeft = GridPortalLink::make( - cylPhi4, BinningValue::binRPhi, + cylPhi4, AxisDirection::AxisRPhi, Axis{AxisBound, {-90_degree * 30_mm, 25_degree * 30_mm, 90_degree * 30_mm}}); auto gridRight = - GridPortalLink::make(cylPhi3, BinningValue::binRPhi, + GridPortalLink::make(cylPhi3, AxisDirection::AxisRPhi, Axis{AxisBound, {-90_degree * 30_mm, -10_degree * 30_mm, 10_degree * 30_mm, 90_degree * 30_mm}}); - auto mergedPtr = GridPortalLink::merge(*gridLeft, *gridRight, - BinningValue::binRPhi, *logger); + auto mergedPtr = GridPortalLink::merge( + *gridLeft, *gridRight, AxisDirection::AxisRPhi, *logger); BOOST_REQUIRE_NE(mergedPtr, nullptr); const auto* merged = @@ -1105,14 +1263,14 @@ BOOST_AUTO_TEST_CASE(ParallelMerge) { Transform3::Identity() * AngleAxis3(85_degree, Vector3::UnitZ()), 30_mm, 100_mm, 20_degree, 0_degree); - auto portalPhi1 = GridPortalLink::make(cylPhi1, BinningValue::binZ, + auto portalPhi1 = GridPortalLink::make(cylPhi1, AxisDirection::AxisZ, Axis{AxisBound, -100_mm, 100_mm, 5}); - auto portalPhi2 = GridPortalLink::make(cylPhi2, BinningValue::binZ, + auto portalPhi2 = GridPortalLink::make(cylPhi2, AxisDirection::AxisZ, Axis{AxisBound, -100_mm, 100_mm, 5}); auto merged12Ptr = GridPortalLink::merge(*portalPhi1, *portalPhi2, - BinningValue::binRPhi, *logger); + AxisDirection::AxisRPhi, *logger); BOOST_REQUIRE_NE(merged12Ptr, nullptr); auto merged12 = dynamic_cast(merged12Ptr.get()); BOOST_REQUIRE_NE(merged12, nullptr); @@ -1154,7 +1312,7 @@ BOOST_AUTO_TEST_CASE(ZDirection) { // We're merging in z direction, so the phi binnings need to be the same auto mergedPtr = - GridPortalLink::merge(*grid1, *grid2, BinningValue::binZ, *logger); + GridPortalLink::merge(*grid1, *grid2, AxisDirection::AxisZ, *logger); const auto* merged = dynamic_cast(mergedPtr.get()); BOOST_REQUIRE_NE(mergedPtr, nullptr); @@ -1178,7 +1336,7 @@ BOOST_AUTO_TEST_CASE(ZDirection) { Axis{AxisBound, -50_mm, 50_mm, 5}); auto composite = PortalLinkBase::merge(copy(grid1), copy(grid3), - BinningValue::binZ, *logger); + AxisDirection::AxisZ, *logger); BOOST_CHECK_NE(dynamic_cast(composite.get()), nullptr); } @@ -1202,7 +1360,7 @@ BOOST_AUTO_TEST_CASE(ZDirection) { Axis{AxisBound, -50_mm, 50_mm, 5}); auto mergedPtr = - GridPortalLink::merge(*grid1, *grid2, BinningValue::binZ, *logger); + GridPortalLink::merge(*grid1, *grid2, AxisDirection::AxisZ, *logger); const auto* merged = dynamic_cast(mergedPtr.get()); BOOST_REQUIRE_NE(mergedPtr, nullptr); @@ -1240,7 +1398,7 @@ BOOST_AUTO_TEST_CASE(RPhiDirection) { // We're merging in z direction, so the phi binnings need to be the same auto mergedPtr = - GridPortalLink::merge(*grid1, *grid2, BinningValue::binRPhi, *logger); + GridPortalLink::merge(*grid1, *grid2, AxisDirection::AxisRPhi, *logger); const auto* merged = dynamic_cast(mergedPtr.get()); BOOST_REQUIRE_NE(mergedPtr, nullptr); @@ -1266,17 +1424,17 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { auto disc1 = Surface::makeShared(Transform3::Identity(), 30_mm, 100_mm); - auto grid1 = GridPortalLink::make(disc1, BinningValue::binR, + auto grid1 = GridPortalLink::make(disc1, AxisDirection::AxisR, Axis{AxisBound, 30_mm, 100_mm, 7}); auto disc2 = Surface::makeShared(Transform3::Identity(), 100_mm, 150_mm); - auto grid2 = GridPortalLink::make(disc2, BinningValue::binR, + auto grid2 = GridPortalLink::make(disc2, AxisDirection::AxisR, Axis{AxisBound, 100_mm, 150_mm, 5}); auto mergedPtr = - GridPortalLink::merge(*grid1, *grid2, BinningValue::binR, *logger); + GridPortalLink::merge(*grid1, *grid2, AxisDirection::AxisR, *logger); BOOST_REQUIRE(mergedPtr); const auto* merged = dynamic_cast(mergedPtr.get()); BOOST_REQUIRE_NE(merged, nullptr); @@ -1289,17 +1447,17 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { auto discPhi1 = Surface::makeShared(Transform3::Identity(), 30_mm, 100_mm, 30_degree); - auto discPhiGrid1 = GridPortalLink::make(discPhi1, BinningValue::binR, + auto discPhiGrid1 = GridPortalLink::make(discPhi1, AxisDirection::AxisR, Axis{AxisBound, 30_mm, 100_mm, 7}); auto discPhi2 = Surface::makeShared(Transform3::Identity(), 100_mm, 150_mm, 30_degree); - auto discPhiGrid2 = GridPortalLink::make(discPhi2, BinningValue::binR, + auto discPhiGrid2 = GridPortalLink::make(discPhi2, AxisDirection::AxisR, Axis{AxisBound, 100_mm, 150_mm, 5}); auto mergedPhiPtr = GridPortalLink::merge(*discPhiGrid1, *discPhiGrid2, - BinningValue::binR, *logger); + AxisDirection::AxisR, *logger); BOOST_REQUIRE(mergedPhiPtr); const auto* mergedPhi = dynamic_cast(mergedPhiPtr.get()); @@ -1314,18 +1472,18 @@ BOOST_AUTO_TEST_CASE(ParallelMerge) { Surface::makeShared(Transform3::Identity(), 30_mm, 100_mm); auto grid1 = - GridPortalLink::make(disc1, BinningValue::binPhi, + GridPortalLink::make(disc1, AxisDirection::AxisPhi, Axis{AxisClosed, -180_degree, 180_degree, 5}); auto disc2 = Surface::makeShared(Transform3::Identity(), 100_mm, 150_mm); auto grid2 = - GridPortalLink::make(disc2, BinningValue::binPhi, + GridPortalLink::make(disc2, AxisDirection::AxisPhi, Axis{AxisClosed, -180_degree, 180_degree, 5}); auto mergedPtr = - GridPortalLink::merge(*grid1, *grid2, BinningValue::binR, *logger); + GridPortalLink::merge(*grid1, *grid2, AxisDirection::AxisR, *logger); BOOST_REQUIRE(mergedPtr); const auto* merged = dynamic_cast(mergedPtr.get()); BOOST_REQUIRE_NE(merged, nullptr); @@ -1347,18 +1505,18 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { auto disc1 = Surface::makeShared(Transform3::Identity(), 30_mm, 100_mm, 30_degree); - auto grid1 = GridPortalLink::make(disc1, BinningValue::binPhi, + auto grid1 = GridPortalLink::make(disc1, AxisDirection::AxisPhi, Axis{AxisBound, -30_degree, 30_degree, 3}); auto disc2 = Surface::makeShared( Transform3{AngleAxis3{90_degree, Vector3::UnitZ()}}, 30_mm, 100_mm, 60_degree); - auto grid2 = GridPortalLink::make(disc2, BinningValue::binPhi, + auto grid2 = GridPortalLink::make(disc2, AxisDirection::AxisPhi, Axis{AxisBound, -60_degree, 60_degree, 6}); auto mergedPtr = - GridPortalLink::merge(*grid1, *grid2, BinningValue::binPhi, *logger); + GridPortalLink::merge(*grid1, *grid2, AxisDirection::AxisPhi, *logger); BOOST_REQUIRE(mergedPtr); const auto* merged = dynamic_cast(mergedPtr.get()); BOOST_REQUIRE_NE(merged, nullptr); @@ -1376,7 +1534,7 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { 90_degree); auto grid1Half = - GridPortalLink::make(disc1Half, BinningValue::binPhi, + GridPortalLink::make(disc1Half, AxisDirection::AxisPhi, Axis{AxisBound, -90_degree, 90_degree, 3}); auto disc2Half = Surface::makeShared( @@ -1384,11 +1542,11 @@ BOOST_AUTO_TEST_CASE(ColinearMerge) { 90_degree); auto grid2Half = - GridPortalLink::make(disc2Half, BinningValue::binPhi, + GridPortalLink::make(disc2Half, AxisDirection::AxisPhi, Axis{AxisBound, -90_degree, 90_degree, 3}); auto mergedHalfPtr = GridPortalLink::merge(*grid1Half, *grid2Half, - BinningValue::binPhi, *logger); + AxisDirection::AxisPhi, *logger); BOOST_REQUIRE(mergedHalfPtr); const auto* mergedHalf = dynamic_cast(mergedHalfPtr.get()); @@ -1403,18 +1561,18 @@ BOOST_AUTO_TEST_CASE(ParallelMerge) { auto disc1 = Surface::makeShared(Transform3::Identity(), 30_mm, 100_mm, 30_degree); - auto grid1 = GridPortalLink::make(disc1, BinningValue::binR, + auto grid1 = GridPortalLink::make(disc1, AxisDirection::AxisR, Axis{AxisBound, 30_mm, 100_mm, 3}); auto disc2 = Surface::makeShared( Transform3{AngleAxis3{90_degree, Vector3::UnitZ()}}, 30_mm, 100_mm, 60_degree); - auto grid2 = GridPortalLink::make(disc2, BinningValue::binR, + auto grid2 = GridPortalLink::make(disc2, AxisDirection::AxisR, Axis{AxisBound, 30_mm, 100_mm, 3}); auto mergedPtr = - GridPortalLink::merge(*grid1, *grid2, BinningValue::binPhi, *logger); + GridPortalLink::merge(*grid1, *grid2, AxisDirection::AxisPhi, *logger); BOOST_REQUIRE(mergedPtr); const auto* merged = dynamic_cast(mergedPtr.get()); BOOST_REQUIRE_NE(merged, nullptr); @@ -1446,7 +1604,7 @@ BOOST_AUTO_TEST_CASE(BinFilling) { auto disc1 = Surface::makeShared(Transform3::Identity(), 30_mm, 60_mm, 30_degree); - auto grid1 = GridPortalLink::make(disc1, BinningValue::binR, + auto grid1 = GridPortalLink::make(disc1, AxisDirection::AxisR, Axis{AxisBound, 30_mm, 60_mm, 2}); grid1->setVolume(vol1.get()); @@ -1454,13 +1612,13 @@ BOOST_AUTO_TEST_CASE(BinFilling) { auto disc2 = Surface::makeShared(Transform3::Identity(), 60_mm, 90_mm, 30_degree); - auto grid2 = GridPortalLink::make(disc2, BinningValue::binR, + auto grid2 = GridPortalLink::make(disc2, AxisDirection::AxisR, Axis{AxisBound, 60_mm, 90_mm, 2}); grid2->setVolume(vol2.get()); auto mergedPtr = - GridPortalLink::merge(*grid1, *grid2, BinningValue::binR, *logger); + GridPortalLink::merge(*grid1, *grid2, AxisDirection::AxisR, *logger); using merged_type = GridPortalLinkT>; @@ -1482,8 +1640,9 @@ BOOST_AUTO_TEST_CASE(BinFilling) { auto disc1 = Surface::makeShared(Transform3::Identity(), 30_mm, 100_mm, 30_degree); - auto grid1 = GridPortalLink::make( - disc1, BinningValue::binPhi, Axis{AxisBound, -30_degree, 30_degree, 2}); + auto grid1 = + GridPortalLink::make(disc1, AxisDirection::AxisPhi, + Axis{AxisBound, -30_degree, 30_degree, 2}); grid1->setVolume(vol1.get()); @@ -1491,13 +1650,14 @@ BOOST_AUTO_TEST_CASE(BinFilling) { Transform3{AngleAxis3{60_degree, Vector3::UnitZ()}}, 30_mm, 100_mm, 30_degree); - auto grid2 = GridPortalLink::make( - disc2, BinningValue::binPhi, Axis{AxisBound, -30_degree, 30_degree, 2}); + auto grid2 = + GridPortalLink::make(disc2, AxisDirection::AxisPhi, + Axis{AxisBound, -30_degree, 30_degree, 2}); grid2->setVolume(vol2.get()); auto mergedPtr = - GridPortalLink::merge(*grid1, *grid2, BinningValue::binPhi, *logger); + GridPortalLink::merge(*grid1, *grid2, AxisDirection::AxisPhi, *logger); BOOST_REQUIRE(mergedPtr); using merged_type = @@ -1538,7 +1698,7 @@ BOOST_AUTO_TEST_CASE(RDirection) { Axis{AxisBound, -30_degree, 30_degree, 3}); auto mergedPtr = GridPortalLink::merge(*discPhiGrid1, *discPhiGrid2, - BinningValue::binR, *logger); + AxisDirection::AxisR, *logger); BOOST_REQUIRE(mergedPtr); const auto* merged = dynamic_cast(mergedPtr.get()); BOOST_REQUIRE_NE(merged, nullptr); @@ -1573,7 +1733,7 @@ BOOST_AUTO_TEST_CASE(PhiDirection) { Axis{AxisBound, -60_degree, 60_degree, 6}); auto mergedPtr = - GridPortalLink::merge(*grid1, *grid2, BinningValue::binPhi, *logger); + GridPortalLink::merge(*grid1, *grid2, AxisDirection::AxisPhi, *logger); BOOST_REQUIRE(mergedPtr); const auto* merged = dynamic_cast(mergedPtr.get()); BOOST_REQUIRE_NE(merged, nullptr); @@ -1649,7 +1809,7 @@ BOOST_AUTO_TEST_CASE(BinFilling) { checkCheckerBoard(discPhiGrid2->grid()); auto mergedPtr = GridPortalLink::merge(*discPhiGrid1, *discPhiGrid2, - BinningValue::binR, *logger); + AxisDirection::AxisR, *logger); using merged_type = GridPortalLinkT, @@ -1664,7 +1824,7 @@ BOOST_AUTO_TEST_CASE(BinFilling) { discPhiGrid2->setVolume(vol2.get()); mergedPtr = GridPortalLink::merge(*discPhiGrid1, *discPhiGrid2, - BinningValue::binR, *logger); + AxisDirection::AxisR, *logger); merged = dynamic_cast(mergedPtr.get()); BOOST_REQUIRE(merged); @@ -1720,7 +1880,7 @@ BOOST_AUTO_TEST_CASE(BinFilling) { checkCheckerBoard(grid2->grid()); auto mergedPtr = - GridPortalLink::merge(*grid1, *grid2, BinningValue::binPhi, *logger); + GridPortalLink::merge(*grid1, *grid2, AxisDirection::AxisPhi, *logger); BOOST_REQUIRE(mergedPtr); @@ -1738,7 +1898,7 @@ BOOST_AUTO_TEST_CASE(BinFilling) { grid2->setVolume(vol2.get()); mergedPtr = - GridPortalLink::merge(*grid1, *grid2, BinningValue::binPhi, *logger); + GridPortalLink::merge(*grid1, *grid2, AxisDirection::AxisPhi, *logger); merged = dynamic_cast(mergedPtr.get()); BOOST_REQUIRE(merged); @@ -1787,18 +1947,18 @@ BOOST_AUTO_TEST_CASE(RDirection) { 100_mm, 150_mm, 30_degree); auto discPhiGrid21dPhi = - GridPortalLink::make(discPhi2, BinningValue::binPhi, + GridPortalLink::make(discPhi2, AxisDirection::AxisPhi, Axis{AxisBound, -30_degree, 30_degree, 3}); auto merged12PhiPtr = GridPortalLink::merge(*discPhiGrid1, *discPhiGrid21dPhi, - BinningValue::binR, *logger); + AxisDirection::AxisR, *logger); BOOST_REQUIRE(merged12PhiPtr); const auto* merged12Phi = dynamic_cast(merged12PhiPtr.get()); BOOST_REQUIRE_NE(merged12Phi, nullptr); auto merged21PhiPtr = GridPortalLink::merge(*discPhiGrid21dPhi, *discPhiGrid1, - BinningValue::binR, *logger); + AxisDirection::AxisR, *logger); BOOST_REQUIRE(merged21PhiPtr); const auto* merged21Phi = dynamic_cast(merged21PhiPtr.get()); @@ -1822,17 +1982,17 @@ BOOST_AUTO_TEST_CASE(RDirection) { BOOST_CHECK_EQUAL(axis2.getBoundaryType(), AxisBoundaryType::Bound); auto discPhiGrid21dR = GridPortalLink::make( - discPhi2, BinningValue::binR, Axis{AxisBound, 100_mm, 150_mm, 5}); + discPhi2, AxisDirection::AxisR, Axis{AxisBound, 100_mm, 150_mm, 5}); auto merged12RPtr = GridPortalLink::merge(*discPhiGrid1, *discPhiGrid21dR, - BinningValue::binR, *logger); + AxisDirection::AxisR, *logger); BOOST_REQUIRE(merged12RPtr); const auto* merged12R = dynamic_cast(merged12RPtr.get()); BOOST_REQUIRE_NE(merged12R, nullptr); auto merged21RPtr = GridPortalLink::merge(*discPhiGrid21dR, *discPhiGrid1, - BinningValue::binR, *logger); + AxisDirection::AxisR, *logger); BOOST_REQUIRE(merged21RPtr); const auto* merged21R = dynamic_cast(merged21RPtr.get()); @@ -1867,12 +2027,12 @@ BOOST_AUTO_TEST_CASE(PhiDirection) { 60_degree); auto grid21dPhi = - GridPortalLink::make(disc2, BinningValue::binPhi, + GridPortalLink::make(disc2, AxisDirection::AxisPhi, Axis{AxisBound, -60_degree, 60_degree, 6}); - auto merged12PhiPtr = - GridPortalLink::merge(*grid1, *grid21dPhi, BinningValue::binPhi, *logger); + auto merged12PhiPtr = GridPortalLink::merge(*grid1, *grid21dPhi, + AxisDirection::AxisPhi, *logger); BOOST_REQUIRE(merged12PhiPtr); const auto* merged12Phi = dynamic_cast(merged12PhiPtr.get()); @@ -1893,11 +2053,11 @@ BOOST_AUTO_TEST_CASE(PhiDirection) { BOOST_CHECK_EQUAL(axis2.getType(), AxisType::Equidistant); BOOST_CHECK_EQUAL(axis2.getBoundaryType(), AxisBoundaryType::Bound); - auto grid21dR = GridPortalLink::make(disc2, BinningValue::binR, + auto grid21dR = GridPortalLink::make(disc2, AxisDirection::AxisR, Axis{AxisBound, 30_mm, 100_mm, 3}); auto merged12RPtr = - GridPortalLink::merge(*grid1, *grid21dR, BinningValue::binPhi, *logger); + GridPortalLink::merge(*grid1, *grid21dR, AxisDirection::AxisPhi, *logger); BOOST_REQUIRE(merged12RPtr); const auto* merged12R = dynamic_cast(merged12RPtr.get()); @@ -1933,7 +2093,7 @@ BOOST_AUTO_TEST_CASE(RDirection) { auto disc1 = Surface::makeShared(Transform3::Identity(), 30_mm, 100_mm, 30_degree); - auto grid1 = GridPortalLink::make(disc1, BinningValue::binR, + auto grid1 = GridPortalLink::make(disc1, AxisDirection::AxisR, Axis{AxisBound, 30_mm, 100_mm, 2}); grid1->grid().atLocalBins({1}) = vol1.get(); grid1->grid().atLocalBins({2}) = vol2.get(); @@ -1941,14 +2101,14 @@ BOOST_AUTO_TEST_CASE(RDirection) { auto disc2 = Surface::makeShared(Transform3::Identity(), 100_mm, 150_mm, 30_degree); - auto grid2 = GridPortalLink::make(disc2, BinningValue::binPhi, + auto grid2 = GridPortalLink::make(disc2, AxisDirection::AxisPhi, Axis{AxisBound, -30_degree, 30_degree, 2}); grid2->grid().atLocalBins({1}) = vol3.get(); grid2->grid().atLocalBins({2}) = vol4.get(); auto mergedPtr = - GridPortalLink::merge(*grid1, *grid2, BinningValue::binR, *logger); + GridPortalLink::merge(*grid1, *grid2, AxisDirection::AxisR, *logger); const auto* merged = dynamic_cast(mergedPtr.get()); BOOST_REQUIRE_NE(merged, nullptr); @@ -1990,7 +2150,7 @@ BOOST_AUTO_TEST_CASE(PhiDirection) { auto disc1 = Surface::makeShared(Transform3::Identity(), 30_mm, 100_mm, 30_degree); - auto grid1 = GridPortalLink::make(disc1, BinningValue::binR, + auto grid1 = GridPortalLink::make(disc1, AxisDirection::AxisR, Axis{AxisBound, 30_mm, 100_mm, 2}); grid1->grid().atLocalBins({1}) = vol1.get(); @@ -2000,14 +2160,14 @@ BOOST_AUTO_TEST_CASE(PhiDirection) { Transform3{AngleAxis3{90_degree, Vector3::UnitZ()}}, 30_mm, 100_mm, 60_degree); - auto grid2 = GridPortalLink::make(disc2, BinningValue::binPhi, + auto grid2 = GridPortalLink::make(disc2, AxisDirection::AxisPhi, Axis{AxisBound, -60_degree, 60_degree, 2}); grid2->grid().atLocalBins({1}) = vol3.get(); grid2->grid().atLocalBins({2}) = vol4.get(); auto mergedPtr = - GridPortalLink::merge(*grid1, *grid2, BinningValue::binPhi, *logger); + GridPortalLink::merge(*grid1, *grid2, AxisDirection::AxisPhi, *logger); using merged_type = GridPortalLinkT, @@ -2046,6 +2206,391 @@ BOOST_AUTO_TEST_CASE(PhiDirection) { BOOST_AUTO_TEST_SUITE_END() // MergeCrossDisc +BOOST_AUTO_TEST_SUITE(Merging1dPlane) + +BOOST_AUTO_TEST_CASE(ColinearMerge) { + auto rBounds1 = std::make_shared(30_mm, 100_mm); + + auto plane1 = + Surface::makeShared(Transform3::Identity(), rBounds1); + + auto gridX1 = GridPortalLink::make(plane1, AxisDirection::AxisX, + Axis{AxisBound, -30_mm, 30_mm, 6}); + auto gridY1 = GridPortalLink::make(plane1, AxisDirection::AxisY, + Axis{AxisBound, -100_mm, 100_mm, 10}); + + auto rBounds2 = std::make_shared(80_mm, 100_mm); + Translation3 offsetX{110_mm, 0., 0.}; + auto planeX2 = Surface::makeShared( + Transform3::Identity() * offsetX, rBounds2); + + auto rBounds3 = std::make_shared(30_mm, 20_mm); + Translation3 offsetY{0, 120_mm, 0.}; + auto planeY2 = Surface::makeShared( + Transform3::Identity() * offsetY, rBounds3); + + auto gridX2 = GridPortalLink::make(planeX2, AxisDirection::AxisX, + Axis{AxisBound, -80_mm, 80_mm, 16}); + auto gridY2 = GridPortalLink::make(planeY2, AxisDirection::AxisY, + Axis{AxisBound, -20_mm, 20_mm, 2}); + + auto mergedPtrX = + GridPortalLink::merge(*gridX1, *gridX2, AxisDirection::AxisX, *logger); + BOOST_REQUIRE(mergedPtrX); + const auto* mergedX = dynamic_cast(mergedPtrX.get()); + BOOST_REQUIRE_NE(mergedX, nullptr); + + BOOST_CHECK_EQUAL(mergedX->grid().axes().size(), 1); + Axis axisXExpected{AxisBound, -110_mm, 110_mm, 22}; + BOOST_CHECK_EQUAL(*mergedX->grid().axes().front(), axisXExpected); + + auto mergedPtrY = + GridPortalLink::merge(*gridY1, *gridY2, AxisDirection::AxisY, *logger); + BOOST_REQUIRE(mergedPtrY); + const auto* mergedY = dynamic_cast(mergedPtrY.get()); + BOOST_REQUIRE_NE(mergedY, nullptr); + + BOOST_CHECK_EQUAL(mergedY->grid().axes().size(), 1); + Axis axisYExpected{AxisBound, -120_mm, 120_mm, 12}; + BOOST_CHECK_EQUAL(*mergedY->grid().axes().front(), axisYExpected); +} + +BOOST_AUTO_TEST_CASE(ParallelMerge) { + auto rBounds = std::make_shared(30_mm, 100_mm); + auto plane1 = + Surface::makeShared(Transform3::Identity(), rBounds); + + auto grid1X = GridPortalLink::make(plane1, AxisDirection::AxisX, + Axis{AxisBound, -30_mm, 30_mm, 6}); + + auto grid1Y = GridPortalLink::make(plane1, AxisDirection::AxisY, + Axis{AxisBound, -100_mm, 100_mm, 5}); + + Translation3 offsetX{60_mm, 0, 0.}; + auto plane2 = Surface::makeShared( + Transform3::Identity() * offsetX, rBounds); + auto grid2 = GridPortalLink::make(plane2, AxisDirection::AxisY, + Axis{AxisBound, -100_mm, 100_mm, 5}); + + Translation3 offsetY{0, 200_mm, 0.}; + auto plane3 = Surface::makeShared( + Transform3::Identity() * offsetY, rBounds); + auto grid3 = GridPortalLink::make(plane3, AxisDirection::AxisX, + Axis{AxisBound, -30_mm, 30_mm, 6}); + + auto mergedPtrX = + GridPortalLink::merge(*grid1Y, *grid2, AxisDirection::AxisX, *logger); + BOOST_REQUIRE(mergedPtrX); + const auto* mergedX = dynamic_cast(mergedPtrX.get()); + BOOST_REQUIRE_NE(mergedX, nullptr); + + BOOST_CHECK_EQUAL(mergedX->grid().axes().size(), 2); + const auto& axisX1 = *mergedX->grid().axes().front(); + const auto& axisX2 = *mergedX->grid().axes().back(); + Axis axisX1Expected{AxisBound, -60_mm, 60_mm, 2}; + BOOST_CHECK_EQUAL(axisX1, axisX1Expected); + Axis axisX2Expected{AxisBound, -100_mm, 100_mm, 5}; + BOOST_CHECK_EQUAL(axisX2, axisX2Expected); + + auto mergedPtrY = + GridPortalLink::merge(*grid1X, *grid3, AxisDirection::AxisY, *logger); + BOOST_REQUIRE(mergedPtrY); + const auto* mergedY = dynamic_cast(mergedPtrY.get()); + BOOST_REQUIRE_NE(mergedY, nullptr); + + BOOST_CHECK_EQUAL(mergedY->grid().axes().size(), 2); + const auto& axisY1 = *mergedY->grid().axes().front(); + const auto& axisY2 = *mergedY->grid().axes().back(); + Axis axisY1Expected{AxisBound, -30_mm, 30_mm, 6}; + BOOST_CHECK_EQUAL(axisY1, axisY1Expected); + Axis axisY2Expected{AxisBound, -200_mm, 200_mm, 2}; + BOOST_CHECK_EQUAL(axisY2, axisY2Expected); +} + +BOOST_AUTO_TEST_CASE(BinFilling) { + // Volumes for bin content checking + auto vol1 = std::make_shared( + Transform3::Identity(), + std::make_shared(30_mm, 40_mm, 100_mm)); + auto vol2 = std::make_shared( + Transform3::Identity(), + std::make_shared(30_mm, 40_mm, 100_mm)); + + auto rBounds = std::make_shared(30_mm, 100_mm); + auto plane1 = + Surface::makeShared(Transform3::Identity(), rBounds); + + auto grid1X = GridPortalLink::make(plane1, AxisDirection::AxisX, + Axis{AxisBound, -30_mm, 30_mm, 2}); + grid1X->setVolume(vol1.get()); + + auto grid1Y = GridPortalLink::make(plane1, AxisDirection::AxisY, + Axis{AxisBound, -100_mm, 100_mm, 2}); + grid1Y->setVolume(vol1.get()); + + Translation3 offsetX{60_mm, 0., 0.}; + auto plane2 = Surface::makeShared( + Transform3::Identity() * offsetX, rBounds); + auto grid2 = GridPortalLink::make(plane2, AxisDirection::AxisX, + Axis{AxisBound, -30_mm, 30_mm, 2}); + grid2->setVolume(vol2.get()); + + Translation3 offsetY{0., 200_mm, 0.}; + auto plane3 = Surface::makeShared( + Transform3::Identity() * offsetY, rBounds); + auto grid3 = GridPortalLink::make(plane3, AxisDirection::AxisY, + Axis{AxisBound, -100_mm, 100_mm, 2}); + grid3->setVolume(vol2.get()); + + auto mergedPtrX = + GridPortalLink::merge(*grid1X, *grid2, AxisDirection::AxisX, *logger); + + auto mergedPtrY = + GridPortalLink::merge(*grid1Y, *grid3, AxisDirection::AxisY, *logger); + + using merged_type = + GridPortalLinkT>; + + const auto* mergedX = dynamic_cast(mergedPtrX.get()); + BOOST_REQUIRE(mergedX); + + grid1X->printContents(std::cout); + grid2->printContents(std::cout); + mergedX->printContents(std::cout); + + BOOST_CHECK_EQUAL(mergedX->grid().atLocalBins({1}), vol1.get()); + BOOST_CHECK_EQUAL(mergedX->grid().atLocalBins({2}), vol1.get()); + BOOST_CHECK_EQUAL(mergedX->grid().atLocalBins({3}), vol2.get()); + BOOST_CHECK_EQUAL(mergedX->grid().atLocalBins({4}), vol2.get()); + + const auto* mergedY = dynamic_cast(mergedPtrX.get()); + BOOST_REQUIRE(mergedY); + + BOOST_CHECK_EQUAL(mergedY->grid().atLocalBins({1}), vol1.get()); + BOOST_CHECK_EQUAL(mergedY->grid().atLocalBins({2}), vol1.get()); + BOOST_CHECK_EQUAL(mergedY->grid().atLocalBins({3}), vol2.get()); + BOOST_CHECK_EQUAL(mergedY->grid().atLocalBins({4}), vol2.get()); + + grid1X->printContents(std::cout); + grid2->printContents(std::cout); + grid3->printContents(std::cout); + mergedX->printContents(std::cout); + mergedY->printContents(std::cout); +} + +BOOST_AUTO_TEST_SUITE_END() // Merging1dPlane + +BOOST_AUTO_TEST_SUITE(Merging2dPlane) + +BOOST_AUTO_TEST_CASE(XYDirection) { + // Basic, because the parallel 1D case already tests this to some degree + auto rBounds = std::make_shared(30_mm, 100_mm); + auto plane1 = + Surface::makeShared(Transform3::Identity(), rBounds); + + auto grid1 = GridPortalLink::make(plane1, Axis{AxisBound, -30_mm, 30_mm, 10}, + Axis{AxisBound, -100_mm, 100_mm, 3}); + + Translation3 offsetX{60_mm, 0., 0.}; + auto plane2 = Surface::makeShared( + Transform3::Identity() * offsetX, rBounds); + auto grid2 = GridPortalLink::make(plane2, Axis{AxisBound, -30_mm, 30_mm, 10}, + Axis{AxisBound, -100_mm, 100_mm, 3}); + + Translation3 offsetY{0., 200_mm, 0.}; + auto plane3 = Surface::makeShared( + Transform3::Identity() * offsetY, rBounds); + auto grid3 = GridPortalLink::make(plane3, Axis{AxisBound, -30_mm, 30_mm, 10}, + Axis{AxisBound, -100_mm, 100_mm, 3}); + + auto mergedPtrX = + GridPortalLink::merge(*grid1, *grid2, AxisDirection::AxisX, *logger); + + auto mergedPtrY = + GridPortalLink::merge(*grid1, *grid3, AxisDirection::AxisY, *logger); + + BOOST_REQUIRE(mergedPtrX); + const auto* mergedX = dynamic_cast(mergedPtrX.get()); + BOOST_REQUIRE_NE(mergedX, nullptr); + BOOST_CHECK_EQUAL(mergedX->grid().axes().size(), 2); + const auto& axisX1 = *mergedX->grid().axes().front(); + const auto& axisX2 = *mergedX->grid().axes().back(); + + BOOST_CHECK_EQUAL(axisX1.getMin(), -60_mm); + BOOST_CHECK_EQUAL(axisX1.getMax(), 60_mm); + BOOST_CHECK_EQUAL(axisX1.getNBins(), 20); + BOOST_CHECK_EQUAL(axisX1.getType(), AxisType::Equidistant); + BOOST_CHECK_EQUAL(axisX1.getBoundaryType(), AxisBoundaryType::Bound); + BOOST_CHECK_EQUAL(axisX2.getMin(), -100_mm); + BOOST_CHECK_EQUAL(axisX2.getMax(), 100_mm); + BOOST_CHECK_EQUAL(axisX2.getNBins(), 3); + BOOST_CHECK_EQUAL(axisX2.getType(), AxisType::Equidistant); + + BOOST_REQUIRE(mergedPtrY); + const auto* mergedY = dynamic_cast(mergedPtrY.get()); + BOOST_REQUIRE_NE(mergedY, nullptr); + BOOST_CHECK_EQUAL(mergedY->grid().axes().size(), 2); + const auto& axisY1 = *mergedY->grid().axes().front(); + const auto& axisY2 = *mergedY->grid().axes().back(); + + BOOST_CHECK_EQUAL(axisY1.getMin(), -30_mm); + BOOST_CHECK_EQUAL(axisY1.getMax(), 30_mm); + BOOST_CHECK_EQUAL(axisY1.getNBins(), 10); + BOOST_CHECK_EQUAL(axisY1.getType(), AxisType::Equidistant); + BOOST_CHECK_EQUAL(axisY1.getBoundaryType(), AxisBoundaryType::Bound); + BOOST_CHECK_EQUAL(axisY2.getMin(), -200_mm); + BOOST_CHECK_EQUAL(axisY2.getMax(), 200_mm); + BOOST_CHECK_EQUAL(axisY2.getNBins(), 6); + BOOST_CHECK_EQUAL(axisY2.getType(), AxisType::Equidistant); +} + +BOOST_AUTO_TEST_CASE(BinFilling) { + // Volumes for bin content checking + // Volume shape/transform is irrelevant, only used for pointer identity + auto vol1 = std::make_shared( + Transform3::Identity(), + std::make_shared(30_mm, 40_mm, 100_mm)); + + auto vol2 = std::make_shared( + Transform3::Identity(), + std::make_shared(30_mm, 40_mm, 100_mm)); + + auto fillCheckerBoard = [&](auto& grid) { + auto loc = grid.numLocalBins(); + for (std::size_t i = 1; i <= loc[0]; ++i) { + for (std::size_t j = 1; j <= loc[1]; ++j) { + grid.atLocalBins({i, j}) = (i + j) % 2 == 0 ? vol1.get() : vol2.get(); + } + } + }; + + auto checkCheckerBoard = [&](const auto& grid) { + auto loc = grid.numLocalBins(); + for (std::size_t i = 1; i <= loc[0]; ++i) { + for (std::size_t j = 1; j <= loc[1]; ++j) { + const auto* vol = grid.atLocalBins({i, j}); + if (vol != ((i + j) % 2 == 0 ? vol1.get() : vol2.get())) { + BOOST_ERROR("Is not a checkerboard pattern"); + return; + } + } + } + }; + + // Basic, because the parallel 1D case already tests this to some degree + auto rBounds = std::make_shared(30_mm, 100_mm); + auto plane1 = + Surface::makeShared(Transform3::Identity(), rBounds); + + auto grid1 = GridPortalLink::make(plane1, Axis{AxisBound, -30_mm, 30_mm, 2}, + Axis{AxisBound, -100_mm, 100_mm, 2}); + + Translation3 offsetX{60_mm, 0., 0.}; + auto plane2 = Surface::makeShared( + Transform3::Identity() * offsetX, rBounds); + auto grid2 = GridPortalLink::make(plane2, Axis{AxisBound, -30_mm, 30_mm, 2}, + Axis{AxisBound, -100_mm, 100_mm, 2}); + + Translation3 offsetY{0., 200_mm, 0.}; + auto plane3 = Surface::makeShared( + Transform3::Identity() * offsetY, rBounds); + auto grid3 = GridPortalLink::make(plane3, Axis{AxisBound, -30_mm, 30_mm, 2}, + Axis{AxisBound, -100_mm, 100_mm, 2}); + + fillCheckerBoard(grid1->grid()); + checkCheckerBoard(grid1->grid()); + + fillCheckerBoard(grid2->grid()); + checkCheckerBoard(grid2->grid()); + + fillCheckerBoard(grid3->grid()); + checkCheckerBoard(grid3->grid()); + + auto mergedPtrX = + GridPortalLink::merge(*grid1, *grid2, AxisDirection::AxisX, *logger); + auto mergedPtrY = + GridPortalLink::merge(*grid1, *grid3, AxisDirection::AxisY, *logger); + + using merged_type = + GridPortalLinkT, + Axis>; + + const auto* mergedX = dynamic_cast(mergedPtrX.get()); + BOOST_REQUIRE(mergedX); + checkCheckerBoard(mergedX->grid()); + + const auto* mergedY = dynamic_cast(mergedPtrY.get()); + BOOST_REQUIRE(mergedY); + checkCheckerBoard(mergedY->grid()); + + // Fill a / b + grid1->setVolume(vol1.get()); + grid2->setVolume(vol2.get()); + grid3->setVolume(vol2.get()); + + mergedPtrX = + GridPortalLink::merge(*grid1, *grid2, AxisDirection::AxisX, *logger); + mergedPtrY = + GridPortalLink::merge(*grid1, *grid3, AxisDirection::AxisY, *logger); + + mergedX = dynamic_cast(mergedPtrX.get()); + BOOST_REQUIRE(mergedX); + + mergedY = dynamic_cast(mergedPtrY.get()); + BOOST_REQUIRE(mergedY); + + const auto* v1 = vol1.get(); + const auto* v2 = vol2.get(); + + std::vector> locationsX = { + {{-45_mm, 0_mm}, v1}, + {{-15_mm, 0_mm}, v1}, + {{15_mm, 0_mm}, v2}, + {{45_mm, 0_mm}, v2}, + }; + std::vector> locationsY = { + {{0_mm, -150_mm}, v1}, + {{0_mm, -50_mm}, v1}, + {{0_mm, 50_mm}, v2}, + {{0_mm, 150_mm}, v2}, + }; + + for (const auto& [loc, vol] : locationsX) { + BOOST_TEST_CONTEXT(loc.transpose()) + BOOST_CHECK_EQUAL(mergedX->resolveVolume(gctx, loc).value(), vol); + } + for (const auto& [loc, vol] : locationsY) { + BOOST_TEST_CONTEXT(loc.transpose()) + BOOST_CHECK_EQUAL(mergedY->resolveVolume(gctx, loc).value(), vol); + } + + std::vector> contentsX = { + {v1, v1}, + {v1, v1}, + {v2, v2}, + {v2, v2}, + }; + std::vector> contentsY = { + {v1, v1, v2, v2}, + {v1, v1, v2, v2}, + }; + + for (std::size_t i = 0; i < 4; ++i) { + for (std::size_t j = 0; j < 2; ++j) { + BOOST_CHECK_EQUAL(mergedX->grid().atLocalBins({i + 1, j + 1}), + contentsX.at(i).at(j)); + } + } + for (std::size_t i = 0; i < 2; ++i) { + for (std::size_t j = 0; j < 4; ++j) { + BOOST_CHECK_EQUAL(mergedY->grid().atLocalBins({i + 1, j + 1}), + contentsY.at(i).at(j)); + } + } +} + +BOOST_AUTO_TEST_SUITE_END() // Merging2dPlane + BOOST_AUTO_TEST_SUITE_END() // GridMerging BOOST_AUTO_TEST_CASE(CompositeConstruction) { @@ -2072,10 +2617,10 @@ BOOST_AUTO_TEST_CASE(CompositeConstruction) { auto trivial2 = std::make_unique(disc2, *vol2); auto composite = std::make_unique( - copy(trivial1), copy(trivial2), BinningValue::binR); + copy(trivial1), copy(trivial2), AxisDirection::AxisR); auto compositeCopy = std::make_unique( - copy(trivial1), copy(trivial2), BinningValue::binR); + copy(trivial1), copy(trivial2), AxisDirection::AxisR); BOOST_CHECK_EQUAL( composite->resolveVolume(gctx, Vector2{40_mm, 0_degree}).value(), @@ -2090,9 +2635,9 @@ BOOST_AUTO_TEST_CASE(CompositeConstruction) { auto cyl = Surface::makeShared(Transform3::Identity(), 30_mm, 40_mm); auto trivialCyl = std::make_unique(cyl, *vol3); - BOOST_CHECK_THROW( - CompositePortalLink(copy(trivial1), copy(trivialCyl), BinningValue::binR), - std::invalid_argument); + BOOST_CHECK_THROW(CompositePortalLink(copy(trivial1), copy(trivialCyl), + AxisDirection::AxisR), + std::invalid_argument); auto disc3 = Surface::makeShared(Transform3::Identity(), 90_mm, 120_mm); @@ -2100,13 +2645,13 @@ BOOST_AUTO_TEST_CASE(CompositeConstruction) { // Test exception on un-mergable surfaces BOOST_CHECK_THROW( - CompositePortalLink(copy(trivial1), copy(trivial3), BinningValue::binR), + CompositePortalLink(copy(trivial1), copy(trivial3), AxisDirection::AxisR), SurfaceMergingException); // Composite with a composite (this should work regardless of flattening) CompositePortalLink composite2(std::move(composite), copy(trivial3), - BinningValue::binR, false); + AxisDirection::AxisR, false); BOOST_CHECK_EQUAL( composite2.resolveVolume(gctx, Vector2{40_mm, 0_degree}).value(), @@ -2122,7 +2667,7 @@ BOOST_AUTO_TEST_CASE(CompositeConstruction) { BOOST_CHECK_EQUAL(composite2.depth(), 2); CompositePortalLink composite2Flat(std::move(compositeCopy), copy(trivial3), - BinningValue::binR, true); + AxisDirection::AxisR, true); // One because of flattening BOOST_CHECK_EQUAL(composite2Flat.depth(), 1); @@ -2177,17 +2722,18 @@ BOOST_DATA_TEST_CASE(TrivialTrivial, auto trivial3 = std::make_unique(disc3, *vol3); BOOST_REQUIRE(trivial3); - auto grid1 = trivial1->makeGrid(BinningValue::binR); + auto grid1 = trivial1->makeGrid(AxisDirection::AxisR); auto compGridTrivial = PortalLinkBase::merge( std::move(grid1), std::make_unique(*trivial2), - BinningValue::binR, *logger); + AxisDirection::AxisR, *logger); BOOST_REQUIRE(compGridTrivial); BOOST_CHECK_EQUAL(dynamic_cast(*compGridTrivial) .makeGrid(gctx, *logger), nullptr); - auto composite = PortalLinkBase::merge( - std::move(trivial1), std::move(trivial2), BinningValue::binR, *logger); + auto composite = + PortalLinkBase::merge(std::move(trivial1), std::move(trivial2), + AxisDirection::AxisR, *logger); BOOST_REQUIRE(composite); auto grid12 = @@ -2203,7 +2749,7 @@ BOOST_DATA_TEST_CASE(TrivialTrivial, vol2.get()); composite = PortalLinkBase::merge(std::move(composite), std::move(trivial3), - BinningValue::binR, *logger); + AxisDirection::AxisR, *logger); BOOST_REQUIRE(composite); auto grid123 = @@ -2250,17 +2796,18 @@ BOOST_DATA_TEST_CASE(TrivialTrivial, auto trivial3 = std::make_unique(cyl3, *vol3); BOOST_REQUIRE(trivial3); - auto grid1 = trivial1->makeGrid(BinningValue::binZ); + auto grid1 = trivial1->makeGrid(AxisDirection::AxisZ); auto compGridTrivial = PortalLinkBase::merge( std::move(grid1), std::make_unique(*trivial2), - BinningValue::binZ, *logger); + AxisDirection::AxisZ, *logger); BOOST_REQUIRE(compGridTrivial); BOOST_CHECK_EQUAL(dynamic_cast(*compGridTrivial) .makeGrid(gctx, *logger), nullptr); - auto composite = PortalLinkBase::merge( - std::move(trivial1), std::move(trivial2), BinningValue::binZ, *logger); + auto composite = + PortalLinkBase::merge(std::move(trivial1), std::move(trivial2), + AxisDirection::AxisZ, *logger); BOOST_REQUIRE(composite); auto grid12 = @@ -2275,7 +2822,7 @@ BOOST_DATA_TEST_CASE(TrivialTrivial, grid12->resolveVolume(gctx, Vector2{40_mm, 40_mm}).value(), vol2.get()); composite = PortalLinkBase::merge(std::move(composite), std::move(trivial3), - BinningValue::binZ, *logger); + AxisDirection::AxisZ, *logger); BOOST_REQUIRE(composite); auto grid123 = @@ -2294,6 +2841,152 @@ BOOST_DATA_TEST_CASE(TrivialTrivial, grid123->resolveVolume(gctx, Vector2{40_mm, 190_mm}).value(), vol3.get()); } + BOOST_TEST_CONTEXT("PlaneXDirection") { + auto vol1 = std::make_shared( + Transform3::Identity(), + std::make_shared(30_mm, 40_mm, 100_mm)); + + auto vol2 = std::make_shared( + Transform3::Identity() * Translation3{Vector3::UnitX() * 60}, + std::make_shared(30_mm, 40_mm, 100_mm)); + + auto vol3 = std::make_shared( + Transform3::Identity() * Translation3{Vector3::UnitX() * 120}, + std::make_shared(30_mm, 40_mm, 100_mm)); + + auto rBounds = std::make_shared(30_mm, 40_mm); + auto plane1 = + Surface::makeShared(Transform3::Identity(), rBounds); + + auto plane2 = Surface::makeShared( + Transform3::Identity() * Translation3{Vector3::UnitX() * 60}, rBounds); + + auto plane3 = Surface::makeShared( + Transform3::Identity() * Translation3{Vector3::UnitX() * 120}, rBounds); + + auto trivial1 = std::make_unique(plane1, *vol1); + BOOST_REQUIRE(trivial1); + auto trivial2 = std::make_unique(plane2, *vol2); + BOOST_REQUIRE(trivial2); + auto trivial3 = std::make_unique(plane3, *vol3); + BOOST_REQUIRE(trivial3); + + auto grid1 = trivial1->makeGrid(AxisDirection::AxisX); + auto compGridTrivial = PortalLinkBase::merge( + std::move(grid1), std::make_unique(*trivial2), + AxisDirection::AxisX, *logger); + BOOST_REQUIRE(compGridTrivial); + BOOST_CHECK_EQUAL(dynamic_cast(*compGridTrivial) + .makeGrid(gctx, *logger), + nullptr); + + auto composite = + PortalLinkBase::merge(std::move(trivial1), std::move(trivial2), + AxisDirection::AxisX, *logger); + BOOST_REQUIRE(composite); + + auto grid12 = + dynamic_cast(*composite).makeGrid(gctx, *logger); + BOOST_REQUIRE(grid12); + + BOOST_CHECK_EQUAL(grid12->resolveVolume(gctx, Vector2{-30_mm, 0}).value(), + vol1.get()); + + BOOST_CHECK_EQUAL(grid12->resolveVolume(gctx, Vector2{30_mm, 0}).value(), + vol2.get()); + + composite = PortalLinkBase::merge(std::move(composite), std::move(trivial3), + AxisDirection::AxisX, *logger); + BOOST_REQUIRE(composite); + + auto grid123 = + dynamic_cast(*composite).makeGrid(gctx, *logger); + BOOST_REQUIRE(grid123); + + BOOST_CHECK_EQUAL( + grid123->resolveVolume(gctx, Vector2{-80_mm, 0_mm}).value(), + vol1.get()); + + BOOST_CHECK_EQUAL(grid123->resolveVolume(gctx, Vector2{0_mm, 0_mm}).value(), + vol2.get()); + + BOOST_CHECK_EQUAL( + grid123->resolveVolume(gctx, Vector2{80_mm, 0_mm}).value(), vol3.get()); + } + BOOST_TEST_CONTEXT("PlaneYDirection") { + auto vol1 = std::make_shared( + Transform3::Identity(), + std::make_shared(30_mm, 40_mm, 100_mm)); + + auto vol2 = std::make_shared( + Transform3::Identity() * Translation3{Vector3::UnitY() * 80}, + std::make_shared(30_mm, 40_mm, 100_mm)); + + auto vol3 = std::make_shared( + Transform3::Identity() * Translation3{Vector3::UnitY() * 160}, + std::make_shared(30_mm, 40_mm, 100_mm)); + + auto rBounds = std::make_shared(30_mm, 40_mm); + auto plane1 = + Surface::makeShared(Transform3::Identity(), rBounds); + + auto plane2 = Surface::makeShared( + Transform3::Identity() * Translation3{Vector3::UnitY() * 80}, rBounds); + + auto plane3 = Surface::makeShared( + Transform3::Identity() * Translation3{Vector3::UnitY() * 160}, rBounds); + + auto trivial1 = std::make_unique(plane1, *vol1); + BOOST_REQUIRE(trivial1); + auto trivial2 = std::make_unique(plane2, *vol2); + BOOST_REQUIRE(trivial2); + auto trivial3 = std::make_unique(plane3, *vol3); + BOOST_REQUIRE(trivial3); + + auto grid1 = trivial1->makeGrid(AxisDirection::AxisY); + auto compGridTrivial = PortalLinkBase::merge( + std::move(grid1), std::make_unique(*trivial2), + AxisDirection::AxisY, *logger); + BOOST_REQUIRE(compGridTrivial); + BOOST_CHECK_EQUAL(dynamic_cast(*compGridTrivial) + .makeGrid(gctx, *logger), + nullptr); + + auto composite = + PortalLinkBase::merge(std::move(trivial1), std::move(trivial2), + AxisDirection::AxisY, *logger); + BOOST_REQUIRE(composite); + + auto grid12 = + dynamic_cast(*composite).makeGrid(gctx, *logger); + BOOST_REQUIRE(grid12); + + BOOST_CHECK_EQUAL( + grid12->resolveVolume(gctx, Vector2{0_mm, -40_mm}).value(), vol1.get()); + + BOOST_CHECK_EQUAL(grid12->resolveVolume(gctx, Vector2{0_mm, 40_mm}).value(), + vol2.get()); + + composite = PortalLinkBase::merge(std::move(composite), std::move(trivial3), + AxisDirection::AxisY, *logger); + BOOST_REQUIRE(composite); + + auto grid123 = + dynamic_cast(*composite).makeGrid(gctx, *logger); + BOOST_REQUIRE(grid123); + + BOOST_CHECK_EQUAL( + grid123->resolveVolume(gctx, Vector2{0_mm, -110_mm}).value(), + vol1.get()); + + BOOST_CHECK_EQUAL( + grid123->resolveVolume(gctx, Vector2{0_mm, -10_mm}).value(), + vol2.get()); + + BOOST_CHECK_EQUAL( + grid123->resolveVolume(gctx, Vector2{0_mm, 110_mm}).value(), + vol3.get()); + } } BOOST_AUTO_TEST_CASE(TrivialGridR) { @@ -2315,24 +3008,24 @@ BOOST_AUTO_TEST_CASE(TrivialGridR) { BOOST_REQUIRE(trivial); auto gridPhi = GridPortalLink::make( - disc1, BinningValue::binPhi, + disc1, AxisDirection::AxisPhi, Axis{AxisClosed, -std::numbers::pi, std::numbers::pi, 2}); gridPhi->setVolume(vol1.get()); - auto gridR = GridPortalLink::make(disc1, BinningValue::binR, + auto gridR = GridPortalLink::make(disc1, AxisDirection::AxisR, Axis{AxisBound, 30_mm, 60_mm, 2}); gridR->setVolume(vol1.get()); BOOST_TEST_CONTEXT("Colinear") { auto merged = PortalLinkBase::merge(copy(trivial), copy(gridR), - BinningValue::binR, *logger); + AxisDirection::AxisR, *logger); BOOST_REQUIRE(merged); BOOST_CHECK_NE(dynamic_cast(merged.get()), nullptr); } BOOST_TEST_CONTEXT("Orthogonal") { auto merged = PortalLinkBase::merge(copy(gridPhi), copy(trivial), - BinningValue::binR, *logger); + AxisDirection::AxisR, *logger); BOOST_REQUIRE(merged); BOOST_CHECK_NE(dynamic_cast(merged.get()), nullptr); } @@ -2358,23 +3051,65 @@ BOOST_AUTO_TEST_CASE(TrivialGridPhi) { BOOST_REQUIRE(trivial); auto gridPhi = GridPortalLink::make( - disc1, BinningValue::binPhi, Axis{AxisBound, -30_degree, 30_degree, 2}); + disc1, AxisDirection::AxisPhi, Axis{AxisBound, -30_degree, 30_degree, 2}); gridPhi->setVolume(vol1.get()); - auto gridR = GridPortalLink::make(disc1, BinningValue::binR, + auto gridR = GridPortalLink::make(disc1, AxisDirection::AxisR, Axis{AxisBound, 30_mm, 100_mm, 2}); gridR->setVolume(vol1.get()); BOOST_TEST_CONTEXT("Colinear") { auto merged = PortalLinkBase::merge(copy(trivial), copy(gridPhi), - BinningValue::binPhi, *logger); + AxisDirection::AxisPhi, *logger); BOOST_REQUIRE(merged); BOOST_CHECK_NE(dynamic_cast(merged.get()), nullptr); } BOOST_TEST_CONTEXT("Orthogonal") { auto merged = PortalLinkBase::merge(copy(gridR), copy(trivial), - BinningValue::binPhi, *logger); + AxisDirection::AxisPhi, *logger); + BOOST_REQUIRE(merged); + BOOST_CHECK_NE(dynamic_cast(merged.get()), nullptr); + } +} + +BOOST_AUTO_TEST_CASE(TrivialGridXY) { + auto vol1 = std::make_shared( + Transform3::Identity(), + std::make_shared(30_mm, 30_mm, 30_mm)); + + auto vol2 = std::make_shared( + Transform3::Identity() * Translation3{Vector3::UnitX() * 60}, + std::make_shared(30_mm, 30_mm, 30_mm)); + + auto rBounds = std::make_shared(30_mm, 30_mm); + auto plane1 = + Surface::makeShared(Transform3::Identity(), rBounds); + + auto plane2 = Surface::makeShared( + Transform3::Identity() * Translation3{Vector3::UnitX() * 60}, rBounds); + + auto gridX = GridPortalLink::make(plane1, AxisDirection::AxisX, + Axis{AxisBound, -30_mm, 30_mm, 2}); + gridX->setVolume(vol1.get()); + + auto gridY = GridPortalLink::make(plane1, AxisDirection::AxisY, + Axis{AxisBound, -30_mm, 30_mm, 2}); + gridY->setVolume(vol1.get()); + + auto trivial = std::make_unique(plane2, *vol2); + BOOST_REQUIRE(trivial); + + BOOST_TEST_CONTEXT("Colinear") { + auto merged = PortalLinkBase::merge(copy(trivial), copy(gridX), + AxisDirection::AxisX, *logger); + BOOST_REQUIRE(merged); + BOOST_CHECK_NE(dynamic_cast(merged.get()), nullptr); + } + + BOOST_TEST_CONTEXT("Orthogonal") { + auto merged = PortalLinkBase::merge(copy(gridY), copy(trivial), + AxisDirection::AxisX, *logger); BOOST_REQUIRE(merged); BOOST_CHECK_NE(dynamic_cast(merged.get()), nullptr); } @@ -2400,19 +3135,20 @@ BOOST_AUTO_TEST_CASE(CompositeOther) { auto disc3 = Surface::makeShared(Transform3::Identity(), 90_mm, 120_mm); - auto grid1 = GridPortalLink::make(disc1, *vol1, BinningValue::binR); + auto grid1 = GridPortalLink::make(disc1, *vol1, AxisDirection::AxisR); auto trivial2 = std::make_unique(disc2, *vol2); auto composite12 = std::make_unique( - std::move(grid1), std::move(trivial2), BinningValue::binR); + std::move(grid1), std::move(trivial2), AxisDirection::AxisR); BOOST_CHECK_EQUAL(composite12->depth(), 1); BOOST_CHECK_EQUAL(composite12->size(), 2); auto trivial3 = std::make_unique(disc3, *vol3); - auto composite123Ptr = PortalLinkBase::merge( - std::move(composite12), std::move(trivial3), BinningValue::binR, *logger); + auto composite123Ptr = + PortalLinkBase::merge(std::move(composite12), std::move(trivial3), + AxisDirection::AxisR, *logger); const auto* composite123 = dynamic_cast(composite123Ptr.get()); diff --git a/Tests/UnitTests/Core/Geometry/PortalShellTests.cpp b/Tests/UnitTests/Core/Geometry/PortalShellTests.cpp index 090dc851611..b4e9eaa6dfe 100644 --- a/Tests/UnitTests/Core/Geometry/PortalShellTests.cpp +++ b/Tests/UnitTests/Core/Geometry/PortalShellTests.cpp @@ -314,13 +314,13 @@ BOOST_AUTO_TEST_CASE(PortalAssignment) { // Setting new outer cylinder BOOST_REQUIRE_NE(oCyl, nullptr); auto* oCylLink = dynamic_cast( - oCyl->getLink(Direction::OppositeNormal)); + oCyl->getLink(Direction::OppositeNormal())); BOOST_REQUIRE_NE(oCylLink, nullptr); - auto grid = oCylLink->makeGrid(BinningValue::binZ); + auto grid = oCylLink->makeGrid(AxisDirection::AxisZ); auto portal2 = - std::make_shared(Direction::OppositeNormal, std::move(grid)); + std::make_shared(Direction::OppositeNormal(), std::move(grid)); shell.setPortal(portal2, OuterCylinder); BOOST_CHECK_EQUAL(shell.portal(OuterCylinder), portal2.get()); @@ -332,13 +332,13 @@ BOOST_AUTO_TEST_CASE(PortalAssignment) { // Setting new negative disc BOOST_REQUIRE_NE(nDisc, nullptr); auto* nDiscLink = dynamic_cast( - nDisc->getLink(Direction::AlongNormal)); + nDisc->getLink(Direction::AlongNormal())); BOOST_REQUIRE_NE(nDiscLink, nullptr); - grid = nDiscLink->makeGrid(BinningValue::binR); + grid = nDiscLink->makeGrid(AxisDirection::AxisR); auto portal3 = - std::make_shared(Direction::AlongNormal, std::move(grid)); + std::make_shared(Direction::AlongNormal(), std::move(grid)); shell.setPortal(portal3, NegativeDisc); BOOST_CHECK_EQUAL(shell.portal(NegativeDisc), portal3.get()); @@ -366,7 +366,7 @@ BOOST_AUTO_TEST_CASE(ZDirection) { BOOST_CHECK_NE(shell1.portal(PositiveDisc), shell2.portal(NegativeDisc)); CylinderStackPortalShell stack{ - gctx, {&shell1, &shell2}, BinningValue::binZ}; + gctx, {&shell1, &shell2}, AxisDirection::AxisZ}; BOOST_CHECK_EQUAL(stack.size(), 4); const auto* iCyl = stack.portal(InnerCylinder); @@ -392,9 +392,9 @@ BOOST_AUTO_TEST_CASE(ZDirection) { shell1 = SingleCylinderPortalShell{vol1}; shell2 = SingleCylinderPortalShell{vol2}; - BOOST_CHECK_THROW( - CylinderStackPortalShell(gctx, {&shell1, &shell2}, BinningValue::binR), - SurfaceMergingException); + BOOST_CHECK_THROW(CylinderStackPortalShell(gctx, {&shell1, &shell2}, + AxisDirection::AxisR), + SurfaceMergingException); } BOOST_TEST_CONTEXT("rMin==0") { @@ -415,7 +415,7 @@ BOOST_AUTO_TEST_CASE(ZDirection) { BOOST_CHECK_NE(shell1.portal(PositiveDisc), shell2.portal(NegativeDisc)); CylinderStackPortalShell stack{ - gctx, {&shell1, &shell2}, BinningValue::binZ}; + gctx, {&shell1, &shell2}, AxisDirection::AxisZ}; BOOST_CHECK_EQUAL(stack.size(), 3); // Disc portals have been fused @@ -440,9 +440,9 @@ BOOST_AUTO_TEST_CASE(ZDirection) { shell1 = SingleCylinderPortalShell{vol1}; shell2 = SingleCylinderPortalShell{vol2}; - BOOST_CHECK_THROW( - CylinderStackPortalShell(gctx, {&shell1, &shell2}, BinningValue::binR), - SurfaceMergingException); + BOOST_CHECK_THROW(CylinderStackPortalShell(gctx, {&shell1, &shell2}, + AxisDirection::AxisR), + SurfaceMergingException); } } @@ -463,7 +463,7 @@ BOOST_AUTO_TEST_CASE(RDirection) { BOOST_CHECK_NE(shell1.portal(OuterCylinder), shell2.portal(InnerCylinder)); CylinderStackPortalShell stack{ - gctx, {&shell1, &shell2}, BinningValue::binR}; + gctx, {&shell1, &shell2}, AxisDirection::AxisR}; BOOST_CHECK_EQUAL(stack.size(), 4); // Internal cylinder portals have been fused @@ -492,9 +492,9 @@ BOOST_AUTO_TEST_CASE(RDirection) { shell1 = SingleCylinderPortalShell{vol1}; shell2 = SingleCylinderPortalShell{vol2}; - BOOST_CHECK_THROW( - CylinderStackPortalShell(gctx, {&shell1, &shell2}, BinningValue::binZ), - SurfaceMergingException); + BOOST_CHECK_THROW(CylinderStackPortalShell(gctx, {&shell1, &shell2}, + AxisDirection::AxisZ), + SurfaceMergingException); } BOOST_TEST_CONTEXT("rMin==0") { @@ -513,7 +513,7 @@ BOOST_AUTO_TEST_CASE(RDirection) { BOOST_CHECK_NE(shell1.portal(OuterCylinder), shell2.portal(InnerCylinder)); CylinderStackPortalShell stack{ - gctx, {&shell1, &shell2}, BinningValue::binR}; + gctx, {&shell1, &shell2}, AxisDirection::AxisR}; BOOST_CHECK_EQUAL(stack.size(), 4); // Internal cylinder portals have been fused @@ -541,9 +541,9 @@ BOOST_AUTO_TEST_CASE(RDirection) { shell1 = SingleCylinderPortalShell{vol1}; shell2 = SingleCylinderPortalShell{vol2}; - BOOST_CHECK_THROW( - CylinderStackPortalShell(gctx, {&shell1, &shell2}, BinningValue::binZ), - std::invalid_argument); + BOOST_CHECK_THROW(CylinderStackPortalShell(gctx, {&shell1, &shell2}, + AxisDirection::AxisZ), + std::invalid_argument); } } @@ -599,7 +599,7 @@ BOOST_AUTO_TEST_CASE(NestedStacks) { BOOST_CHECK(shell2.isValid()); CylinderStackPortalShell stack{ - gctx, {&shell1, &gapShell, &shell2}, BinningValue::binR}; + gctx, {&shell1, &gapShell, &shell2}, AxisDirection::AxisR}; BOOST_CHECK(stack.isValid()); @@ -607,7 +607,7 @@ BOOST_AUTO_TEST_CASE(NestedStacks) { BOOST_CHECK(shell3.isValid()); CylinderStackPortalShell stack2{ - gctx, {&stack, &shell3}, BinningValue::binZ, *logger}; + gctx, {&stack, &shell3}, AxisDirection::AxisZ, *logger}; BOOST_CHECK(stack2.isValid()); using enum CylinderVolumeBounds::Face; @@ -728,24 +728,28 @@ BOOST_AUTO_TEST_CASE(Fill) { using enum CylinderVolumeBounds::Face; BOOST_CHECK_EQUAL( - shell.portal(OuterCylinder)->getLink(Direction::AlongNormal), nullptr); + shell.portal(OuterCylinder)->getLink(Direction::AlongNormal()), nullptr); BOOST_CHECK_EQUAL( - shell.portal(InnerCylinder)->getLink(Direction::OppositeNormal), nullptr); - BOOST_CHECK_EQUAL(shell.portal(PositiveDisc)->getLink(Direction::AlongNormal), - nullptr); + shell.portal(InnerCylinder)->getLink(Direction::OppositeNormal()), + nullptr); BOOST_CHECK_EQUAL( - shell.portal(NegativeDisc)->getLink(Direction::OppositeNormal), nullptr); + shell.portal(PositiveDisc)->getLink(Direction::AlongNormal()), nullptr); + BOOST_CHECK_EQUAL( + shell.portal(NegativeDisc)->getLink(Direction::OppositeNormal()), + nullptr); shell.fill(cyl2); - BOOST_CHECK_NE(shell.portal(OuterCylinder)->getLink(Direction::AlongNormal), + BOOST_CHECK_NE(shell.portal(OuterCylinder)->getLink(Direction::AlongNormal()), nullptr); BOOST_CHECK_NE( - shell.portal(InnerCylinder)->getLink(Direction::OppositeNormal), nullptr); - BOOST_CHECK_NE(shell.portal(PositiveDisc)->getLink(Direction::AlongNormal), - nullptr); - BOOST_CHECK_NE(shell.portal(NegativeDisc)->getLink(Direction::OppositeNormal), + shell.portal(InnerCylinder)->getLink(Direction::OppositeNormal()), + nullptr); + BOOST_CHECK_NE(shell.portal(PositiveDisc)->getLink(Direction::AlongNormal()), nullptr); + BOOST_CHECK_NE( + shell.portal(NegativeDisc)->getLink(Direction::OppositeNormal()), + nullptr); } BOOST_AUTO_TEST_CASE(RegisterInto) { diff --git a/Tests/UnitTests/Core/Geometry/PortalTests.cpp b/Tests/UnitTests/Core/Geometry/PortalTests.cpp index 8997ccedda7..3586bf0a115 100644 --- a/Tests/UnitTests/Core/Geometry/PortalTests.cpp +++ b/Tests/UnitTests/Core/Geometry/PortalTests.cpp @@ -71,7 +71,7 @@ BOOST_AUTO_TEST_CASE(Cylinder) { auto cyl2 = Surface::makeShared( Transform3{Translation3{Vector3::UnitZ() * 100_mm}}, 50_mm, 100_mm); - Portal portal1{Direction::AlongNormal, + Portal portal1{Direction::AlongNormal(), std::make_unique(cyl1, *vol1)}; BOOST_CHECK(portal1.isValid()); @@ -87,7 +87,7 @@ BOOST_AUTO_TEST_CASE(Cylinder) { .value(), nullptr); - Portal portal2{Direction::AlongNormal, cyl2, *vol2}; + Portal portal2{Direction::AlongNormal(), cyl2, *vol2}; BOOST_CHECK(portal2.isValid()); BOOST_CHECK_EQUAL( @@ -106,15 +106,15 @@ BOOST_AUTO_TEST_CASE(Cylinder) { nullptr}; BOOST_CHECK(portal3.isValid()); - BOOST_CHECK_NE(portal3.getLink(Direction::AlongNormal), nullptr); - BOOST_CHECK_EQUAL(portal3.getLink(Direction::OppositeNormal), nullptr); + BOOST_CHECK_NE(portal3.getLink(Direction::AlongNormal()), nullptr); + BOOST_CHECK_EQUAL(portal3.getLink(Direction::OppositeNormal()), nullptr); Portal portal4{gctx, nullptr, std::make_unique(cyl2, *vol2)}; BOOST_CHECK(portal4.isValid()); - BOOST_CHECK_EQUAL(portal4.getLink(Direction::AlongNormal), nullptr); - BOOST_CHECK_NE(portal4.getLink(Direction::OppositeNormal), nullptr); + BOOST_CHECK_EQUAL(portal4.getLink(Direction::AlongNormal()), nullptr); + BOOST_CHECK_NE(portal4.getLink(Direction::OppositeNormal()), nullptr); // Not mergeable because 1 has portal along but 4 has portal oppsite // ^ @@ -127,7 +127,7 @@ BOOST_AUTO_TEST_CASE(Cylinder) { // | // v BOOST_CHECK_THROW( - Portal::merge(gctx, portal1, portal4, BinningValue::binZ, *logger), + Portal::merge(gctx, portal1, portal4, AxisDirection::AxisZ, *logger), PortalMergingException); // This call leaves both valid because the exception is thrown before the @@ -146,9 +146,9 @@ BOOST_AUTO_TEST_CASE(Cylinder) { .value(), nullptr); - // Cannot merge in binRPhi + // Cannot merge in AxisRPhi BOOST_CHECK_THROW( - Portal::merge(gctx, portal1, portal2, BinningValue::binRPhi, *logger), + Portal::merge(gctx, portal1, portal2, AxisDirection::AxisRPhi, *logger), SurfaceMergingException); // The call above leaves both portals invalid because the exception is thrown @@ -168,12 +168,12 @@ BOOST_AUTO_TEST_CASE(Cylinder) { portal2 = Portal{gctx, {.alongNormal = {cyl2, *vol2}}}; Portal merged12 = - Portal::merge(gctx, portal1, portal2, BinningValue::binZ, *logger); - BOOST_CHECK_NE(merged12.getLink(Direction::AlongNormal), nullptr); - BOOST_CHECK_EQUAL(merged12.getLink(Direction::OppositeNormal), nullptr); + Portal::merge(gctx, portal1, portal2, AxisDirection::AxisZ, *logger); + BOOST_CHECK_NE(merged12.getLink(Direction::AlongNormal()), nullptr); + BOOST_CHECK_EQUAL(merged12.getLink(Direction::OppositeNormal()), nullptr); auto composite12 = dynamic_cast( - merged12.getLink(Direction::AlongNormal)); + merged12.getLink(Direction::AlongNormal())); BOOST_REQUIRE_NE(composite12, nullptr); BOOST_CHECK_EQUAL( @@ -204,14 +204,14 @@ BOOST_AUTO_TEST_CASE(Cylinder) { // Can't merge with self BOOST_CHECK_THROW( - Portal::merge(gctx, portal1, portal1, BinningValue::binZ, *logger), + Portal::merge(gctx, portal1, portal1, AxisDirection::AxisZ, *logger), PortalMergingException); // Can't merge because the surfaces are the same portal1 = Portal{gctx, {.alongNormal = {cyl1, *vol1}}}; portal2 = Portal{gctx, {.alongNormal = {cyl1, *vol2}}}; BOOST_CHECK_THROW( - Portal::merge(gctx, portal1, portal2, BinningValue::binZ, *logger), + Portal::merge(gctx, portal1, portal2, AxisDirection::AxisZ, *logger), AssertionFailureException); // Can't merge because surface has material @@ -221,7 +221,7 @@ BOOST_AUTO_TEST_CASE(Cylinder) { portal1 = Portal{gctx, {.alongNormal = {cyl1, *vol1}}}; portal2 = Portal{gctx, {.alongNormal = {cyl2, *vol2}}}; BOOST_CHECK_THROW( - Portal::merge(gctx, portal1, portal2, BinningValue::binZ, *logger), + Portal::merge(gctx, portal1, portal2, AxisDirection::AxisZ, *logger), PortalMergingException); } @@ -270,14 +270,14 @@ BOOST_AUTO_TEST_CASE(Disc) { vol4.get()); BOOST_CHECK_THROW( - Portal::merge(gctx, portal1, portal2, BinningValue::binZ, *logger), + Portal::merge(gctx, portal1, portal2, AxisDirection::AxisZ, *logger), AssertionFailureException); BOOST_CHECK(portal1.isValid()); BOOST_CHECK(portal2.isValid()); BOOST_CHECK_THROW( - Portal::merge(gctx, portal1, portal2, BinningValue::binPhi, *logger), + Portal::merge(gctx, portal1, portal2, AxisDirection::AxisPhi, *logger), SurfaceMergingException); // Portals not valid anymore because they were moved before the exception was @@ -302,7 +302,7 @@ BOOST_AUTO_TEST_CASE(Disc) { // | | // v v Portal merged12 = - Portal::merge(gctx, portal1, portal2, BinningValue::binR, *logger); + Portal::merge(gctx, portal1, portal2, AxisDirection::AxisR, *logger); BOOST_CHECK_EQUAL( merged12.resolveVolume(gctx, Vector3{55_mm, 0_mm, 0_mm}, Vector3::UnitZ()) @@ -334,7 +334,7 @@ BOOST_AUTO_TEST_CASE(Disc) { portal2 = Portal{ gctx, {.alongNormal = {disc2, *vol3}, .oppositeNormal = {disc2, *vol4}}}; BOOST_CHECK_THROW( - Portal::merge(gctx, portal1, portal2, BinningValue::binR, *logger), + Portal::merge(gctx, portal1, portal2, AxisDirection::AxisR, *logger), PortalMergingException); } @@ -369,9 +369,10 @@ BOOST_AUTO_TEST_CASE(Separated) { BOOST_CHECK(portal2.isValid()); // Same way can't set cyl2 as other link - BOOST_CHECK_THROW(portal1.setLink(gctx, Direction::AlongNormal, cyl2, *vol2), - PortalFusingException); - BOOST_CHECK_EQUAL(portal1.getLink(Direction::AlongNormal), nullptr); + BOOST_CHECK_THROW( + portal1.setLink(gctx, Direction::AlongNormal(), cyl2, *vol2), + PortalFusingException); + BOOST_CHECK_EQUAL(portal1.getLink(Direction::AlongNormal()), nullptr); Portal portal1b{gctx, {.oppositeNormal = {cyl1, *vol1}}}; BOOST_CHECK(portal1b.isValid()); @@ -452,7 +453,7 @@ BOOST_AUTO_TEST_CASE(Success) { // | | | | // +---+ +---+ Portal portal1{gctx, {.oppositeNormal = {cyl1, *vol1}}}; - BOOST_CHECK_EQUAL(&portal1.getLink(Direction::OppositeNormal)->surface(), + BOOST_CHECK_EQUAL(&portal1.getLink(Direction::OppositeNormal())->surface(), cyl1.get()); Portal portal2{gctx, {.alongNormal = {cyl2, *vol2}}}; @@ -471,7 +472,7 @@ BOOST_AUTO_TEST_CASE(Success) { // Portal surface is set to the one from "along", because it gets set first BOOST_CHECK_EQUAL(&portal3.surface(), cyl2.get()); // "Opposite" gets the already-set surface set as well - BOOST_CHECK_EQUAL(&portal3.getLink(Direction::OppositeNormal)->surface(), + BOOST_CHECK_EQUAL(&portal3.getLink(Direction::OppositeNormal())->surface(), cyl2.get()); } @@ -565,7 +566,7 @@ BOOST_AUTO_TEST_CASE(GridCreationOnFuse) { links.push_back(std::move(trivial3)); auto composite = std::make_unique(std::move(links), - BinningValue::binR); + AxisDirection::AxisR); auto discOpposite = Surface::makeShared(Transform3::Identity(), 30_mm, 120_mm); @@ -579,11 +580,11 @@ BOOST_AUTO_TEST_CASE(GridCreationOnFuse) { Portal fused = Portal::fuse(gctx, aPortal, bPortal, *logger); BOOST_CHECK_NE(dynamic_cast( - fused.getLink(Direction::OppositeNormal)), + fused.getLink(Direction::OppositeNormal())), nullptr); const auto* grid = dynamic_cast( - fused.getLink(Direction::AlongNormal)); + fused.getLink(Direction::AlongNormal())); BOOST_REQUIRE_NE(grid, nullptr); BOOST_CHECK_EQUAL(grid->grid().axes().front()->getNBins(), 3); @@ -612,19 +613,19 @@ BOOST_AUTO_TEST_CASE(Construction) { } BOOST_AUTO_TEST_CASE(InvalidConstruction) { - BOOST_CHECK_THROW(Portal(Direction::AlongNormal, nullptr), + BOOST_CHECK_THROW(Portal(Direction::AlongNormal(), nullptr), std::invalid_argument); auto vol1 = makeDummyVolume(); - BOOST_CHECK_THROW(Portal(Direction::AlongNormal, nullptr, *vol1), + BOOST_CHECK_THROW(Portal(Direction::AlongNormal(), nullptr, *vol1), std::invalid_argument); auto disc1 = Surface::makeShared( Transform3::Identity(), std::make_shared(50_mm, 100_mm)); - Portal portal(Direction::AlongNormal, disc1, *vol1); + Portal portal(Direction::AlongNormal(), disc1, *vol1); - BOOST_CHECK_THROW(portal.setLink(gctx, Direction::AlongNormal, nullptr), + BOOST_CHECK_THROW(portal.setLink(gctx, Direction::AlongNormal(), nullptr), std::invalid_argument); } @@ -646,12 +647,12 @@ BOOST_AUTO_TEST_CASE(PortalFill) { portal1 = Portal{gctx, {.oppositeNormal = {cyl1, *vol1}}}; portal2 = Portal{gctx, {.alongNormal = {cyl1, *vol2}}}; - BOOST_CHECK_EQUAL(portal1.getLink(Direction::AlongNormal), nullptr); - BOOST_CHECK_NE(portal1.getLink(Direction::OppositeNormal), nullptr); + BOOST_CHECK_EQUAL(portal1.getLink(Direction::AlongNormal()), nullptr); + BOOST_CHECK_NE(portal1.getLink(Direction::OppositeNormal()), nullptr); portal1.fill(*vol2); - BOOST_CHECK_NE(portal1.getLink(Direction::AlongNormal), nullptr); - BOOST_CHECK_NE(portal1.getLink(Direction::OppositeNormal), nullptr); + BOOST_CHECK_NE(portal1.getLink(Direction::AlongNormal()), nullptr); + BOOST_CHECK_NE(portal1.getLink(Direction::OppositeNormal()), nullptr); BOOST_CHECK_THROW(portal1.fill(*vol2), std::logic_error); } diff --git a/Tests/UnitTests/Core/Geometry/ProtoLayerHelperTests.cpp b/Tests/UnitTests/Core/Geometry/ProtoLayerHelperTests.cpp index c6ccd763095..10d446cff53 100644 --- a/Tests/UnitTests/Core/Geometry/ProtoLayerHelperTests.cpp +++ b/Tests/UnitTests/Core/Geometry/ProtoLayerHelperTests.cpp @@ -74,7 +74,7 @@ BOOST_AUTO_TEST_CASE(ProtoLayerHelperTests) { // Sort into ProtoLayers auto radialLayers = plHelper.protoLayers( tgContext, cylinderSurfaces, - ProtoLayerHelper::SortingConfig(BinningValue::binR, 5.)); + ProtoLayerHelper::SortingConfig(AxisDirection::AxisR, 5.)); BOOST_CHECK_EQUAL(radialLayers.size(), 4); @@ -129,7 +129,7 @@ BOOST_AUTO_TEST_CASE(ProtoLayerHelperTests) { // Sort into ProtoLayers auto discLayersZ = - plHelper.protoLayers(tgContext, discSurfaces, {BinningValue::binZ, 5.}); + plHelper.protoLayers(tgContext, discSurfaces, {AxisDirection::AxisZ, 5.}); BOOST_CHECK_EQUAL(discLayersZ.size(), 4); @@ -181,7 +181,7 @@ BOOST_AUTO_TEST_CASE(ProtoLayerHelperTests) { // First: Sort into ProtoLayers radially auto rSorted = plHelper.protoLayers( tgContext, ringSurfaces, - ProtoLayerHelper::SortingConfig(BinningValue::binR, 1.)); + ProtoLayerHelper::SortingConfig(AxisDirection::AxisR, 1.)); BOOST_CHECK_EQUAL(rSorted.size(), 3); Color dColor = {0, 0, 0}; @@ -190,7 +190,7 @@ BOOST_AUTO_TEST_CASE(ProtoLayerHelperTests) { for (auto& rBatch : rSorted) { auto lSorted = plHelper.protoLayers( tgContext, rBatch.surfaces(), - ProtoLayerHelper::SortingConfig(BinningValue::binZ, 5.)); + ProtoLayerHelper::SortingConfig(AxisDirection::AxisZ, 5.)); il = 0; dColor[ir] = 256; for (auto& layer : lSorted) { @@ -206,9 +206,9 @@ BOOST_AUTO_TEST_CASE(ProtoLayerHelperTests) { objVis.write("ProtoLayerHelper_RingLayers_sorted"); // Perform the split at once - auto rzSorted = - plHelper.protoLayers(tgContext, ringSurfaces, - {{BinningValue::binR, 1.}, {BinningValue::binZ, 5}}); + auto rzSorted = plHelper.protoLayers( + tgContext, ringSurfaces, + {{AxisDirection::AxisR, 1.}, {AxisDirection::AxisZ, 5}}); std::size_t irz = 0; for (auto& layer : rzSorted) { diff --git a/Tests/UnitTests/Core/Geometry/ProtoLayerTests.cpp b/Tests/UnitTests/Core/Geometry/ProtoLayerTests.cpp index 3fdf8ec1c16..a0cc315b4b1 100644 --- a/Tests/UnitTests/Core/Geometry/ProtoLayerTests.cpp +++ b/Tests/UnitTests/Core/Geometry/ProtoLayerTests.cpp @@ -36,7 +36,7 @@ GeometryContext tgContext = GeometryContext(); BOOST_AUTO_TEST_SUITE(Geometry) BOOST_AUTO_TEST_CASE(ProtoLayerTests) { - using enum BinningValue; + using enum AxisDirection; // Create a proto layer with 4 surfaces on the x/y grid auto recBounds = std::make_shared(3., 6.); @@ -111,20 +111,20 @@ BOOST_AUTO_TEST_CASE(ProtoLayerTests) { // Test 1 - identity transform auto protoLayer = createProtoLayer(Transform3::Identity()); - CHECK_CLOSE_ABS(protoLayer.range(binX), 12., 1e-8); - CHECK_CLOSE_ABS(protoLayer.medium(binX), 0., 1e-8); - CHECK_CLOSE_ABS(protoLayer.min(binX), -6., 1e-8); - CHECK_CLOSE_ABS(protoLayer.max(binX), 6., 1e-8); - CHECK_CLOSE_ABS(protoLayer.range(binY), 6., 1e-8); - CHECK_CLOSE_ABS(protoLayer.medium(binY), 0., 1e-8); - CHECK_CLOSE_ABS(protoLayer.min(binY), -3., 1e-8); - CHECK_CLOSE_ABS(protoLayer.max(binY), 3., 1e-8); - CHECK_CLOSE_ABS(protoLayer.range(binZ), 12., 1e-8); - CHECK_CLOSE_ABS(protoLayer.medium(binZ), 0., 1e-8); - CHECK_CLOSE_ABS(protoLayer.min(binZ), -6., 1e-8); - CHECK_CLOSE_ABS(protoLayer.max(binZ), 6., 1e-8); - CHECK_CLOSE_ABS(protoLayer.max(binR), std::hypot(3, 6), 1e-8); - CHECK_CLOSE_ABS(protoLayer.min(binR), 3., 1e-8); + CHECK_CLOSE_ABS(protoLayer.range(AxisX), 12., 1e-8); + CHECK_CLOSE_ABS(protoLayer.medium(AxisX), 0., 1e-8); + CHECK_CLOSE_ABS(protoLayer.min(AxisX), -6., 1e-8); + CHECK_CLOSE_ABS(protoLayer.max(AxisX), 6., 1e-8); + CHECK_CLOSE_ABS(protoLayer.range(AxisY), 6., 1e-8); + CHECK_CLOSE_ABS(protoLayer.medium(AxisY), 0., 1e-8); + CHECK_CLOSE_ABS(protoLayer.min(AxisY), -3., 1e-8); + CHECK_CLOSE_ABS(protoLayer.max(AxisY), 3., 1e-8); + CHECK_CLOSE_ABS(protoLayer.range(AxisZ), 12., 1e-8); + CHECK_CLOSE_ABS(protoLayer.medium(AxisZ), 0., 1e-8); + CHECK_CLOSE_ABS(protoLayer.min(AxisZ), -6., 1e-8); + CHECK_CLOSE_ABS(protoLayer.max(AxisZ), 6., 1e-8); + CHECK_CLOSE_ABS(protoLayer.max(AxisR), std::hypot(3, 6), 1e-8); + CHECK_CLOSE_ABS(protoLayer.min(AxisR), 3., 1e-8); // Test 1a @@ -133,35 +133,35 @@ BOOST_AUTO_TEST_CASE(ProtoLayerTests) { auto protoLayerRot = createProtoLayer(AngleAxis3(-0.345, Vector3::UnitZ()) * Transform3::Identity()); - BOOST_CHECK_NE(protoLayer.min(binX), -6.); - CHECK_CLOSE_ABS(protoLayerRot.medium(binX), 0., 1e-8); - CHECK_CLOSE_ABS(protoLayerRot.medium(binY), 0., 1e-8); - CHECK_CLOSE_ABS(protoLayerRot.range(binZ), 12., 1e-8); - CHECK_CLOSE_ABS(protoLayerRot.medium(binZ), 0., 1e-8); - CHECK_CLOSE_ABS(protoLayerRot.min(binZ), -6., 1e-8); - CHECK_CLOSE_ABS(protoLayerRot.max(binZ), 6., 1e-8); - CHECK_CLOSE_ABS(protoLayerRot.min(binR), 3., 1e-8); - CHECK_CLOSE_ABS(protoLayerRot.max(binR), std::hypot(3, 6), 1e-8); + BOOST_CHECK_NE(protoLayer.min(AxisX), -6.); + CHECK_CLOSE_ABS(protoLayerRot.medium(AxisX), 0., 1e-8); + CHECK_CLOSE_ABS(protoLayerRot.medium(AxisY), 0., 1e-8); + CHECK_CLOSE_ABS(protoLayerRot.range(AxisZ), 12., 1e-8); + CHECK_CLOSE_ABS(protoLayerRot.medium(AxisZ), 0., 1e-8); + CHECK_CLOSE_ABS(protoLayerRot.min(AxisZ), -6., 1e-8); + CHECK_CLOSE_ABS(protoLayerRot.max(AxisZ), 6., 1e-8); + CHECK_CLOSE_ABS(protoLayerRot.min(AxisR), 3., 1e-8); + CHECK_CLOSE_ABS(protoLayerRot.max(AxisR), std::hypot(3, 6), 1e-8); std::stringstream sstream; protoLayerRot.toStream(sstream); std::string oString = R"(ProtoLayer with dimensions (min/max) Extent in space : - - value : binX | range = [-6.66104, 6.66104] - - value : binY | range = [-4.85241, 4.85241] - - value : binZ | range = [-6, 6] - - value : binR | range = [3, 6.7082] - - value : binPhi | range = [-3.02295, 2.33295] - - value : binRPhi | range = [-20.2785, 15.6499] - - value : binH | range = [0.61548, 2.52611] - - value : binEta | range = [-1.14622, 1.14622] - - value : binMag | range = [7.34847, 7.34847] + - value : AxisX | range = [-6.66104, 6.66104] + - value : AxisY | range = [-4.85241, 4.85241] + - value : AxisZ | range = [-6, 6] + - value : AxisR | range = [3, 6.7082] + - value : AxisPhi | range = [-3.02295, 2.33295] + - value : AxisRPhi | range = [-20.2785, 15.6499] + - value : AxisTheta | range = [0.61548, 2.52611] + - value : AxisEta | range = [-1.14622, 1.14622] + - value : AxisMag | range = [7.34847, 7.34847] )"; BOOST_CHECK_EQUAL(sstream.str(), oString); } BOOST_AUTO_TEST_CASE(OrientedLayer) { - using enum BinningValue; + using enum AxisDirection; using namespace Acts::UnitLiterals; Transform3 base = Transform3::Identity(); @@ -197,14 +197,14 @@ BOOST_AUTO_TEST_CASE(OrientedLayer) { ProtoLayer protoLayer(tgContext, surfaces); BOOST_CHECK_EQUAL(protoLayer.surfaces().size(), 8); - BOOST_CHECK_CLOSE(protoLayer.min(binX), -23_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.max(binX), 23_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.min(binY), -23_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.max(binY), 23_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.min(binZ), 0_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.max(binZ), 0_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.min(binR), 17_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.max(binR), 23.769728648_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.min(AxisX), -23_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.max(AxisX), 23_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.min(AxisY), -23_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.max(AxisY), 23_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.min(AxisZ), 0_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.max(AxisZ), 0_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.min(AxisR), 17_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.max(AxisR), 23.769728648_mm, 1e-8); surfaces = makeFan(45_degree); @@ -212,41 +212,41 @@ BOOST_AUTO_TEST_CASE(OrientedLayer) { protoLayer = {tgContext, surfaces}; BOOST_CHECK_EQUAL(protoLayer.surfaces().size(), 8); - BOOST_CHECK_CLOSE(protoLayer.min(binX), -16.26345596_mm, 1e-4); - BOOST_CHECK_CLOSE(protoLayer.max(binX), 16.26345596_mm, 1e-4); - BOOST_CHECK_CLOSE(protoLayer.min(binY), -23_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.max(binY), 23_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.min(binZ), -16.26345596_mm, 1e-4); - BOOST_CHECK_CLOSE(protoLayer.max(binZ), 16.26345596_mm, 1e-4); + BOOST_CHECK_CLOSE(protoLayer.min(AxisX), -16.26345596_mm, 1e-4); + BOOST_CHECK_CLOSE(protoLayer.max(AxisX), 16.26345596_mm, 1e-4); + BOOST_CHECK_CLOSE(protoLayer.min(AxisY), -23_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.max(AxisY), 23_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.min(AxisZ), -16.26345596_mm, 1e-4); + BOOST_CHECK_CLOSE(protoLayer.max(AxisZ), 16.26345596_mm, 1e-4); protoLayer = {tgContext, surfaces, Transform3{AngleAxis3{45_degree, Vector3::UnitY()}}.inverse()}; BOOST_CHECK_EQUAL(protoLayer.surfaces().size(), 8); - BOOST_CHECK_CLOSE(protoLayer.range(binX), 46_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.min(binX), -23_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.max(binX), 23_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.range(binY), 46_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.min(binY), -23_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.max(binY), 23_mm, 1e-8); - CHECK_SMALL(protoLayer.range(binZ), 1e-14); - CHECK_SMALL(protoLayer.min(binZ), 1e-14); - CHECK_SMALL(protoLayer.max(binZ), 1e-14); + BOOST_CHECK_CLOSE(protoLayer.range(AxisX), 46_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.min(AxisX), -23_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.max(AxisX), 23_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.range(AxisY), 46_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.min(AxisY), -23_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.max(AxisY), 23_mm, 1e-8); + CHECK_SMALL(protoLayer.range(AxisZ), 1e-14); + CHECK_SMALL(protoLayer.min(AxisZ), 1e-14); + CHECK_SMALL(protoLayer.max(AxisZ), 1e-14); surfaces = makeFan(0_degree, 10_mm); protoLayer = {tgContext, surfaces}; BOOST_CHECK_EQUAL(protoLayer.surfaces().size(), 8); - BOOST_CHECK_CLOSE(protoLayer.range(binX), 46_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.min(binX), -23_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.max(binX), 23_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.range(binY), 46_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.min(binY), -23_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.max(binY), 23_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.range(binZ), 10_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.min(binZ), -5_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.max(binZ), 5_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.range(AxisX), 46_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.min(AxisX), -23_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.max(AxisX), 23_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.range(AxisY), 46_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.min(AxisY), -23_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.max(AxisY), 23_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.range(AxisZ), 10_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.min(AxisZ), -5_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.max(AxisZ), 5_mm, 1e-8); surfaces = makeFan(45_degree, 10_mm); @@ -254,15 +254,15 @@ BOOST_AUTO_TEST_CASE(OrientedLayer) { Transform3{AngleAxis3{45_degree, Vector3::UnitY()}}.inverse()}; BOOST_CHECK_EQUAL(protoLayer.surfaces().size(), 8); - BOOST_CHECK_CLOSE(protoLayer.range(binX), 46_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.min(binX), -23_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.max(binX), 23_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.range(binY), 46_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.min(binY), -23_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.max(binY), 23_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.range(binZ), 10_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.min(binZ), -5_mm, 1e-8); - BOOST_CHECK_CLOSE(protoLayer.max(binZ), 5_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.range(AxisX), 46_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.min(AxisX), -23_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.max(AxisX), 23_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.range(AxisY), 46_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.min(AxisY), -23_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.max(AxisY), 23_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.range(AxisZ), 10_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.min(AxisZ), -5_mm, 1e-8); + BOOST_CHECK_CLOSE(protoLayer.max(AxisZ), 5_mm, 1e-8); } BOOST_AUTO_TEST_SUITE_END() diff --git a/Tests/UnitTests/Core/Geometry/SurfaceArrayCreatorTests.cpp b/Tests/UnitTests/Core/Geometry/SurfaceArrayCreatorTests.cpp index 6d69c1667da..9681f1b221d 100644 --- a/Tests/UnitTests/Core/Geometry/SurfaceArrayCreatorTests.cpp +++ b/Tests/UnitTests/Core/Geometry/SurfaceArrayCreatorTests.cpp @@ -20,7 +20,7 @@ #include "Acts/Surfaces/SurfaceBounds.hpp" #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp" #include "Acts/Utilities/Axis.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/BinningType.hpp" #include "Acts/Utilities/Grid.hpp" #include "Acts/Utilities/Helpers.hpp" @@ -272,9 +272,9 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_createEquidistantAxis_Phi, std::vector emptyRaw; ProtoLayer pl(tgContext, emptyRaw); auto tr = Transform3::Identity(); - BOOST_CHECK_THROW( - createEquidistantAxis(tgContext, emptyRaw, BinningValue::binPhi, pl, tr), - std::logic_error); + BOOST_CHECK_THROW(createEquidistantAxis(tgContext, emptyRaw, + AxisDirection::AxisPhi, pl, tr), + std::logic_error); std::vector bdExp = { -3.14159, -2.93215, -2.72271, -2.51327, -2.30383, -2.0944, -1.88496, @@ -296,7 +296,7 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_createEquidistantAxis_Phi, pl = ProtoLayer(tgContext, surfacesRaw); tr = Transform3::Identity(); auto axis = createEquidistantAxis(tgContext, surfacesRaw, - BinningValue::binPhi, pl, tr); + AxisDirection::AxisPhi, pl, tr); BOOST_CHECK_EQUAL(axis.nBins, 30u); CHECK_CLOSE_REL(axis.max, std::numbers::pi, 1e-6); @@ -310,7 +310,7 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_createEquidistantAxis_Phi, surfacesRaw = unpack_shared_vector(surfaces); pl = ProtoLayer(tgContext, surfacesRaw); tr = Transform3::Identity(); - axis = createEquidistantAxis(tgContext, surfacesRaw, BinningValue::binPhi, + axis = createEquidistantAxis(tgContext, surfacesRaw, AxisDirection::AxisPhi, pl, tr); draw_surfaces(surfaces, "SurfaceArrayCreator_createEquidistantAxis_EC_2.obj"); @@ -326,7 +326,7 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_createEquidistantAxis_Phi, surfacesRaw = unpack_shared_vector(surfaces); pl = ProtoLayer(tgContext, surfacesRaw); tr = Transform3::Identity(); - axis = createEquidistantAxis(tgContext, surfacesRaw, BinningValue::binPhi, + axis = createEquidistantAxis(tgContext, surfacesRaw, AxisDirection::AxisPhi, pl, tr); draw_surfaces(surfaces, "SurfaceArrayCreator_createEquidistantAxis_EC_3.obj"); @@ -343,7 +343,7 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_createEquidistantAxis_Phi, pl = ProtoLayer(tgContext, surfaces); surfacesRaw = unpack_shared_vector(surfaces); tr = Transform3::Identity(); - axis = createEquidistantAxis(tgContext, surfacesRaw, BinningValue::binPhi, + axis = createEquidistantAxis(tgContext, surfacesRaw, AxisDirection::AxisPhi, pl, tr); surfacesRaw = unpack_shared_vector(surfaces); draw_surfaces(surfaces, @@ -364,7 +364,7 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_createEquidistantAxis_Phi, pl = ProtoLayer(tgContext, surfacesRaw); tr = Transform3::Identity(); auto axis = createEquidistantAxis(tgContext, surfacesRaw, - BinningValue::binPhi, pl, tr); + AxisDirection::AxisPhi, pl, tr); draw_surfaces(surfaces, "SurfaceArrayCreator_createEquidistantAxis_BRL_1.obj"); BOOST_CHECK_EQUAL(axis.nBins, 30u); @@ -379,7 +379,7 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_createEquidistantAxis_Phi, surfacesRaw = unpack_shared_vector(surfaces); pl = ProtoLayer(tgContext, surfacesRaw); tr = Transform3::Identity(); - axis = createEquidistantAxis(tgContext, surfacesRaw, BinningValue::binPhi, + axis = createEquidistantAxis(tgContext, surfacesRaw, AxisDirection::AxisPhi, pl, tr); draw_surfaces(surfaces, "SurfaceArrayCreator_createEquidistantAxis_BRL_2.obj"); @@ -396,7 +396,7 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_createEquidistantAxis_Phi, surfacesRaw = unpack_shared_vector(surfaces); pl = ProtoLayer(tgContext, surfacesRaw); tr = Transform3::Identity(); - axis = createEquidistantAxis(tgContext, surfacesRaw, BinningValue::binPhi, + axis = createEquidistantAxis(tgContext, surfacesRaw, AxisDirection::AxisPhi, pl, tr); draw_surfaces(surfaces, "SurfaceArrayCreator_createEquidistantAxis_BRL_3.obj"); @@ -413,7 +413,7 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_createEquidistantAxis_Phi, surfacesRaw = unpack_shared_vector(surfaces); pl = ProtoLayer(tgContext, surfacesRaw); tr = Transform3::Identity(); - axis = createEquidistantAxis(tgContext, surfacesRaw, BinningValue::binPhi, + axis = createEquidistantAxis(tgContext, surfacesRaw, AxisDirection::AxisPhi, pl, tr); draw_surfaces(surfaces, "SurfaceArrayCreator_createEquidistantAxis_BRL_4.obj"); @@ -436,7 +436,7 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_createEquidistantAxis_Phi, pl = ProtoLayer(tgContext, surfacesRaw); tr = Transform3::Identity(); auto axis = createEquidistantAxis(tgContext, surfacesRaw, - BinningValue::binPhi, pl, tr); + AxisDirection::AxisPhi, pl, tr); BOOST_CHECK_EQUAL(axis.nBins, 1u); CHECK_CLOSE_ABS(axis.max, phi(Vector3(8, 1, 0)), 1e-3); @@ -451,8 +451,8 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_createEquidistantAxis_Z, auto surfacesRaw = unpack_shared_vector(surfaces); ProtoLayer pl = ProtoLayer(tgContext, surfacesRaw); auto trf = Transform3::Identity(); - auto axis = createEquidistantAxis(tgContext, surfacesRaw, BinningValue::binZ, - pl, trf); + auto axis = createEquidistantAxis(tgContext, surfacesRaw, + AxisDirection::AxisZ, pl, trf); draw_surfaces(surfaces, "SurfaceArrayCreator_createEquidistantAxis_Z_1.obj"); BOOST_CHECK_EQUAL(axis.nBins, 1u); CHECK_CLOSE_ABS(axis.max, 3, 1e-6); @@ -466,8 +466,8 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_createEquidistantAxis_Z, surfacesRaw = unpack_shared_vector(surfaces); pl = ProtoLayer(tgContext, surfacesRaw); trf = Transform3::Identity(); - axis = createEquidistantAxis(tgContext, surfacesRaw, BinningValue::binZ, pl, - trf); + axis = createEquidistantAxis(tgContext, surfacesRaw, AxisDirection::AxisZ, + pl, trf); draw_surfaces( surfaces, (boost::format( @@ -487,7 +487,7 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_createEquidistantAxis_Z, surfacesRaw = unpack_shared_vector(surfaces); pl = ProtoLayer(tgContext, surfacesRaw); trf = Transform3::Identity(); - axis = createEquidistantAxis(tgContext, surfacesRaw, BinningValue::binZ, pl, + axis = createEquidistantAxis(tgContext, surfacesRaw, AxisDirection::AxisZ, pl, trf); draw_surfaces(surfaces, "SurfaceArrayCreator_createEquidistantAxis_Z_3.obj"); BOOST_CHECK_EQUAL(axis.nBins, 10u); @@ -504,8 +504,8 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_createEquidistantAxis_R, draw_surfaces(surfaces, "SurfaceArrayCreator_createEquidistantAxis_R_1.obj"); auto trf = Transform3::Identity(); ProtoLayer pl = ProtoLayer(tgContext, surfacesRaw); - auto axis = createEquidistantAxis(tgContext, surfacesRaw, BinningValue::binR, - pl, trf); + auto axis = createEquidistantAxis(tgContext, surfacesRaw, + AxisDirection::AxisR, pl, trf); BOOST_CHECK_EQUAL(axis.nBins, 1u); CHECK_CLOSE_ABS(axis.max, perp(Vector3(17, 1, 0)), 1e-3); CHECK_CLOSE_ABS(axis.min, 13, 1e-3); @@ -524,7 +524,7 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_createEquidistantAxis_R, surfacesRaw = unpack_shared_vector(surfaces); pl = ProtoLayer(tgContext, surfacesRaw); trf = Transform3::Identity(); - axis = createEquidistantAxis(tgContext, surfacesRaw, BinningValue::binR, pl, + axis = createEquidistantAxis(tgContext, surfacesRaw, AxisDirection::AxisR, pl, trf); BOOST_CHECK_EQUAL(axis.nBins, 3u); @@ -595,7 +595,7 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_completeBinning, // actually filled SA for (const auto& srf : brl) { - Vector3 ctr = srf->binningPosition(tgContext, BinningValue::binR); + Vector3 ctr = srf->referencePosition(tgContext, AxisDirection::AxisR); auto binContent = sa.at(ctr); BOOST_CHECK_EQUAL(binContent.size(), 1u); @@ -616,9 +616,9 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_barrelStagger, Transform3 tr = Transform3::Identity(); auto pAxisPhi = - createEquidistantAxis(tgContext, brlRaw, BinningValue::binPhi, pl, tr); + createEquidistantAxis(tgContext, brlRaw, AxisDirection::AxisPhi, pl, tr); auto pAxisZ = - createEquidistantAxis(tgContext, brlRaw, BinningValue::binZ, pl, tr); + createEquidistantAxis(tgContext, brlRaw, AxisDirection::AxisZ, pl, tr); double R = 10.; Transform3 itr = tr.inverse(); @@ -645,7 +645,7 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_barrelStagger, auto A = pr.first; auto B = pr.second; - Vector3 ctr = A->binningPosition(tgContext, BinningValue::binR); + Vector3 ctr = A->referencePosition(tgContext, AxisDirection::AxisR); auto binContent = sa.at(ctr); BOOST_CHECK_EQUAL(binContent.size(), 2u); std::set act; @@ -664,9 +664,9 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_barrelStagger, tr = Transform3::Identity(); auto pAxisPhiVar = - createVariableAxis(tgContext, brlRaw, BinningValue::binPhi, pl, tr); + createVariableAxis(tgContext, brlRaw, AxisDirection::AxisPhi, pl, tr); auto pAxisZVar = - createVariableAxis(tgContext, brlRaw, BinningValue::binZ, pl, tr); + createVariableAxis(tgContext, brlRaw, AxisDirection::AxisZ, pl, tr); itr = tr.inverse(); @@ -715,7 +715,7 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArrayCreator_barrelStagger, auto A = pr.first; auto B = pr.second; - Vector3 ctr = A->binningPosition(tgContext, BinningValue::binR); + Vector3 ctr = A->referencePosition(tgContext, AxisDirection::AxisR); auto binContent = sa2.at(ctr); BOOST_CHECK_EQUAL(binContent.size(), 2u); std::set act; diff --git a/Tests/UnitTests/Core/Geometry/SurfaceBinningMatcherTests.cpp b/Tests/UnitTests/Core/Geometry/SurfaceBinningMatcherTests.cpp index 6a3c92aa8a3..726620a15c1 100644 --- a/Tests/UnitTests/Core/Geometry/SurfaceBinningMatcherTests.cpp +++ b/Tests/UnitTests/Core/Geometry/SurfaceBinningMatcherTests.cpp @@ -58,25 +58,25 @@ BOOST_AUTO_TEST_CASE(PlaneSurfaceMatcher) { Surface::makeShared(identity, similarPhiBounds); SurfaceBinningMatcher sbm; - sbm.tolerances[toUnderlying(BinningValue::binR)] = {rMinTol, rMaxTol}; - sbm.tolerances[toUnderlying(BinningValue::binPhi)] = {phiTol, phiTol}; + sbm.tolerances[toUnderlying(AxisDirection::AxisR)] = {rMinTol, rMaxTol}; + sbm.tolerances[toUnderlying(AxisDirection::AxisPhi)] = {phiTol, phiTol}; // Always true - for (BinningValue ib : allBinningValues()) { + for (AxisDirection ib : allAxisDirections()) { BOOST_CHECK(sbm(tgContext, ib, oneSurface.get(), oneSurface.get())); } // Not matching in R - BOOST_CHECK(!sbm(tgContext, BinningValue::binR, oneSurface.get(), + BOOST_CHECK(!sbm(tgContext, AxisDirection::AxisR, oneSurface.get(), otherSurface.get())); // Not matching in phi - BOOST_CHECK(!sbm(tgContext, BinningValue::binPhi, oneSurface.get(), + BOOST_CHECK(!sbm(tgContext, AxisDirection::AxisPhi, oneSurface.get(), otherSurface.get())); // Good enough matching in R - BOOST_CHECK(sbm(tgContext, BinningValue::binR, oneSurface.get(), + BOOST_CHECK(sbm(tgContext, AxisDirection::AxisR, oneSurface.get(), similarRSurface.get())); // Good enough matching in phi - BOOST_CHECK(sbm(tgContext, BinningValue::binPhi, oneSurface.get(), + BOOST_CHECK(sbm(tgContext, AxisDirection::AxisPhi, oneSurface.get(), similarPhiSurface.get())); } diff --git a/Tests/UnitTests/Core/Geometry/TrackingVolumeCreation.hpp b/Tests/UnitTests/Core/Geometry/TrackingVolumeCreation.hpp index d895f74ccab..899bcaa8a41 100644 --- a/Tests/UnitTests/Core/Geometry/TrackingVolumeCreation.hpp +++ b/Tests/UnitTests/Core/Geometry/TrackingVolumeCreation.hpp @@ -96,14 +96,14 @@ MutableTrackingVolumePtr constructContainerVolume(const GeometryContext& gctx, /// create the volume array using VAP = std::pair; std::vector volumes = { - {iVolume, iVolume->binningPosition(gctx, BinningValue::binR)}, - {oVolume, oVolume->binningPosition(gctx, BinningValue::binR)}}; + {iVolume, iVolume->referencePosition(gctx, AxisDirection::AxisR)}, + {oVolume, oVolume->referencePosition(gctx, AxisDirection::AxisR)}}; /// the bounds for the container auto hVolumeBounds = std::make_shared(0., hVolumeR, hVolumeHalflength); /// create the BinUtility & the BinnedArray auto vUtility = std::make_unique( - volumes.size(), 0., hVolumeR, open, BinningValue::binR); + volumes.size(), 0., hVolumeR, open, AxisDirection::AxisR); std::shared_ptr vArray = std::make_shared>( volumes, std::move(vUtility)); diff --git a/Tests/UnitTests/Core/Geometry/VolumeTests.cpp b/Tests/UnitTests/Core/Geometry/VolumeTests.cpp index 8c10abc18c2..8e9c8296ef3 100644 --- a/Tests/UnitTests/Core/Geometry/VolumeTests.cpp +++ b/Tests/UnitTests/Core/Geometry/VolumeTests.cpp @@ -72,7 +72,7 @@ BOOST_AUTO_TEST_CASE(VolumeTest) { // Binning test GeometryContext gctx; - BOOST_CHECK_EQUAL(volume.binningPosition(gctx, BinningValue::binX), + BOOST_CHECK_EQUAL(volume.referencePosition(gctx, AxisDirection::AxisX), volume.center()); } diff --git a/Tests/UnitTests/Core/MagneticField/InterpolatedBFieldMapTests.cpp b/Tests/UnitTests/Core/MagneticField/InterpolatedBFieldMapTests.cpp index 925d6617018..e7620de6d06 100644 --- a/Tests/UnitTests/Core/MagneticField/InterpolatedBFieldMapTests.cpp +++ b/Tests/UnitTests/Core/MagneticField/InterpolatedBFieldMapTests.cpp @@ -13,7 +13,7 @@ #include "Acts/MagneticField/MagneticFieldContext.hpp" #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp" #include "Acts/Utilities/Axis.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Grid.hpp" #include "Acts/Utilities/Result.hpp" #include "Acts/Utilities/VectorHelpers.hpp" diff --git a/Tests/UnitTests/Core/Material/AccumulatedSurfaceMaterialTests.cpp b/Tests/UnitTests/Core/Material/AccumulatedSurfaceMaterialTests.cpp index 9eb412a344d..3326c258c77 100644 --- a/Tests/UnitTests/Core/Material/AccumulatedSurfaceMaterialTests.cpp +++ b/Tests/UnitTests/Core/Material/AccumulatedSurfaceMaterialTests.cpp @@ -35,7 +35,7 @@ BOOST_AUTO_TEST_CASE(AccumulatedSurfaceMaterial_construction_test) { // Test: // BinsSurfaceMaterial accumulation - 1D - BinUtility binUtility1D(10, -5., 5., open, BinningValue::binX); + BinUtility binUtility1D(10, -5., 5., open, AxisDirection::AxisX); AccumulatedSurfaceMaterial material1D{binUtility1D}; auto accMat1D = material1D.accumulatedMaterial(); BOOST_CHECK_EQUAL(accMat1D.size(), 1u); @@ -43,8 +43,8 @@ BOOST_AUTO_TEST_CASE(AccumulatedSurfaceMaterial_construction_test) { // Test: // BinsSurfaceMaterial accumulation - 2D - BinUtility binUtility2D(10, -5., 5., open, BinningValue::binX); - binUtility2D += BinUtility(20, -10., 10., open, BinningValue::binY); + BinUtility binUtility2D(10, -5., 5., open, AxisDirection::AxisX); + binUtility2D += BinUtility(20, -10., 10., open, AxisDirection::AxisY); AccumulatedSurfaceMaterial material2D{binUtility2D}; auto accMat2D = material2D.accumulatedMaterial(); BOOST_CHECK_EQUAL(accMat2D.size(), 20u); @@ -91,8 +91,8 @@ BOOST_AUTO_TEST_CASE(AccumulatedSurfaceMaterial_fill_convert_1D) { MaterialSlab four(mat, 4.); // BinsSurfaceMaterial accumulation - 2D - BinUtility binUtility2D(2, -1., 1., open, BinningValue::binX); - binUtility2D += BinUtility(2, -1., 1., open, BinningValue::binY); + BinUtility binUtility2D(2, -1., 1., open, AxisDirection::AxisX); + binUtility2D += BinUtility(2, -1., 1., open, AxisDirection::AxisY); AccumulatedSurfaceMaterial material2D{binUtility2D}; const std::vector> bin; diff --git a/Tests/UnitTests/Core/Material/BinnedSurfaceMaterialAccumulaterTests.cpp b/Tests/UnitTests/Core/Material/BinnedSurfaceMaterialAccumulaterTests.cpp index a249d22ba4b..d3759c16400 100644 --- a/Tests/UnitTests/Core/Material/BinnedSurfaceMaterialAccumulaterTests.cpp +++ b/Tests/UnitTests/Core/Material/BinnedSurfaceMaterialAccumulaterTests.cpp @@ -87,14 +87,14 @@ BOOST_AUTO_TEST_CASE(AccumulationTest) { // Second surface is binned Phi / Z BinUtility sb1(4, -std::numbers::pi, std::numbers::pi, closed, - BinningValue::binPhi); - sb1 += BinUtility(2, -100., 100., open, BinningValue::binZ); + AxisDirection::AxisPhi); + sb1 += BinUtility(2, -100., 100., open, AxisDirection::AxisZ); surfaces[1u]->assignSurfaceMaterial( std::make_shared(sb1)); // Third is binned std::vector mps = {mp, mp, mp}; - BinUtility sb2(3, -100., 100., open, BinningValue::binZ); + BinUtility sb2(3, -100., 100., open, AxisDirection::AxisZ); surfaces[2u]->assignSurfaceMaterial( std::make_shared(sb2, mps)); diff --git a/Tests/UnitTests/Core/Material/BinnedSurfaceMaterialTests.cpp b/Tests/UnitTests/Core/Material/BinnedSurfaceMaterialTests.cpp index f9c2d26df40..9551c131adc 100644 --- a/Tests/UnitTests/Core/Material/BinnedSurfaceMaterialTests.cpp +++ b/Tests/UnitTests/Core/Material/BinnedSurfaceMaterialTests.cpp @@ -21,8 +21,8 @@ namespace Acts::Test { /// Test the constructors BOOST_AUTO_TEST_CASE(BinnedSurfaceMaterial_construction_test) { - BinUtility xyBinning(2, -1., 1., open, BinningValue::binX); - xyBinning += BinUtility(3, -3., 3., open, BinningValue::binY); + BinUtility xyBinning(2, -1., 1., open, AxisDirection::AxisX); + xyBinning += BinUtility(3, -3., 3., open, AxisDirection::AxisY); // Constructor a few material properties MaterialSlab a00(Material::fromMolarDensity(1., 2., 3., 4., 5.), 6.); diff --git a/Tests/UnitTests/Core/Material/HomogeneousSurfaceMaterialTests.cpp b/Tests/UnitTests/Core/Material/HomogeneousSurfaceMaterialTests.cpp index 10db0c4b689..c353d1e92e0 100644 --- a/Tests/UnitTests/Core/Material/HomogeneousSurfaceMaterialTests.cpp +++ b/Tests/UnitTests/Core/Material/HomogeneousSurfaceMaterialTests.cpp @@ -82,8 +82,8 @@ BOOST_AUTO_TEST_CASE(HomogeneousSurfaceMaterial_access_test) { BOOST_CHECK_EQUAL(mat, mat2d); BOOST_CHECK_EQUAL(mat, mat3d); - Direction fDir = Direction::Forward; - Direction bDir = Direction::Backward; + Direction fDir = Direction::Forward(); + Direction bDir = Direction::Backward(); MaterialUpdateStage pre = MaterialUpdateStage::PreUpdate; MaterialUpdateStage full = MaterialUpdateStage::FullUpdate; diff --git a/Tests/UnitTests/Core/Material/ISurfaceMaterialTests.cpp b/Tests/UnitTests/Core/Material/ISurfaceMaterialTests.cpp index 1bdb2cef716..f302acf37f0 100644 --- a/Tests/UnitTests/Core/Material/ISurfaceMaterialTests.cpp +++ b/Tests/UnitTests/Core/Material/ISurfaceMaterialTests.cpp @@ -45,25 +45,25 @@ BOOST_AUTO_TEST_CASE(ISurfaceMaterial_factor_test) { SurfaceMaterialStub stub{splitFactor}; BOOST_CHECK_EQUAL( - stub.factor(Direction::Forward, MaterialUpdateStage::FullUpdate), 1.0); + stub.factor(Direction::Forward(), MaterialUpdateStage::FullUpdate), 1.0); BOOST_CHECK_EQUAL( - stub.factor(Direction::Backward, MaterialUpdateStage::FullUpdate), 1.0); + stub.factor(Direction::Backward(), MaterialUpdateStage::FullUpdate), 1.0); BOOST_CHECK_EQUAL( - stub.factor(Direction::Forward, MaterialUpdateStage::PostUpdate), + stub.factor(Direction::Forward(), MaterialUpdateStage::PostUpdate), splitFactor); BOOST_CHECK_EQUAL( - stub.factor(Direction::Backward, MaterialUpdateStage::PreUpdate), + stub.factor(Direction::Backward(), MaterialUpdateStage::PreUpdate), splitFactor); BOOST_CHECK_EQUAL( - stub.factor(Direction::Forward, MaterialUpdateStage::PreUpdate), + stub.factor(Direction::Forward(), MaterialUpdateStage::PreUpdate), 1 - splitFactor); BOOST_CHECK_EQUAL( - stub.factor(Direction::Backward, MaterialUpdateStage::PostUpdate), + stub.factor(Direction::Backward(), MaterialUpdateStage::PostUpdate), 1 - splitFactor); } diff --git a/Tests/UnitTests/Core/Material/InterpolatedMaterialMapTests.cpp b/Tests/UnitTests/Core/Material/InterpolatedMaterialMapTests.cpp index 10933ccfa0c..4977918c05d 100644 --- a/Tests/UnitTests/Core/Material/InterpolatedMaterialMapTests.cpp +++ b/Tests/UnitTests/Core/Material/InterpolatedMaterialMapTests.cpp @@ -13,7 +13,7 @@ #include "Acts/Material/Material.hpp" #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp" #include "Acts/Utilities/Axis.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Grid.hpp" #include diff --git a/Tests/UnitTests/Core/Material/MaterialGridHelperTests.cpp b/Tests/UnitTests/Core/Material/MaterialGridHelperTests.cpp index 1c76cf866f7..51d330a2bc9 100644 --- a/Tests/UnitTests/Core/Material/MaterialGridHelperTests.cpp +++ b/Tests/UnitTests/Core/Material/MaterialGridHelperTests.cpp @@ -15,7 +15,7 @@ #include "Acts/Material/MaterialSlab.hpp" #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp" #include "Acts/Utilities/Axis.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/BinUtility.hpp" #include "Acts/Utilities/BinningType.hpp" #include "Acts/Utilities/Grid.hpp" @@ -40,8 +40,8 @@ using MaterialGrid3D = /// @brief Various test for the Material in the case of a Cuboid volume and 2D /// Grid BOOST_AUTO_TEST_CASE(Square_Grid_test) { - BinUtility bu(7, -3., 3., open, BinningValue::binX); - bu += BinUtility(3, -2., 2., open, BinningValue::binY); + BinUtility bu(7, -3., 3., open, AxisDirection::AxisX); + bu += BinUtility(3, -2., 2., open, AxisDirection::AxisY); auto bd = bu.binningData(); std::function transfoGlobalToLocal; @@ -129,9 +129,9 @@ BOOST_AUTO_TEST_CASE(Square_Grid_test) { /// @brief Various test for the Material in the case of a Cylindrical volume /// with a 2D grid BOOST_AUTO_TEST_CASE(PhiZ_Grid_test) { - BinUtility bu(2, -2., 2., open, BinningValue::binZ); + BinUtility bu(2, -2., 2., open, AxisDirection::AxisZ); bu += BinUtility(3, -std::numbers::pi, std::numbers::pi, closed, - BinningValue::binPhi); + AxisDirection::AxisPhi); auto bd = bu.binningData(); std::function transfoGlobalToLocal; @@ -219,9 +219,9 @@ BOOST_AUTO_TEST_CASE(PhiZ_Grid_test) { /// @brief Various test for the Material in the case of a Cuboid volume BOOST_AUTO_TEST_CASE(Cubic_Grid_test) { - BinUtility bu(7, -3., 3., open, BinningValue::binX); - bu += BinUtility(3, -2., 2., open, BinningValue::binY); - bu += BinUtility(2, -1., 1., open, BinningValue::binZ); + BinUtility bu(7, -3., 3., open, AxisDirection::AxisX); + bu += BinUtility(3, -2., 2., open, AxisDirection::AxisY); + bu += BinUtility(2, -1., 1., open, AxisDirection::AxisZ); auto bd = bu.binningData(); std::function transfoGlobalToLocal; @@ -310,10 +310,10 @@ BOOST_AUTO_TEST_CASE(Cubic_Grid_test) { /// @brief Various test for the Material in the case of a Cylindrical volume BOOST_AUTO_TEST_CASE(Cylindrical_Grid_test) { - BinUtility bu(4, 1., 4., open, BinningValue::binR); + BinUtility bu(4, 1., 4., open, AxisDirection::AxisR); bu += BinUtility(3, -std::numbers::pi, std::numbers::pi, closed, - BinningValue::binPhi); - bu += BinUtility(2, -2., 2., open, BinningValue::binZ); + AxisDirection::AxisPhi); + bu += BinUtility(2, -2., 2., open, AxisDirection::AxisZ); auto bd = bu.binningData(); std::function transfoGlobalToLocal; diff --git a/Tests/UnitTests/Core/Material/PropagatorMaterialAssignerTests.cpp b/Tests/UnitTests/Core/Material/PropagatorMaterialAssignerTests.cpp index 03ab7415d1b..18f5880c98e 100644 --- a/Tests/UnitTests/Core/Material/PropagatorMaterialAssignerTests.cpp +++ b/Tests/UnitTests/Core/Material/PropagatorMaterialAssignerTests.cpp @@ -69,7 +69,7 @@ BOOST_AUTO_TEST_CASE(FindSurfaceIntersectionsTrackingGeometry) { LayerArrayCreator::Config lacConfig; LayerArrayCreator lac = LayerArrayCreator(lacConfig); auto layers = lac.layerArray(tContext, {pCylinderLayer}, rMin, rMid, - arbitrary, BinningValue::binR); + arbitrary, AxisDirection::AxisR); auto innerVolume = std::make_shared( Transform3::Identity(), vCylinderInner, nullptr, std::move(layers), @@ -85,7 +85,7 @@ BOOST_AUTO_TEST_CASE(FindSurfaceIntersectionsTrackingGeometry) { TrackingVolumeArrayCreator tvac = TrackingVolumeArrayCreator(tvacConfig); auto volumes = tvac.trackingVolumeArray(tContext, {innerVolume, outerVolume}, - BinningValue::binR); + AxisDirection::AxisR); auto vCylinderTop = std::make_shared(rMin, rMax, 110.); diff --git a/Tests/UnitTests/Core/Material/ProtoSurfaceMaterialTests.cpp b/Tests/UnitTests/Core/Material/ProtoSurfaceMaterialTests.cpp index 195ef30b81d..b2b3b153626 100644 --- a/Tests/UnitTests/Core/Material/ProtoSurfaceMaterialTests.cpp +++ b/Tests/UnitTests/Core/Material/ProtoSurfaceMaterialTests.cpp @@ -18,8 +18,8 @@ namespace Acts::Test { /// Test the constructors BOOST_AUTO_TEST_CASE(ProtoSurfaceMaterial_construction_test) { - BinUtility smpBU(10, -10., 10., open, BinningValue::binX); - smpBU += BinUtility(10, -10., 10., open, BinningValue::binY); + BinUtility smpBU(10, -10., 10., open, AxisDirection::AxisX); + smpBU += BinUtility(10, -10., 10., open, AxisDirection::AxisY); // Constructor from arguments ProtoSurfaceMaterial smp(smpBU); diff --git a/Tests/UnitTests/Core/Material/ProtoVolumeMaterialTests.cpp b/Tests/UnitTests/Core/Material/ProtoVolumeMaterialTests.cpp index f5cc2c90953..fac92072e41 100644 --- a/Tests/UnitTests/Core/Material/ProtoVolumeMaterialTests.cpp +++ b/Tests/UnitTests/Core/Material/ProtoVolumeMaterialTests.cpp @@ -18,9 +18,9 @@ namespace Acts::Test { /// Test the constructors BOOST_AUTO_TEST_CASE(ProtoVolumeMaterial_construction_test) { - BinUtility vmpBU(10, -10., 10., open, BinningValue::binX); - vmpBU += BinUtility(10, -10., 10., open, BinningValue::binY); - vmpBU += BinUtility(10, -10., 10., open, BinningValue::binZ); + BinUtility vmpBU(10, -10., 10., open, AxisDirection::AxisX); + vmpBU += BinUtility(10, -10., 10., open, AxisDirection::AxisY); + vmpBU += BinUtility(10, -10., 10., open, AxisDirection::AxisZ); // Constructor from arguments ProtoVolumeMaterial vmp(vmpBU); diff --git a/Tests/UnitTests/Core/Material/SurfaceMaterialMapperTests.cpp b/Tests/UnitTests/Core/Material/SurfaceMaterialMapperTests.cpp index 6d7b94fecde..d31e8bac9cf 100644 --- a/Tests/UnitTests/Core/Material/SurfaceMaterialMapperTests.cpp +++ b/Tests/UnitTests/Core/Material/SurfaceMaterialMapperTests.cpp @@ -40,7 +40,7 @@ namespace Acts { std::shared_ptr trackingGeometry() { using namespace Acts::UnitLiterals; - BinUtility zbinned(8, -40, 40, open, BinningValue::binZ); + BinUtility zbinned(8, -40, 40, open, AxisDirection::AxisZ); auto matProxy = std::make_shared(zbinned); Logging::Level surfaceLLevel = Logging::INFO; diff --git a/Tests/UnitTests/Core/Material/VolumeMaterialMapperTests.cpp b/Tests/UnitTests/Core/Material/VolumeMaterialMapperTests.cpp index ffe731cb6ca..ec3d0d733c9 100644 --- a/Tests/UnitTests/Core/Material/VolumeMaterialMapperTests.cpp +++ b/Tests/UnitTests/Core/Material/VolumeMaterialMapperTests.cpp @@ -85,17 +85,17 @@ namespace Acts::Test { BOOST_AUTO_TEST_CASE(SurfaceMaterialMapper_tests) { using namespace Acts::UnitLiterals; - BinUtility bu1(4, 0_m, 1_m, open, BinningValue::binX); - bu1 += BinUtility(2, -0.5_m, 0.5_m, open, BinningValue::binY); - bu1 += BinUtility(2, -0.5_m, 0.5_m, open, BinningValue::binZ); + BinUtility bu1(4, 0_m, 1_m, open, AxisDirection::AxisX); + bu1 += BinUtility(2, -0.5_m, 0.5_m, open, AxisDirection::AxisY); + bu1 += BinUtility(2, -0.5_m, 0.5_m, open, AxisDirection::AxisZ); - BinUtility bu2(4, 1_m, 2_m, open, BinningValue::binX); - bu2 += BinUtility(2, -0.5_m, 0.5_m, open, BinningValue::binY); - bu2 += BinUtility(2, -0.5_m, 0.5_m, open, BinningValue::binZ); + BinUtility bu2(4, 1_m, 2_m, open, AxisDirection::AxisX); + bu2 += BinUtility(2, -0.5_m, 0.5_m, open, AxisDirection::AxisY); + bu2 += BinUtility(2, -0.5_m, 0.5_m, open, AxisDirection::AxisZ); - BinUtility bu3(4, 2_m, 3_m, open, BinningValue::binX); - bu3 += BinUtility(2, -0.5_m, 0.5_m, open, BinningValue::binY); - bu3 += BinUtility(2, -0.5_m, 0.5_m, open, BinningValue::binZ); + BinUtility bu3(4, 2_m, 3_m, open, AxisDirection::AxisX); + bu3 += BinUtility(2, -0.5_m, 0.5_m, open, AxisDirection::AxisY); + bu3 += BinUtility(2, -0.5_m, 0.5_m, open, AxisDirection::AxisZ); // Build a vacuum volume CuboidVolumeBuilder::VolumeConfig vCfg1; diff --git a/Tests/UnitTests/Core/Navigation/DetectorNavigatorTests.cpp b/Tests/UnitTests/Core/Navigation/DetectorNavigatorTests.cpp index 2dc5bbacdbd..c69bd100ea9 100644 --- a/Tests/UnitTests/Core/Navigation/DetectorNavigatorTests.cpp +++ b/Tests/UnitTests/Core/Navigation/DetectorNavigatorTests.cpp @@ -117,17 +117,15 @@ BOOST_AUTO_TEST_CASE(DetectorNavigatorTestsInitialization) { auto state = propagator.makeState(start, options); - navigator.initialize(state, stepper); + navigator.initialize(state.navigation, stepper.position(state.stepping), + stepper.direction(state.stepping), + state.options.direction); - navigator.preStep(state, stepper); + navigator.nextTarget(state.navigation, stepper.position(state.stepping), + stepper.direction(state.stepping)); auto preStepState = state.navigation; BOOST_CHECK_EQUAL(preStepState.currentSurface, nullptr); BOOST_CHECK_EQUAL(preStepState.currentPortal, nullptr); - - navigator.postStep(state, stepper); - auto postStepState = state.navigation; - BOOST_CHECK_EQUAL(postStepState.currentSurface, nullptr); - BOOST_CHECK_EQUAL(postStepState.currentPortal, nullptr); } // @@ -166,7 +164,10 @@ BOOST_AUTO_TEST_CASE(DetectorNavigatorTestsInitialization) { auto state = propagator.makeState(start, options); - navigator.initialize(state, stepper); + navigator.initialize(state.navigation, stepper.position(state.stepping), + stepper.direction(state.stepping), + state.options.direction); + auto initState = state.navigation; BOOST_CHECK_EQUAL(initState.currentDetector, detector.get()); BOOST_CHECK_EQUAL( @@ -232,7 +233,7 @@ BOOST_AUTO_TEST_CASE(DetectorNavigatorTestsForwardBackward) { auto portalContainer = Acts::Experimental::detail::CuboidalDetectorHelper::connect( - geoContext, detectorVolumes, Acts::BinningValue::binX, {}, + geoContext, detectorVolumes, Acts::AxisDirection::AxisX, {}, Acts::Logging::VERBOSE); // Make sure that the geometry ids are @@ -279,7 +280,7 @@ BOOST_AUTO_TEST_CASE(DetectorNavigatorTestsForwardBackward) { Acts::Logging::Level::VERBOSE)); PropagatorOptions options(geoContext, mfContext); - options.direction = Acts::Direction::Forward; + options.direction = Acts::Direction::Forward(); Propagator propagator( stepper, navigator, @@ -295,7 +296,7 @@ BOOST_AUTO_TEST_CASE(DetectorNavigatorTestsForwardBackward) { auto resultFwd = propagator.propagate(startFwd, options).value(); auto statesFwd = resultFwd.get(); - options.direction = Acts::Direction::Backward; + options.direction = Acts::Direction::Backward(); Acts::Vector4 posBwd(14, 0, 0, 0); Acts::CurvilinearTrackParameters startBwd( @@ -439,7 +440,7 @@ BOOST_AUTO_TEST_CASE(DetectorNavigatorTestsAmbiguity) { Acts::Logging::Level::VERBOSE)); PropagatorOptions options(geoContext, mfContext); - options.direction = Acts::Direction::Forward; + options.direction = Acts::Direction::Forward(); Propagator propagator( stepper, navigator, @@ -457,7 +458,7 @@ BOOST_AUTO_TEST_CASE(DetectorNavigatorTestsAmbiguity) { auto resultFwd = propagator.propagate(start, options).value(); auto statesFwd = resultFwd.get(); - options.direction = Acts::Direction::Backward; + options.direction = Acts::Direction::Backward(); auto resultBwd = propagator.propagate(start, options).value(); auto statesBwd = resultBwd.get(); @@ -554,7 +555,7 @@ BOOST_AUTO_TEST_CASE(DetectorNavigatorTestsMultipleIntersection) { Acts::Logging::Level::VERBOSE)); PropagatorOptions options(geoContext, mfContext); - options.direction = Acts::Direction::Forward; + options.direction = Acts::Direction::Forward(); Propagator propagator( stepper, navigator, @@ -572,7 +573,7 @@ BOOST_AUTO_TEST_CASE(DetectorNavigatorTestsMultipleIntersection) { auto resultFwd = propagator.propagate(startFwd, options).value(); auto statesFwd = resultFwd.get(); - options.direction = Acts::Direction::Backward; + options.direction = Acts::Direction::Backward(); Acts::Vector4 posBwd(5, 0, 0, 0); Acts::CurvilinearTrackParameters startBwd( posBwd, 0_degree, 90_degree, 1_e / 1_GeV, std::nullopt, diff --git a/Tests/UnitTests/Core/Navigation/DetectorVolumeFindersTests.cpp b/Tests/UnitTests/Core/Navigation/DetectorVolumeFindersTests.cpp index 1b6d423ed75..83ed81e5d56 100644 --- a/Tests/UnitTests/Core/Navigation/DetectorVolumeFindersTests.cpp +++ b/Tests/UnitTests/Core/Navigation/DetectorVolumeFindersTests.cpp @@ -19,7 +19,7 @@ #include "Acts/Navigation/InternalNavigation.hpp" #include "Acts/Navigation/NavigationState.hpp" #include "Acts/Utilities/Axis.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/BinningType.hpp" #include "Acts/Utilities/Grid.hpp" @@ -131,7 +131,7 @@ BOOST_AUTO_TEST_CASE(IndexedDetectorVolumeFinder) { g.atPosition(std::array{150.}) = 2u; Acts::Experimental::IndexedDetectorVolumesImpl idv( - std::move(g), {Acts::BinningValue::binR}); + std::move(g), {Acts::AxisDirection::AxisR}); // Cylinder 0 nState.position = Acts::Vector3(5., 0., 0.); diff --git a/Tests/UnitTests/Core/Navigation/MultiWireNavigationTests.cpp b/Tests/UnitTests/Core/Navigation/MultiWireNavigationTests.cpp index dbf40914e27..ccce81a5b62 100644 --- a/Tests/UnitTests/Core/Navigation/MultiWireNavigationTests.cpp +++ b/Tests/UnitTests/Core/Navigation/MultiWireNavigationTests.cpp @@ -76,9 +76,9 @@ BOOST_AUTO_TEST_CASE(Navigation_in_Indexed_Surfaces) { mlCfg.mlSurfaces = strawSurfaces; mlCfg.mlBinning = { - ProtoBinning(Acts::BinningValue::binX, Acts::AxisBoundaryType::Bound, + ProtoBinning(Acts::AxisDirection::AxisX, Acts::AxisBoundaryType::Bound, -vBounds[0], vBounds[0], nSurfacesX, 1u), - ProtoBinning(Acts::BinningValue::binY, Acts::AxisBoundaryType::Bound, + ProtoBinning(Acts::AxisDirection::AxisY, Acts::AxisBoundaryType::Bound, -vBounds[1], vBounds[1], nSurfacesY, 0u)}; mlCfg.mlBounds = vBounds; diff --git a/Tests/UnitTests/Core/Navigation/NavigationStateUpdatersTests.cpp b/Tests/UnitTests/Core/Navigation/NavigationStateUpdatersTests.cpp index 93996bcae07..8f0eaefca4a 100644 --- a/Tests/UnitTests/Core/Navigation/NavigationStateUpdatersTests.cpp +++ b/Tests/UnitTests/Core/Navigation/NavigationStateUpdatersTests.cpp @@ -13,7 +13,7 @@ #include "Acts/Navigation/NavigationState.hpp" #include "Acts/Navigation/NavigationStateFillers.hpp" #include "Acts/Navigation/NavigationStateUpdaters.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/BinningType.hpp" #include "Acts/Utilities/IAxis.hpp" @@ -268,7 +268,7 @@ BOOST_AUTO_TEST_CASE(AllPortalsGrid1DSurfaces) { Acts::Experimental::IndexedSurfacesExtractor, Acts::Experimental::SurfacesFiller>; auto grid1DSurfaces = - Grid1DSurfacesProvider(std::move(grid), {Acts::BinningValue::binR}); + Grid1DSurfacesProvider(std::move(grid), {Acts::AxisDirection::AxisR}); auto allPortalsGrid1DSurfaces = Acts::Experimental::ChainedNavigation< Acts::Experimental::IInternalNavigation, AllPortalsProvider, @@ -295,7 +295,8 @@ BOOST_AUTO_TEST_CASE(AllPortalsGrid2DSurfaces) { Acts::Experimental::IndexedSurfacesExtractor, Acts::Experimental::SurfacesFiller>; auto grid2DSurfaces = Grid2DSurfacesProvider( - std::move(grid), {Acts::BinningValue::binR, Acts::BinningValue::binZ}); + std::move(grid), + {Acts::AxisDirection::AxisR, Acts::AxisDirection::AxisZ}); auto allPortalsGrid2DSurfaces = Acts::Experimental::ChainedNavigation< Acts::Experimental::IInternalNavigation, AllPortalsProvider, diff --git a/Tests/UnitTests/Core/Navigation/PortalNavigationTests.cpp b/Tests/UnitTests/Core/Navigation/PortalNavigationTests.cpp index 30836c9396e..822a5d949dc 100644 --- a/Tests/UnitTests/Core/Navigation/PortalNavigationTests.cpp +++ b/Tests/UnitTests/Core/Navigation/PortalNavigationTests.cpp @@ -76,7 +76,7 @@ BOOST_AUTO_TEST_CASE(VolumeArrayUpdate) { std::vector volumes = { volumeA.get(), volumeB.get(), volumeC.get(), volumeD.get()}; Acts::Experimental::BoundVolumesGrid1Navigation bvg( - zArray, Acts::BinningValue::binZ, volumes); + zArray, Acts::AxisDirection::AxisZ, volumes); // Reset the navigation state nState.currentVolume = nullptr; @@ -94,7 +94,7 @@ BOOST_AUTO_TEST_CASE(VolumeArrayUpdate) { shift300.pretranslate(Acts::Vector3(0, 0, 300)); Acts::Experimental::BoundVolumesGrid1Navigation bvgs( - zArray, Acts::BinningValue::binZ, volumes, shift300.inverse()); + zArray, Acts::AxisDirection::AxisZ, volumes, shift300.inverse()); // 150 (-300) -> transforms to -150, hence it yields A nState.position = Acts::Vector3(0., 0., 150.); diff --git a/Tests/UnitTests/Core/Propagator/AtlasStepperTests.cpp b/Tests/UnitTests/Core/Propagator/AtlasStepperTests.cpp index f7bdbe1e6b0..a5dc3ecc331 100644 --- a/Tests/UnitTests/Core/Propagator/AtlasStepperTests.cpp +++ b/Tests/UnitTests/Core/Propagator/AtlasStepperTests.cpp @@ -64,7 +64,7 @@ struct MockPropagatorState { Stepper::State stepping; /// Propagator options with only the relevant components. struct { - Direction direction = Direction::Backward; + Direction direction = Direction::Backward(); struct { double stepTolerance = 10_um; } stepping; @@ -80,7 +80,7 @@ static constexpr auto eps = 1024 * std::numeric_limits::epsilon(); // propagation settings static constexpr auto stepSize = 10_mm; -static constexpr Direction navDir = Direction::Backward; +static constexpr Direction navDir = Direction::Backward(); static auto magneticField = std::make_shared(Vector3(0.1_T, -0.2_T, 2_T)); @@ -404,7 +404,7 @@ BOOST_AUTO_TEST_CASE(Reset) { particleHypothesis); FreeVector freeParams = transformBoundToFreeParameters( cp.referenceSurface(), geoCtx, cp.parameters()); - Direction navDir = Direction::Forward; + Direction navDir = Direction::Forward(); double stepSize = -256.; auto copyState = [&](auto& field, const auto& other) { @@ -585,11 +585,11 @@ BOOST_AUTO_TEST_CASE(StepSize) { Stepper::State state = stepper.makeState(options, cp); - stepper.updateStepSize(state, -5_cm, ConstrainedStep::actor, true); + stepper.updateStepSize(state, -5_cm, ConstrainedStep::Type::Navigator); BOOST_CHECK_EQUAL(state.previousStepSize, stepSize); BOOST_CHECK_EQUAL(state.stepSize.value(), -5_cm); - stepper.releaseStepSize(state, ConstrainedStep::actor); + stepper.releaseStepSize(state, ConstrainedStep::Type::Navigator); BOOST_CHECK_EQUAL(state.stepSize.value(), stepSize); } @@ -609,10 +609,11 @@ BOOST_AUTO_TEST_CASE(StepSizeSurface) { auto target = CurvilinearSurface(pos + navDir * distance * unitDir, unitDir) .planeSurface(); - stepper.updateSurfaceStatus(state, *target, 0, navDir, - BoundaryTolerance::Infinite(), - s_onSurfaceTolerance); - BOOST_CHECK_EQUAL(state.stepSize.value(ConstrainedStep::actor), distance); + stepper.updateSurfaceStatus( + state, *target, 0, navDir, BoundaryTolerance::Infinite(), + s_onSurfaceTolerance, ConstrainedStep::Type::Navigator); + BOOST_CHECK_EQUAL(state.stepSize.value(ConstrainedStep::Type::Navigator), + distance); // test the step size modification in the context of a surface stepper.updateStepSize(state, @@ -621,18 +622,19 @@ BOOST_AUTO_TEST_CASE(StepSizeSurface) { navDir * stepper.direction(state), BoundaryTolerance::Infinite()) .closest(), - navDir, false); + navDir, ConstrainedStep::Type::Navigator); BOOST_CHECK_EQUAL(state.stepSize.value(), distance); // start with a different step size state.stepSize.setUser(navDir * stepSize); + stepper.releaseStepSize(state, ConstrainedStep::Type::Navigator); stepper.updateStepSize(state, target ->intersect(geoCtx, stepper.position(state), navDir * stepper.direction(state), BoundaryTolerance::Infinite()) .closest(), - navDir, true); + navDir, ConstrainedStep::Type::Navigator); BOOST_CHECK_EQUAL(state.stepSize.value(), navDir * stepSize); } diff --git a/Tests/UnitTests/Core/Propagator/ConstrainedStepTests.cpp b/Tests/UnitTests/Core/Propagator/ConstrainedStepTests.cpp index ecbcf32054f..a766b950837 100644 --- a/Tests/UnitTests/Core/Propagator/ConstrainedStepTests.cpp +++ b/Tests/UnitTests/Core/Propagator/ConstrainedStepTests.cpp @@ -22,11 +22,11 @@ BOOST_AUTO_TEST_CASE(ConstrainedStepTest) { // All of the types should be 0.25 now BOOST_CHECK_EQUAL(stepSize_p.accuracy(), std::numeric_limits::max()); - BOOST_CHECK_EQUAL(stepSize_p.value(ConstrainedStep::actor), + BOOST_CHECK_EQUAL(stepSize_p.value(ConstrainedStep::Type::Navigator), std::numeric_limits::max()); - BOOST_CHECK_EQUAL(stepSize_p.value(ConstrainedStep::aborter), + BOOST_CHECK_EQUAL(stepSize_p.value(ConstrainedStep::Type::Actor), std::numeric_limits::max()); - BOOST_CHECK_EQUAL(stepSize_p.value(ConstrainedStep::user), 0.25); + BOOST_CHECK_EQUAL(stepSize_p.value(ConstrainedStep::Type::User), 0.25); // Check the cast operation to double BOOST_CHECK_EQUAL(stepSize_p.value(), 0.25); @@ -36,18 +36,19 @@ BOOST_AUTO_TEST_CASE(ConstrainedStepTest) { BOOST_CHECK_EQUAL(stepSize_p.value(), 0.1); // now we update the actor to smaller - stepSize_p.update(0.05, ConstrainedStep::actor); + stepSize_p.update(0.05, ConstrainedStep::Type::Navigator); BOOST_CHECK_EQUAL(stepSize_p.value(), 0.05); // we increase the actor, but do not release the step size - stepSize_p.update(0.15, ConstrainedStep::actor, false); + stepSize_p.update(0.15, ConstrainedStep::Type::Navigator); BOOST_CHECK_EQUAL(stepSize_p.value(), 0.05); // we increase the actor, but now DO release the step size // it falls back to the accuracy - stepSize_p.update(0.15, ConstrainedStep::actor, true); + stepSize_p.release(ConstrainedStep::Type::Navigator); + stepSize_p.update(0.15, ConstrainedStep::Type::Navigator); BOOST_CHECK_EQUAL(stepSize_p.value(), 0.1); // now set two and update them - stepSize_p.update(0.05, ConstrainedStep::user); + stepSize_p.update(0.05, ConstrainedStep::Type::User); stepSize_p.setAccuracy(0.03); BOOST_CHECK_EQUAL(stepSize_p.value(), 0.03); diff --git a/Tests/UnitTests/Core/Propagator/EigenStepperTests.cpp b/Tests/UnitTests/Core/Propagator/EigenStepperTests.cpp index d4197d7f61c..33ff3a68f29 100644 --- a/Tests/UnitTests/Core/Propagator/EigenStepperTests.cpp +++ b/Tests/UnitTests/Core/Propagator/EigenStepperTests.cpp @@ -86,7 +86,7 @@ struct PropState { stepper_state_t stepping; /// Propagator options which only carry the relevant components struct { - Direction direction = Direction::Forward; + Direction direction = Direction::Forward(); struct { double stepTolerance = 1e-4; double stepSizeCutOff = 0.; @@ -226,7 +226,7 @@ BOOST_AUTO_TEST_CASE(eigen_stepper_state_test) { /// The numerical correctness of the stepper is tested in the integration tests BOOST_AUTO_TEST_CASE(eigen_stepper_test) { // Set up some variables for the state - Direction navDir = Direction::Backward; + Direction navDir = Direction::Backward(); double stepSize = 123.; auto bField = std::make_shared(Vector3(1., 2.5, 33.33)); auto bCache = bField->makeCache(mfContext); @@ -260,11 +260,11 @@ BOOST_AUTO_TEST_CASE(eigen_stepper_test) { // Step size modifies const std::string originalStepSize = esState.stepSize.toString(); - es.updateStepSize(esState, -1337., ConstrainedStep::actor, true); + es.updateStepSize(esState, -1337., ConstrainedStep::Type::Navigator); BOOST_CHECK_EQUAL(esState.previousStepSize, stepSize); BOOST_CHECK_EQUAL(esState.stepSize.value(), -1337.); - es.releaseStepSize(esState, ConstrainedStep::actor); + es.releaseStepSize(esState, ConstrainedStep::Type::Navigator); BOOST_CHECK_EQUAL(esState.stepSize.value(), stepSize); BOOST_CHECK_EQUAL(es.outputStepSize(esState), originalStepSize); @@ -338,7 +338,7 @@ BOOST_AUTO_TEST_CASE(eigen_stepper_test) { ParticleHypothesis::pion()); FreeVector freeParams = transformBoundToFreeParameters( cp2.referenceSurface(), tgContext, cp2.parameters()); - navDir = Direction::Forward; + navDir = Direction::Forward(); double stepSize2 = -2. * stepSize; auto copyState = [&](auto& field, const auto& state) { @@ -449,9 +449,10 @@ BOOST_AUTO_TEST_CASE(eigen_stepper_test) { auto targetSurface = CurvilinearSurface(pos + navDir * 2. * dir, dir).planeSurface(); es.updateSurfaceStatus(esState, *targetSurface, 0, navDir, - BoundaryTolerance::Infinite(), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(esState.stepSize.value(ConstrainedStep::actor), navDir * 2., - eps); + BoundaryTolerance::Infinite(), s_onSurfaceTolerance, + ConstrainedStep::Type::Navigator); + CHECK_CLOSE_ABS(esState.stepSize.value(ConstrainedStep::Type::Navigator), + navDir * 2., eps); // Test the step size modification in the context of a surface es.updateStepSize(esState, @@ -460,16 +461,17 @@ BOOST_AUTO_TEST_CASE(eigen_stepper_test) { navDir * es.direction(esState), BoundaryTolerance::Infinite()) .closest(), - navDir); + navDir, ConstrainedStep::Type::Navigator); CHECK_CLOSE_ABS(esState.stepSize.value(), 2., eps); esState.stepSize.setUser(navDir * stepSize); + es.releaseStepSize(esState, ConstrainedStep::Type::Navigator); es.updateStepSize(esState, targetSurface ->intersect(tgContext, es.position(esState), navDir * es.direction(esState), BoundaryTolerance::Infinite()) .closest(), - navDir); + navDir, ConstrainedStep::Type::Navigator); CHECK_CLOSE_ABS(esState.stepSize.value(), 2., eps); // Test the bound state construction diff --git a/Tests/UnitTests/Core/Propagator/LoopProtectionTests.cpp b/Tests/UnitTests/Core/Propagator/LoopProtectionTests.cpp index ecb3fab014b..a7a3503d006 100644 --- a/Tests/UnitTests/Core/Propagator/LoopProtectionTests.cpp +++ b/Tests/UnitTests/Core/Propagator/LoopProtectionTests.cpp @@ -95,7 +95,7 @@ struct Options { double pathLimit = std::numeric_limits::max(); bool loopProtection = true; double loopFraction = 0.5; - Direction direction = Direction::Forward; + Direction direction = Direction::Forward(); bool debug = false; std::string debugString; diff --git a/Tests/UnitTests/Core/Propagator/MaterialCollectionTests.cpp b/Tests/UnitTests/Core/Propagator/MaterialCollectionTests.cpp index e7f8f70080c..4d25392f9e1 100644 --- a/Tests/UnitTests/Core/Propagator/MaterialCollectionTests.cpp +++ b/Tests/UnitTests/Core/Propagator/MaterialCollectionTests.cpp @@ -135,7 +135,7 @@ void runTest(const propagator_t& prop, Options bwdOptions(tgContext, mfContext); bwdOptions.stepping.maxStepSize = 25_cm; bwdOptions.pathLimit = -25_cm; - bwdOptions.direction = Direction::Backward; + bwdOptions.direction = Direction::Backward(); // get the material collector and configure it auto& bwdMaterialInteractor = @@ -266,7 +266,7 @@ void runTest(const propagator_t& prop, Options bwdStepOptions(tgContext, mfContext); bwdStepOptions.stepping.maxStepSize = 25_cm; bwdStepOptions.pathLimit = -25_cm; - bwdStepOptions.direction = Direction::Backward; + bwdStepOptions.direction = Direction::Backward(); // get the material collector and configure it auto& bwdStepMaterialInteractor = diff --git a/Tests/UnitTests/Core/Propagator/MultiStepperTests.cpp b/Tests/UnitTests/Core/Propagator/MultiStepperTests.cpp index a1d4c89fdc5..992e39c8d2e 100644 --- a/Tests/UnitTests/Core/Propagator/MultiStepperTests.cpp +++ b/Tests/UnitTests/Core/Propagator/MultiStepperTests.cpp @@ -67,7 +67,7 @@ using MultiStepperLoop = MultiEigenStepperLoop; using SingleStepper = EigenStepper; const double defaultStepSize = 123.; -const auto defaultNDir = Direction::Backward; +const auto defaultNDir = Direction::Backward(); const auto defaultBField = std::make_shared(Vector3(1., 2.5, 33.33)); @@ -507,8 +507,9 @@ void test_multi_stepper_surface_status_update() { // Update surface status and check { auto status = multi_stepper.updateSurfaceStatus( - multi_state, *right_surface, 0, Direction::Forward, - BoundaryTolerance::Infinite(), s_onSurfaceTolerance); + multi_state, *right_surface, 0, Direction::Forward(), + BoundaryTolerance::Infinite(), s_onSurfaceTolerance, + ConstrainedStep::Type::Navigator); BOOST_CHECK_EQUAL(status, IntersectionStatus::reachable); @@ -525,19 +526,20 @@ void test_multi_stepper_surface_status_update() { // Step forward now { - auto multi_prop_state = DummyPropState(Direction::Forward, multi_state); + auto multi_prop_state = DummyPropState(Direction::Forward(), multi_state); multi_stepper.step(multi_prop_state, mockNavigator); // Single stepper - auto single_prop_state = DummyPropState(Direction::Forward, single_state); + auto single_prop_state = DummyPropState(Direction::Forward(), single_state); single_stepper.step(single_prop_state, mockNavigator); } // Update surface status and check again { auto status = multi_stepper.updateSurfaceStatus( - multi_state, *right_surface, 0, Direction::Forward, - BoundaryTolerance::Infinite(), s_onSurfaceTolerance); + multi_state, *right_surface, 0, Direction::Forward(), + BoundaryTolerance::Infinite(), s_onSurfaceTolerance, + ConstrainedStep::Type::Navigator); BOOST_CHECK_EQUAL(status, IntersectionStatus::onSurface); @@ -552,8 +554,9 @@ void test_multi_stepper_surface_status_update() { // Start surface should be reachable { auto status = multi_stepper.updateSurfaceStatus( - multi_state, *start_surface, 0, Direction::Forward, - BoundaryTolerance::Infinite(), s_onSurfaceTolerance); + multi_state, *start_surface, 0, Direction::Forward(), + BoundaryTolerance::Infinite(), s_onSurfaceTolerance, + ConstrainedStep::Type::Navigator); BOOST_CHECK_EQUAL(status, IntersectionStatus::reachable); @@ -621,16 +624,18 @@ void test_component_bound_state() { // Step forward now { multi_stepper.updateSurfaceStatus( - multi_state, *right_surface, 0, Direction::Forward, - BoundaryTolerance::Infinite(), s_onSurfaceTolerance); - auto multi_prop_state = DummyPropState(Direction::Forward, multi_state); + multi_state, *right_surface, 0, Direction::Forward(), + BoundaryTolerance::Infinite(), s_onSurfaceTolerance, + ConstrainedStep::Type::Navigator); + auto multi_prop_state = DummyPropState(Direction::Forward(), multi_state); multi_stepper.step(multi_prop_state, mockNavigator); // Single stepper single_stepper.updateSurfaceStatus( - single_state, *right_surface, 0, Direction::Forward, - BoundaryTolerance::Infinite(), s_onSurfaceTolerance); - auto single_prop_state = DummyPropState(Direction::Forward, single_state); + single_state, *right_surface, 0, Direction::Forward(), + BoundaryTolerance::Infinite(), s_onSurfaceTolerance, + ConstrainedStep::Type::Navigator); + auto single_prop_state = DummyPropState(Direction::Forward(), single_state); single_stepper.step(single_prop_state, mockNavigator); } diff --git a/Tests/UnitTests/Core/Propagator/NavigatorTests.cpp b/Tests/UnitTests/Core/Propagator/NavigatorTests.cpp index 5be6d28382c..7fe511136bc 100644 --- a/Tests/UnitTests/Core/Propagator/NavigatorTests.cpp +++ b/Tests/UnitTests/Core/Propagator/NavigatorTests.cpp @@ -10,42 +10,25 @@ #include #include "Acts/Definitions/Algebra.hpp" -#include "Acts/Definitions/Common.hpp" #include "Acts/Definitions/Direction.hpp" #include "Acts/Definitions/Tolerance.hpp" -#include "Acts/Definitions/TrackParametrization.hpp" #include "Acts/Definitions/Units.hpp" -#include "Acts/EventData/GenericBoundTrackParameters.hpp" -#include "Acts/EventData/TrackParameters.hpp" #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/TrackingGeometry.hpp" #include "Acts/Geometry/TrackingVolume.hpp" #include "Acts/MagneticField/ConstantBField.hpp" -#include "Acts/Propagator/ConstrainedStep.hpp" +#include "Acts/Propagator/NavigationTarget.hpp" #include "Acts/Propagator/Navigator.hpp" -#include "Acts/Propagator/StepperConcept.hpp" -#include "Acts/Propagator/detail/SteppingHelper.hpp" -#include "Acts/Surfaces/BoundaryTolerance.hpp" #include "Acts/Surfaces/PerigeeSurface.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Tests/CommonHelpers/CylindricalTrackingGeometry.hpp" #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp" #include "Acts/Utilities/Intersection.hpp" #include "Acts/Utilities/Logger.hpp" -#include "Acts/Utilities/Result.hpp" #include -#include #include #include -#include -#include -#include - -namespace Acts { -class Layer; -struct FreeToBoundCorrection; -} // namespace Acts namespace bdata = boost::unit_test::data; using namespace Acts::UnitLiterals; @@ -57,218 +40,17 @@ namespace Acts::Test { GeometryContext tgContext = GeometryContext(); MagneticFieldContext mfContext = MagneticFieldContext(); -/// This is a simple cache struct to mimic the -/// Propagator cache -struct PropagatorState { - /// This is a simple cache struct to mimic a Stepper - struct Stepper { - // comply with concept - using Jacobian = BoundMatrix; - using Covariance = BoundSquareMatrix; - using BoundState = std::tuple; - using CurvilinearState = - std::tuple; - using BField = int; - - template - using return_parameter_type = void; - - struct Options { - const GeometryContext& geoContext = tgContext; - }; - - /// This is a simple cache struct to mimic the - /// Stepper cache in the propagation - struct State { - Options options{}; - - /// Position - Vector4 pos4 = Vector4(0., 0., 0., 0.); - - /// Direction - Vector3 dir = Vector3(1., 0., 0.); - - /// Momentum - double p = 0; - - /// Charge - double q = 0; - - /// Particle hypothesis - ParticleHypothesis particleHypothesis = ParticleHypothesis::pion(); - - // accummulated path length cache - double pathAccumulated = 0.; - - // adaptive sep size of the runge-kutta integration - ConstrainedStep stepSize = ConstrainedStep(100_cm); - - // Previous step size for overstep estimation (ignored here) - double previousStepSize = 0.; - - GeometryContext geoContext = GeometryContext(); - }; - - /// State resetter - void resetState(State& /*state*/, const BoundVector& /*boundParams*/, - const BoundSquareMatrix& /*cov*/, - const Surface& /*surface*/, - const double /*stepSize*/) const {} - - /// Global particle position accessor - Vector3 position(const State& state) const { - return state.pos4.segment<3>(Acts::ePos0); - } - - /// Time access - double time(const State& state) const { return state.pos4[Acts::eTime]; } - - /// Momentum direction accessor - Vector3 direction(const State& state) const { return state.dir; } - - /// QoP accessor - double qOverP(const State& state) const { - return (state.q == 0 ? 1 : state.q) / state.p; - } - - /// Absolute momentum accessor - double absoluteMomentum(const State& state) const { return state.p; } - - /// Momentum accessor - Vector3 momentum(const State& state) const { return state.p * state.dir; } - - /// Charge access - double charge(const State& state) const { return state.q; } - - /// Overstep limit access - double overstepLimit(const State& /*state*/) const { - return s_onSurfaceTolerance; - } - - IntersectionStatus updateSurfaceStatus( - State& state, const Surface& surface, std::uint8_t index, - Direction navDir, const BoundaryTolerance& boundaryTolerance, - double surfaceTolerance, const Logger& logger) const { - return detail::updateSingleSurfaceStatus( - *this, state, surface, index, navDir, boundaryTolerance, - surfaceTolerance, logger); - } - - template - void updateStepSize(State& state, - const object_intersection_t& oIntersection, - Direction /*direction*/, bool release = true) const { - detail::updateSingleStepSize(state, oIntersection, release); - } - - void updateStepSize(State& state, double stepSize, - ConstrainedStep::Type stype, - bool release = true) const { - state.previousStepSize = state.stepSize.value(); - state.stepSize.update(stepSize, stype, release); - } - - double getStepSize(const State& state, ConstrainedStep::Type stype) const { - return state.stepSize.value(stype); - } - - void releaseStepSize(State& state, ConstrainedStep::Type stype) const { - state.stepSize.release(stype); - } - - std::string outputStepSize(const State& state) const { - return state.stepSize.toString(); - } - - Result boundState( - State& state, const Surface& surface, bool /*transportCov*/, - const FreeToBoundCorrection& /*freeToBoundCorrection*/ - ) const { - auto bound = BoundTrackParameters::create( - surface.getSharedPtr(), tgContext, state.pos4, state.dir, - state.q / state.p, std::nullopt, state.particleHypothesis); - if (!bound.ok()) { - return bound.error(); - } - BoundState bState{std::move(*bound), Jacobian::Identity(), - state.pathAccumulated}; - return bState; - } - - CurvilinearState curvilinearState(State& state, bool /*transportCov*/ - ) const { - CurvilinearTrackParameters parameters(state.pos4, state.dir, - state.q / state.p, std::nullopt, - state.particleHypothesis); - // Create the bound state - CurvilinearState curvState{std::move(parameters), Jacobian::Identity(), - state.pathAccumulated}; - return curvState; - } - - void update(State& /*state*/, const FreeVector& /*freePars*/, - const BoundVector& /*boundPars*/, const Covariance& /*cov*/, - const Surface& /*surface*/) const {} - - void update(State& /*state*/, const Vector3& /*uposition*/, - const Vector3& /*udirection*/, double /*up*/, - double /*time*/) const {} - - void transportCovarianceToCurvilinear(State& /*state*/) const {} - - void transportCovarianceToBound( - State& /*state*/, const Surface& /*surface*/, - const FreeToBoundCorrection& /*freeToBoundCorrection*/) const {} - - Result getField(State& /*state*/, const Vector3& /*pos*/) const { - // get the field from the cell - return Result::success({0., 0., 0.}); - } - }; - - static_assert(StepperConcept, - "Dummy stepper does not fulfill concept"); - - /// emulate the options template - struct Options { - Direction direction = Direction::Forward; - - const Acts::Logger& logger = Acts::getDummyLogger(); - - double surfaceTolerance = s_onSurfaceTolerance; - }; - - /// Navigation cache: the start surface - const Surface* startSurface = nullptr; - - /// Navigation cache: the current surface - const Surface* currentSurface = nullptr; - - /// Navigation cache: the target surface - const Surface* targetSurface = nullptr; - bool targetReached = false; - - /// Give some options - Options options; - - /// The Stepper state - internal state of the Stepper - Stepper::State stepping; - - /// Navigation state - internal state of the Navigator - Navigator::State navigation; - - // The context cache for this propagation - GeometryContext geoContext = GeometryContext(); -}; - -template -void step(stepper_state_t& sstate) { - // update the cache position - sstate.pos4[Acts::ePos0] += sstate.stepSize.value() * sstate.dir[Acts::eMom0]; - sstate.pos4[Acts::ePos1] += sstate.stepSize.value() * sstate.dir[Acts::eMom1]; - sstate.pos4[Acts::ePos2] += sstate.stepSize.value() * sstate.dir[Acts::eMom2]; - // create navigation parameters - return; +void step(Vector3& pos, const Vector3& dir, double stepSize) { + pos += stepSize * dir; +} + +void step(Vector3& pos, const Vector3& dir, const Surface& surface) { + auto intersection = surface.intersect(tgContext, pos, dir).closestForward(); + step(pos, dir, intersection.pathLength()); +} + +void step(Vector3& pos, const Vector3& dir, const NavigationTarget& target) { + step(pos, dir, *target.surface); } /// @brief Method for testing vectors in @c Navigator::State @@ -288,30 +70,37 @@ bool testNavigatorStateVectors(Navigator::State& state, std::size_t navSurf, /// @brief Method for testing pointers in @c Navigator::State /// /// @param [in] state Navigation state -/// @param [in] worldVol World volume /// @param [in] startVol Start volume /// @param [in] startLay Start layer /// @param [in] startSurf Start surface /// @param [in] currSurf Current surface /// @param [in] currVol Current volume -/// @param [in] targetVol Target volume -/// @param [in] targetLay Target layer /// @param [in] targetSurf Target surface bool testNavigatorStatePointers(Navigator::State& state, - const TrackingVolume* worldVol, const TrackingVolume* startVol, const Layer* startLay, const Surface* startSurf, const Surface* currSurf, const TrackingVolume* currVol, const Surface* targetSurf) { - return ((state.worldVolume == worldVol) && (state.startVolume == startVol) && - (state.startLayer == startLay) && (state.startSurface == startSurf) && - (state.currentSurface == currSurf) && - (state.currentVolume == currVol) && - (state.targetSurface == targetSurf)); + std::cout << "startVol: " << startVol << " startLay: " << startLay + << " startSurf: " << startSurf << " currSurf: " << currSurf + << " currVol: " << currVol << " targetSurf: " << targetSurf + << std::endl; + + std::cout << "state.startVolume: " << state.startVolume + << " state.startLayer: " << state.startLayer + << " state.startSurface: " << state.startSurface + << " state.currentSurface: " << state.currentSurface + << " state.currentVolume: " << state.currentVolume + << " state.targetSurface: " << state.targetSurface << std::endl; + + return ( + (state.startVolume == startVol) && (state.startLayer == startLay) && + (state.startSurface == startSurf) && (state.currentSurface == currSurf) && + (state.currentVolume == currVol) && (state.targetSurface == targetSurf)); } -// the surface cache & the creation of the geometry +// the surface cache & the creation of the geometry CylindricalTrackingGeometry cGeometry(tgContext); auto tGeometry = cGeometry(); @@ -321,21 +110,11 @@ auto bField = std::make_shared(Vector3{0, 0, Bz}); Acts::Logging::Level logLevel = Acts::Logging::INFO; BOOST_AUTO_TEST_CASE(Navigator_status_methods) { - ACTS_LOCAL_LOGGER(Acts::getDefaultLogger("NavigatorTest", logLevel)) + ACTS_LOCAL_LOGGER(Acts::getDefaultLogger("NavigatorTest", logLevel)); // position and direction vector - Vector4 position4(0., 0., 0, 0); - Vector3 momentum(1., 1., 0); - - // the propagator cache - PropagatorState state; - - // the stepper cache - state.stepping.pos4 = position4; - state.stepping.dir = momentum.normalized(); - - // Stepper - PropagatorState::Stepper stepper; + Vector3 position = Vector3::Zero(); + Vector3 direction = Vector3(1., 1., 0).normalized(); ACTS_INFO("(1) Test for inactivity"); ACTS_INFO(" a) Run without anything present"); @@ -346,11 +125,13 @@ BOOST_AUTO_TEST_CASE(Navigator_status_methods) { navCfg.resolvePassive = false; Navigator navigator{navCfg}; - navigator.postStep(state, stepper); - BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u)); - BOOST_CHECK(testNavigatorStatePointers(state.navigation, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr)); + Navigator::Options options(tgContext); + + Navigator::State state = navigator.makeState(options); + + BOOST_CHECK(testNavigatorStateVectors(state, 0u, 0u, 0u)); + BOOST_CHECK(testNavigatorStatePointers(state, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr)); } ACTS_INFO(" b) Run with geometry but without resolving"); @@ -362,11 +143,13 @@ BOOST_AUTO_TEST_CASE(Navigator_status_methods) { navCfg.trackingGeometry = tGeometry; Navigator navigator{navCfg}; - navigator.postStep(state, stepper); - BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u)); - BOOST_CHECK(testNavigatorStatePointers(state.navigation, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr)); + Navigator::Options options(tgContext); + + Navigator::State state = navigator.makeState(options); + + BOOST_CHECK(testNavigatorStateVectors(state, 0u, 0u, 0u)); + BOOST_CHECK(testNavigatorStatePointers(state, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr)); } ACTS_INFO( @@ -380,69 +163,64 @@ BOOST_AUTO_TEST_CASE(Navigator_status_methods) { navCfg.trackingGeometry = tGeometry; Navigator navigator{navCfg}; - state.navigation.navigationBreak = true; + Navigator::Options options(tgContext); + + Navigator::State state = navigator.makeState(options); + ACTS_INFO(" i) Because target is reached"); - state.navigation.targetReached = true; - navigator.postStep(state, stepper); - BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u)); - BOOST_CHECK(testNavigatorStatePointers(state.navigation, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr)); + state.navigationBreak = true; + navigator.nextTarget(state, position, direction); + BOOST_CHECK(testNavigatorStateVectors(state, 0u, 0u, 0u)); + BOOST_CHECK(testNavigatorStatePointers(state, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr)); ACTS_INFO(" ii) Because of no target surface"); - state.navigation.targetReached = false; - state.navigation.targetSurface = nullptr; - navigator.postStep(state, stepper); - BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u)); - BOOST_CHECK(testNavigatorStatePointers(state.navigation, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr)); - ACTS_INFO(" iii) Because the target surface is reached"); + state.targetSurface = nullptr; + navigator.nextTarget(state, position, direction); + BOOST_CHECK(testNavigatorStateVectors(state, 0u, 0u, 0u)); + BOOST_CHECK(testNavigatorStatePointers(state, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr)); + ACTS_INFO(" iii) Because the target surface is reached"); auto beamline = Surface::makeShared(Vector3::Zero()); const Surface* startSurf = beamline.get(); - state.stepping.pos4.segment<3>(Acts::ePos0) = - startSurf->center(state.geoContext); - const Surface* targetSurf = startSurf; - state.navigation.targetSurface = targetSurf; - navigator.postStep(state, stepper); - BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u)); - BOOST_CHECK(testNavigatorStatePointers(state.navigation, nullptr, nullptr, - nullptr, nullptr, targetSurf, - nullptr, targetSurf)); + position = startSurf->center(tgContext); + const TrackingVolume* startVol = + tGeometry->lowestTrackingVolume(tgContext, position); + const Layer* startLay = startVol->associatedLayer(tgContext, position); + state.startSurface = startSurf; + state.targetSurface = startSurf; + navigator.initialize(state, position, direction, Direction::Forward()); + BOOST_CHECK(testNavigatorStateVectors(state, 0u, 0u, 0u)); + BOOST_CHECK(testNavigatorStatePointers(state, startVol, startLay, startSurf, + startSurf, startVol, startSurf)); ACTS_INFO("(2) Test the initialisation"); ACTS_INFO(" a) Initialise without additional information"); - state.navigation = Navigator::State(); - state.stepping.pos4 << 0., 0., 0., 0.; - const TrackingVolume* worldVol = tGeometry->highestTrackingVolume(); - const TrackingVolume* startVol = tGeometry->lowestTrackingVolume( - state.geoContext, stepper.position(state.stepping)); - const Layer* startLay = startVol->associatedLayer( - state.geoContext, stepper.position(state.stepping)); - navigator.initialize(state, stepper); - BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u)); - BOOST_CHECK(testNavigatorStatePointers(state.navigation, worldVol, startVol, - startLay, nullptr, nullptr, startVol, - nullptr)); + state = navigator.makeState(options); + position = Vector3::Zero(); + startVol = tGeometry->lowestTrackingVolume(tgContext, position); + startLay = startVol->associatedLayer(tgContext, position); + navigator.initialize(state, position, direction, Direction::Forward()); + BOOST_CHECK(testNavigatorStateVectors(state, 0u, 0u, 0u)); + BOOST_CHECK(testNavigatorStatePointers(state, startVol, startLay, nullptr, + nullptr, startVol, nullptr)); ACTS_INFO(" b) Initialise having a start surface"); - state.navigation = Navigator::State(); - state.navigation.startSurface = startSurf; - navigator.initialize(state, stepper); - BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u)); - BOOST_CHECK(testNavigatorStatePointers(state.navigation, worldVol, startVol, - startLay, startSurf, startSurf, - startVol, nullptr)); + state = navigator.makeState(options); + state.startSurface = startSurf; + navigator.initialize(state, position, direction, Direction::Forward()); + BOOST_CHECK(testNavigatorStateVectors(state, 0u, 0u, 0u)); + BOOST_CHECK(testNavigatorStatePointers(state, startVol, startLay, startSurf, + startSurf, startVol, nullptr)); ACTS_INFO(" c) Initialise having a start volume"); - state.navigation = Navigator::State(); - state.navigation.startVolume = startVol; - navigator.initialize(state, stepper); - BOOST_CHECK(testNavigatorStateVectors(state.navigation, 0u, 0u, 0u)); - BOOST_CHECK(testNavigatorStatePointers(state.navigation, worldVol, startVol, - startLay, nullptr, nullptr, startVol, - nullptr)); + state = navigator.makeState(options); + state.startVolume = startVol; + navigator.initialize(state, position, direction, Direction::Forward()); + BOOST_CHECK(testNavigatorStateVectors(state, 0u, 0u, 0u)); + BOOST_CHECK(testNavigatorStatePointers(state, startVol, startLay, nullptr, + nullptr, startVol, nullptr)); } } @@ -457,187 +235,198 @@ BOOST_AUTO_TEST_CASE(Navigator_target_methods) { navCfg.resolvePassive = false; Navigator navigator{navCfg}; - // position and direction vector - Vector4 position4(0., 0., 0, 0); - Vector3 momentum(1., 1., 0); + Navigator::Options options(tgContext); - // the propagator cache - PropagatorState state; + Navigator::State state = navigator.makeState(options); - // the stepper cache - state.stepping.pos4 = position4; - state.stepping.dir = momentum.normalized(); + // position and direction vector + Vector3 position = Vector3::Zero(); + Vector3 direction = Vector3(1., 1., 0).normalized(); // forward navigation ---------------------------------------------- ACTS_INFO("<<<<<<<<<<<<<<<<<<<<< FORWARD NAVIGATION >>>>>>>>>>>>>>>>>>"); - // Stepper - PropagatorState::Stepper stepper; - // (1) Initialization navigation from start point // - this will call resolveLayers() as well // - and thus should call a return to the stepper - navigator.initialize(state, stepper); + navigator.initialize(state, position, direction, Direction::Forward()); // Check that the currentVolume is set - BOOST_CHECK_NE(state.navigation.currentVolume, nullptr); + BOOST_CHECK_NE(state.currentVolume, nullptr); // Check that the currentVolume is the startVolume - BOOST_CHECK_EQUAL(state.navigation.currentVolume, - state.navigation.startVolume); + BOOST_CHECK_EQUAL(state.currentVolume, state.startVolume); // Check that the currentSurface is reset to: - BOOST_CHECK_EQUAL(state.navigation.currentSurface, nullptr); + BOOST_CHECK_EQUAL(state.currentSurface, nullptr); // No layer has been found - BOOST_CHECK_EQUAL(state.navigation.navLayers.size(), 0u); - // ACTORS-ABORTERS-TARGET - navigator.preStep(state, stepper); + BOOST_CHECK_EQUAL(state.navLayers.size(), 0u); + + // Estimate the next target + NavigationTarget target = navigator.nextTarget(state, position, direction); + BOOST_CHECK(!target.isNone()); // A layer has been found - BOOST_CHECK_EQUAL(state.navigation.navLayers.size(), 1u); + BOOST_CHECK_EQUAL(state.navLayers.size(), 1u); // The index should points to the begin - BOOST_CHECK_EQUAL(state.navigation.navLayerIndex, 0); + BOOST_CHECK_EQUAL(state.navLayerIndex.value(), 0); + // Check the target is correct + BOOST_CHECK_EQUAL(target.surface, state.navLayer().first.object()); + // Intersect the target + auto targetIntersection = + target.surface->intersect(tgContext, position, direction) + .closestForward(); // Cache the beam pipe radius - double beamPipeR = perp(state.navigation.navLayer().first.position()); + double beamPipeR = perp(state.navLayer().first.position()); // step size has been updated - CHECK_CLOSE_ABS(state.stepping.stepSize.value(), beamPipeR, + CHECK_CLOSE_ABS(targetIntersection.pathLength(), beamPipeR, s_onSurfaceTolerance); - ACTS_INFO("<<< Test 1a >>> initialize at " << toString(state.stepping.pos4)); + ACTS_INFO("<<< Test 1a >>> initialize at " << toString(position)); // Do the step towards the beam pipe - step(state.stepping); + step(position, direction, target); // (2) re-entering navigator: // POST STEP - navigator.postStep(state, stepper); + navigator.handleSurfaceReached(state, position, direction, *target.surface); // Check that the currentVolume is the still startVolume - BOOST_CHECK_EQUAL(state.navigation.currentVolume, - state.navigation.startVolume); + BOOST_CHECK_EQUAL(state.currentVolume, state.startVolume); // The layer number has not changed - BOOST_CHECK_EQUAL(state.navigation.navLayers.size(), 1u); + BOOST_CHECK_EQUAL(state.navLayers.size(), 1u); // The index still points to the begin - BOOST_CHECK_EQUAL(state.navigation.navLayerIndex, 0); - // ACTORS - ABORTERS - PRE STEP - navigator.preStep(state, stepper); + BOOST_CHECK_EQUAL(state.navLayerIndex.value(), 0); + + ACTS_INFO("<<< Test 1b >>> step to the BeamPipe at " << toString(position)); - ACTS_INFO("<<< Test 1b >>> step to the BeamPipe at " - << toString(state.stepping.pos4)); + // Estimate the next target + target = navigator.nextTarget(state, position, direction); + BOOST_CHECK(!target.isNone()); // Do the step towards the boundary - step(state.stepping); + step(position, direction, target); // (3) re-entering navigator: // POST STEP - navigator.postStep(state, stepper); - // ACTORS - ABORTERS - PRE STEP - navigator.preStep(state, stepper); + navigator.handleSurfaceReached(state, position, direction, *target.surface); + + ACTS_INFO("<<< Test 1c >>> step to the Boundary at " << toString(position)); - ACTS_INFO("<<< Test 1c >>> step to the Boundary at " - << toString(state.stepping.pos4)); + // Estimate the next target + target = navigator.nextTarget(state, position, direction); + BOOST_CHECK(!target.isNone()); + // Intersect the target + targetIntersection = target.surface->intersect(tgContext, position, direction) + .closestForward(); // positive return: do the step - step(state.stepping); + step(position, direction, target); + // (4) re-entering navigator: // POST STEP - navigator.postStep(state, stepper); - // ACTORS - ABORTERS - PRE STEP - navigator.preStep(state, stepper); + navigator.handleSurfaceReached(state, position, direction, *target.surface); + + ACTS_INFO("<<< Test 1d >>> step to 1st layer at " << toString(position)); - ACTS_INFO("<<< Test 1d >>> step to 1st layer at " - << toString(state.stepping.pos4)); + // Estimate the next target + target = navigator.nextTarget(state, position, direction); + BOOST_CHECK(!target.isNone()); // Step through the surfaces on first layer for (std::size_t isf = 0; isf < 5; ++isf) { - step(state.stepping); + step(position, direction, target); // (5-9) re-entering navigator: // POST STEP - navigator.postStep(state, stepper); + navigator.handleSurfaceReached(state, position, direction, *target.surface); // ACTORS - ABORTERS - PRE STEP - navigator.preStep(state, stepper); + target = navigator.nextTarget(state, position, direction); + BOOST_CHECK(!target.isNone()); ACTS_INFO("<<< Test 1e-1i >>> step within 1st layer at " - << toString(state.stepping.pos4)); + << toString(position)); } // positive return: do the step - step(state.stepping); + step(position, direction, target); // (10) re-entering navigator: // POST STEP - navigator.postStep(state, stepper); + navigator.handleSurfaceReached(state, position, direction, *target.surface); // ACTORS - ABORTERS - PRE STEP - navigator.preStep(state, stepper); + target = navigator.nextTarget(state, position, direction); + BOOST_CHECK(!target.isNone()); - ACTS_INFO("<<< Test 1j >>> step to 2nd layer at " - << toString(state.stepping.pos4)); + ACTS_INFO("<<< Test 1j >>> step to 2nd layer at " << toString(position)); // Step through the surfaces on second layer for (std::size_t isf = 0; isf < 5; ++isf) { - step(state.stepping); + step(position, direction, target); // (11-15) re-entering navigator: // POST STEP - navigator.postStep(state, stepper); + navigator.handleSurfaceReached(state, position, direction, *target.surface); // ACTORS - ABORTERS - PRE STEP - navigator.preStep(state, stepper); + target = navigator.nextTarget(state, position, direction); + BOOST_CHECK(!target.isNone()); ACTS_INFO("<<< Test 1k-1o >>> step within 2nd layer at " - << toString(state.stepping.pos4)); + << toString(position)); } // positive return: do the step - step(state.stepping); + step(position, direction, target); // (16) re-entering navigator: // POST STEP - navigator.postStep(state, stepper); + navigator.handleSurfaceReached(state, position, direction, *target.surface); // ACTORS - ABORTERS - PRE STEP - navigator.preStep(state, stepper); + target = navigator.nextTarget(state, position, direction); + BOOST_CHECK(!target.isNone()); - ACTS_INFO("<<< Test 1p >>> step to 3rd layer at " - << toString(state.stepping.pos4)); + ACTS_INFO("<<< Test 1p >>> step to 3rd layer at " << toString(position)); // Step through the surfaces on third layer for (std::size_t isf = 0; isf < 3; ++isf) { - step(state.stepping); + step(position, direction, target); // (17-19) re-entering navigator: // POST STEP - navigator.postStep(state, stepper); + navigator.handleSurfaceReached(state, position, direction, *target.surface); // ACTORS - ABORTERS - PRE STEP - navigator.preStep(state, stepper); + target = navigator.nextTarget(state, position, direction); + BOOST_CHECK(!target.isNone()); ACTS_INFO("<<< Test 1q-1s >>> step within 3rd layer at " - << toString(state.stepping.pos4)); + << toString(position)); } // positive return: do the step - step(state.stepping); + step(position, direction, target); // (20) re-entering navigator: // POST STEP - navigator.postStep(state, stepper); + navigator.handleSurfaceReached(state, position, direction, *target.surface); // ACTORS - ABORTERS - PRE STEP - navigator.preStep(state, stepper); + target = navigator.nextTarget(state, position, direction); + BOOST_CHECK(!target.isNone()); - ACTS_INFO("<<< Test 1t >>> step to 4th layer at " - << toString(state.stepping.pos4)); + ACTS_INFO("<<< Test 1t >>> step to 4th layer at " << toString(position)); // Step through the surfaces on second layer for (std::size_t isf = 0; isf < 3; ++isf) { - step(state.stepping); + step(position, direction, target); // (21-23) re-entering navigator: // POST STEP - navigator.postStep(state, stepper); + navigator.handleSurfaceReached(state, position, direction, *target.surface); // ACTORS - ABORTERS - PRE STEP - navigator.preStep(state, stepper); + target = navigator.nextTarget(state, position, direction); + BOOST_CHECK(!target.isNone()); ACTS_INFO("<<< Test 1t-1v >>> step within 4th layer at " - << toString(state.stepping.pos4)); + << toString(position)); } // positive return: do the step - step(state.stepping); + step(position, direction, target); // (24) re-entering navigator: // POST STEP - navigator.postStep(state, stepper); + navigator.handleSurfaceReached(state, position, direction, *target.surface); // ACTORS - ABORTERS - PRE STEP - navigator.preStep(state, stepper); + target = navigator.nextTarget(state, position, direction); + BOOST_CHECK(target.isNone()); - ACTS_INFO("<<< Test 1w >>> step to boundary at " - << toString(state.stepping.pos4)); + ACTS_INFO("<<< Test 1w >>> step to boundary at " << toString(position)); } } // namespace Acts::Test diff --git a/Tests/UnitTests/Core/Propagator/PropagatorTests.cpp b/Tests/UnitTests/Core/Propagator/PropagatorTests.cpp index 8ec7c11948d..a4a7df56b9d 100644 --- a/Tests/UnitTests/Core/Propagator/PropagatorTests.cpp +++ b/Tests/UnitTests/Core/Propagator/PropagatorTests.cpp @@ -25,12 +25,14 @@ #include "Acts/Propagator/EigenStepperDenseExtension.hpp" #include "Acts/Propagator/Propagator.hpp" #include "Acts/Propagator/StraightLineStepper.hpp" +#include "Acts/Propagator/VoidNavigator.hpp" #include "Acts/Surfaces/CurvilinearSurface.hpp" #include "Acts/Surfaces/CylinderBounds.hpp" #include "Acts/Surfaces/CylinderSurface.hpp" #include "Acts/Surfaces/PlaneSurface.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp" +#include "Acts/Utilities/Logger.hpp" #include "Acts/Utilities/Result.hpp" #include @@ -81,7 +83,7 @@ struct SurfaceObserver { // the surface to be intersected const Surface* surface = nullptr; // the tolerance for intersection - double tolerance = 1.e-5; + double tolerance = 1e-5; /// Simple result struct to be returned struct this_result { @@ -91,32 +93,34 @@ struct SurfaceObserver { using result_type = this_result; - SurfaceObserver() = default; - template void act(propagator_state_t& state, const stepper_t& stepper, const navigator_t& /*navigator*/, result_type& result, const Logger& /*logger*/) const { - if (surface && !result.surfaces_passed) { - // calculate the distance to the surface - const double distance = - surface - ->intersect(state.geoContext, stepper.position(state.stepping), - stepper.direction(state.stepping), - BoundaryTolerance::None()) - .closest() - .pathLength(); - // Adjust the step size so that we cannot cross the target surface - state.stepping.stepSize.update(distance * state.options.direction, - ConstrainedStep::actor); - // return true if you fall below tolerance - if (std::abs(distance) <= tolerance) { - ++result.surfaces_passed; - result.surface_passed_r = perp(stepper.position(state.stepping)); - // release the step size, will be re-adjusted - state.stepping.stepSize.release(ConstrainedStep::actor); - } + if (surface == nullptr || result.surfaces_passed != 0) { + return; + } + + // calculate the distance to the surface + const double distance = + surface + ->intersect(state.geoContext, stepper.position(state.stepping), + stepper.direction(state.stepping), + BoundaryTolerance::None()) + .closest() + .pathLength(); + + // Adjust the step size so that we cannot cross the target surface + state.stepping.stepSize.release(ConstrainedStep::Type::Actor); + state.stepping.stepSize.update(distance * state.options.direction, + ConstrainedStep::Type::Actor); + + // return true if you fall below tolerance + if (std::abs(distance) <= tolerance) { + ++result.surfaces_passed; + result.surface_passed_r = perp(stepper.position(state.stepping)); + state.stepping.stepSize.release(ConstrainedStep::Type::Actor); } } }; @@ -129,7 +133,8 @@ using EigenPropagatorType = Propagator; const double Bz = 2_T; auto bField = std::make_shared(Vector3{0, 0, Bz}); EigenStepperType estepper(bField); -EigenPropagatorType epropagator(std::move(estepper)); +EigenPropagatorType epropagator(std::move(estepper), VoidNavigator(), + getDefaultLogger("prop", Logging::VERBOSE)); auto mCylinder = std::make_shared(10_mm, 1000_mm); auto mSurface = @@ -398,14 +403,14 @@ BOOST_AUTO_TEST_CASE(BasicPropagatorInterface) { MagneticFieldContext mctx; { + EigenPropagatorType::Options<> options{gctx, mctx}; + Propagator propagator{eigenStepper, navigator}; static_assert(std::is_base_of_v, "Propagator does not inherit from BasePropagator"); const BasePropagator* base = static_cast(&propagator); - EigenPropagatorType::Options<> options{gctx, mctx}; - // Ensure the propagation does the same thing auto result = propagator.propagate(startParameters, *targetSurface, options); @@ -431,14 +436,14 @@ BOOST_AUTO_TEST_CASE(BasicPropagatorInterface) { StraightLineStepper slStepper{}; { + Propagator::Options<> options{gctx, mctx}; + Propagator propagator{slStepper, navigator}; static_assert(std::is_base_of_v, "Propagator does not inherit from BasePropagator"); const BasePropagator* base = static_cast(&propagator); - Propagator::Options<> options{gctx, mctx}; - // Ensure the propagation does the same thing auto result = propagator.propagate(startParameters, *targetSurface, options); diff --git a/Tests/UnitTests/Core/Propagator/StraightLineStepperTests.cpp b/Tests/UnitTests/Core/Propagator/StraightLineStepperTests.cpp index 31697d1bb67..2a9a81e9d5c 100644 --- a/Tests/UnitTests/Core/Propagator/StraightLineStepperTests.cpp +++ b/Tests/UnitTests/Core/Propagator/StraightLineStepperTests.cpp @@ -50,7 +50,7 @@ struct PropState { StraightLineStepper::State stepping; /// Propagator options which only carry the particle's mass struct { - Direction direction = Direction::Forward; + Direction direction = Direction::Forward(); } options; }; @@ -119,7 +119,7 @@ BOOST_AUTO_TEST_CASE(straight_line_stepper_test) { // Set up some variables for the state GeometryContext tgContext = GeometryContext(); MagneticFieldContext mfContext = MagneticFieldContext(); - Direction navDir = Direction::Backward; + Direction navDir = Direction::Backward(); double stepSize = 123.; // Construct the parameters @@ -149,11 +149,11 @@ BOOST_AUTO_TEST_CASE(straight_line_stepper_test) { // Step size modifies const std::string originalStepSize = slsState.stepSize.toString(); - sls.updateStepSize(slsState, -1337., ConstrainedStep::actor, true); + sls.updateStepSize(slsState, -1337., ConstrainedStep::Type::Navigator); BOOST_CHECK_EQUAL(slsState.previousStepSize, stepSize); BOOST_CHECK_EQUAL(slsState.stepSize.value(), -1337.); - sls.releaseStepSize(slsState, ConstrainedStep::actor); + sls.releaseStepSize(slsState, ConstrainedStep::Type::Navigator); BOOST_CHECK_EQUAL(slsState.stepSize.value(), stepSize); BOOST_CHECK_EQUAL(sls.outputStepSize(slsState), originalStepSize); @@ -234,7 +234,7 @@ BOOST_AUTO_TEST_CASE(straight_line_stepper_test) { BOOST_CHECK(cp2.covariance().has_value()); FreeVector freeParams = transformBoundToFreeParameters( cp2.referenceSurface(), tgContext, cp2.parameters()); - navDir = Direction::Forward; + navDir = Direction::Forward(); double stepSize2 = -2. * stepSize; // Reset all possible parameters @@ -323,9 +323,10 @@ BOOST_AUTO_TEST_CASE(straight_line_stepper_test) { auto targetSurface = CurvilinearSurface(pos + navDir * 2. * dir, dir).planeSurface(); sls.updateSurfaceStatus(slsState, *targetSurface, 0, navDir, - BoundaryTolerance::Infinite(), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(slsState.stepSize.value(ConstrainedStep::actor), navDir * 2., - 1e-6); + BoundaryTolerance::Infinite(), s_onSurfaceTolerance, + ConstrainedStep::Type::Navigator); + CHECK_CLOSE_ABS(slsState.stepSize.value(ConstrainedStep::Type::Navigator), + navDir * 2., 1e-6); // Test the step size modification in the context of a surface sls.updateStepSize(slsState, @@ -334,16 +335,17 @@ BOOST_AUTO_TEST_CASE(straight_line_stepper_test) { navDir * sls.direction(slsState), BoundaryTolerance::Infinite()) .closest(), - navDir); + navDir, ConstrainedStep::Type::Navigator); CHECK_CLOSE_ABS(slsState.stepSize.value(), 2, 1e-6); slsState.stepSize.setUser(navDir * stepSize); + sls.releaseStepSize(slsState, ConstrainedStep::Type::Navigator); sls.updateStepSize(slsState, targetSurface ->intersect(tgContext, sls.position(slsState), navDir * sls.direction(slsState), BoundaryTolerance::Infinite()) .closest(), - navDir); + navDir, ConstrainedStep::Type::Navigator); CHECK_CLOSE_ABS(slsState.stepSize.value(), 2, 1e-6); // Test the bound state construction diff --git a/Tests/UnitTests/Core/Propagator/SympyStepperTests.cpp b/Tests/UnitTests/Core/Propagator/SympyStepperTests.cpp index 433cb8421b6..1efc0dfa0ba 100644 --- a/Tests/UnitTests/Core/Propagator/SympyStepperTests.cpp +++ b/Tests/UnitTests/Core/Propagator/SympyStepperTests.cpp @@ -65,7 +65,7 @@ struct PropState { stepper_state_t stepping; /// Propagator options which only carry the relevant components struct { - Direction direction = Direction::Forward; + Direction direction = Direction::Forward(); struct { double stepTolerance = 1e-4; double stepSizeCutOff = 0.; @@ -200,7 +200,7 @@ BOOST_AUTO_TEST_CASE(sympy_stepper_state_test) { /// The numerical correctness of the stepper is tested in the integration tests BOOST_AUTO_TEST_CASE(sympy_stepper_test) { // Set up some variables for the state - Direction navDir = Direction::Backward; + Direction navDir = Direction::Backward(); double stepSize = 123.; auto bField = std::make_shared(Vector3(1., 2.5, 33.33)); auto bCache = bField->makeCache(mfContext); @@ -234,11 +234,11 @@ BOOST_AUTO_TEST_CASE(sympy_stepper_test) { // Step size modifies const std::string originalStepSize = esState.stepSize.toString(); - es.updateStepSize(esState, -1337., ConstrainedStep::actor, true); + es.updateStepSize(esState, -1337., ConstrainedStep::Type::Navigator); BOOST_CHECK_EQUAL(esState.previousStepSize, stepSize); BOOST_CHECK_EQUAL(esState.stepSize.value(), -1337.); - es.releaseStepSize(esState, ConstrainedStep::actor); + es.releaseStepSize(esState, ConstrainedStep::Type::Navigator); BOOST_CHECK_EQUAL(esState.stepSize.value(), stepSize); BOOST_CHECK_EQUAL(es.outputStepSize(esState), originalStepSize); @@ -312,7 +312,7 @@ BOOST_AUTO_TEST_CASE(sympy_stepper_test) { ParticleHypothesis::pion()); FreeVector freeParams = transformBoundToFreeParameters( cp2.referenceSurface(), tgContext, cp2.parameters()); - navDir = Direction::Forward; + navDir = Direction::Forward(); double stepSize2 = -2. * stepSize; auto copyState = [&](auto& field, const auto& state) { @@ -421,9 +421,10 @@ BOOST_AUTO_TEST_CASE(sympy_stepper_test) { auto targetSurface = CurvilinearSurface(pos + navDir * 2. * dir, dir).planeSurface(); es.updateSurfaceStatus(esState, *targetSurface, 0, navDir, - BoundaryTolerance::None(), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(esState.stepSize.value(ConstrainedStep::actor), navDir * 2., - eps); + BoundaryTolerance::None(), s_onSurfaceTolerance, + ConstrainedStep::Type::Navigator); + CHECK_CLOSE_ABS(esState.stepSize.value(ConstrainedStep::Type::Navigator), + navDir * 2., eps); // Test the step size modification in the context of a surface es.updateStepSize( @@ -432,16 +433,17 @@ BOOST_AUTO_TEST_CASE(sympy_stepper_test) { ->intersect(tgContext, es.position(esState), navDir * es.direction(esState), BoundaryTolerance::None()) .closest(), - navDir); + navDir, ConstrainedStep::Type::Navigator); CHECK_CLOSE_ABS(esState.stepSize.value(), 2., eps); esState.stepSize.setUser(navDir * stepSize); + es.releaseStepSize(esState, ConstrainedStep::Type::Navigator); es.updateStepSize( esState, targetSurface ->intersect(tgContext, es.position(esState), navDir * es.direction(esState), BoundaryTolerance::None()) .closest(), - navDir); + navDir, ConstrainedStep::Type::Navigator); CHECK_CLOSE_ABS(esState.stepSize.value(), 2., eps); // Test the bound state construction diff --git a/Tests/UnitTests/Core/Propagator/VolumeMaterialInteractionTests.cpp b/Tests/UnitTests/Core/Propagator/VolumeMaterialInteractionTests.cpp index 5bc361fc0a0..c97f8e4876d 100644 --- a/Tests/UnitTests/Core/Propagator/VolumeMaterialInteractionTests.cpp +++ b/Tests/UnitTests/Core/Propagator/VolumeMaterialInteractionTests.cpp @@ -44,7 +44,7 @@ struct NaivgatorState { /// @brief Simplified propagator state struct State { struct { - Direction direction = Direction::Forward; + Direction direction = Direction::Forward(); } options; StepperState stepping; @@ -98,7 +98,7 @@ BOOST_AUTO_TEST_CASE(volume_material_interaction_test) { state.stepping.q = 9.; state.stepping.absCharge = std::abs(state.stepping.q); state.stepping.covTransport = true; - state.options.direction = Direction::Backward; + state.options.direction = Direction::Backward(); state.navigation.currentVolume = volume.get(); Stepper stepper; diff --git a/Tests/UnitTests/Core/Seeding/PathSeederTest.cpp b/Tests/UnitTests/Core/Seeding/PathSeederTest.cpp index 1a347344592..0162fb78525 100644 --- a/Tests/UnitTests/Core/Seeding/PathSeederTest.cpp +++ b/Tests/UnitTests/Core/Seeding/PathSeederTest.cpp @@ -265,7 +265,7 @@ std::shared_ptr constructTelescopeDetector() { // Connect the volumes auto portalContainer = Experimental::detail::CuboidalDetectorHelper::connect( - gctx, volumes, BinningValue::binX, {}, Logging::INFO); + gctx, volumes, AxisDirection::AxisX, {}, Logging::INFO); // Make sure that the geometry ids are // independent of the potential Id generation diff --git a/Tests/UnitTests/Core/Surfaces/BoundaryToleranceTests.cpp b/Tests/UnitTests/Core/Surfaces/BoundaryToleranceTests.cpp index e80035a10a8..47238d51068 100644 --- a/Tests/UnitTests/Core/Surfaces/BoundaryToleranceTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/BoundaryToleranceTests.cpp @@ -39,11 +39,11 @@ BOOST_AUTO_TEST_CASE(BoundaryToleranceConstructors) { { // Valid positive tolerances auto tolerance = BoundaryTolerance::AbsoluteBound(1.0, 2.0); - BOOST_CHECK_EQUAL(tolerance.tolerance0, 1.0); - BOOST_CHECK_EQUAL(tolerance.tolerance1, 2.0); - BOOST_CHECK(BoundaryTolerance{tolerance}.toleranceMode() == Extend); - BOOST_CHECK(BoundaryTolerance{BoundaryTolerance::AbsoluteBound(0.0, 0.0)} - .toleranceMode() == None); + BOOST_CHECK_EQUAL(tolerance.asAbsoluteBound().tolerance0, 1.0); + BOOST_CHECK_EQUAL(tolerance.asAbsoluteBound().tolerance1, 2.0); + BOOST_CHECK(tolerance.toleranceMode() == Extend); + BOOST_CHECK(BoundaryTolerance::AbsoluteBound(0.0, 0.0).toleranceMode() == + None); // Negative tolerances should throw BOOST_CHECK_THROW(BoundaryTolerance::AbsoluteBound(-1.0, 2.0), @@ -56,27 +56,26 @@ BOOST_AUTO_TEST_CASE(BoundaryToleranceConstructors) { { // Valid positive tolerance auto tolerance = BoundaryTolerance::AbsoluteEuclidean(1.0); - BOOST_CHECK_EQUAL(tolerance.tolerance, 1.0); - BOOST_CHECK(BoundaryTolerance{tolerance}.toleranceMode() == Extend); - BOOST_CHECK(BoundaryTolerance{BoundaryTolerance::AbsoluteEuclidean(0.0)} - .toleranceMode() == None); + BOOST_CHECK_EQUAL(tolerance.asAbsoluteEuclidean().tolerance, 1.0); + BOOST_CHECK(tolerance.toleranceMode() == Extend); + BOOST_CHECK(BoundaryTolerance::AbsoluteEuclidean(0.0).toleranceMode() == + None); // Valid negative tolerance tolerance = BoundaryTolerance::AbsoluteEuclidean(-1.0); - BOOST_CHECK_EQUAL(tolerance.tolerance, -1.0); - BOOST_CHECK(BoundaryTolerance{tolerance}.toleranceMode() == Shrink); + BOOST_CHECK_EQUAL(tolerance.asAbsoluteEuclidean().tolerance, -1.0); + BOOST_CHECK(tolerance.toleranceMode() == Shrink); } // Test AbsoluteCartesian constructor { // Valid positive tolerance auto tolerance = BoundaryTolerance::AbsoluteCartesian(1.0, 2.0); - BOOST_CHECK_EQUAL(tolerance.tolerance0, 1.0); - BOOST_CHECK_EQUAL(tolerance.tolerance1, 2.0); - BOOST_CHECK(BoundaryTolerance{tolerance}.toleranceMode() == Extend); + BOOST_CHECK_EQUAL(tolerance.asAbsoluteCartesian().tolerance0, 1.0); + BOOST_CHECK_EQUAL(tolerance.asAbsoluteCartesian().tolerance1, 2.0); + BOOST_CHECK(tolerance.toleranceMode() == Extend); BOOST_CHECK( - BoundaryTolerance{BoundaryTolerance::AbsoluteCartesian(0.0, 0.0)} - .toleranceMode() == None); + BoundaryTolerance::AbsoluteCartesian(0.0, 0.0).toleranceMode() == None); // Negative tolerances should throw BOOST_CHECK_THROW(BoundaryTolerance::AbsoluteCartesian(-1.0, 2.0), @@ -92,15 +91,14 @@ BOOST_AUTO_TEST_CASE(BoundaryToleranceConstructors) { // Valid positive chi2 bound auto tolerance = BoundaryTolerance::Chi2Bound(cov, 3.0); - BOOST_CHECK_EQUAL(tolerance.maxChi2, 3.0); - BOOST_CHECK(BoundaryTolerance{tolerance}.toleranceMode() == Extend); - BOOST_CHECK(BoundaryTolerance{BoundaryTolerance::Chi2Bound(cov, 0.0)} - .toleranceMode() == None); + BOOST_CHECK_EQUAL(tolerance.asChi2Bound().maxChi2, 3.0); + BOOST_CHECK(tolerance.toleranceMode() == Extend); + BOOST_CHECK(BoundaryTolerance::Chi2Bound(cov, 0.0).toleranceMode() == None); // Valid negative chi2 bound tolerance = BoundaryTolerance::Chi2Bound(cov, -3.0); - BOOST_CHECK_EQUAL(tolerance.maxChi2, -3.0); - BOOST_CHECK(BoundaryTolerance{tolerance}.toleranceMode() == Shrink); + BOOST_CHECK_EQUAL(tolerance.asChi2Bound().maxChi2, -3.0); + BOOST_CHECK(tolerance.toleranceMode() == Shrink); } // Test None constructor diff --git a/Tests/UnitTests/Core/Surfaces/ConeSurfaceTests.cpp b/Tests/UnitTests/Core/Surfaces/ConeSurfaceTests.cpp index 4e037a105ba..3c9e114c05e 100644 --- a/Tests/UnitTests/Core/Surfaces/ConeSurfaceTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/ConeSurfaceTests.cpp @@ -103,11 +103,11 @@ BOOST_AUTO_TEST_CASE(ConeSurfaceProperties) { /// Test type (redundant) BOOST_CHECK_EQUAL(coneSurfaceObject->type(), Surface::Cone); - /// Test binningPosition - Vector3 binningPosition{0., 1., 2.}; + /// Test referencePosition + Vector3 referencePosition{0., 1., 2.}; CHECK_CLOSE_ABS( - coneSurfaceObject->binningPosition(tgContext, BinningValue::binPhi), - binningPosition, 1e-6); + coneSurfaceObject->referencePosition(tgContext, AxisDirection::AxisPhi), + referencePosition, 1e-6); /// Test referenceFrame Vector3 globalPosition{2., 2., 2.}; @@ -225,21 +225,21 @@ BOOST_AUTO_TEST_CASE(ConeSurfaceExtent) { auto pConeExtent = pCone->polyhedronRepresentation(tgContext, 1).extent(); double rMax = zMax * std::tan(alpha); - CHECK_CLOSE_ABS(zMin, pConeExtent.min(BinningValue::binZ), + CHECK_CLOSE_ABS(zMin, pConeExtent.min(AxisDirection::AxisZ), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(zMax, pConeExtent.max(BinningValue::binZ), + CHECK_CLOSE_ABS(zMax, pConeExtent.max(AxisDirection::AxisZ), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(0., pConeExtent.min(BinningValue::binR), + CHECK_CLOSE_ABS(0., pConeExtent.min(AxisDirection::AxisR), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(rMax, pConeExtent.max(BinningValue::binR), + CHECK_CLOSE_ABS(rMax, pConeExtent.max(AxisDirection::AxisR), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(-rMax, pConeExtent.min(BinningValue::binX), + CHECK_CLOSE_ABS(-rMax, pConeExtent.min(AxisDirection::AxisX), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(rMax, pConeExtent.max(BinningValue::binX), + CHECK_CLOSE_ABS(rMax, pConeExtent.max(AxisDirection::AxisX), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(-rMax, pConeExtent.min(BinningValue::binY), + CHECK_CLOSE_ABS(-rMax, pConeExtent.min(AxisDirection::AxisY), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(rMax, pConeExtent.max(BinningValue::binY), + CHECK_CLOSE_ABS(rMax, pConeExtent.max(AxisDirection::AxisY), s_onSurfaceTolerance); /// Now a sector @@ -248,13 +248,13 @@ BOOST_AUTO_TEST_CASE(ConeSurfaceExtent) { pCone = Surface::makeShared(pTransform, pConeBounds); pConeExtent = pCone->polyhedronRepresentation(tgContext, 1).extent(); - CHECK_CLOSE_ABS(zMin, pConeExtent.min(BinningValue::binZ), + CHECK_CLOSE_ABS(zMin, pConeExtent.min(AxisDirection::AxisZ), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(zMax, pConeExtent.max(BinningValue::binZ), + CHECK_CLOSE_ABS(zMax, pConeExtent.max(AxisDirection::AxisZ), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(0., pConeExtent.min(BinningValue::binR), + CHECK_CLOSE_ABS(0., pConeExtent.min(AxisDirection::AxisR), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(rMax, pConeExtent.max(BinningValue::binR), + CHECK_CLOSE_ABS(rMax, pConeExtent.max(AxisDirection::AxisR), s_onSurfaceTolerance); } diff --git a/Tests/UnitTests/Core/Surfaces/CylinderSurfaceTests.cpp b/Tests/UnitTests/Core/Surfaces/CylinderSurfaceTests.cpp index e37b339d00c..073f743ad29 100644 --- a/Tests/UnitTests/Core/Surfaces/CylinderSurfaceTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/CylinderSurfaceTests.cpp @@ -107,11 +107,11 @@ BOOST_AUTO_TEST_CASE(CylinderSurfaceProperties) { /// 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 referencePosition + Vector3 referencePosition{0., 1., 2.}; + CHECK_CLOSE_ABS(cylinderSurfaceObject->referencePosition( + testContext, AxisDirection::AxisPhi), + referencePosition, 1e-9); /// Test referenceFrame const double invSqrt2 = 1. / std::numbers::sqrt2; @@ -254,6 +254,8 @@ BOOST_AUTO_TEST_CASE(CylinderSurfaceEqualityOperators) { /// Unit test for testing CylinderSurface properties BOOST_AUTO_TEST_CASE(CylinderSurfaceExtent) { + using enum AxisDirection; + // Some radius and half length const double radius = 1.; const double halfZ = 10.; @@ -266,22 +268,14 @@ BOOST_AUTO_TEST_CASE(CylinderSurfaceExtent) { auto cylinderExtent = cylinderSurface->polyhedronRepresentation(testContext, 1).extent(); - CHECK_CLOSE_ABS(-8, cylinderExtent.min(BinningValue::binZ), - s_onSurfaceTolerance); - CHECK_CLOSE_ABS(12, cylinderExtent.max(BinningValue::binZ), - s_onSurfaceTolerance); - CHECK_CLOSE_ABS(radius, cylinderExtent.min(BinningValue::binR), - s_onSurfaceTolerance); - CHECK_CLOSE_ABS(radius, cylinderExtent.max(BinningValue::binR), - s_onSurfaceTolerance); - CHECK_CLOSE_ABS(-radius, cylinderExtent.min(BinningValue::binX), - s_onSurfaceTolerance); - CHECK_CLOSE_ABS(radius, cylinderExtent.max(BinningValue::binX), - s_onSurfaceTolerance); - CHECK_CLOSE_ABS(-radius, cylinderExtent.min(BinningValue::binY), - s_onSurfaceTolerance); - CHECK_CLOSE_ABS(radius, cylinderExtent.max(BinningValue::binY), - s_onSurfaceTolerance); + CHECK_CLOSE_ABS(-8, cylinderExtent.min(AxisZ), s_onSurfaceTolerance); + CHECK_CLOSE_ABS(12, cylinderExtent.max(AxisZ), s_onSurfaceTolerance); + CHECK_CLOSE_ABS(radius, cylinderExtent.min(AxisR), s_onSurfaceTolerance); + CHECK_CLOSE_ABS(radius, cylinderExtent.max(AxisR), s_onSurfaceTolerance); + CHECK_CLOSE_ABS(-radius, cylinderExtent.min(AxisX), s_onSurfaceTolerance); + CHECK_CLOSE_ABS(radius, cylinderExtent.max(AxisX), s_onSurfaceTolerance); + CHECK_CLOSE_ABS(-radius, cylinderExtent.min(AxisY), s_onSurfaceTolerance); + CHECK_CLOSE_ABS(radius, cylinderExtent.max(AxisY), s_onSurfaceTolerance); } /// Unit test for testing CylinderSurface alignment derivatives @@ -331,23 +325,23 @@ BOOST_AUTO_TEST_CASE(CylinderSurfaceBinningPosition) { Vector3 exp = Vector3{r * std::cos(averagePhi), r * std::sin(averagePhi), 0}; exp = trf * exp; - Vector3 bp = cylinder->binningPosition(testContext, BinningValue::binR); + Vector3 bp = cylinder->referencePosition(testContext, AxisDirection::AxisR); CHECK_CLOSE_ABS(bp, exp, 1e-10); CHECK_CLOSE_ABS( - cylinder->binningPositionValue(testContext, BinningValue::binR), + cylinder->referencePositionValue(testContext, AxisDirection::AxisR), VectorHelpers::perp(exp), 1e-10); - bp = cylinder->binningPosition(testContext, BinningValue::binRPhi); + bp = cylinder->referencePosition(testContext, AxisDirection::AxisRPhi); CHECK_CLOSE_ABS(bp, exp, 1e-10); CHECK_CLOSE_ABS( - cylinder->binningPositionValue(testContext, BinningValue::binRPhi), + cylinder->referencePositionValue(testContext, AxisDirection::AxisRPhi), VectorHelpers::phi(exp) * VectorHelpers::perp(exp), 1e-10); - for (auto b : - {BinningValue::binX, BinningValue::binY, BinningValue::binZ, - BinningValue::binEta, BinningValue::binH, BinningValue::binMag}) { + for (auto b : {AxisDirection::AxisX, AxisDirection::AxisY, + AxisDirection::AxisZ, AxisDirection::AxisEta, + AxisDirection::AxisTheta, AxisDirection::AxisMag}) { BOOST_TEST_CONTEXT("binValue: " << b) { - BOOST_CHECK_EQUAL(cylinder->binningPosition(testContext, b), + BOOST_CHECK_EQUAL(cylinder->referencePosition(testContext, b), cylinder->center(testContext)); } } @@ -363,7 +357,7 @@ BOOST_AUTO_TEST_CASE(InvalidDetectorElement) { auto cyl2 = Surface::makeShared(bounds, detElem); BOOST_CHECK_THROW( - cyl1->mergedWith(*cyl2, Acts::BinningValue::binR, false, *logger), + cyl1->mergedWith(*cyl2, Acts::AxisDirection::AxisR, false, *logger), SurfaceMergingException); } @@ -385,28 +379,28 @@ BOOST_DATA_TEST_CASE(IncompatibleZDirection, base * Translation3{Vector3::UnitZ() * 200_mm}, 30_mm, 100_mm); BOOST_CHECK_THROW( - cyl->mergedWith(*cyl2, Acts::BinningValue::binPhi, false, *logger), + cyl->mergedWith(*cyl2, Acts::AxisDirection::AxisPhi, false, *logger), SurfaceMergingException); auto cylShiftedXy = Surface::makeShared( base * Translation3{Vector3{1_mm, 2_mm, 200_mm}}, 30_mm, 100_mm); - BOOST_CHECK_THROW( - cyl->mergedWith(*cylShiftedXy, Acts::BinningValue::binZ, false, *logger), - SurfaceMergingException); + BOOST_CHECK_THROW(cyl->mergedWith(*cylShiftedXy, Acts::AxisDirection::AxisZ, + false, *logger), + SurfaceMergingException); auto cylRotatedX = Surface::makeShared( base * AngleAxis3{10_degree, Vector3::UnitX()} * Translation3{Vector3::UnitZ() * 200_mm}, 30_mm, 100_mm); BOOST_CHECK_THROW( - cyl->mergedWith(*cylRotatedX, Acts::BinningValue::binZ, false, *logger), + cyl->mergedWith(*cylRotatedX, Acts::AxisDirection::AxisZ, false, *logger), SurfaceMergingException); // Cylinder with different radius auto cyl3 = Surface::makeShared( base * Translation3{Vector3::UnitZ() * 200_mm}, 35_mm, 100_mm); BOOST_CHECK_THROW( - cyl->mergedWith(*cyl3, Acts::BinningValue::binZ, false, *logger), + cyl->mergedWith(*cyl3, Acts::AxisDirection::AxisZ, false, *logger), SurfaceMergingException); // Cylinder with bevel @@ -414,28 +408,28 @@ BOOST_DATA_TEST_CASE(IncompatibleZDirection, 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), + cyl->mergedWith(*cyl4, Acts::AxisDirection::AxisZ, false, *logger), SurfaceMergingException); auto cyl5 = Surface::makeShared( 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), + cyl->mergedWith(*cyl5, Acts::AxisDirection::AxisZ, false, *logger), SurfaceMergingException); // Cylinder with overlap in z auto cyl6 = Surface::makeShared( base * Translation3{Vector3::UnitZ() * 150_mm}, 30_mm, 100_mm); BOOST_CHECK_THROW( - cyl->mergedWith(*cyl6, Acts::BinningValue::binZ, false, *logger), + cyl->mergedWith(*cyl6, Acts::AxisDirection::AxisZ, false, *logger), SurfaceMergingException); // Cylinder with gap in z auto cyl7 = Surface::makeShared( base * Translation3{Vector3::UnitZ() * 250_mm}, 30_mm, 100_mm); BOOST_CHECK_THROW( - cyl->mergedWith(*cyl7, Acts::BinningValue::binZ, false, *logger), + cyl->mergedWith(*cyl7, Acts::AxisDirection::AxisZ, false, *logger), SurfaceMergingException); // Cylinder with phi sector and relative z rotation @@ -444,7 +438,7 @@ BOOST_DATA_TEST_CASE(IncompatibleZDirection, Translation3{Vector3::UnitZ() * 200_mm}, 30_mm, 100_mm, 10_degree, 40_degree); BOOST_CHECK_THROW( - cyl->mergedWith(*cyl8, Acts::BinningValue::binZ, false, *logger), + cyl->mergedWith(*cyl8, Acts::AxisDirection::AxisZ, false, *logger), SurfaceMergingException); auto cylPhi1 = Surface::makeShared(Transform3::Identity(), @@ -453,7 +447,7 @@ BOOST_DATA_TEST_CASE(IncompatibleZDirection, Transform3{Translation3{Vector3::UnitZ() * 150_mm}}, 30_mm, 50_mm, 55_degree); BOOST_CHECK_THROW( - cylPhi1->mergedWith(*cylPhi2, Acts::BinningValue::binZ, false, *logger), + cylPhi1->mergedWith(*cylPhi2, Acts::AxisDirection::AxisZ, false, *logger), SurfaceMergingException); } @@ -476,12 +470,12 @@ BOOST_DATA_TEST_CASE(ZDirection, 30_mm, 100_mm); auto [cyl3, reversed] = - cyl->mergedWith(*cyl2, Acts::BinningValue::binZ, false, *logger); + cyl->mergedWith(*cyl2, Acts::AxisDirection::AxisZ, false, *logger); BOOST_REQUIRE_NE(cyl3, nullptr); BOOST_CHECK(!reversed); auto [cyl3Reversed, reversed2] = - cyl2->mergedWith(*cyl, Acts::BinningValue::binZ, false, *logger); + cyl2->mergedWith(*cyl, Acts::AxisDirection::AxisZ, false, *logger); BOOST_REQUIRE_NE(cyl3Reversed, nullptr); BOOST_CHECK(cyl3->bounds() == cyl3Reversed->bounds()); BOOST_CHECK(reversed2); @@ -509,7 +503,7 @@ BOOST_DATA_TEST_CASE(ZDirection, 45_degree); auto [cylPhi12, reversedPhy12] = - cylPhi1->mergedWith(*cylPhi2, Acts::BinningValue::binZ, false, *logger); + cylPhi1->mergedWith(*cylPhi2, Acts::AxisDirection::AxisZ, false, *logger); BOOST_REQUIRE_NE(cylPhi12, nullptr); auto boundsPhi12 = cylPhi12->bounds(); @@ -542,31 +536,31 @@ BOOST_DATA_TEST_CASE(IncompatibleRPhiDirection, // Cylinder with overlap in phi auto cylPhi2 = Surface::makeShared(base, 30_mm, 100_mm, 45_degree, a(85_degree)); - BOOST_CHECK_THROW( - cylPhi->mergedWith(*cylPhi2, Acts::BinningValue::binRPhi, false, *logger), - SurfaceMergingException); + BOOST_CHECK_THROW(cylPhi->mergedWith(*cylPhi2, Acts::AxisDirection::AxisRPhi, + false, *logger), + SurfaceMergingException); // Cylinder with gap in phi auto cylPhi3 = Surface::makeShared(base, 30_mm, 100_mm, 45_degree, a(105_degree)); - BOOST_CHECK_THROW( - cylPhi->mergedWith(*cylPhi3, Acts::BinningValue::binRPhi, false, *logger), - SurfaceMergingException); + BOOST_CHECK_THROW(cylPhi->mergedWith(*cylPhi3, Acts::AxisDirection::AxisRPhi, + false, *logger), + SurfaceMergingException); // Cylinder with a z shift auto cylPhi4 = Surface::makeShared( base * Translation3{Vector3::UnitZ() * 20_mm}, 30_mm, 100_mm, 45_degree, a(95_degree)); - BOOST_CHECK_THROW( - cylPhi->mergedWith(*cylPhi4, Acts::BinningValue::binRPhi, false, *logger), - SurfaceMergingException); + BOOST_CHECK_THROW(cylPhi->mergedWith(*cylPhi4, Acts::AxisDirection::AxisRPhi, + false, *logger), + SurfaceMergingException); // Test phi sector with different z halflengths auto cylPhi5 = Surface::makeShared(base, 30_mm, 110_mm, 45_degree, a(95_degree)); - BOOST_CHECK_THROW( - cylPhi->mergedWith(*cylPhi5, Acts::BinningValue::binRPhi, false, *logger), - SurfaceMergingException); + BOOST_CHECK_THROW(cylPhi->mergedWith(*cylPhi5, Acts::AxisDirection::AxisRPhi, + false, *logger), + SurfaceMergingException); } BOOST_DATA_TEST_CASE(RPhiDirection, @@ -592,13 +586,13 @@ BOOST_DATA_TEST_CASE(RPhiDirection, 45_degree, a(95_degree)); auto [cyl3, reversed] = - cyl->mergedWith(*cyl2, Acts::BinningValue::binRPhi, false, *logger); + cyl->mergedWith(*cyl2, Acts::AxisDirection::AxisRPhi, false, *logger); BOOST_REQUIRE_NE(cyl3, nullptr); BOOST_CHECK_EQUAL(base.matrix(), cyl3->transform(testContext).matrix()); BOOST_CHECK(reversed); auto [cyl3Reversed, reversed2] = - cyl2->mergedWith(*cyl, Acts::BinningValue::binRPhi, false, *logger); + cyl2->mergedWith(*cyl, Acts::AxisDirection::AxisRPhi, false, *logger); BOOST_REQUIRE_NE(cyl3Reversed, nullptr); BOOST_CHECK(*cyl3 == *cyl3Reversed); BOOST_CHECK(!reversed2); @@ -617,13 +611,13 @@ BOOST_DATA_TEST_CASE(RPhiDirection, auto cyl5 = Surface::makeShared(base, 30_mm, 100_mm, 10_degree, a(-160_degree)); auto [cyl45, reversed45] = - cyl4->mergedWith(*cyl5, Acts::BinningValue::binRPhi, false, *logger); + cyl4->mergedWith(*cyl5, Acts::AxisDirection::AxisRPhi, false, *logger); BOOST_REQUIRE_NE(cyl45, nullptr); BOOST_CHECK_EQUAL(base.matrix(), cyl45->transform(testContext).matrix()); BOOST_CHECK(reversed45); auto [cyl54, reversed54] = - cyl5->mergedWith(*cyl4, Acts::BinningValue::binRPhi, false, *logger); + cyl5->mergedWith(*cyl4, Acts::AxisDirection::AxisRPhi, false, *logger); BOOST_REQUIRE_NE(cyl54, nullptr); BOOST_CHECK(!reversed54); @@ -642,12 +636,12 @@ BOOST_DATA_TEST_CASE(RPhiDirection, 90_degree, a(-90_degree)); auto [cyl67, reversed67] = - cyl6->mergedWith(*cyl7, Acts::BinningValue::binRPhi, false, *logger); + cyl6->mergedWith(*cyl7, Acts::AxisDirection::AxisRPhi, false, *logger); BOOST_REQUIRE_NE(cyl67, nullptr); BOOST_CHECK_EQUAL(base.matrix(), cyl67->transform(testContext).matrix()); auto [cyl76, reversed76] = - cyl7->mergedWith(*cyl6, Acts::BinningValue::binRPhi, false, *logger); + cyl7->mergedWith(*cyl6, Acts::AxisDirection::AxisRPhi, false, *logger); BOOST_REQUIRE_NE(cyl76, nullptr); BOOST_CHECK_EQUAL(base.matrix(), cyl76->transform(testContext).matrix()); @@ -674,7 +668,7 @@ BOOST_DATA_TEST_CASE(RPhiDirection, 45_degree, 0_degree); auto [cyl3, reversed] = - cyl1->mergedWith(*cyl2, Acts::BinningValue::binRPhi, true, *logger); + cyl1->mergedWith(*cyl2, Acts::AxisDirection::AxisRPhi, true, *logger); BOOST_REQUIRE_NE(cyl3, nullptr); Transform3 trfExpected12 = @@ -694,7 +688,7 @@ BOOST_DATA_TEST_CASE(RPhiDirection, auto cyl5 = Surface::makeShared(trf5, 30_mm, 100_mm, 10_degree, 0_degree); auto [cyl45, reversed45] = - cyl4->mergedWith(*cyl5, Acts::BinningValue::binRPhi, true, *logger); + cyl4->mergedWith(*cyl5, Acts::AxisDirection::AxisRPhi, true, *logger); BOOST_REQUIRE_NE(cyl45, nullptr); Transform3 trfExpected45 = base * AngleAxis3(a(180_degree), Vector3::UnitZ()); @@ -703,7 +697,7 @@ BOOST_DATA_TEST_CASE(RPhiDirection, BOOST_CHECK(reversed45); auto [cyl54, reversed54] = - cyl5->mergedWith(*cyl4, Acts::BinningValue::binRPhi, true, *logger); + cyl5->mergedWith(*cyl4, Acts::AxisDirection::AxisRPhi, true, *logger); BOOST_REQUIRE_NE(cyl54, nullptr); BOOST_CHECK(!reversed54); @@ -721,14 +715,14 @@ BOOST_DATA_TEST_CASE(RPhiDirection, 90_degree, 0_degree); auto [cyl67, reversed67] = - cyl6->mergedWith(*cyl7, Acts::BinningValue::binRPhi, true, *logger); + cyl6->mergedWith(*cyl7, Acts::AxisDirection::AxisRPhi, true, *logger); BOOST_REQUIRE_NE(cyl67, nullptr); Transform3 expected67 = trf6 * AngleAxis3(90_degree, Vector3::UnitZ()); CHECK_CLOSE_OR_SMALL(cyl67->transform(testContext).matrix(), expected67.matrix(), 1e-6, 1e-10); auto [cyl76, reversed76] = - cyl7->mergedWith(*cyl6, Acts::BinningValue::binRPhi, true, *logger); + cyl7->mergedWith(*cyl6, Acts::AxisDirection::AxisRPhi, true, *logger); BOOST_REQUIRE_NE(cyl76, nullptr); Transform3 expected76 = trf7 * AngleAxis3(90_degree, Vector3::UnitZ()); CHECK_CLOSE_OR_SMALL(cyl76->transform(testContext).matrix(), diff --git a/Tests/UnitTests/Core/Surfaces/DiscSurfaceTests.cpp b/Tests/UnitTests/Core/Surfaces/DiscSurfaceTests.cpp index 15140f73c7a..4a304f23510 100644 --- a/Tests/UnitTests/Core/Surfaces/DiscSurfaceTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/DiscSurfaceTests.cpp @@ -106,9 +106,9 @@ BOOST_AUTO_TEST_CASE(DiscSurfaceProperties) { Vector2 lpos(2., 0.05); BOOST_CHECK_EQUAL(discSurfaceObject->normal(tgContext, lpos), zAxis); - /// Test binningPosition + /// Test referencePosition BOOST_CHECK_EQUAL( - discSurfaceObject->binningPosition(tgContext, BinningValue::binRPhi), + discSurfaceObject->referencePosition(tgContext, AxisDirection::AxisRPhi), origin3D); /// Test bounds @@ -248,46 +248,46 @@ BOOST_AUTO_TEST_CASE(DiscSurfaceExtent) { Surface::makeShared(Transform3::Identity(), 0., rMax); auto pDiscExtent = pDisc->polyhedronRepresentation(tgContext, 1).extent(); - CHECK_CLOSE_ABS(0., pDiscExtent.min(BinningValue::binZ), + CHECK_CLOSE_ABS(0., pDiscExtent.min(AxisDirection::AxisZ), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(0., pDiscExtent.max(BinningValue::binZ), + CHECK_CLOSE_ABS(0., pDiscExtent.max(AxisDirection::AxisZ), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(0., pDiscExtent.min(BinningValue::binR), + CHECK_CLOSE_ABS(0., pDiscExtent.min(AxisDirection::AxisR), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(rMax, pDiscExtent.max(BinningValue::binR), + CHECK_CLOSE_ABS(rMax, pDiscExtent.max(AxisDirection::AxisR), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(-rMax, pDiscExtent.min(BinningValue::binX), + CHECK_CLOSE_ABS(-rMax, pDiscExtent.min(AxisDirection::AxisX), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(rMax, pDiscExtent.max(BinningValue::binX), + CHECK_CLOSE_ABS(rMax, pDiscExtent.max(AxisDirection::AxisX), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(-rMax, pDiscExtent.min(BinningValue::binY), + CHECK_CLOSE_ABS(-rMax, pDiscExtent.min(AxisDirection::AxisY), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(rMax, pDiscExtent.max(BinningValue::binY), + CHECK_CLOSE_ABS(rMax, pDiscExtent.max(AxisDirection::AxisY), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(-std::numbers::pi, pDiscExtent.min(BinningValue::binPhi), + CHECK_CLOSE_ABS(-std::numbers::pi, pDiscExtent.min(AxisDirection::AxisPhi), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(std::numbers::pi, pDiscExtent.max(BinningValue::binPhi), + CHECK_CLOSE_ABS(std::numbers::pi, pDiscExtent.max(AxisDirection::AxisPhi), s_onSurfaceTolerance); auto pRing = Surface::makeShared(Transform3::Identity(), rMin, rMax); auto pRingExtent = pRing->polyhedronRepresentation(tgContext, 1).extent(); - CHECK_CLOSE_ABS(0., pRingExtent.min(BinningValue::binZ), + CHECK_CLOSE_ABS(0., pRingExtent.min(AxisDirection::AxisZ), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(0., pRingExtent.max(BinningValue::binZ), + CHECK_CLOSE_ABS(0., pRingExtent.max(AxisDirection::AxisZ), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(rMin, pRingExtent.min(BinningValue::binR), + CHECK_CLOSE_ABS(rMin, pRingExtent.min(AxisDirection::AxisR), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(rMax, pRingExtent.max(BinningValue::binR), + CHECK_CLOSE_ABS(rMax, pRingExtent.max(AxisDirection::AxisR), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(-rMax, pRingExtent.min(BinningValue::binX), + CHECK_CLOSE_ABS(-rMax, pRingExtent.min(AxisDirection::AxisX), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(rMax, pRingExtent.max(BinningValue::binX), + CHECK_CLOSE_ABS(rMax, pRingExtent.max(AxisDirection::AxisX), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(-rMax, pRingExtent.min(BinningValue::binY), + CHECK_CLOSE_ABS(-rMax, pRingExtent.min(AxisDirection::AxisY), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(rMax, pRingExtent.max(BinningValue::binY), + CHECK_CLOSE_ABS(rMax, pRingExtent.max(AxisDirection::AxisY), s_onSurfaceTolerance); } @@ -349,27 +349,29 @@ BOOST_AUTO_TEST_CASE(DiscSurfaceBinningPosition) { 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); + Vector3 bp = disc->referencePosition(tgContext, AxisDirection::AxisR); double r = (bounds->rMax() + bounds->rMin()) / 2.0; double phi = bounds->get(RadialBounds::eAveragePhi); Vector3 exp = Vector3{r * std::cos(phi), r * std::sin(phi), 0}; exp = trf * exp; BOOST_CHECK_EQUAL(bp, exp); - BOOST_CHECK_EQUAL(disc->binningPositionValue(tgContext, BinningValue::binR), - VectorHelpers::perp(exp)); + BOOST_CHECK_EQUAL( + disc->referencePositionValue(tgContext, AxisDirection::AxisR), + VectorHelpers::perp(exp)); - bp = disc->binningPosition(tgContext, BinningValue::binPhi); + bp = disc->referencePosition(tgContext, AxisDirection::AxisPhi); BOOST_CHECK_EQUAL(bp, exp); BOOST_CHECK_EQUAL( - disc->binningPositionValue(tgContext, BinningValue::binPhi), + disc->referencePositionValue(tgContext, AxisDirection::AxisPhi), VectorHelpers::phi(exp)); - for (auto b : {BinningValue::binX, BinningValue::binY, BinningValue::binZ, - BinningValue::binEta, BinningValue::binRPhi, - BinningValue::binH, BinningValue::binMag}) { + for (auto b : + {AxisDirection::AxisX, AxisDirection::AxisY, AxisDirection::AxisZ, + AxisDirection::AxisEta, AxisDirection::AxisRPhi, + AxisDirection::AxisTheta, AxisDirection::AxisMag}) { BOOST_TEST_CONTEXT("binValue: " << b) { - BOOST_CHECK_EQUAL(disc->binningPosition(tgContext, b), + BOOST_CHECK_EQUAL(disc->referencePosition(tgContext, b), disc->center(tgContext)); } } @@ -385,7 +387,7 @@ BOOST_AUTO_TEST_CASE(DiscSurfaceBinningPosition) { auto disc = Acts::Surface::makeShared(trf, bounds); - Vector3 bp = disc->binningPosition(tgContext, BinningValue::binR); + Vector3 bp = disc->referencePosition(tgContext, AxisDirection::AxisR); double r = (bounds->rMax() + bounds->rMin()) / 2.0; double phi = bounds->get(AnnulusBounds::eAveragePhi); Vector3 exp = Vector3{r * std::cos(phi), r * std::sin(phi), 0}; @@ -393,14 +395,15 @@ BOOST_AUTO_TEST_CASE(DiscSurfaceBinningPosition) { BOOST_CHECK_EQUAL(bp, exp); - bp = disc->binningPosition(tgContext, BinningValue::binPhi); + bp = disc->referencePosition(tgContext, AxisDirection::AxisPhi); BOOST_CHECK_EQUAL(bp, exp); - for (auto b : {BinningValue::binX, BinningValue::binY, BinningValue::binZ, - BinningValue::binEta, BinningValue::binRPhi, - BinningValue::binH, BinningValue::binMag}) { + for (auto b : + {AxisDirection::AxisX, AxisDirection::AxisY, AxisDirection::AxisZ, + AxisDirection::AxisEta, AxisDirection::AxisRPhi, + AxisDirection::AxisTheta, AxisDirection::AxisMag}) { BOOST_TEST_CONTEXT("binValue: " << b) { - BOOST_CHECK_EQUAL(disc->binningPosition(tgContext, b), + BOOST_CHECK_EQUAL(disc->referencePosition(tgContext, b), disc->center(tgContext)); } } @@ -430,12 +433,12 @@ BOOST_AUTO_TEST_CASE(IncompatibleBounds) { Surface::makeShared(base, 20_mm, 40_mm, 30_mm, 100_mm); BOOST_CHECK_THROW( - discRadial->mergedWith(*discTrap, BinningValue::binR, false, *logger), + discRadial->mergedWith(*discTrap, AxisDirection::AxisR, false, *logger), SurfaceMergingException); BOOST_CHECK_THROW( - discTrap2->mergedWith(*discTrap, BinningValue::binR, false, *logger), + discTrap2->mergedWith(*discTrap, AxisDirection::AxisR, false, *logger), SurfaceMergingException); } @@ -449,7 +452,7 @@ BOOST_AUTO_TEST_CASE(InvalidDetectorElement) { auto disc2 = Surface::makeShared(bounds2, detElem); BOOST_CHECK_THROW( - disc1->mergedWith(*disc2, BinningValue::binR, false, *logger), + disc1->mergedWith(*disc2, AxisDirection::AxisR, false, *logger), SurfaceMergingException); } @@ -470,50 +473,50 @@ BOOST_DATA_TEST_CASE(IncompatibleRDirection, // Disc with overlap in r auto discOverlap = makeDisc(base, 90_mm, 150_mm); - BOOST_CHECK_THROW( - disc->mergedWith(*discOverlap, Acts::BinningValue::binR, false, *logger), - SurfaceMergingException); + BOOST_CHECK_THROW(disc->mergedWith(*discOverlap, Acts::AxisDirection::AxisR, + false, *logger), + SurfaceMergingException); // Disc with gap in r auto discGap = makeDisc(base, 110_mm, 150_mm); BOOST_CHECK_THROW( - disc->mergedWith(*discGap, Acts::BinningValue::binR, false, *logger), + disc->mergedWith(*discGap, Acts::AxisDirection::AxisR, false, *logger), SurfaceMergingException); auto discShiftedZ = Surface::makeShared( base * Translation3{Vector3::UnitZ() * 10_mm}, 100_mm, 150_mm); - BOOST_CHECK_THROW( - disc->mergedWith(*discShiftedZ, Acts::BinningValue::binR, false, *logger), - SurfaceMergingException); + BOOST_CHECK_THROW(disc->mergedWith(*discShiftedZ, Acts::AxisDirection::AxisR, + false, *logger), + SurfaceMergingException); auto discShiftedXy = makeDisc( base * Translation3{Vector3{1_mm, 2_mm, 200_mm}}, 100_mm, 150_mm); - BOOST_CHECK_THROW(disc->mergedWith(*discShiftedXy, Acts::BinningValue::binZ, + BOOST_CHECK_THROW(disc->mergedWith(*discShiftedXy, Acts::AxisDirection::AxisZ, false, *logger), SurfaceMergingException); auto discRotatedZ = makeDisc(base * AngleAxis3{10_degree, Vector3::UnitZ()}, 100_mm, 150_mm, 60_degree, 0_degree); - BOOST_CHECK_THROW( - disc->mergedWith(*discRotatedZ, Acts::BinningValue::binR, false, *logger), - SurfaceMergingException); + BOOST_CHECK_THROW(disc->mergedWith(*discRotatedZ, Acts::AxisDirection::AxisR, + false, *logger), + SurfaceMergingException); auto discRotatedX = makeDisc(base * AngleAxis3{10_degree, Vector3::UnitX()}, 100_mm, 150_mm); - BOOST_CHECK_THROW( - disc->mergedWith(*discRotatedX, Acts::BinningValue::binR, false, *logger), - SurfaceMergingException); + BOOST_CHECK_THROW(disc->mergedWith(*discRotatedX, Acts::AxisDirection::AxisR, + false, *logger), + SurfaceMergingException); // Test not same phi sector auto discPhi1 = makeDisc(base, 30_mm, 100_mm, 10_degree, 40_degree); auto discPhi2 = makeDisc(base, 100_mm, 160_mm, 20_degree, 40_degree); auto discPhi3 = makeDisc(base, 100_mm, 160_mm, 10_degree, 50_degree); BOOST_CHECK_THROW( - discPhi1->mergedWith(*discPhi2, BinningValue::binR, false, *logger), + discPhi1->mergedWith(*discPhi2, AxisDirection::AxisR, false, *logger), SurfaceMergingException); BOOST_CHECK_THROW( - discPhi1->mergedWith(*discPhi3, BinningValue::binR, false, *logger), + discPhi1->mergedWith(*discPhi3, AxisDirection::AxisR, false, *logger), SurfaceMergingException); } @@ -534,12 +537,12 @@ BOOST_DATA_TEST_CASE(RDirection, makeDisc(base * AngleAxis3(14_degree, Vector3::UnitZ()), 100_mm, 150_mm); auto [disc3, reversed] = - disc->mergedWith(*disc2, Acts::BinningValue::binR, false, *logger); + disc->mergedWith(*disc2, Acts::AxisDirection::AxisR, false, *logger); BOOST_REQUIRE_NE(disc3, nullptr); BOOST_CHECK(!reversed); auto [disc3Reversed, reversed2] = - disc2->mergedWith(*disc, Acts::BinningValue::binR, false, *logger); + disc2->mergedWith(*disc, Acts::AxisDirection::AxisR, false, *logger); BOOST_REQUIRE_NE(disc3Reversed, nullptr); BOOST_CHECK(disc3->bounds() == disc3Reversed->bounds()); BOOST_CHECK(reversed2); @@ -565,7 +568,7 @@ BOOST_DATA_TEST_CASE(RDirection, auto discPhi1 = makeDisc(base, 30_mm, 100_mm, 10_degree, 40_degree); auto discPhi2 = makeDisc(base, 100_mm, 160_mm, 10_degree, 40_degree); auto [discPhi12, reversedPhi12] = - discPhi1->mergedWith(*discPhi2, BinningValue::binR, false, *logger); + discPhi1->mergedWith(*discPhi2, AxisDirection::AxisR, false, *logger); BOOST_REQUIRE_NE(discPhi12, nullptr); const auto* boundsPhi12 = @@ -598,26 +601,26 @@ BOOST_DATA_TEST_CASE(IncompatiblePhiDirection, // Disc with overlap in phi auto discPhi2 = makeDisc(base, 30_mm, 100_mm, 45_degree, a(85_degree)); - BOOST_CHECK_THROW(discPhi->mergedWith(*discPhi2, Acts::BinningValue::binPhi, + BOOST_CHECK_THROW(discPhi->mergedWith(*discPhi2, Acts::AxisDirection::AxisPhi, false, *logger), SurfaceMergingException); // Disc with gap in phi auto discPhi3 = makeDisc(base, 30_mm, 100_mm, 45_degree, a(105_degree)); - BOOST_CHECK_THROW(discPhi->mergedWith(*discPhi3, Acts::BinningValue::binPhi, + BOOST_CHECK_THROW(discPhi->mergedWith(*discPhi3, Acts::AxisDirection::AxisPhi, false, *logger), SurfaceMergingException); // Disc with a z shift auto discPhi4 = makeDisc(base * Translation3{Vector3::UnitZ() * 20_mm}, 30_mm, 100_mm, 45_degree, a(95_degree)); - BOOST_CHECK_THROW(discPhi->mergedWith(*discPhi4, Acts::BinningValue::binPhi, + BOOST_CHECK_THROW(discPhi->mergedWith(*discPhi4, Acts::AxisDirection::AxisPhi, false, *logger), SurfaceMergingException); // Disc with different r bounds: could be merged in r but not in phi auto discPhi5 = makeDisc(base, 100_mm, 150_mm, 45_degree, a(95_degree)); - BOOST_CHECK_THROW(discPhi->mergedWith(*discPhi5, Acts::BinningValue::binPhi, + BOOST_CHECK_THROW(discPhi->mergedWith(*discPhi5, Acts::AxisDirection::AxisPhi, false, *logger), SurfaceMergingException); } @@ -643,13 +646,13 @@ BOOST_DATA_TEST_CASE(PhiDirection, auto disc2 = makeDisc(base, 30_mm, 100_mm, 45_degree, a(95_degree)); auto [disc3, reversed] = - disc->mergedWith(*disc2, Acts::BinningValue::binPhi, false, *logger); + disc->mergedWith(*disc2, Acts::AxisDirection::AxisPhi, false, *logger); BOOST_REQUIRE_NE(disc3, nullptr); BOOST_CHECK_EQUAL(base.matrix(), disc3->transform(tgContext).matrix()); BOOST_CHECK(reversed); auto [disc3Reversed, reversed2] = - disc2->mergedWith(*disc, Acts::BinningValue::binPhi, false, *logger); + disc2->mergedWith(*disc, Acts::AxisDirection::AxisPhi, false, *logger); BOOST_REQUIRE_NE(disc3Reversed, nullptr); BOOST_CHECK(*disc3 == *disc3Reversed); BOOST_CHECK(!reversed2); @@ -667,13 +670,13 @@ BOOST_DATA_TEST_CASE(PhiDirection, auto disc4 = makeDisc(base, 30_mm, 100_mm, 20_degree, a(170_degree)); auto disc5 = makeDisc(base, 30_mm, 100_mm, 10_degree, a(-160_degree)); auto [disc45, reversed45] = - disc4->mergedWith(*disc5, Acts::BinningValue::binPhi, false, *logger); + disc4->mergedWith(*disc5, Acts::AxisDirection::AxisPhi, false, *logger); BOOST_REQUIRE_NE(disc45, nullptr); BOOST_CHECK_EQUAL(base.matrix(), disc45->transform(tgContext).matrix()); BOOST_CHECK(reversed45); auto [disc54, reversed54] = - disc5->mergedWith(*disc4, Acts::BinningValue::binPhi, false, *logger); + disc5->mergedWith(*disc4, Acts::AxisDirection::AxisPhi, false, *logger); BOOST_REQUIRE_NE(disc54, nullptr); BOOST_CHECK(!reversed54); @@ -693,14 +696,14 @@ BOOST_DATA_TEST_CASE(PhiDirection, auto disc7 = makeDisc(base, 30_mm, 100_mm, 90_degree, a(180_degree)); auto [disc67, reversed67] = - disc6->mergedWith(*disc7, Acts::BinningValue::binPhi, false, *logger); + disc6->mergedWith(*disc7, Acts::AxisDirection::AxisPhi, false, *logger); BOOST_REQUIRE_NE(disc67, nullptr); CHECK_CLOSE_OR_SMALL(disc67->transform(tgContext).matrix(), base.matrix(), 1e-6, 1e-10); BOOST_CHECK(!reversed67); auto [disc76, reversed76] = - disc7->mergedWith(*disc6, Acts::BinningValue::binPhi, false, *logger); + disc7->mergedWith(*disc6, Acts::AxisDirection::AxisPhi, false, *logger); BOOST_REQUIRE_NE(disc76, nullptr); // surfaces are not equal because bounds are not equal BOOST_CHECK(*disc76 != *disc67); @@ -729,7 +732,7 @@ BOOST_DATA_TEST_CASE(PhiDirection, auto disc2 = makeDisc(trf2, 30_mm, 100_mm, 45_degree, 0_degree); auto [disc3, reversed] = - disc->mergedWith(*disc2, Acts::BinningValue::binPhi, true, *logger); + disc->mergedWith(*disc2, Acts::AxisDirection::AxisPhi, true, *logger); BOOST_REQUIRE_NE(disc3, nullptr); Transform3 trfExpected12 = base * AngleAxis3(a(85_degree), Vector3::UnitZ()); @@ -738,7 +741,7 @@ BOOST_DATA_TEST_CASE(PhiDirection, BOOST_CHECK(reversed); auto [disc3Reversed, reversed2] = - disc2->mergedWith(*disc, Acts::BinningValue::binPhi, true, *logger); + disc2->mergedWith(*disc, Acts::AxisDirection::AxisPhi, true, *logger); BOOST_REQUIRE_NE(disc3Reversed, nullptr); BOOST_CHECK(*disc3 == *disc3Reversed); BOOST_CHECK(!reversed2); @@ -755,7 +758,7 @@ BOOST_DATA_TEST_CASE(PhiDirection, Transform3 trf5 = base * AngleAxis3(a(-160_degree), Vector3::UnitZ()); auto disc5 = makeDisc(trf5, 30_mm, 100_mm, 10_degree, 0_degree); auto [disc45, reversed45] = - disc4->mergedWith(*disc5, Acts::BinningValue::binPhi, true, *logger); + disc4->mergedWith(*disc5, Acts::AxisDirection::AxisPhi, true, *logger); BOOST_REQUIRE_NE(disc45, nullptr); Transform3 trfExpected45 = base * AngleAxis3(a(180_degree), Vector3::UnitZ()); @@ -764,7 +767,7 @@ BOOST_DATA_TEST_CASE(PhiDirection, BOOST_CHECK(reversed45); auto [disc54, reversed54] = - disc5->mergedWith(*disc4, Acts::BinningValue::binPhi, true, *logger); + disc5->mergedWith(*disc4, Acts::AxisDirection::AxisPhi, true, *logger); BOOST_REQUIRE_NE(disc54, nullptr); BOOST_CHECK(!reversed54); @@ -782,7 +785,7 @@ BOOST_DATA_TEST_CASE(PhiDirection, Transform3 trf7 = base * AngleAxis3(a(180_degree), Vector3::UnitZ()); auto disc7 = makeDisc(trf7, 30_mm, 100_mm, 90_degree, 0_degree); auto [disc67, reversed67] = - disc6->mergedWith(*disc7, Acts::BinningValue::binPhi, true, *logger); + disc6->mergedWith(*disc7, Acts::AxisDirection::AxisPhi, true, *logger); BOOST_REQUIRE_NE(disc67, nullptr); Transform3 trfExpected67 = base * AngleAxis3(a(90_degree), Vector3::UnitZ()); @@ -791,7 +794,7 @@ BOOST_DATA_TEST_CASE(PhiDirection, BOOST_CHECK(!reversed67); auto [disc76, reversed76] = - disc7->mergedWith(*disc6, Acts::BinningValue::binPhi, true, *logger); + disc7->mergedWith(*disc6, Acts::AxisDirection::AxisPhi, true, *logger); BOOST_REQUIRE_NE(disc76, nullptr); // surfaces are not equal due to different transforms BOOST_CHECK(*disc76 != *disc67); diff --git a/Tests/UnitTests/Core/Surfaces/LineSurfaceTests.cpp b/Tests/UnitTests/Core/Surfaces/LineSurfaceTests.cpp index 0721039acef..e9577bc8fa6 100644 --- a/Tests/UnitTests/Core/Surfaces/LineSurfaceTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/LineSurfaceTests.cpp @@ -92,13 +92,14 @@ BOOST_AUTO_TEST_CASE(LineSurface_Constructors_test) { /// Unit tests of all named methods BOOST_AUTO_TEST_CASE(LineSurface_allNamedMethods_test) { - // binningPosition() + // referencePosition() Translation3 translation{0., 1., 2.}; Transform3 transform(translation); LineSurfaceStub line(transform, 2., 20.); Vector3 referencePosition{0., 1., 2.}; CHECK_CLOSE_ABS(referencePosition, - line.binningPosition(tgContext, BinningValue::binX), 1e-6); + line.referencePosition(tgContext, AxisDirection::AxisX), + 1e-6); // bounds() auto pLineBounds = std::make_shared(2., 10.); @@ -320,7 +321,7 @@ BOOST_AUTO_TEST_CASE(LineSurfaceIntersection) { ParticleHypothesis::pion()}; { PropagatorOptions options(tgContext, {}); - options.direction = Acts::Direction::Backward; + options.direction = Acts::Direction::Backward(); options.pathLimit = pathLimit; auto result = propagator.propagate(initialParams, options); @@ -342,7 +343,7 @@ BOOST_AUTO_TEST_CASE(LineSurfaceIntersection) { std::nullopt, ParticleHypothesis::pion()}; { PropagatorOptions options(tgContext, {}); - options.direction = Acts::Direction::Forward; + options.direction = Acts::Direction::Forward(); options.stepping.maxStepSize = 1_mm; auto result = propagator.propagate(displacedParameters, *surface, options); diff --git a/Tests/UnitTests/Core/Surfaces/PlaneSurfaceTests.cpp b/Tests/UnitTests/Core/Surfaces/PlaneSurfaceTests.cpp index b62517f3e2c..bd045b72888 100644 --- a/Tests/UnitTests/Core/Surfaces/PlaneSurfaceTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/PlaneSurfaceTests.cpp @@ -6,6 +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 @@ -21,10 +22,10 @@ #include "Acts/Surfaces/RectangleBounds.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Surfaces/SurfaceBounds.hpp" +#include "Acts/Surfaces/SurfaceMergingException.hpp" #include "Acts/Surfaces/TrapezoidBounds.hpp" #include "Acts/Tests/CommonHelpers/DetectorElementStub.hpp" #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp" -#include "Acts/Utilities/BinningType.hpp" #include "Acts/Utilities/Intersection.hpp" #include "Acts/Utilities/Result.hpp" #include "Acts/Utilities/ThrowAssert.hpp" @@ -97,11 +98,11 @@ BOOST_AUTO_TEST_CASE(PlaneSurfaceProperties) { /// Test type (redundant) BOOST_CHECK_EQUAL(planeSurfaceObject->type(), Surface::Plane); - /// Test binningPosition - Vector3 binningPosition{0., 1., 2.}; + /// Test referencePosition + Vector3 referencePosition{0., 1., 2.}; BOOST_CHECK_EQUAL( - planeSurfaceObject->binningPosition(tgContext, BinningValue::binX), - binningPosition); + planeSurfaceObject->referencePosition(tgContext, AxisDirection::AxisX), + referencePosition); /// Test referenceFrame Vector3 arbitraryGlobalPosition{2., 2., 2.}; @@ -246,21 +247,21 @@ BOOST_AUTO_TEST_CASE(PlaneSurfaceExtent) { auto planeExtent = plane->polyhedronRepresentation(tgContext, 1).extent(); - CHECK_CLOSE_ABS(planeExtent.min(BinningValue::binZ), -rHx, + CHECK_CLOSE_ABS(planeExtent.min(AxisDirection::AxisZ), -rHx, s_onSurfaceTolerance); - CHECK_CLOSE_ABS(planeExtent.max(BinningValue::binZ), rHx, + CHECK_CLOSE_ABS(planeExtent.max(AxisDirection::AxisZ), rHx, s_onSurfaceTolerance); - CHECK_CLOSE_ABS(planeExtent.min(BinningValue::binX), -rHy, + CHECK_CLOSE_ABS(planeExtent.min(AxisDirection::AxisX), -rHy, s_onSurfaceTolerance); - CHECK_CLOSE_ABS(planeExtent.max(BinningValue::binX), rHy, + CHECK_CLOSE_ABS(planeExtent.max(AxisDirection::AxisX), rHy, s_onSurfaceTolerance); - CHECK_CLOSE_ABS(planeExtent.min(BinningValue::binY), yPs, + CHECK_CLOSE_ABS(planeExtent.min(AxisDirection::AxisY), yPs, s_onSurfaceTolerance); - CHECK_CLOSE_ABS(planeExtent.max(BinningValue::binY), yPs, + CHECK_CLOSE_ABS(planeExtent.max(AxisDirection::AxisY), yPs, s_onSurfaceTolerance); - CHECK_CLOSE_ABS(planeExtent.min(BinningValue::binR), yPs, + CHECK_CLOSE_ABS(planeExtent.min(AxisDirection::AxisR), yPs, s_onSurfaceTolerance); - CHECK_CLOSE_ABS(planeExtent.max(BinningValue::binR), std::hypot(yPs, rHy), + CHECK_CLOSE_ABS(planeExtent.max(AxisDirection::AxisR), std::hypot(yPs, rHy), s_onSurfaceTolerance); // Now rotate @@ -272,20 +273,20 @@ BOOST_AUTO_TEST_CASE(PlaneSurfaceExtent) { auto planeExtentRot = planeRot->polyhedronRepresentation(tgContext, 1).extent(); - CHECK_CLOSE_ABS(planeExtentRot.min(BinningValue::binZ), -rHx, + CHECK_CLOSE_ABS(planeExtentRot.min(AxisDirection::AxisZ), -rHx, s_onSurfaceTolerance); - CHECK_CLOSE_ABS(planeExtentRot.max(BinningValue::binZ), rHx, + CHECK_CLOSE_ABS(planeExtentRot.max(AxisDirection::AxisZ), rHx, s_onSurfaceTolerance); - CHECK_CLOSE_ABS(planeExtentRot.min(BinningValue::binX), + CHECK_CLOSE_ABS(planeExtentRot.min(AxisDirection::AxisX), -rHy * std::cos(alpha), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(planeExtentRot.max(BinningValue::binX), rHy * std::cos(alpha), - s_onSurfaceTolerance); - CHECK_CLOSE_ABS(planeExtentRot.min(BinningValue::binY), + CHECK_CLOSE_ABS(planeExtentRot.max(AxisDirection::AxisX), + rHy * std::cos(alpha), s_onSurfaceTolerance); + CHECK_CLOSE_ABS(planeExtentRot.min(AxisDirection::AxisY), yPs - rHy * std::sin(alpha), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(planeExtentRot.max(BinningValue::binY), + CHECK_CLOSE_ABS(planeExtentRot.max(AxisDirection::AxisY), yPs + rHy * std::sin(alpha), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(planeExtentRot.min(BinningValue::binR), yPs * std::cos(alpha), - s_onSurfaceTolerance); + CHECK_CLOSE_ABS(planeExtentRot.min(AxisDirection::AxisR), + yPs * std::cos(alpha), s_onSurfaceTolerance); } BOOST_AUTO_TEST_CASE(RotatedTrapezoid) { @@ -378,6 +379,169 @@ BOOST_AUTO_TEST_CASE(PlaneSurfaceAlignment) { CHECK_CLOSE_ABS(alignToloc1, expAlignToloc1, 1e-10); } +BOOST_AUTO_TEST_SUITE(PlaneSurfaceMerging) + +auto logger = Acts::getDefaultLogger("UnitTests", Acts::Logging::VERBOSE); + +// Create a test context +GeometryContext gctx = GeometryContext(); + +auto rBounds = std::make_shared(1., 2.); + +BOOST_AUTO_TEST_CASE(SurfaceOverlap) { + // Correct orientation, overlapping along merging direction + Translation3 offsetX{4., 0., 0.}; + Translation3 offsetY{0., 2., 0.}; + + Transform3 base(Translation3::Identity()); + Transform3 otherX = base * offsetX; + Transform3 otherY = base * offsetY; + + auto plane = Surface::makeShared(base, rBounds); + auto planeX = Surface::makeShared(otherX, rBounds); + auto planeY = Surface::makeShared(otherY, rBounds); + + BOOST_CHECK_THROW(plane->mergedWith(*planeX, Acts::AxisDirection::AxisX), + SurfaceMergingException); + BOOST_CHECK_THROW(plane->mergedWith(*planeY, Acts::AxisDirection::AxisY), + SurfaceMergingException); + + BOOST_CHECK_THROW(planeX->mergedWith(*plane, Acts::AxisDirection::AxisX), + SurfaceMergingException); + BOOST_CHECK_THROW(planeY->mergedWith(*plane, Acts::AxisDirection::AxisY), + SurfaceMergingException); +} + +BOOST_AUTO_TEST_CASE(SurfaceMisalignmentShift) { + // Correct orientation, not aligned along orthogonal to merging direction + Translation3 offsetX{2., 1., 0.}; + Translation3 offsetY{-1., 4., 0.}; + Translation3 offsetZ{0., 4., 1.}; + + Transform3 base(Translation3::Identity()); + Transform3 otherX = base * offsetX; + Transform3 otherY = base * offsetY; + Transform3 otherZ = base * offsetZ; + + auto plane = Surface::makeShared(base, rBounds); + auto planeX = Surface::makeShared(otherX, rBounds); + auto planeY = Surface::makeShared(otherY, rBounds); + auto planeZ = Surface::makeShared(otherZ, rBounds); + + BOOST_CHECK_THROW(plane->mergedWith(*planeX, Acts::AxisDirection::AxisX), + SurfaceMergingException); + BOOST_CHECK_THROW(plane->mergedWith(*planeY, Acts::AxisDirection::AxisY), + SurfaceMergingException); + BOOST_CHECK_THROW(plane->mergedWith(*planeZ, Acts::AxisDirection::AxisX), + SurfaceMergingException); + + BOOST_CHECK_THROW(planeX->mergedWith(*plane, Acts::AxisDirection::AxisX), + SurfaceMergingException); + BOOST_CHECK_THROW(planeY->mergedWith(*plane, Acts::AxisDirection::AxisY), + SurfaceMergingException); + BOOST_CHECK_THROW(planeZ->mergedWith(*plane, Acts::AxisDirection::AxisX), + SurfaceMergingException); +} + +BOOST_AUTO_TEST_CASE(SurfaceMisalignedAngle) { + // Correct positioning, rotated in different directions + Translation3 offsetX{2., 0., 0.}; + Translation3 offsetY{0., 4., 0.}; + + double angle = std::numbers::pi / 12; + Transform3 base(Translation3::Identity()); + Transform3 otherX = base * offsetX * AngleAxis3(angle, Vector3::UnitZ()); + Transform3 otherY = base * offsetY * AngleAxis3(angle, Vector3::UnitY()); + Transform3 otherZ = base * offsetY * AngleAxis3(angle, Vector3::UnitZ()); + + auto plane = Surface::makeShared(base, rBounds); + auto planeX = Surface::makeShared(otherX, rBounds); + auto planeY = Surface::makeShared(otherY, rBounds); + auto planeZ = Surface::makeShared(otherZ, rBounds); + + BOOST_CHECK_THROW(plane->mergedWith(*planeX, Acts::AxisDirection::AxisX), + SurfaceMergingException); + BOOST_CHECK_THROW(plane->mergedWith(*planeY, Acts::AxisDirection::AxisY), + SurfaceMergingException); + BOOST_CHECK_THROW(plane->mergedWith(*planeZ, Acts::AxisDirection::AxisY), + SurfaceMergingException); + + BOOST_CHECK_THROW(planeX->mergedWith(*plane, Acts::AxisDirection::AxisX), + SurfaceMergingException); + BOOST_CHECK_THROW(planeY->mergedWith(*plane, Acts::AxisDirection::AxisY), + SurfaceMergingException); + BOOST_CHECK_THROW(planeZ->mergedWith(*plane, Acts::AxisDirection::AxisY), + SurfaceMergingException); +} + +BOOST_AUTO_TEST_CASE(SurfaceDifferentBounds) { + // Correct orientation and alignment, different bounds lengths along + // orthogonal to merging direction + Translation3 offset{2., 0., 0.}; + + Transform3 base(Translation3::Identity()); + Transform3 other = base * offset; + + auto plane = Surface::makeShared(base, rBounds); + + auto rBoundsOther = std::make_shared(2., 4.); + auto planeOther = Surface::makeShared(other, rBoundsOther); + + BOOST_CHECK_THROW(plane->mergedWith(*planeOther, Acts::AxisDirection::AxisX), + SurfaceMergingException); +} + +BOOST_AUTO_TEST_CASE(XYDirection) { + double angle = std::numbers::pi / 12; + Translation3 offsetX{2., 0., 0.}; + Translation3 offsetY{0., 4., 0.}; + + Transform3 base = + AngleAxis3(angle, Vector3::UnitX()) * Translation3::Identity(); + Transform3 otherX = base * offsetX; + Transform3 otherY = base * offsetY; + + auto plane = Surface::makeShared(base, rBounds); + auto planeX = Surface::makeShared(otherX, rBounds); + auto planeY = Surface::makeShared(otherY, rBounds); + + BOOST_CHECK_THROW(plane->mergedWith(*planeX, Acts::AxisDirection::AxisZ), + SurfaceMergingException); + + auto expectedBoundsX = std::make_shared(2, 2); + auto [planeXMerged, reversedX] = + plane->mergedWith(*planeX, Acts::AxisDirection::AxisX, *logger); + BOOST_REQUIRE_NE(planeXMerged, nullptr); + BOOST_CHECK(!reversedX); + BOOST_CHECK_EQUAL(planeXMerged->bounds(), *expectedBoundsX); + BOOST_CHECK_EQUAL(planeXMerged->center(gctx), base * Vector3::UnitX() * 1); + + auto expectedBoundsY = std::make_shared(1, 4); + auto [planeYMerged, reversedY] = + plane->mergedWith(*planeY, Acts::AxisDirection::AxisY, *logger); + BOOST_REQUIRE_NE(planeYMerged, nullptr); + BOOST_CHECK(!reversedY); + BOOST_CHECK_EQUAL(planeYMerged->bounds(), *expectedBoundsY); + BOOST_CHECK_EQUAL(planeYMerged->center(gctx), base * Vector3::UnitY() * 2); + + auto [planeXMerged2, reversedX2] = + planeX->mergedWith(*plane, Acts::AxisDirection::AxisX, *logger); + BOOST_REQUIRE_NE(planeXMerged2, nullptr); + BOOST_CHECK(planeXMerged->bounds() == planeXMerged2->bounds()); + BOOST_CHECK(reversedX2); + BOOST_CHECK_EQUAL(planeXMerged2->bounds(), *expectedBoundsX); + BOOST_CHECK_EQUAL(planeXMerged2->center(gctx), base * Vector3::UnitX() * 1); + + auto [planeYMerged2, reversedY2] = + planeY->mergedWith(*plane, Acts::AxisDirection::AxisY, *logger); + BOOST_REQUIRE_NE(planeYMerged2, nullptr); + BOOST_CHECK(planeYMerged->bounds() == planeYMerged2->bounds()); + BOOST_CHECK(reversedY2); + BOOST_CHECK_EQUAL(planeYMerged2->bounds(), *expectedBoundsY); + BOOST_CHECK_EQUAL(planeYMerged2->center(gctx), base * Vector3::UnitY() * 2); +} + +BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END() } // namespace Acts::Test diff --git a/Tests/UnitTests/Core/Surfaces/PolyhedronSurfacesTests.cpp b/Tests/UnitTests/Core/Surfaces/PolyhedronSurfacesTests.cpp index 8029a53426b..fc8a865f813 100644 --- a/Tests/UnitTests/Core/Surfaces/PolyhedronSurfacesTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/PolyhedronSurfacesTests.cpp @@ -70,14 +70,14 @@ BOOST_AUTO_TEST_CASE(ConeSurfacePolyhedrons) { auto oneConePh = oneCone->polyhedronRepresentation(tgContext, segments); const auto extent = oneConePh.extent(); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).min(), -rMax, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).max(), rMax, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).min(), -rMax, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).max(), rMax, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).min(), 0_mm, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).max(), rMax, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).min(), 0_mm, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).max(), hzPos, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -rMax, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), rMax, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -rMax, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), rMax, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), 0_mm, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), rMax, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0_mm, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), hzPos, epsAbs); const unsigned int expectedFaces = 4 * segments; BOOST_CHECK_EQUAL(oneConePh.faces.size(), expectedFaces); @@ -97,14 +97,14 @@ BOOST_AUTO_TEST_CASE(ConeSurfacePolyhedrons) { oneConePiece->polyhedronRepresentation(tgContext, segments); const auto extent = oneConePiecePh.extent(); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).min(), -rMax, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).max(), rMax, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).min(), -rMax, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).max(), rMax, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).min(), rMin, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).max(), rMax, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).min(), hzpMin, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).max(), hzPos, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -rMax, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), rMax, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -rMax, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), rMax, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), rMin, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), rMax, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), hzpMin, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), hzPos, epsAbs); const unsigned int expectedFaces = 4 * segments; BOOST_CHECK_EQUAL(oneConePiecePh.faces.size(), expectedFaces); @@ -119,14 +119,14 @@ BOOST_AUTO_TEST_CASE(ConeSurfacePolyhedrons) { auto twoConesPh = twoCones->polyhedronRepresentation(tgContext, segments); const auto extent = twoConesPh.extent(); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).min(), -rMax, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).max(), rMax, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).min(), -rMax, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).max(), rMax, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).min(), 0_mm, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).max(), rMax, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).min(), hzNeg, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).max(), hzPos, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -rMax, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), rMax, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -rMax, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), rMax, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), 0_mm, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), rMax, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), hzNeg, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), hzPos, epsAbs); const unsigned int expectedFaces = 2 * segments * 4; const unsigned int expectedVertices = 2 * (4 * segments + 1) + 1; @@ -147,16 +147,16 @@ BOOST_AUTO_TEST_CASE(ConeSurfacePolyhedrons) { sectoralCones->polyhedronRepresentation(tgContext, segments); const auto extent = sectoralConesPh.extent(); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).min(), 0, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).max(), rMax, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).min(), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), 0, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), rMax, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -rMax * std::sin(phiSector), epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).max(), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), rMax * std::sin(phiSector), epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).min(), 0_mm, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).max(), rMax, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).min(), hzNeg, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).max(), hzPos, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), 0_mm, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), rMax, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), hzNeg, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), hzPos, epsAbs); // Segment numbers are further checked with the VertexHelper checks } @@ -185,14 +185,14 @@ BOOST_AUTO_TEST_CASE(CylinderSurfacePolyhedrons) { fullCylinder->polyhedronRepresentation(tgContext, segments); const auto extent = fullCylinderPh.extent(); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).min(), -r, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).max(), r, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).min(), -r, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).max(), r, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).min(), r, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).max(), r, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).min(), -hZ, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).max(), hZ, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -r, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), r, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -r, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), r, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), r, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), r, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), -hZ, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), hZ, epsAbs); const unsigned int expectedFaces = 4 * segments; const unsigned int expectedVertices = (4 * segments + 1) * 2; @@ -211,17 +211,17 @@ BOOST_AUTO_TEST_CASE(CylinderSurfacePolyhedrons) { centerSectoredCylinder->polyhedronRepresentation(tgContext, segments); const auto extent = centerSectoredCylinderPh.extent(); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).min(), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), r * std::cos(phiSector), epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).max(), r, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).min(), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), r, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -r * std::sin(phiSector), epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).max(), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), r * std::sin(phiSector), epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).min(), r, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).max(), r, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).min(), -hZ, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).max(), hZ, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), r, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), r, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), -hZ, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), hZ, epsAbs); } } } @@ -247,14 +247,16 @@ BOOST_AUTO_TEST_CASE(DiscSurfacePolyhedrons) { auto fullDiscPh = fullDisc->polyhedronRepresentation(tgContext, segments); const auto extent = fullDiscPh.extent(); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).min(), -outerR, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).max(), outerR, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).min(), -outerR, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).max(), outerR, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).min(), 0., epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).max(), outerR, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).min(), 0., epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).max(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -outerR, + epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), outerR, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -outerR, + epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), outerR, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), outerR, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs); const unsigned int expectedFaces = 1; // Segments + overlap + center @@ -270,14 +272,16 @@ BOOST_AUTO_TEST_CASE(DiscSurfacePolyhedrons) { auto radialPh = radialDisc->polyhedronRepresentation(tgContext, segments); const auto extent = radialPh.extent(); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).min(), -outerR, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).max(), outerR, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).min(), -outerR, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).max(), outerR, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).min(), innerR, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).max(), outerR, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).min(), 0., epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).max(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -outerR, + epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), outerR, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -outerR, + epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), outerR, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), innerR, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), outerR, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs); } /// Sectoral disc - around 0. @@ -287,16 +291,16 @@ BOOST_AUTO_TEST_CASE(DiscSurfacePolyhedrons) { auto sectorPh = sectorDisc->polyhedronRepresentation(tgContext, segments); const auto extent = sectorPh.extent(); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).min(), 0., epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).max(), outerR, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).min(), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), outerR, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -outerR * std::sin(phiSector), epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).max(), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), outerR * std::sin(phiSector), epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).min(), 0., epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).max(), outerR, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).min(), 0., epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).max(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), outerR, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs); } /// Sectoral ring - around 0. @@ -309,17 +313,17 @@ BOOST_AUTO_TEST_CASE(DiscSurfacePolyhedrons) { sectorRingDisc->polyhedronRepresentation(tgContext, segments); const auto extent = sectorRingDiscPh.extent(); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).min(), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), innerR * std::cos(phiSector), epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).max(), outerR, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).min(), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), outerR, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -outerR * std::sin(phiSector), epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).max(), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), outerR * std::sin(phiSector), epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).min(), innerR, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).max(), outerR, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).min(), 0., epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).max(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), innerR, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), outerR, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs); } /// Trapezoid for a disc @@ -335,19 +339,20 @@ BOOST_AUTO_TEST_CASE(DiscSurfacePolyhedrons) { trapezoidDiscSf->polyhedronRepresentation(tgContext, segments); const auto extent = trapezoidDiscSfPh.extent(); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).min(), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -std::abs(outerR - innerR) / 2., epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).max(), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), std::abs(outerR - innerR) / 2., epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).min(), -halfXmax, + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -halfXmax, + epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), halfXmax, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).max(), halfXmax, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).min(), 0., epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).max(), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), std::hypot(std::abs(outerR - innerR) / 2., halfXmax), epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).min(), 0., epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).max(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs); } /// AnnulusBounds for a disc @@ -364,12 +369,12 @@ BOOST_AUTO_TEST_CASE(DiscSurfacePolyhedrons) { auto annulusDiscPh = annulusDisc->polyhedronRepresentation(tgContext, segments); const auto extent = annulusDiscPh.extent(); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).min(), minRadius, + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), minRadius, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).max(), maxRadius, + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), maxRadius, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).min(), 0., epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).max(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs); } } } @@ -396,15 +401,15 @@ BOOST_AUTO_TEST_CASE(PlaneSurfacePolyhedrons) { rectangularPlane->polyhedronRepresentation(tgContext, segments); const auto extent = rectangularPh.extent(); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).min(), -rhX, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).max(), rhX, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).min(), -rhY, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).max(), rhY, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).min(), 0., epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).max(), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -rhX, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), rhX, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -rhY, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), rhY, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), std::hypot(rhX, rhY), epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).min(), 0., epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).max(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs); BOOST_CHECK_EQUAL(rectangularPh.vertices.size(), 4); BOOST_CHECK_EQUAL(rectangularPh.faces.size(), 1); @@ -426,17 +431,17 @@ BOOST_AUTO_TEST_CASE(PlaneSurfacePolyhedrons) { trapezoidalPlane->polyhedronRepresentation(tgContext, segments); const auto extent = trapezoidalPh.extent(); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).min(), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -std::max(thX1, thX2), epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).max(), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), std::max(thX1, thX2), epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).min(), -thY, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).max(), thY, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).min(), 0., epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).max(), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -thY, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), thY, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), std::hypot(std::max(thX1, thX2), thY), epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).min(), 0., epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).max(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs); BOOST_CHECK_EQUAL(trapezoidalPh.vertices.size(), 4); BOOST_CHECK_EQUAL(trapezoidalPh.faces.size(), 1); @@ -459,16 +464,16 @@ BOOST_AUTO_TEST_CASE(PlaneSurfacePolyhedrons) { ellipsoidPlane->polyhedronRepresentation(tgContext, segments); const auto extent = ellipsoidPh.extent(); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).min(), -rMaxX, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).max(), rMaxX, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).min(), -rMaxY, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).max(), rMaxY, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).min(), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -rMaxX, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), rMaxX, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -rMaxY, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), rMaxY, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), std::min(rMinX, rMinY), epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).max(), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), std::max(rMaxX, rMaxY), epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).min(), 0., epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).max(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs); } { @@ -484,16 +489,16 @@ BOOST_AUTO_TEST_CASE(PlaneSurfacePolyhedrons) { ellipsoidRingPlane->polyhedronRepresentation(tgContext, segments); const auto extent = ellipsoidRingPh.extent(); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).min(), -rMaxX, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).max(), rMaxX, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).min(), -rMaxY, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).max(), rMaxY, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).min(), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -rMaxX, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), rMaxX, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -rMaxY, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), rMaxY, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), std::min(rMinX, rMinY), epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).max(), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), std::max(rMaxX, rMaxY), epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).min(), 0., epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).max(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs); } /// ConvexPolygonBounds test @@ -509,15 +514,15 @@ BOOST_AUTO_TEST_CASE(PlaneSurfacePolyhedrons) { hexagonPlane->polyhedronRepresentation(tgContext, segments); const auto extent = hexagonPlanePh.extent(); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).min(), -40, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).max(), 30, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).min(), -30, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).max(), 50, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).min(), 0, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).max(), std::sqrt(2900), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -40, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), 30, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -30, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), 50, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), 0, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), std::sqrt(2900), epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).min(), 0., epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).max(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs); } /// Diamond shaped plane @@ -535,15 +540,15 @@ BOOST_AUTO_TEST_CASE(PlaneSurfacePolyhedrons) { diamondPlane->polyhedronRepresentation(tgContext, segments); const auto extent = diamondPh.extent(); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).min(), -hMedX, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).max(), hMedX, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).min(), -hMinY, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).max(), hMaxY, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).min(), 0., epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).max(), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -hMedX, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), hMedX, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -hMinY, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), hMaxY, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), std::hypot(hMaxX, hMaxY), epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).min(), 0., epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).max(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs); BOOST_CHECK_EQUAL(diamondPh.vertices.size(), 6); BOOST_CHECK_EQUAL(diamondPh.faces.size(), 1); @@ -578,17 +583,17 @@ BOOST_AUTO_TEST_CASE(ShiftedSurfacePolyhedrons) { rectangularPlane->polyhedronRepresentation(tgContext, segments); const auto extent = rectangularPh.extent(); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).min(), -rhX, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binX).max(), rhX, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).min(), -rhY + shiftY, + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).min(), -rhX, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisX).max(), rhX, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).min(), -rhY + shiftY, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binY).max(), rhY + shiftY, + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisY).max(), rhY + shiftY, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).min(), 25, epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binR).max(), + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).min(), 25, epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisR).max(), std::hypot(rhX, rhY + shiftY), epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).min(), 0., epsAbs); - CHECK_CLOSE_ABS(extent.range(BinningValue::binZ).max(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).min(), 0., epsAbs); + CHECK_CLOSE_ABS(extent.range(AxisDirection::AxisZ).max(), 0., epsAbs); BOOST_CHECK_EQUAL(rectangularPh.vertices.size(), 4); BOOST_CHECK_EQUAL(rectangularPh.faces.size(), 1); diff --git a/Tests/UnitTests/Core/Surfaces/SurfaceArrayTests.cpp b/Tests/UnitTests/Core/Surfaces/SurfaceArrayTests.cpp index 732e7d9ff6a..bf2474d3101 100644 --- a/Tests/UnitTests/Core/Surfaces/SurfaceArrayTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/SurfaceArrayTests.cpp @@ -16,7 +16,7 @@ #include "Acts/Surfaces/Surface.hpp" #include "Acts/Surfaces/SurfaceArray.hpp" #include "Acts/Utilities/Axis.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/BinningType.hpp" #include "Acts/Utilities/Helpers.hpp" @@ -208,7 +208,7 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArray_create, SurfaceArrayFixture) { sa.toStream(tgContext, std::cout); for (const auto& srf : brl) { - Vector3 ctr = srf->binningPosition(tgContext, BinningValue::binR); + Vector3 ctr = srf->referencePosition(tgContext, AxisDirection::AxisR); std::vector binContent = sa.at(ctr); BOOST_CHECK_EQUAL(binContent.size(), 1u); @@ -228,7 +228,7 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArray_create, SurfaceArrayFixture) { SurfaceArray sa2(std::move(sl2), brl); sa.toStream(tgContext, std::cout); for (const auto& srf : brl) { - Vector3 ctr = srf->binningPosition(tgContext, BinningValue::binR); + Vector3 ctr = srf->referencePosition(tgContext, AxisDirection::AxisR); std::vector binContent = sa2.at(ctr); BOOST_CHECK_EQUAL(binContent.size(), 1u); diff --git a/Tests/UnitTests/Core/Surfaces/SurfaceStub.hpp b/Tests/UnitTests/Core/Surfaces/SurfaceStub.hpp index 647372e124c..4815420aa1c 100644 --- a/Tests/UnitTests/Core/Surfaces/SurfaceStub.hpp +++ b/Tests/UnitTests/Core/Surfaces/SurfaceStub.hpp @@ -76,8 +76,8 @@ class SurfaceStub : public RegularSurface { } /// Inherited from GeometryObject base - Vector3 binningPosition(const GeometryContext& /*txt*/, - BinningValue /*bValue*/) const final { + Vector3 referencePosition(const GeometryContext& /*txt*/, + AxisDirection /*bValue*/) const final { const Vector3 v{0., 0., 0.}; return v; } diff --git a/Tests/UnitTests/Core/Surfaces/TrapezoidBoundsTests.cpp b/Tests/UnitTests/Core/Surfaces/TrapezoidBoundsTests.cpp index 52155fec5fe..76ac35d4bd9 100644 --- a/Tests/UnitTests/Core/Surfaces/TrapezoidBoundsTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/TrapezoidBoundsTests.cpp @@ -189,7 +189,7 @@ BOOST_DATA_TEST_CASE( BoundaryTolerance tolerance = BoundaryTolerance::None(); if (tol != 0.) { - tolerance = BoundaryTolerance::AbsoluteBound{tol, tol}; + tolerance = BoundaryTolerance::AbsoluteBound(tol, tol); } BOOST_CHECK_EQUAL( diff --git a/Tests/UnitTests/Core/TrackFinding/CombinatorialKalmanFilterTests.cpp b/Tests/UnitTests/Core/TrackFinding/CombinatorialKalmanFilterTests.cpp index 6cb9559691c..22ce0a52c55 100644 --- a/Tests/UnitTests/Core/TrackFinding/CombinatorialKalmanFilterTests.cpp +++ b/Tests/UnitTests/Core/TrackFinding/CombinatorialKalmanFilterTests.cpp @@ -39,6 +39,7 @@ #include "Acts/Tests/CommonHelpers/MeasurementsCreator.hpp" #include "Acts/TrackFinding/CombinatorialKalmanFilter.hpp" #include "Acts/TrackFinding/MeasurementSelector.hpp" +#include "Acts/TrackFinding/TrackStateCreator.hpp" #include "Acts/TrackFitting/GainMatrixSmoother.hpp" #include "Acts/TrackFitting/GainMatrixUpdater.hpp" #include "Acts/TrackFitting/KalmanFitter.hpp" @@ -168,8 +169,7 @@ struct Fixture { std::unordered_multimap; using TestSourceLinkAccessor = TestContainerAccessor; using CombinatorialKalmanFilterOptions = - Acts::CombinatorialKalmanFilterOptions; + Acts::CombinatorialKalmanFilterOptions; KalmanUpdater kfUpdater; KalmanSmoother kfSmoother; @@ -201,13 +201,8 @@ struct Fixture { Acts::CombinatorialKalmanFilterExtensions getExtensions() const { Acts::CombinatorialKalmanFilterExtensions extensions; - extensions.calibrator.template connect< - &testSourceLinkCalibrator>(); extensions.updater.template connect< &KalmanUpdater::operator()>(&kfUpdater); - extensions.measurementSelector.template connect< - &Acts::MeasurementSelector::select>( - &measSel); return extensions; } @@ -289,14 +284,40 @@ struct Fixture { CombinatorialKalmanFilterOptions makeCkfOptions() const { // leave the accessor empty, this will have to be set before running the CKF return CombinatorialKalmanFilterOptions( - geoCtx, magCtx, calCtx, - Acts::SourceLinkAccessorDelegate{}, - getExtensions(), Acts::PropagatorPlainOptions(geoCtx, magCtx)); + geoCtx, magCtx, calCtx, getExtensions(), + Acts::PropagatorPlainOptions(geoCtx, magCtx)); } }; +// set up composable track state creator from these components: +// - source link accessor, +// - measurement selector +// - track state candidate creator +template +inline auto makeTrackStateCreator(const source_link_accessor_t& slAccessor, + const Acts::MeasurementSelector& measSel) { + using TrackStateCreatorType = + Acts::TrackStateCreator; + TrackStateCreatorType trackStateCreator; + trackStateCreator.sourceLinkAccessor + .template connect<&source_link_accessor_t::range>(&slAccessor); + trackStateCreator.calibrator.template connect< + &testSourceLinkCalibrator>(); + trackStateCreator.measurementSelector.template connect< + &Acts::MeasurementSelector::select>(&measSel); + return trackStateCreator; +} } // namespace +// somehow this is not automatically instantiated +template Acts::Result<::std::pair< + std::vector::iterator, + std::vector::iterator>> +Acts::MeasurementSelector::select( + std::vector&, bool&, + const Acts::Logger&) const; + BOOST_AUTO_TEST_SUITE(TrackFindingCombinatorialKalmanFilter) BOOST_AUTO_TEST_CASE(ZeroFieldForward) { @@ -304,7 +325,7 @@ BOOST_AUTO_TEST_CASE(ZeroFieldForward) { auto options = f.makeCkfOptions(); // this is the default option. set anyway for consistency - options.propagatorPlainOptions.direction = Acts::Direction::Forward; + options.propagatorPlainOptions.direction = Acts::Direction::Forward(); // Construct a plane surface as the target surface auto pSurface = Acts::CurvilinearSurface(Acts::Vector3{-3_m, 0., 0.}, Acts::Vector3{1., 0., 0}) @@ -312,8 +333,12 @@ BOOST_AUTO_TEST_CASE(ZeroFieldForward) { Fixture::TestSourceLinkAccessor slAccessor; slAccessor.container = &f.sourceLinks; - options.sourceLinkAccessor.connect<&Fixture::TestSourceLinkAccessor::range>( - &slAccessor); + + auto trackStateCreator = makeTrackStateCreator(slAccessor, f.measSel); + + options.extensions.createTrackStates + .template connect<&decltype(trackStateCreator)::createTrackStates>( + &trackStateCreator); TrackContainer tc{Acts::VectorTrackContainer{}, Acts::VectorMultiTrajectory{}}; @@ -362,7 +387,7 @@ BOOST_AUTO_TEST_CASE(ZeroFieldBackward) { Fixture f(0_T); auto options = f.makeCkfOptions(); - options.propagatorPlainOptions.direction = Acts::Direction::Backward; + options.propagatorPlainOptions.direction = Acts::Direction::Backward(); // Construct a plane surface as the target surface auto pSurface = Acts::CurvilinearSurface(Acts::Vector3{3_m, 0., 0.}, Acts::Vector3{1., 0., 0}) @@ -370,8 +395,11 @@ BOOST_AUTO_TEST_CASE(ZeroFieldBackward) { Fixture::TestSourceLinkAccessor slAccessor; slAccessor.container = &f.sourceLinks; - options.sourceLinkAccessor.connect<&Fixture::TestSourceLinkAccessor::range>( - &slAccessor); + + auto trackStateCreator = makeTrackStateCreator(slAccessor, f.measSel); + options.extensions.createTrackStates + .template connect<&decltype(trackStateCreator)::createTrackStates>( + &trackStateCreator); TrackContainer tc{Acts::VectorTrackContainer{}, Acts::VectorMultiTrajectory{}}; diff --git a/Tests/UnitTests/Core/TrackFinding/TrackParamsLookupAccumulatorTests.cpp b/Tests/UnitTests/Core/TrackFinding/TrackParamsLookupAccumulatorTests.cpp index 358753810db..af442f428d9 100644 --- a/Tests/UnitTests/Core/TrackFinding/TrackParamsLookupAccumulatorTests.cpp +++ b/Tests/UnitTests/Core/TrackFinding/TrackParamsLookupAccumulatorTests.cpp @@ -19,7 +19,7 @@ #include "Acts/Surfaces/Surface.hpp" #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp" #include "Acts/TrackFinding/TrackParamsLookupAccumulator.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Grid.hpp" #include "Acts/Utilities/GridAxisGenerators.hpp" diff --git a/Tests/UnitTests/Core/TrackFitting/FitterTestsCommon.hpp b/Tests/UnitTests/Core/TrackFitting/FitterTestsCommon.hpp index dca8ac045ca..757e6f5da81 100644 --- a/Tests/UnitTests/Core/TrackFitting/FitterTestsCommon.hpp +++ b/Tests/UnitTests/Core/TrackFitting/FitterTestsCommon.hpp @@ -236,7 +236,7 @@ struct FitterTester { // backward filtering requires a reference surface options.referenceSurface = &start.referenceSurface(); // this is the default option. set anyway for consistency - options.propagatorPlainOptions.direction = Acts::Direction::Forward; + options.propagatorPlainOptions.direction = Acts::Direction::Forward(); Acts::TrackContainer tracks{Acts::VectorTrackContainer{}, Acts::VectorMultiTrajectory{}}; @@ -295,7 +295,7 @@ struct FitterTester { Acts::ParticleHypothesis::pion()); options.referenceSurface = &startOuter.referenceSurface(); - options.propagatorPlainOptions.direction = Acts::Direction::Backward; + options.propagatorPlainOptions.direction = Acts::Direction::Backward(); Acts::TrackContainer tracks{Acts::VectorTrackContainer{}, Acts::VectorMultiTrajectory{}}; diff --git a/Tests/UnitTests/Core/Utilities/AxesTests.cpp b/Tests/UnitTests/Core/Utilities/AxesTests.cpp index 5c849e777ba..76ba41cf39e 100644 --- a/Tests/UnitTests/Core/Utilities/AxesTests.cpp +++ b/Tests/UnitTests/Core/Utilities/AxesTests.cpp @@ -10,7 +10,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Utilities/Axis.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include #include @@ -271,6 +271,8 @@ BOOST_AUTO_TEST_CASE(neighborhood) { bins_t({8, 9, 10, 1, 2})); BOOST_CHECK(a4.neighborHoodIndices(5, 2).collect() == bins_t({3, 4, 5, 6, 7})); + BOOST_CHECK(a4.neighborHoodIndices(3, 2).collect() == + bins_t({1, 2, 3, 4, 5})); Axis a5( {0.0, 2.0, 4.0, 9.0, 9.5, 10.0}); @@ -442,6 +444,202 @@ BOOST_AUTO_TEST_CASE(AxisVisit) { std::vector edges = varClosed.visit([](const auto& axis) { return axis.getBinEdges(); }); BOOST_CHECK_EQUAL(edges.size(), varClosed.getBinEdges().size()); + + // Test return values from visit method with type-dependent values + int typeValue = eqOpen.visit([](const auto& axis) { + if constexpr (std::is_same_v, + Axis>) { + return 1; + } else if constexpr (std::is_same_v, + Axis>) { + return 2; + } else if constexpr (std::is_same_v, + Axis>) { + return 3; + } else if constexpr (std::is_same_v, + Axis>) { + return 4; + } else if constexpr (std::is_same_v, + Axis>) { + return 5; + } else { + return 6; // Variable, Closed + } + }); + BOOST_CHECK_EQUAL(typeValue, 1); // Should be Equidistant, Open + + typeValue = eqBound.visit([](const auto& axis) { + if constexpr (std::is_same_v, + Axis>) { + return 1; + } else if constexpr (std::is_same_v, + Axis>) { + return 2; + } else if constexpr (std::is_same_v, + Axis>) { + return 3; + } else if constexpr (std::is_same_v, + Axis>) { + return 4; + } else if constexpr (std::is_same_v, + Axis>) { + return 5; + } else { + return 6; // Variable, Closed + } + }); + BOOST_CHECK_EQUAL(typeValue, 2); // Should be Equidistant, Bound + + typeValue = eqClosed.visit([](const auto& axis) { + if constexpr (std::is_same_v, + Axis>) { + return 1; + } else if constexpr (std::is_same_v, + Axis>) { + return 2; + } else if constexpr (std::is_same_v, + Axis>) { + return 3; + } else if constexpr (std::is_same_v, + Axis>) { + return 4; + } else if constexpr (std::is_same_v, + Axis>) { + return 5; + } else { + return 6; // Variable, Closed + } + }); + BOOST_CHECK_EQUAL(typeValue, 3); // Should be Equidistant, Closed + + typeValue = varOpen.visit([](const auto& axis) { + if constexpr (std::is_same_v, + Axis>) { + return 1; + } else if constexpr (std::is_same_v, + Axis>) { + return 2; + } else if constexpr (std::is_same_v, + Axis>) { + return 3; + } else if constexpr (std::is_same_v, + Axis>) { + return 4; + } else if constexpr (std::is_same_v, + Axis>) { + return 5; + } else { + return 6; // Variable, Closed + } + }); + BOOST_CHECK_EQUAL(typeValue, 4); // Should be Variable, Open + + typeValue = varBound.visit([](const auto& axis) { + if constexpr (std::is_same_v, + Axis>) { + return 1; + } else if constexpr (std::is_same_v, + Axis>) { + return 2; + } else if constexpr (std::is_same_v, + Axis>) { + return 3; + } else if constexpr (std::is_same_v, + Axis>) { + return 4; + } else if constexpr (std::is_same_v, + Axis>) { + return 5; + } else { + return 6; // Variable, Closed + } + }); + BOOST_CHECK_EQUAL(typeValue, 5); // Should be Variable, Bound + + typeValue = varClosed.visit([](const auto& axis) { + if constexpr (std::is_same_v, + Axis>) { + return 1; + } else if constexpr (std::is_same_v, + Axis>) { + return 2; + } else if constexpr (std::is_same_v, + Axis>) { + return 3; + } else if constexpr (std::is_same_v, + Axis>) { + return 4; + } else if constexpr (std::is_same_v, + Axis>) { + return 5; + } else { + return 6; // Variable, Closed + } + }); + BOOST_CHECK_EQUAL(typeValue, 6); // Should be Variable, Closed + + // Test return value using axis properties + double minValue = + eqOpen.visit([](const auto& axis) { return axis.getMin(); }); + BOOST_CHECK_EQUAL(minValue, 0.0); + + double maxValue = + eqBound.visit([](const auto& axis) { return axis.getMax(); }); + BOOST_CHECK_EQUAL(maxValue, 10.0); + + std::size_t nBins = + varClosed.visit([](const auto& axis) { return axis.getNBins(); }); + BOOST_CHECK_EQUAL(nBins, 4u); +} + +BOOST_AUTO_TEST_CASE(IAxis_Factories) { + using enum AxisType; + using enum AxisBoundaryType; + + // Equidistan: Bound, Open, Closed + auto eb = IAxis::createEquidistant(Bound, 0.0, 10., 10); + BOOST_CHECK_EQUAL(eb->getType(), Equidistant); + BOOST_CHECK_EQUAL(eb->getBoundaryType(), Bound); + + auto eo = IAxis::createEquidistant(Open, 0.0, 10., 10); + BOOST_CHECK_EQUAL(eo->getType(), Equidistant); + BOOST_CHECK_EQUAL(eo->getBoundaryType(), Open); + + auto ec = IAxis::createEquidistant(Closed, 0.0, 10., 10); + BOOST_CHECK_EQUAL(ec->getType(), Equidistant); + BOOST_CHECK_EQUAL(ec->getBoundaryType(), Closed); + + // Variable: Bound, Open, Closed + auto vb = IAxis::createVariable(Bound, {0, 1, 2., 3, 4}); + BOOST_CHECK_EQUAL(vb->getType(), Variable); + BOOST_CHECK_EQUAL(vb->getBoundaryType(), Bound); + + auto vo = IAxis::createVariable(Open, {0, 1, 2., 3, 4}); + BOOST_CHECK_EQUAL(vo->getType(), Variable); + BOOST_CHECK_EQUAL(vo->getBoundaryType(), Open); + + auto vc = IAxis::createVariable(Closed, {0, 1, 2., 3, 4}); + BOOST_CHECK_EQUAL(vc->getType(), Variable); + BOOST_CHECK_EQUAL(vc->getBoundaryType(), Closed); + + // Invalid constructors + // min > max + BOOST_CHECK_THROW(IAxis::createEquidistant(Bound, 10., 0., 3.), + std::invalid_argument); + // nBins = 0 + BOOST_CHECK_THROW(IAxis::createEquidistant(Bound, 0., 10., 0.), + std::invalid_argument); + // #edges < 2 + BOOST_CHECK_THROW(IAxis::createVariable(Bound, std::vector{2.}), + std::invalid_argument); + // edges not ordered + BOOST_CHECK_THROW( + IAxis::createVariable(Bound, std::vector{2., 1.5, 1.}), + std::invalid_argument); + + // Test memory management + auto axis = IAxis::createEquidistant(Bound, 0.0, 10., 10); + BOOST_CHECK_NO_THROW(axis.reset()); } BOOST_AUTO_TEST_CASE(Output) { diff --git a/Tests/UnitTests/Core/Utilities/BinAdjustmentTests.cpp b/Tests/UnitTests/Core/Utilities/BinAdjustmentTests.cpp index 1db5ee9ccfe..ecf8d4ca457 100644 --- a/Tests/UnitTests/Core/Utilities/BinAdjustmentTests.cpp +++ b/Tests/UnitTests/Core/Utilities/BinAdjustmentTests.cpp @@ -28,8 +28,8 @@ namespace Acts::Test { BOOST_AUTO_TEST_CASE(BinAdjustment_Radial) { RadialBounds bound(50, 75, std::numbers::pi, 0); BinUtility bu; - bu += BinUtility(1, 0, 1, Acts::open, Acts::BinningValue::binR); - bu += BinUtility(1, 0, 1, Acts::closed, Acts::BinningValue::binPhi); + bu += BinUtility(1, 0, 1, Acts::open, Acts::AxisDirection::AxisR); + bu += BinUtility(1, 0, 1, Acts::closed, Acts::AxisDirection::AxisPhi); BinUtility buAdjust = adjustBinUtility(bu, bound, Transform3::Identity()); @@ -43,8 +43,8 @@ BOOST_AUTO_TEST_CASE(BinAdjustment_Radial) { BOOST_AUTO_TEST_CASE(BinAdjustment_Cylinder) { CylinderBounds bound(25, 50, std::numbers::pi / 4, 0); BinUtility bu; - bu += BinUtility(1, 0, 1, Acts::open, Acts::BinningValue::binPhi); - bu += BinUtility(1, 0, 1, Acts::open, Acts::BinningValue::binZ); + bu += BinUtility(1, 0, 1, Acts::open, Acts::AxisDirection::AxisPhi); + bu += BinUtility(1, 0, 1, Acts::open, Acts::AxisDirection::AxisZ); BinUtility buAdjust = adjustBinUtility(bu, bound, Transform3::Identity()); @@ -60,8 +60,8 @@ BOOST_AUTO_TEST_CASE(BinAdjustment_Cylinder) { BOOST_AUTO_TEST_CASE(BinAdjustment_Rectangle) { RectangleBounds bound(20, 30); BinUtility bu; - bu += BinUtility(1, 0, 1, Acts::open, Acts::BinningValue::binX); - bu += BinUtility(1, 0, 1, Acts::open, Acts::BinningValue::binY); + bu += BinUtility(1, 0, 1, Acts::open, Acts::AxisDirection::AxisX); + bu += BinUtility(1, 0, 1, Acts::open, Acts::AxisDirection::AxisY); BinUtility buAdjust = adjustBinUtility(bu, bound, Transform3::Identity()); @@ -75,8 +75,8 @@ BOOST_AUTO_TEST_CASE(BinAdjustment_Rectangle) { BOOST_AUTO_TEST_CASE(BinAdjustment_Trapezoid) { TrapezoidBounds bound(5, 15, 30); BinUtility bu; - bu += BinUtility(1, 0, 1, Acts::open, Acts::BinningValue::binX); - bu += BinUtility(1, 0, 1, Acts::open, Acts::BinningValue::binY); + bu += BinUtility(1, 0, 1, Acts::open, Acts::AxisDirection::AxisX); + bu += BinUtility(1, 0, 1, Acts::open, Acts::AxisDirection::AxisY); BinUtility buAdjust = adjustBinUtility(bu, bound, Transform3::Identity()); diff --git a/Tests/UnitTests/Core/Utilities/BinAdjustmentVolumeTests.cpp b/Tests/UnitTests/Core/Utilities/BinAdjustmentVolumeTests.cpp index 1b91120dd7f..2d6aa35e867 100644 --- a/Tests/UnitTests/Core/Utilities/BinAdjustmentVolumeTests.cpp +++ b/Tests/UnitTests/Core/Utilities/BinAdjustmentVolumeTests.cpp @@ -27,9 +27,9 @@ namespace Acts::Test { BOOST_AUTO_TEST_CASE(BinAdjustmentVolume_Cylinder) { CylinderVolumeBounds bound(10, 50, 150, std::numbers::pi / 2., 0); BinUtility bu; - bu += BinUtility(1, 0, 1, Acts::open, Acts::BinningValue::binR); - bu += BinUtility(1, 0, 1, Acts::open, Acts::BinningValue::binPhi); - bu += BinUtility(1, 0, 1, Acts::open, Acts::BinningValue::binZ); + bu += BinUtility(1, 0, 1, Acts::open, Acts::AxisDirection::AxisR); + bu += BinUtility(1, 0, 1, Acts::open, Acts::AxisDirection::AxisPhi); + bu += BinUtility(1, 0, 1, Acts::open, Acts::AxisDirection::AxisZ); BinUtility buAdjust = adjustBinUtility(bu, bound, Transform3::Identity()); @@ -47,9 +47,9 @@ BOOST_AUTO_TEST_CASE(BinAdjustmentVolume_Cylinder) { BOOST_AUTO_TEST_CASE(BinAdjustmentVolume_CutoutCylinder) { CutoutCylinderVolumeBounds bound(10, 20, 50, 100, 15); BinUtility bu; - bu += BinUtility(1, 0, 1, Acts::open, Acts::BinningValue::binR); - bu += BinUtility(1, 0, 1, Acts::closed, Acts::BinningValue::binPhi); - bu += BinUtility(1, 0, 1, Acts::open, Acts::BinningValue::binZ); + bu += BinUtility(1, 0, 1, Acts::open, Acts::AxisDirection::AxisR); + bu += BinUtility(1, 0, 1, Acts::closed, Acts::AxisDirection::AxisPhi); + bu += BinUtility(1, 0, 1, Acts::open, Acts::AxisDirection::AxisZ); BinUtility buAdjust = adjustBinUtility(bu, bound, Transform3::Identity()); @@ -65,9 +65,9 @@ BOOST_AUTO_TEST_CASE(BinAdjustmentVolume_CutoutCylinder) { BOOST_AUTO_TEST_CASE(BinAdjustmentVolume_Cuboid) { CuboidVolumeBounds bound(13, 23, 42); BinUtility bu; - bu += BinUtility(1, 0, 1, Acts::open, Acts::BinningValue::binX); - bu += BinUtility(1, 0, 1, Acts::open, Acts::BinningValue::binY); - bu += BinUtility(1, 0, 1, Acts::open, Acts::BinningValue::binZ); + bu += BinUtility(1, 0, 1, Acts::open, Acts::AxisDirection::AxisX); + bu += BinUtility(1, 0, 1, Acts::open, Acts::AxisDirection::AxisY); + bu += BinUtility(1, 0, 1, Acts::open, Acts::AxisDirection::AxisZ); BinUtility buAdjust = adjustBinUtility(bu, bound, Transform3::Identity()); diff --git a/Tests/UnitTests/Core/Utilities/BinUtilityTests.cpp b/Tests/UnitTests/Core/Utilities/BinUtilityTests.cpp index b44d939831f..ab38d7bd78a 100644 --- a/Tests/UnitTests/Core/Utilities/BinUtilityTests.cpp +++ b/Tests/UnitTests/Core/Utilities/BinUtilityTests.cpp @@ -27,12 +27,12 @@ BOOST_AUTO_TEST_CASE(BinUtility_equidistant_binning) { Vector3 edgePosition(0.5, 0.5, 0.5); // | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | - BinUtility xUtil_eq(10, 0., 10., open, BinningValue::binX); - BinUtility yUtil_eq(10, 0., 10., open, BinningValue::binY); - BinUtility zUtil_eq(10, 0., 10., open, BinningValue::binZ); + BinUtility xUtil_eq(10, 0., 10., open, AxisDirection::AxisX); + BinUtility yUtil_eq(10, 0., 10., open, AxisDirection::AxisY); + BinUtility zUtil_eq(10, 0., 10., open, AxisDirection::AxisZ); BOOST_CHECK_EQUAL(xUtil_eq.bins(), std::size_t{10}); // make it 2-dim - BinUtility xyUtil_eq(10, 0., 10., open, BinningValue::binX); + BinUtility xyUtil_eq(10, 0., 10., open, AxisDirection::AxisX); xyUtil_eq += yUtil_eq; BOOST_CHECK_EQUAL(xyUtil_eq.bins(), 100u); // make it 3-dim @@ -45,7 +45,7 @@ BOOST_AUTO_TEST_CASE(BinUtility_equidistant_binning) { BOOST_CHECK_EQUAL(xyzUtil_eq.dimensions(), 3u); // check equality operator - BinUtility xUtil_eq_copy(10, 0., 10., open, BinningValue::binX); + BinUtility xUtil_eq_copy(10, 0., 10., open, AxisDirection::AxisX); BOOST_CHECK_EQUAL(xUtil_eq_copy, xUtil_eq); BOOST_CHECK_NE(yUtil_eq, xUtil_eq); @@ -70,7 +70,7 @@ BOOST_AUTO_TEST_CASE(BinUtility_equidistant_binning) { // OPEN - equidistant binning tests BOOST_AUTO_TEST_CASE(BinUtility_arbitrary_binning) { std::vector bvalues = {-5., 0., 1., 1.1, 8.}; - BinUtility xUtil(bvalues, Acts::open, Acts::BinningValue::binX); + BinUtility xUtil(bvalues, Acts::open, Acts::AxisDirection::AxisX); // Underflow BOOST_CHECK_EQUAL(xUtil.bin(Vector3(-6., 0., 0.)), 0u); @@ -95,10 +95,10 @@ BOOST_AUTO_TEST_CASE(BinUtility_transform) { Transform3 transform_GtoL = transform_LtoG.inverse(); - BinUtility rUtil(10, 0., 100., open, BinningValue::binR); + BinUtility rUtil(10, 0., 100., open, AxisDirection::AxisR); BinUtility phiUtil(10, -std::numbers::pi, std::numbers::pi, closed, - BinningValue::binPhi); - BinUtility zUtil(10, -100., 100., open, BinningValue::binZ); + AxisDirection::AxisPhi); + BinUtility zUtil(10, -100., 100., open, AxisDirection::AxisZ); BinUtility noTranform; noTranform += rUtil; diff --git a/Tests/UnitTests/Core/Utilities/BinningDataTests.cpp b/Tests/UnitTests/Core/Utilities/BinningDataTests.cpp index 95de3899f92..ff99a53f709 100644 --- a/Tests/UnitTests/Core/Utilities/BinningDataTests.cpp +++ b/Tests/UnitTests/Core/Utilities/BinningDataTests.cpp @@ -37,36 +37,36 @@ Vector2 rphiPosition(3.5, std::numbers::pi / 8.); // x/y/zData // bin boundaries // | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -BinningData xData_eq(open, BinningValue::binX, 10, 0., 10.); -BinningData yData_eq(open, BinningValue::binY, 10, 0., 10.); -BinningData zData_eq(open, BinningValue::binZ, 10, 0., 10.); +BinningData xData_eq(open, AxisDirection::AxisX, 10, 0., 10.); +BinningData yData_eq(open, AxisDirection::AxisY, 10, 0., 10.); +BinningData zData_eq(open, AxisDirection::AxisZ, 10, 0., 10.); // r/phi/rphiData // bin boundaries // | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -BinningData rData_eq(open, BinningValue::binR, 10, 0., 10.); +BinningData rData_eq(open, AxisDirection::AxisR, 10, 0., 10.); // bin boundaries // > -PI | -3/5 PI | -1/5 PI | 1/5 PI | 3/5 PI | PI < -BinningData phiData_eq(closed, BinningValue::binPhi, 5, -std::numbers::pi, +BinningData phiData_eq(closed, AxisDirection::AxisPhi, 5, -std::numbers::pi, std::numbers::pi); -// BinningData rPhiData_eq(closed, BinningValue::binRPhi, 5, -std::numbers::pi, -// std::numbers::pi); h/etaData bin boundaries | 0 | 2 | 4 | 6 | 8 | 10 | -// BinningData hData_eq(open, BinningValue::binH, 5, 0., 10.); -// | -2.5 | -1.5 | -0.5 | 0.5 | 1.5 | 2.5 | -BinningData etaData_eq(open, BinningValue::binEta, 5, -2.5, 2.5); +// BinningData rPhiData_eq(closed, AxisDirection::AxisRPhi, 5, +// -std::numbers::pi, std::numbers::pi); h/etaData bin boundaries | 0 | 2 | 4 | +// 6 | 8 | 10 | BinningData hData_eq(open, AxisDirection::AxisTheta, 5, +// 0., 10.); | -2.5 | -1.5 | -0.5 | 0.5 | 1.5 | 2.5 | +BinningData etaData_eq(open, AxisDirection::AxisEta, 5, -2.5, 2.5); // Fest equality operator -BinningData xData_eq_copy(open, BinningValue::binX, 10, 0., 10.); +BinningData xData_eq_copy(open, AxisDirection::AxisX, 10, 0., 10.); // the binnings - arbitrary std::vector values = {0., 1., 2., 3., 4., 10.}; // bin boundaries // | 0 | 1 | 2 | 3 | 4 | 10 | -BinningData xData_arb(open, BinningValue::binX, values); -BinningData yData_arb(open, BinningValue::binY, values); +BinningData xData_arb(open, AxisDirection::AxisX, values); +BinningData yData_arb(open, AxisDirection::AxisY, values); // | -PI | -2 | -1 | 1 | 2 | PI | std::vector phiValues = {-std::numbers::pi, -2., -1., 1., 2., std::numbers::pi}; -BinningData phiData_arb(closed, BinningValue::binPhi, phiValues); +BinningData phiData_arb(closed, AxisDirection::AxisPhi, phiValues); // the binnings - arbitrary when switching to binary search - for boundary // sizes >= 50 @@ -80,24 +80,24 @@ double phiDelta = 0.1064; std::vector sstr = {0., 1., 1.5, 2., 3.}; // multiplicative auto xData_sstr_mult = - std::make_unique(open, BinningValue::binX, sstr); + std::make_unique(open, AxisDirection::AxisX, sstr); // | 0 | 1 | 1.5 | 2 | 3 | 4 | 4.5 | 5 | 6 | 7 | 7.5 | 8 | 9 | -BinningData xData_mult(open, BinningValue::binX, 3, 0., 9., +BinningData xData_mult(open, AxisDirection::AxisX, 3, 0., 9., std::move(xData_sstr_mult)); /// additive // | 0 | 1 | 1.5 | 2 | 3 | 4 | 5 | std::vector main_sstr = {0., 3., 4., 5.}; auto xData_sstr_add = - std::make_unique(open, BinningValue::binX, sstr); -BinningData xData_add(open, BinningValue::binX, main_sstr, + std::make_unique(open, AxisDirection::AxisX, sstr); +BinningData xData_add(open, AxisDirection::AxisX, main_sstr, std::move(xData_sstr_add)); -// enum BinningValue { BinningValue::binX, BinningValue::binY, -// BinningValue::binZ, BinningValue::binR, BinningValue::binPhi, -// BinningValue::binRPhi, BinningValue::binH, BinningValue::binEta } +// enum AxisDirection { AxisDirection::AxisX, AxisDirection::AxisY, +// AxisDirection::AxisZ, AxisDirection::AxisR, AxisDirection::AxisPhi, +// AxisDirection::AxisRPhi, AxisDirection::AxisTheta, AxisDirection::AxisEta } // // test the different binning values -BOOST_AUTO_TEST_CASE(BinningData_BinningValue) { +BOOST_AUTO_TEST_CASE(BinningData_AxisDirection) { // the binnings - arbitrary when switching to binary search - for boundary // sizes >= 50 std::vector values_binary; @@ -107,8 +107,8 @@ BOOST_AUTO_TEST_CASE(BinningData_BinningValue) { phiValues_binary.push_back(phiMin + i * phiDelta); } // bin boundaries when switching to binary search - for boundary sizes >= 50 - BinningData xData_arb_binary(open, BinningValue::binX, values_binary); - BinningData phiData_arb_binary(closed, BinningValue::binPhi, + BinningData xData_arb_binary(open, AxisDirection::AxisX, values_binary); + BinningData phiData_arb_binary(closed, AxisDirection::AxisPhi, phiValues_binary); /// x/y/zData /// check the global position requests @@ -170,8 +170,8 @@ BOOST_AUTO_TEST_CASE(BinningData_bins) { phiValues_binary.push_back(phiMin + i * phiDelta); } // bin boundaries when switching to binary search - for boundary sizes >= 50 - BinningData xData_arb_binary(open, BinningValue::binX, values_binary); - BinningData phiData_arb_binary(closed, BinningValue::binPhi, + BinningData xData_arb_binary(open, AxisDirection::AxisX, values_binary); + BinningData phiData_arb_binary(closed, AxisDirection::AxisPhi, phiValues_binary); /// x/y/zData /// check the global position requests @@ -239,8 +239,8 @@ BOOST_AUTO_TEST_CASE(BinningData_inside_outside) { phiValues_binary.push_back(phiMin + i * phiDelta); } // bin boundaries when switching to binary search - for boundary sizes >= 50 - BinningData xData_arb_binary(open, BinningValue::binX, values_binary); - BinningData phiData_arb_binary(closed, BinningValue::binPhi, + BinningData xData_arb_binary(open, AxisDirection::AxisX, values_binary); + BinningData phiData_arb_binary(closed, AxisDirection::AxisPhi, phiValues_binary); // check the global inside BOOST_CHECK_EQUAL(xData_eq.inside(xyzPosition), true); @@ -283,8 +283,8 @@ BOOST_AUTO_TEST_CASE(BinningData_open_close) { phiValues_binary.push_back(phiMin + i * phiDelta); } // bin boundaries when switching to binary search - for boundary sizes >= 50 - BinningData xData_arb_binary(open, BinningValue::binX, values_binary); - BinningData phiData_arb_binary(closed, BinningValue::binPhi, + BinningData xData_arb_binary(open, AxisDirection::AxisX, values_binary); + BinningData phiData_arb_binary(closed, AxisDirection::AxisPhi, phiValues_binary); // open values BOOST_CHECK_EQUAL(xData_eq.searchGlobal(xyzPositionOutside), std::size_t{9}); @@ -336,8 +336,8 @@ BOOST_AUTO_TEST_CASE(BinningData_bincenter) { phiValues_binary.push_back(phiMin + i * phiDelta); } // bin boundaries when switching to binary search - for boundary sizes >= 50 - BinningData xData_arb_binary(open, BinningValue::binX, values_binary); - BinningData phiData_arb_binary(closed, BinningValue::binPhi, + BinningData xData_arb_binary(open, AxisDirection::AxisX, values_binary); + BinningData phiData_arb_binary(closed, AxisDirection::AxisPhi, phiValues_binary); /// check the global position requests // | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | @@ -383,7 +383,7 @@ BOOST_AUTO_TEST_CASE(BinningData_phi_modules) { // n phi modules with phi boundary at -pi/+pi are checked above one module // expands over -pi/+pi const float deltaPhi = 0.1; - BinningData phiData_mod(closed, BinningValue::binPhi, 5, + BinningData phiData_mod(closed, AxisDirection::AxisPhi, 5, -std::numbers::pi + deltaPhi, std::numbers::pi + deltaPhi); diff --git a/Tests/UnitTests/Core/Utilities/CMakeLists.txt b/Tests/UnitTests/Core/Utilities/CMakeLists.txt index 955b58b31c9..4b6fe98de96 100644 --- a/Tests/UnitTests/Core/Utilities/CMakeLists.txt +++ b/Tests/UnitTests/Core/Utilities/CMakeLists.txt @@ -27,6 +27,7 @@ add_unittest(Logger LoggerTests.cpp) add_unittest(MaterialMapUtils MaterialMapUtilsTests.cpp) add_unittest(MultiIndex MultiIndexTests.cpp) add_unittest(Periodic PeriodicTests.cpp) +add_unittest(ProtoAxis ProtoAxisTests.cpp) add_unittest(Range1D Range1DTests.cpp) add_unittest(RangeXD RangeXDTests.cpp) add_unittest(Ray RayTest.cpp) diff --git a/Tests/UnitTests/Core/Utilities/GridAccessHelpersTests.cpp b/Tests/UnitTests/Core/Utilities/GridAccessHelpersTests.cpp index 5fbe3b1ffa4..cc310f7e37a 100644 --- a/Tests/UnitTests/Core/Utilities/GridAccessHelpersTests.cpp +++ b/Tests/UnitTests/Core/Utilities/GridAccessHelpersTests.cpp @@ -44,9 +44,9 @@ BOOST_AUTO_TEST_CASE(Grid1DAccess) { // Global access Vector3 gPosition{0.5, 3.5, 6.5}; - std::vector fCast = {Acts::BinningValue::binX}; - std::vector sCast = {Acts::BinningValue::binY}; - std::vector tCast = {Acts::BinningValue::binZ}; + std::vector fCast = {Acts::AxisDirection::AxisX}; + std::vector sCast = {Acts::AxisDirection::AxisY}; + std::vector tCast = {Acts::AxisDirection::AxisZ}; auto fgAccess = GridAccessHelpers::castPosition(gPosition, fCast); auto sgAccess = GridAccessHelpers::castPosition(gPosition, sCast); @@ -57,10 +57,10 @@ BOOST_AUTO_TEST_CASE(Grid1DAccess) { // Can this go into a delegate? auto gsu = std::make_unique< - const Acts::GridAccess::GlobalSubspace>(); + const Acts::GridAccess::GlobalSubspace>(); Acts::GridAccess::GlobalToGridLocal1DimDelegate gsuDelegate; gsuDelegate.connect< - &Acts::GridAccess::GlobalSubspace::toGridLocal>( + &Acts::GridAccess::GlobalSubspace::toGridLocal>( std::move(gsu)); BOOST_CHECK(gsuDelegate.connected()); @@ -88,26 +88,26 @@ BOOST_AUTO_TEST_CASE(Grid2DAccess) { // Global access Vector3 gPosition{0.5, 3.5, 6.5}; - std::vector fCast = {Acts::BinningValue::binX, - Acts::BinningValue::binY}; + std::vector fCast = {Acts::AxisDirection::AxisX, + Acts::AxisDirection::AxisY}; auto fgAccess = GridAccessHelpers::castPosition(gPosition, fCast); BOOST_CHECK_EQUAL(grid.atPosition(fgAccess), 300u); } BOOST_AUTO_TEST_CASE(GlobalToGridLocalTests) { - Acts::GridAccess::GlobalSubspace + Acts::GridAccess::GlobalSubspace gssXY; auto xy = gssXY.toGridLocal(Vector3{1., 2., 3.}); BOOST_CHECK_EQUAL(xy[0], 1.); BOOST_CHECK_EQUAL(xy[1], 2.); - Acts::GridAccess::GlobalSubspace gssZ; + Acts::GridAccess::GlobalSubspace gssZ; auto z = gssZ.toGridLocal(Vector3{1., 2., 3.}); BOOST_CHECK_EQUAL(z[0], 3.); Acts::GridAccess::Affine3Transformed< - Acts::GridAccess::GlobalSubspace> + Acts::GridAccess::GlobalSubspace> gssZT(gssZ, Acts::Transform3{Acts::Transform3::Identity()}.pretranslate( Vector3{0., 0., 100.})); diff --git a/Tests/UnitTests/Core/Utilities/GridAxisGeneratorsTests.cpp b/Tests/UnitTests/Core/Utilities/GridAxisGeneratorsTests.cpp index 4cfb0ea6088..5d865047d28 100644 --- a/Tests/UnitTests/Core/Utilities/GridAxisGeneratorsTests.cpp +++ b/Tests/UnitTests/Core/Utilities/GridAxisGeneratorsTests.cpp @@ -10,7 +10,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Utilities/Axis.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Grid.hpp" #include "Acts/Utilities/GridAxisGenerators.hpp" diff --git a/Tests/UnitTests/Core/Utilities/GridIterationTests.cpp b/Tests/UnitTests/Core/Utilities/GridIterationTests.cpp index 82a92a4be4a..30698c02435 100644 --- a/Tests/UnitTests/Core/Utilities/GridIterationTests.cpp +++ b/Tests/UnitTests/Core/Utilities/GridIterationTests.cpp @@ -8,7 +8,7 @@ #include -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Grid.hpp" #include "Acts/Utilities/GridIterator.hpp" diff --git a/Tests/UnitTests/Core/Utilities/GridTests.cpp b/Tests/UnitTests/Core/Utilities/GridTests.cpp index eceec2e6468..494c406bedc 100644 --- a/Tests/UnitTests/Core/Utilities/GridTests.cpp +++ b/Tests/UnitTests/Core/Utilities/GridTests.cpp @@ -11,7 +11,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp" #include "Acts/Utilities/Axis.hpp" -#include "Acts/Utilities/AxisFwd.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" #include "Acts/Utilities/Grid.hpp" #include "Acts/Utilities/detail/grid_helper.hpp" diff --git a/Tests/UnitTests/Core/Utilities/ProtoAxisTests.cpp b/Tests/UnitTests/Core/Utilities/ProtoAxisTests.cpp new file mode 100644 index 00000000000..1460131a7e9 --- /dev/null +++ b/Tests/UnitTests/Core/Utilities/ProtoAxisTests.cpp @@ -0,0 +1,204 @@ +// 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 + +#include "Acts/Tests/CommonHelpers/FloatComparisons.hpp" +#include "Acts/Utilities/Axis.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" +#include "Acts/Utilities/ProtoAxis.hpp" + +BOOST_AUTO_TEST_SUITE(ProtoAxis) + +BOOST_AUTO_TEST_CASE(EquidistantProtoAxis) { + using enum Acts::AxisBoundaryType; + using enum Acts::AxisDirection; + using enum Acts::AxisType; + + // Bound, equidistant axis + Acts::ProtoAxis epab(AxisX, Bound, 0.0, 1.0, 10); + + // Direct access + BOOST_CHECK_EQUAL(epab.getAxisDirection(), AxisX); + BOOST_CHECK(!epab.isAutorange()); + + // Access via IAxis + BOOST_CHECK(epab.getAxis().isEquidistant()); + + BOOST_CHECK(!epab.getAxis().isVariable()); + + auto edges = epab.getAxis().getBinEdges(); + BOOST_CHECK_EQUAL(edges.size(), 11); + + BOOST_CHECK_EQUAL(epab.getAxis().getType(), Equidistant); + + BOOST_CHECK_EQUAL(epab.getAxis().getBoundaryType(), Bound); + + BOOST_CHECK_EQUAL(epab.getAxis().getNBins(), 10); + + CHECK_CLOSE_ABS(epab.getAxis().getMin(), 0.0, 1e-15); + + CHECK_CLOSE_ABS(epab.getAxis().getMax(), 1.0, 1e-15); + + std::string rString = + "ProtoAxis: 10 bins in AxisX, equidistant within [0, 1]"; + std::string oString = epab.toString(); + BOOST_CHECK_EQUAL(rString, oString); + + // Create a grid from a single proto axis + auto grid1D = Acts::makeGrid(epab); + BOOST_CHECK(grid1D != nullptr); + BOOST_CHECK_EQUAL(grid1D->axes().size(), 1); + auto axis1D = + dynamic_cast*>( + grid1D->axes().front()); + BOOST_CHECK(axis1D != nullptr); + + // Open, equidistant axis + Acts::ProtoAxis epao(AxisY, Open, 0., 2.0, 10.); + BOOST_CHECK_EQUAL(epao.getAxis().getBoundaryType(), Open); + + // Create a 2D grid from a two proto axes + auto grid2D = Acts::makeGrid(epab, epao); + BOOST_CHECK(grid2D != nullptr); + auto grid2Daxes = grid2D->axes(); + BOOST_CHECK_EQUAL(grid2Daxes.size(), 2); + auto axis2D1 = + dynamic_cast*>( + grid2Daxes[0]); + BOOST_CHECK(axis2D1 != nullptr); + auto axis2D2 = + dynamic_cast*>( + grid2Daxes[1]); + BOOST_CHECK(axis2D2 != nullptr); + + // Invalid grid construction with two proto axis in the same direction + BOOST_CHECK_THROW(Acts::makeGrid(epab, epab), std::invalid_argument); + + // Invalid constructor, min > max + BOOST_CHECK_THROW(Acts::ProtoAxis(AxisZ, Bound, 1.0, 0.0, 10), + std::invalid_argument); + + // Invalid constructor, nbins < 1 + BOOST_CHECK_THROW(Acts::ProtoAxis(AxisZ, Bound, 0.0, 1.0, 0), + std::invalid_argument); + + // Invalid constructor, closed with something else than phi or rphi + std::vector invalidDirections = { + AxisX, AxisY, AxisZ, AxisR, AxisEta, AxisTheta, AxisMag}; + for (const auto& adir : invalidDirections) { + BOOST_CHECK_THROW(Acts::ProtoAxis(adir, Closed, 0.0, 1.0, 10), + std::invalid_argument); + } +} + +BOOST_AUTO_TEST_CASE(AutorangeProtoAxis) { + using enum Acts::AxisBoundaryType; + using enum Acts::AxisDirection; + using enum Acts::AxisType; + + // Bound, equidistant axis, autorange + Acts::ProtoAxis epa(AxisX, Bound, 10); + + // Direct access + BOOST_CHECK_EQUAL(epa.getAxisDirection(), AxisX); + + BOOST_CHECK(epa.isAutorange()); + + // Access via IAxis + BOOST_CHECK(epa.getAxis().isEquidistant()); + + BOOST_CHECK(!epa.getAxis().isVariable()); + + BOOST_CHECK_EQUAL(epa.getAxis().getType(), Equidistant); + + BOOST_CHECK_EQUAL(epa.getAxis().getBoundaryType(), Bound); + + BOOST_CHECK_EQUAL(epa.getAxis().getNBins(), 10); + + std::string rString = + "ProtoAxis: 10 bins in AxisX, equidistant within automatic range"; + std::string oString = epa.toString(); + BOOST_CHECK_EQUAL(rString, oString); + + // Invalid 1D grid construction with autorange axis + BOOST_CHECK_THROW(Acts::makeGrid(epa), std::invalid_argument); + + // Invalid 2D grid construction with autorange axis + Acts::ProtoAxis epao(AxisY, Open, 0., 2.0, 10.); + BOOST_CHECK_THROW(Acts::makeGrid(epao, epa), std::invalid_argument); + BOOST_CHECK_THROW(Acts::makeGrid(epa, epao), std::invalid_argument); + + // Set the range now + epa.setRange(0.0, 20.0); + BOOST_CHECK(!epa.isAutorange()); + + // 1D Grid consstruction works now + BOOST_CHECK_NO_THROW(Acts::makeGrid(epa)); + + // 2D Grid consstruction works now + BOOST_CHECK_NO_THROW(Acts::makeGrid(epa, epao)); + + // Invalid constructor, closed with something else than phi or rphi + BOOST_CHECK_THROW(Acts::ProtoAxis(AxisZ, Closed, 10), std::invalid_argument); +} + +BOOST_AUTO_TEST_CASE(VariableProtoAxis) { + using enum Acts::AxisBoundaryType; + using enum Acts::AxisDirection; + using enum Acts::AxisType; + + // Bound, equidistant axis + Acts::ProtoAxis vpab(AxisX, Bound, {0.0, 1.0, 10}); + + // Direct access + BOOST_CHECK_EQUAL(vpab.getAxisDirection(), AxisX); + + BOOST_CHECK(!vpab.isAutorange()); + + // Access via IAxis + BOOST_CHECK(!vpab.getAxis().isEquidistant()); + + BOOST_CHECK(vpab.getAxis().isVariable()); + + auto edges = vpab.getAxis().getBinEdges(); + BOOST_CHECK_EQUAL(edges.size(), 3); + + BOOST_CHECK_EQUAL(vpab.getAxis().getType(), Variable); + + BOOST_CHECK_EQUAL(vpab.getAxis().getBoundaryType(), Bound); + + BOOST_CHECK_EQUAL(vpab.getAxis().getNBins(), 2); + + CHECK_CLOSE_ABS(vpab.getAxis().getMin(), 0.0, 1e-15); + + CHECK_CLOSE_ABS(vpab.getAxis().getMax(), 10.0, 1e-15); + + std::string rString = "ProtoAxis: 2 bins in AxisX, variable within [0, 10]"; + std::string oString = vpab.toString(); + BOOST_CHECK_EQUAL(rString, oString); + + // Invalid constructor, min > max + BOOST_CHECK_THROW(Acts::ProtoAxis(AxisZ, Bound, std::vector{2.}), + std::invalid_argument); + + // Invalid constructor, nbins < 1 + BOOST_CHECK_THROW(Acts::ProtoAxis(AxisZ, Bound, {3., 2., 1}), + std::invalid_argument); + + // Invalid constructor, closed with something else than phi or rphi + std::vector invalidDirections = { + AxisX, AxisY, AxisZ, AxisR, AxisEta, AxisTheta, AxisMag}; + for (const auto& adir : invalidDirections) { + BOOST_CHECK_THROW(Acts::ProtoAxis(adir, Closed, {0., 1., 2., 3.}), + std::invalid_argument); + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/Tests/UnitTests/Examples/Algorithms/Digitization/ModuleClustersTests.cpp b/Tests/UnitTests/Examples/Algorithms/Digitization/ModuleClustersTests.cpp index a1947cde17e..c2e41bd063c 100644 --- a/Tests/UnitTests/Examples/Algorithms/Digitization/ModuleClustersTests.cpp +++ b/Tests/UnitTests/Examples/Algorithms/Digitization/ModuleClustersTests.cpp @@ -8,6 +8,7 @@ #include +#include "Acts/Utilities/BinUtility.hpp" #include "Acts/Utilities/BinningData.hpp" #include "ActsExamples/Digitization/ModuleClusters.hpp" #include "ActsFatras/Digitization/Segmentizer.hpp" @@ -46,10 +47,10 @@ DigitizedParameters makeDigitizationParameters(const Vector2 &position, auto testDigitizedParametersWithTwoClusters(bool merge, const Vector2 &firstHit, const Vector2 &secondHit) { BinUtility binUtility; - binUtility += - BinningData(BinningOption::open, BinningValue::binX, 20, -10.0f, 10.0f); - binUtility += - BinningData(BinningOption::open, BinningValue::binY, 20, -10.0f, 10.0f); + binUtility += BinUtility(BinningData( + BinningOption::open, AxisDirection::AxisX, 20, -10.0f, 10.0f)); + binUtility += BinUtility(BinningData( + BinningOption::open, AxisDirection::AxisY, 20, -10.0f, 10.0f)); std::vector boundIndices = {eBoundLoc0, eBoundLoc1}; double nsigma = 1; bool commonCorner = true; diff --git a/Tests/UnitTests/Examples/Io/Json/JsonDigitizationConfigTests.cpp b/Tests/UnitTests/Examples/Io/Json/JsonDigitizationConfigTests.cpp index f7c1db0f496..dfa8978f17c 100644 --- a/Tests/UnitTests/Examples/Io/Json/JsonDigitizationConfigTests.cpp +++ b/Tests/UnitTests/Examples/Io/Json/JsonDigitizationConfigTests.cpp @@ -157,9 +157,9 @@ BOOST_AUTO_TEST_CASE(DigitizationConfigRoundTrip) { Acts::BinUtility segmentation; segmentation += - Acts::BinUtility(336, -8.4, 8.4, Acts::open, Acts::BinningValue::binX); + Acts::BinUtility(336, -8.4, 8.4, Acts::open, Acts::AxisDirection::AxisX); segmentation += - Acts::BinUtility(1280, -36, 36, Acts::open, Acts::BinningValue::binY); + Acts::BinUtility(1280, -36, 36, Acts::open, Acts::AxisDirection::AxisY); gdc.segmentation = segmentation; gdc.threshold = 0.01; diff --git a/Tests/UnitTests/Fatras/Digitization/ChannelizerTests.cpp b/Tests/UnitTests/Fatras/Digitization/ChannelizerTests.cpp index b1d142cc545..72443aa02c4 100644 --- a/Tests/UnitTests/Fatras/Digitization/ChannelizerTests.cpp +++ b/Tests/UnitTests/Fatras/Digitization/ChannelizerTests.cpp @@ -40,9 +40,9 @@ struct Helper { float max = 200_um; int bins = static_cast((max - min) / pitchSize); segmentation = Acts::BinUtility(bins, min, max, Acts::BinningOption::open, - Acts::BinningValue::binX); + Acts::AxisDirection::AxisX); segmentation += Acts::BinUtility(bins, min, max, Acts::BinningOption::open, - Acts::BinningValue::binY); + Acts::AxisDirection::AxisY); } auto channelize(const Acts::Vector3 &pos3, const Acts::Vector3 &dir3) const { diff --git a/Tests/UnitTests/Fatras/Digitization/PlanarSurfaceTestBeds.hpp b/Tests/UnitTests/Fatras/Digitization/PlanarSurfaceTestBeds.hpp index 42327d7e5eb..c7185dab920 100644 --- a/Tests/UnitTests/Fatras/Digitization/PlanarSurfaceTestBeds.hpp +++ b/Tests/UnitTests/Fatras/Digitization/PlanarSurfaceTestBeds.hpp @@ -54,9 +54,9 @@ struct PlanarSurfaceTestBeds { auto rSurface = Acts::Surface::makeShared( Acts::Transform3::Identity(), rectangle); Acts::BinUtility pixelated(15, -xhalf, xhalf, Acts::open, - Acts::BinningValue::binX); + Acts::AxisDirection::AxisX); pixelated += Acts::BinUtility(26, -yhalf, yhalf, Acts::open, - Acts::BinningValue::binY); + Acts::AxisDirection::AxisY); RectangleRandom rRandom(xhalf * rScale, yhalf * rScale); // Cartesian strip test in Trapezoid @@ -68,9 +68,9 @@ struct PlanarSurfaceTestBeds { auto tSurface = Acts::Surface::makeShared( Acts::Transform3::Identity(), trapezoid); Acts::BinUtility stripsX(35, -xhalfmaxy, xhalfmaxy, Acts::open, - Acts::BinningValue::binX); + Acts::AxisDirection::AxisX); stripsX += Acts::BinUtility(1, -yhalf, yhalf, Acts::open, - Acts::BinningValue::binY); + Acts::AxisDirection::AxisY); TrapezoidRandom tRandom(xhalfminy * rScale, xhalfmaxy * rScale, yhalf * rScale); @@ -87,10 +87,10 @@ struct PlanarSurfaceTestBeds { auto dtSurface = Acts::Surface::makeShared( Acts::Transform3::Identity(), discTrapezoid); Acts::BinUtility stripsPhi(1, rmin, rmax, Acts::open, - Acts::BinningValue::binR); + Acts::AxisDirection::AxisR); stripsPhi += Acts::BinUtility(25, std::numbers::pi / 2. - alpha, std::numbers::pi / 2. + alpha, Acts::open, - Acts::BinningValue::binPhi); + Acts::AxisDirection::AxisPhi); TrapezoidRandom dtRandom(xmin * rScale, xmax * rScale, rmin * irScale, ymax * rScale); @@ -100,11 +100,11 @@ struct PlanarSurfaceTestBeds { auto dSurface = Acts::Surface::makeShared( Acts::Transform3::Identity(), discRadial); Acts::BinUtility rphiseg(10, rmin, rmax, Acts::open, - Acts::BinningValue::binR); + Acts::AxisDirection::AxisR); rphiseg += Acts::BinUtility(20, (std::numbers::pi / 2. - std::numbers::pi / 4.), (std::numbers::pi / 2. + std::numbers::pi / 4.), - Acts::open, Acts::BinningValue::binPhi); + Acts::open, Acts::AxisDirection::AxisPhi); DiscRandom dRandom( rmin * irScale, rmax * rScale, @@ -132,9 +132,9 @@ struct PlanarSurfaceTestBeds { }); Acts::BinUtility stripsPhiA(1, rmin, rmax, Acts::open, - Acts::BinningValue::binR); + Acts::AxisDirection::AxisR); stripsPhiA += Acts::BinUtility(12, phimin, phimax, Acts::open, - Acts::BinningValue::binPhi); + Acts::AxisDirection::AxisPhi); AnnulusRandom aRandom(rmin * irScale, rmax * rScale, phimin * rScale, phimax * rScale, aorigin.x(), aorigin.y()); diff --git a/Tests/UnitTests/Fatras/Digitization/SegmentizerTests.cpp b/Tests/UnitTests/Fatras/Digitization/SegmentizerTests.cpp index ad74a9024d1..9afa5b0d938 100644 --- a/Tests/UnitTests/Fatras/Digitization/SegmentizerTests.cpp +++ b/Tests/UnitTests/Fatras/Digitization/SegmentizerTests.cpp @@ -47,9 +47,10 @@ BOOST_AUTO_TEST_CASE(SegmentizerCartesian) { Acts::Transform3::Identity(), rectangleBounds); // The segmentation - Acts::BinUtility pixelated(20, -1., 1., Acts::open, Acts::BinningValue::binX); + Acts::BinUtility pixelated(20, -1., 1., Acts::open, + Acts::AxisDirection::AxisX); pixelated += - Acts::BinUtility(20, -1., 1., Acts::open, Acts::BinningValue::binY); + Acts::BinUtility(20, -1., 1., Acts::open, Acts::AxisDirection::AxisY); Segmentizer cl; @@ -92,9 +93,9 @@ BOOST_AUTO_TEST_CASE(SegmentizerPolarRadial) { Acts::Transform3::Identity(), radialBounds); // The segmentation - Acts::BinUtility strips(2, 5., 10., Acts::open, Acts::BinningValue::binR); + Acts::BinUtility strips(2, 5., 10., Acts::open, Acts::AxisDirection::AxisR); strips += Acts::BinUtility(250, -0.25, 0.25, Acts::open, - Acts::BinningValue::binPhi); + Acts::AxisDirection::AxisPhi); Segmentizer cl; @@ -169,8 +170,10 @@ BOOST_DATA_TEST_CASE( } // 1 - write the grid grid.open("Segmentizer" + name + "Grid.csv"); - if (segmentation.binningData()[0].binvalue == Acts::BinningValue::binX && - segmentation.binningData()[1].binvalue == Acts::BinningValue::binY) { + if (segmentation.binningData()[0].binvalue == + Acts::AxisDirection::AxisX && + segmentation.binningData()[1].binvalue == + Acts::AxisDirection::AxisY) { double bxmin = segmentation.binningData()[0].min; double bxmax = segmentation.binningData()[0].max; double bymin = segmentation.binningData()[1].min; @@ -184,9 +187,9 @@ BOOST_DATA_TEST_CASE( csvHelper.writeLine(grid, {bxmin, yval}, {bxmax, yval}); } } else if (segmentation.binningData()[0].binvalue == - Acts::BinningValue::binR && + Acts::AxisDirection::AxisR && segmentation.binningData()[1].binvalue == - Acts::BinningValue::binPhi) { + Acts::AxisDirection::AxisPhi) { double brmin = segmentation.binningData()[0].min; double brmax = segmentation.binningData()[0].max; double bphimin = segmentation.binningData()[1].min; diff --git a/Tests/UnitTests/Fatras/Kernel/SimulationActorTests.cpp b/Tests/UnitTests/Fatras/Kernel/SimulationActorTests.cpp index c31f33547e0..a6358d1acb2 100644 --- a/Tests/UnitTests/Fatras/Kernel/SimulationActorTests.cpp +++ b/Tests/UnitTests/Fatras/Kernel/SimulationActorTests.cpp @@ -16,7 +16,6 @@ #include "Acts/Material/HomogeneousSurfaceMaterial.hpp" #include "Acts/Material/MaterialSlab.hpp" #include "Acts/Propagator/ConstrainedStep.hpp" -#include "Acts/Propagator/Propagator.hpp" #include "Acts/Surfaces/CurvilinearSurface.hpp" #include "Acts/Surfaces/PlaneSurface.hpp" #include "Acts/Surfaces/Surface.hpp" @@ -119,23 +118,16 @@ struct MockStepper { } void updateStepSize(State & /*state*/, double /*stepSize*/, Acts::ConstrainedStep::Type /*stype*/) const {} + void releaseStepSize(State & /*state*/, + Acts::ConstrainedStep::Type /*stype*/) const {} }; struct MockNavigatorState { - bool targetReached = false; Acts::Surface *startSurface = nullptr; Acts::Surface *currentSurface = nullptr; }; struct MockNavigator { - bool targetReached(const MockNavigatorState &state) const { - return state.targetReached; - } - - void targetReached(MockNavigatorState &state, bool reached) const { - state.targetReached = reached; - } - const Acts::Surface *startSurface(const MockNavigatorState &state) const { return state.startSurface; } diff --git a/Tests/UnitTests/Plugins/ActSVG/DetectorVolumeSvgConverterTests.cpp b/Tests/UnitTests/Plugins/ActSVG/DetectorVolumeSvgConverterTests.cpp index c1ed95854f8..b3ba0f4f5fc 100644 --- a/Tests/UnitTests/Plugins/ActSVG/DetectorVolumeSvgConverterTests.cpp +++ b/Tests/UnitTests/Plugins/ActSVG/DetectorVolumeSvgConverterTests.cpp @@ -150,7 +150,7 @@ BOOST_AUTO_TEST_CASE(EndcapVolumeWithSurfaces) { lsConfig.auxiliary = "*** Endcap with 22 surfaces ***"; lsConfig.surfacesProvider = endcapSurfaces; lsConfig.binnings = {Acts::Experimental::ProtoBinning( - Acts::BinningValue::binPhi, Acts::AxisBoundaryType::Closed, + Acts::AxisDirection::AxisPhi, Acts::AxisBoundaryType::Closed, -std::numbers::pi, std::numbers::pi, 22u, 1u)}; auto layerBuilder = @@ -220,11 +220,11 @@ BOOST_AUTO_TEST_CASE(BarrelVolumeWithSurfaces) { lsConfig.auxiliary = "*** Barrel with 448 surfaces ***"; lsConfig.surfacesProvider = barrelSurfaces; lsConfig.binnings = { - Acts::Experimental::ProtoBinning{Acts::BinningValue::binZ, + Acts::Experimental::ProtoBinning{Acts::AxisDirection::AxisZ, Acts::AxisBoundaryType::Bound, -480., 480., 14u, 1u}, Acts::Experimental::ProtoBinning( - Acts::BinningValue::binPhi, Acts::AxisBoundaryType::Closed, + Acts::AxisDirection::AxisPhi, Acts::AxisBoundaryType::Closed, -std::numbers::pi, std::numbers::pi, 32u, 1u)}; auto barrelBuilder = diff --git a/Tests/UnitTests/Plugins/ActSVG/GridSvgConverterTests.cpp b/Tests/UnitTests/Plugins/ActSVG/GridSvgConverterTests.cpp index 2fc643b6a53..16e49c7356e 100644 --- a/Tests/UnitTests/Plugins/ActSVG/GridSvgConverterTests.cpp +++ b/Tests/UnitTests/Plugins/ActSVG/GridSvgConverterTests.cpp @@ -58,7 +58,7 @@ BOOST_AUTO_TEST_CASE(BoundGridXY) { Svg::GridConverter::Options cOptions; auto pGrid = Svg::GridConverter::convert( - gridXY, {BinningValue::binX, BinningValue::binY}, cOptions); + gridXY, {AxisDirection::AxisX, AxisDirection::AxisY}, cOptions); BOOST_CHECK_EQUAL(pGrid._type, actsvg::proto::grid::type::e_x_y); // Labelling the grid tiles @@ -110,8 +110,10 @@ BOOST_AUTO_TEST_CASE(BoundGridXY) { std::vector captionText = { "Binning schema for global and local bins: ", - "- axis 0 : AxisBoundaryType::Bound, (-200., 200, 4), BinningValue::binX", - "- axis 1 : AxisBoundaryType::Bound, (-200, 200, 6), BinningValue::binY"}; + "- axis 0 : AxisBoundaryType::Bound, (-200., 200, 4), " + "AxisDirection::AxisX", + "- axis 1 : AxisBoundaryType::Bound, (-200, 200, 6), " + "AxisDirection::AxisY"}; auto caption = actsvg::draw::text("caption", {-180, -220}, captionText); @@ -135,7 +137,7 @@ BOOST_AUTO_TEST_CASE(OpenGridXY) { Svg::GridConverter::Options cOptions; auto pGrid = Svg::GridConverter::convert( - gridXY, {BinningValue::binX, BinningValue::binY}, cOptions); + gridXY, {AxisDirection::AxisX, AxisDirection::AxisY}, cOptions); BOOST_CHECK_EQUAL(pGrid._type, actsvg::proto::grid::type::e_x_y); // Labelling the grid tiles @@ -186,8 +188,10 @@ BOOST_AUTO_TEST_CASE(OpenGridXY) { std::vector captionText = { "Binning schema for global and local bins: ", - "- axis 0 : AxisBoundaryType::Open, (-200., 200, 4), BinningValue::binX", - "- axis 1 : AxisBoundaryType::Open, (-200, 200, 6), BinningValue::binY"}; + "- axis 0 : AxisBoundaryType::Open, (-200., 200, 4), " + "AxisDirection::AxisX", + "- axis 1 : AxisBoundaryType::Open, (-200, 200, 6), " + "AxisDirection::AxisY"}; auto caption = actsvg::draw::text("caption", {-180, -220}, captionText); auto oGrid = actsvg::display::grid("OpenGridXY", pGrid); @@ -212,7 +216,7 @@ BOOST_AUTO_TEST_CASE(ClosedCylinderGridZPhi) { Svg::GridConverter::Options cOptions; auto pGrid = Svg::GridConverter::convert( - gridZPhi, {BinningValue::binZ, BinningValue::binPhi}, cOptions); + gridZPhi, {AxisDirection::AxisZ, AxisDirection::AxisPhi}, cOptions); BOOST_CHECK_EQUAL(pGrid._type, actsvg::proto::grid::type::e_z_phi); pGrid._reference_r = 80.; @@ -264,8 +268,10 @@ BOOST_AUTO_TEST_CASE(ClosedCylinderGridZPhi) { std::vector captionText = { "Binning schema for global and local bins: ", - "- axis 0 : AxisBoundaryType::Bound, (-200., 200, 3), BinningValue::binZ", - "- axis 1 : AxisBoundaryType::Closed, (-PI, PI, 6), BinningValue::binPhi", + "- axis 0 : AxisBoundaryType::Bound, (-200., 200, 3), " + "AxisDirection::AxisZ", + "- axis 1 : AxisBoundaryType::Closed, (-PI, PI, 6), " + "AxisDirection::AxisPhi", "- draw reference radius set to 80"}; auto caption = actsvg::draw::text("caption", {-180, -270}, captionText); @@ -291,7 +297,7 @@ BOOST_AUTO_TEST_CASE(ClosedDiscGridRPhi) { Svg::GridConverter::Options cOptions; auto pGrid = Svg::GridConverter::convert( - gridRPhi, {BinningValue::binR, BinningValue::binPhi}, cOptions); + gridRPhi, {AxisDirection::AxisR, AxisDirection::AxisPhi}, cOptions); BOOST_CHECK_EQUAL(pGrid._type, actsvg::proto::grid::type::e_r_phi); // Labelling the grid tiles @@ -347,7 +353,7 @@ BOOST_AUTO_TEST_CASE(ClosedDiscGridRPhi) { std::vector captionText = { "Binning schema for global and local bins: ", - "- axis 0 : AxisBoundaryType::Bound, (100., 400, 3), binR", + "- axis 0 : AxisBoundaryType::Bound, (100., 400, 3), AxisR", "- axis 1 : AxisBoundaryType::Closed, (-PI, PI, 4), " "binPhi"}; diff --git a/Tests/UnitTests/Plugins/ActSVG/IndexedSurfacesSvgConverterTests.cpp b/Tests/UnitTests/Plugins/ActSVG/IndexedSurfacesSvgConverterTests.cpp index f7f7e247bbb..21066266404 100644 --- a/Tests/UnitTests/Plugins/ActSVG/IndexedSurfacesSvgConverterTests.cpp +++ b/Tests/UnitTests/Plugins/ActSVG/IndexedSurfacesSvgConverterTests.cpp @@ -76,7 +76,7 @@ BOOST_AUTO_TEST_CASE(RingDisc1D) { 55., 0., 2., 22u); IndexedSurfacesGenerator - irSurfaces{rSurfaces, {}, {BinningValue::binPhi}}; + irSurfaces{rSurfaces, {}, {AxisDirection::AxisPhi}}; GridAxisGenerators::EqClosed aGenerator{{-std::numbers::pi, std::numbers::pi}, 44u}; @@ -102,7 +102,7 @@ BOOST_AUTO_TEST_CASE(RingDisc1DWithSupport) { rSurfaces.push_back(dSurface.get()); IndexedSurfacesGenerator - irSurfaces{rSurfaces, {rSurfaces.size() - 1u}, {BinningValue::binPhi}}; + irSurfaces{rSurfaces, {rSurfaces.size() - 1u}, {AxisDirection::AxisPhi}}; GridAxisGenerators::EqClosed aGenerator{{-std::numbers::pi, std::numbers::pi}, 44u}; @@ -129,7 +129,7 @@ BOOST_AUTO_TEST_CASE(RingDisc2D) { rSurfaces.insert(rSurfaces.end(), rSurfacesR1.begin(), rSurfacesR1.end()); IndexedSurfacesGenerator - irSurfaces{rSurfaces, {}, {BinningValue::binR, BinningValue::binPhi}}; + irSurfaces{rSurfaces, {}, {AxisDirection::AxisR, AxisDirection::AxisPhi}}; GridAxisGenerators::VarBoundEqClosed aGenerator{ {24., 74., 110.}, {-std::numbers::pi, std::numbers::pi}, 44u}; @@ -161,7 +161,7 @@ BOOST_AUTO_TEST_CASE(RingDisc2DFine) { rSurfaces.insert(rSurfaces.end(), rSurfacesR2.begin(), rSurfacesR2.end()); IndexedSurfacesGenerator - irSurfaces{rSurfaces, {}, {BinningValue::binR, BinningValue::binPhi}}; + irSurfaces{rSurfaces, {}, {AxisDirection::AxisR, AxisDirection::AxisPhi}}; GridAxisGenerators::EqBoundEqClosed aGenerator{ {24., 152}, 8u, {-std::numbers::pi, std::numbers::pi}, 88u}; @@ -193,8 +193,10 @@ BOOST_AUTO_TEST_CASE(RingDisc2DFineExpanded) { rSurfaces.insert(rSurfaces.end(), rSurfacesR2.begin(), rSurfacesR2.end()); IndexedSurfacesGenerator - irSurfaces{ - rSurfaces, {}, {BinningValue::binR, BinningValue::binPhi}, {2u, 4u}}; + irSurfaces{rSurfaces, + {}, + {AxisDirection::AxisR, AxisDirection::AxisPhi}, + {2u, 4u}}; GridAxisGenerators::EqBoundEqClosed aGenerator{ {24., 152}, 8u, {-std::numbers::pi, std::numbers::pi}, 88u}; @@ -215,8 +217,10 @@ BOOST_AUTO_TEST_CASE(Cylinder2D) { 116., 3., 2., {52, 14}); IndexedSurfacesGenerator - icSurfaces{ - surfaces, {}, {BinningValue::binZ, BinningValue::binPhi}, {1u, 1u}}; + icSurfaces{surfaces, + {}, + {AxisDirection::AxisZ, AxisDirection::AxisPhi}, + {1u, 1u}}; GridAxisGenerators::EqBoundEqClosed aGenerator{ {-500., 500}, 28, {-std::numbers::pi, std::numbers::pi}, 52u}; diff --git a/Tests/UnitTests/Plugins/DD4hep/DD4hepCylinderLayerStructureTests.cpp b/Tests/UnitTests/Plugins/DD4hep/DD4hepCylinderLayerStructureTests.cpp index 994ac8bb927..0bc4e5c97c0 100644 --- a/Tests/UnitTests/Plugins/DD4hep/DD4hepCylinderLayerStructureTests.cpp +++ b/Tests/UnitTests/Plugins/DD4hep/DD4hepCylinderLayerStructureTests.cpp @@ -295,16 +295,16 @@ BOOST_AUTO_TEST_CASE(DD4hepPluginCylinderLayerStructureAutoRange) { lsOptions.name = "AutoRangeLayer"; auto extent = Acts::Extent(); lsOptions.extent = extent; - lsOptions.extentConstraints = {Acts::BinningValue::binZ, - Acts::BinningValue::binR}; + lsOptions.extentConstraints = {Acts::AxisDirection::AxisZ, + Acts::AxisDirection::AxisR}; lsOptions.logLevel = Acts::Logging::VERBOSE; auto [barrelInternalsBuilder, barrelExt] = barrelStructure.builder(dd4hepStore, tContext, world, lsOptions); BOOST_CHECK(barrelExt != std::nullopt); - BOOST_CHECK(barrelExt.value().constrains(Acts::BinningValue::binZ)); - BOOST_CHECK(barrelExt.value().constrains(Acts::BinningValue::binR)); + BOOST_CHECK(barrelExt.value().constrains(Acts::AxisDirection::AxisZ)); + BOOST_CHECK(barrelExt.value().constrains(Acts::AxisDirection::AxisR)); } BOOST_AUTO_TEST_SUITE_END() diff --git a/Tests/UnitTests/Plugins/Detray/DetrayMaterialConverterTests.cpp b/Tests/UnitTests/Plugins/Detray/DetrayMaterialConverterTests.cpp index 28fe7571b54..f5cb3b2ae82 100644 --- a/Tests/UnitTests/Plugins/Detray/DetrayMaterialConverterTests.cpp +++ b/Tests/UnitTests/Plugins/Detray/DetrayMaterialConverterTests.cpp @@ -92,7 +92,7 @@ BOOST_AUTO_TEST_CASE(DetrayHomogeneousMaterialConversion) { BOOST_AUTO_TEST_CASE(DetrayBinnedMaterialConversionX) { // Create a binned material in 4 bins in x direction Acts::BinUtility binUtility(4u, -2., 2., Acts::BinningOption::open, - Acts::BinningValue::binX); + Acts::AxisDirection::AxisX); std::vector materialSlabs = { materialSlab12345, materialSlab678910, materialSlab54321, @@ -152,7 +152,7 @@ BOOST_AUTO_TEST_CASE(DetrayBinnedMaterialConversionX) { BOOST_AUTO_TEST_CASE(DetrayBinnedMaterialConversionY) { // Create a binned material in 4 bins in y direction Acts::BinUtility binUtility(4u, -2., 2., Acts::BinningOption::open, - Acts::BinningValue::binY); + Acts::AxisDirection::AxisY); std::vector materialSlabs = { materialSlab12345, materialSlab678910, materialSlab54321, @@ -212,9 +212,9 @@ BOOST_AUTO_TEST_CASE(DetrayBinnedMaterialConversionY) { BOOST_AUTO_TEST_CASE(DetrayBinnedMaterialConversionXY) { // Create a binned material in 2 x2 bins in x-y direction Acts::BinUtility binUtility(2u, -1., 1., Acts::BinningOption::open, - Acts::BinningValue::binX); + Acts::AxisDirection::AxisX); binUtility += Acts::BinUtility(2u, -2., 2., Acts::BinningOption::open, - Acts::BinningValue::binY); + Acts::AxisDirection::AxisY); std::vector materialSlabs0 = {materialSlab12345, materialSlab678910}; @@ -269,7 +269,7 @@ BOOST_AUTO_TEST_CASE(DetrayBinnedMaterialConversionR) { // Create a binned material in 4 bins (irregularly) in r direction std::vector binEdges = {0., 5., 10., 15., 20.}; Acts::BinUtility binUtility(binEdges, Acts::BinningOption::open, - Acts::BinningValue::binR); + Acts::AxisDirection::AxisR); std::vector materialSlabs = { materialSlab12345, materialSlab678910, materialSlab54321, @@ -308,10 +308,10 @@ BOOST_AUTO_TEST_CASE(DetrayBinnedMaterialConversionRPhi) { // Create a binned material in 2 bins - irregularly in r, 2 bins in phi std::vector binEdges = {0., 5., 20.}; Acts::BinUtility binUtility(binEdges, Acts::BinningOption::open, - Acts::BinningValue::binR); - binUtility += - Acts::BinUtility(2u, -std::numbers::pi, std::numbers::pi, - Acts::BinningOption::closed, Acts::BinningValue::binPhi); + Acts::AxisDirection::AxisR); + binUtility += Acts::BinUtility(2u, -std::numbers::pi, std::numbers::pi, + Acts::BinningOption::closed, + Acts::AxisDirection::AxisPhi); std::vector materialSlabs0 = {materialSlab12345, materialSlab678910}; @@ -347,7 +347,7 @@ BOOST_AUTO_TEST_CASE(DetrayBinnedMaterialConversionZ) { // Create a binned material in 4 bins in x direction std::vector binEdges = {-20, 0, 25, 50, 100}; Acts::BinUtility binUtility(binEdges, Acts::BinningOption::open, - Acts::BinningValue::binZ); + Acts::AxisDirection::AxisZ); std::vector materialSlabs = { materialSlab12345, materialSlab678910, materialSlab54321, @@ -386,10 +386,10 @@ BOOST_AUTO_TEST_CASE(DetrayBinnedMaterialConversionZ) { BOOST_AUTO_TEST_CASE(DetrayBinnedMaterialConversionZPhi) { // Create a binned material in 2 x2 bins in x-y direction Acts::BinUtility binUtility(2u, -1., 1., Acts::BinningOption::open, - Acts::BinningValue::binZ); - binUtility += - Acts::BinUtility(2u, -std::numbers::pi, std::numbers::pi, - Acts::BinningOption::closed, Acts::BinningValue::binPhi); + Acts::AxisDirection::AxisZ); + binUtility += Acts::BinUtility(2u, -std::numbers::pi, std::numbers::pi, + Acts::BinningOption::closed, + Acts::AxisDirection::AxisPhi); std::vector materialSlabs0 = {materialSlab12345, materialSlab678910}; @@ -418,9 +418,9 @@ BOOST_AUTO_TEST_CASE(DetrayBinnedMaterialConversionZPhi) { BOOST_AUTO_TEST_CASE(DetrayBinnedMaterialConversionInvalid) { // Create a binned material in 4 bins in x direction Acts::BinUtility binUtility(2u, -1., 1., Acts::BinningOption::open, - Acts::BinningValue::binR); + Acts::AxisDirection::AxisR); binUtility += Acts::BinUtility(2u, -2., 2., Acts::BinningOption::open, - Acts::BinningValue::binEta); + Acts::AxisDirection::AxisEta); std::vector materialSlabs0 = {materialSlab12345, materialSlab678910}; diff --git a/Tests/UnitTests/Plugins/ExaTrkX/CMakeLists.txt b/Tests/UnitTests/Plugins/ExaTrkX/CMakeLists.txt index 322e4d700b9..19ff7c66ed2 100644 --- a/Tests/UnitTests/Plugins/ExaTrkX/CMakeLists.txt +++ b/Tests/UnitTests/Plugins/ExaTrkX/CMakeLists.txt @@ -4,3 +4,6 @@ add_unittest(ExaTrkXTensorConversion ExaTrkXTensorConversionTests.cpp) add_unittest(ExaTrkXEdgeBuilding ExaTrkXEdgeBuildingTest.cpp) add_unittest(ExaTrkXBoostTrackBuilding ExaTrkXBoostTrackBuildingTests.cpp) add_unittest(ExaTrkXMetricHookTests ExaTrkXMetricHookTests.cpp) +if(ACTS_EXATRKX_ENABLE_CUDA) + add_unittest(ConnectedComponentsCuda ConnectedComponentCudaTests.cu) +endif() diff --git a/Tests/UnitTests/Plugins/ExaTrkX/ConnectedComponentCudaTests.cu b/Tests/UnitTests/Plugins/ExaTrkX/ConnectedComponentCudaTests.cu new file mode 100644 index 00000000000..fd61e68ee64 --- /dev/null +++ b/Tests/UnitTests/Plugins/ExaTrkX/ConnectedComponentCudaTests.cu @@ -0,0 +1,388 @@ +// 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 + +#include +#include +#include +#include +#include + +#include +#include + +using namespace Acts::detail; + +using BoostGraph = + boost::adjacency_list; + +using Vi = std::vector; + +Vi checkLabeling(const std::vector &src, const std::vector &tgt) { + std::size_t numNodes = std::max(*std::max_element(src.begin(), src.end()), + *std::max_element(tgt.begin(), tgt.end())) + + 1; + + int *cudaSrc, *cudaTgt; + BOOST_REQUIRE_EQUAL(cudaMalloc(&cudaSrc, src.size() * sizeof(int)), + cudaSuccess); + BOOST_REQUIRE_EQUAL(cudaMalloc(&cudaTgt, tgt.size() * sizeof(int)), + cudaSuccess); + BOOST_REQUIRE_EQUAL(cudaMemcpy(cudaSrc, src.data(), src.size() * sizeof(int), + cudaMemcpyHostToDevice), + cudaSuccess); + BOOST_REQUIRE_EQUAL(cudaMemcpy(cudaTgt, tgt.data(), src.size() * sizeof(int), + cudaMemcpyHostToDevice), + cudaSuccess); + + int *cudaLabels; + BOOST_REQUIRE_EQUAL(cudaMalloc(&cudaLabels, numNodes * sizeof(int)), + cudaSuccess); + int *cudaLabelsNext; + BOOST_REQUIRE_EQUAL(cudaMalloc(&cudaLabelsNext, numNodes * sizeof(int)), + cudaSuccess); + + labelConnectedComponents<<<1, 1024>>>(src.size(), cudaSrc, cudaTgt, numNodes, + cudaLabels, cudaLabelsNext); + + std::vector labelsFromCuda(numNodes); + BOOST_REQUIRE_EQUAL( + cudaMemcpy(labelsFromCuda.data(), cudaLabels, numNodes * sizeof(int), + cudaMemcpyDeviceToHost), + cudaSuccess); + + BoostGraph G(numNodes); + + for (auto i = 0ul; i < src.size(); ++i) { + boost::add_edge(src[i], tgt[i], G); + } + + std::vector cpuLabels(numNodes); + boost::connected_components(G, &cpuLabels[0]); + + // print + std::cout << "cpu labels: "; + for (auto i = 0ul; i < numNodes; ++i) { + std::cout << cpuLabels[i] << " "; + } + std::cout << std::endl; + + std::cout << "my CUDA labels: "; + for (auto i = 0ul; i < numNodes; ++i) { + std::cout << labelsFromCuda[i] << " "; + } + std::cout << std::endl; + + // check systematically + std::map boostToCuda; + for (auto i = 0ul; i < numNodes; ++i) { + if (boostToCuda.contains(cpuLabels[i])) { + BOOST_CHECK_EQUAL(labelsFromCuda[i], boostToCuda.at(cpuLabels[i])); + } else { + auto [it, success] = + boostToCuda.insert({cpuLabels[i], labelsFromCuda[i]}); + BOOST_CHECK(success); + } + } + + return labelsFromCuda; +} + +BOOST_AUTO_TEST_CASE(simple_test_1) { + Vi src{0, 1, 2, 3}; + Vi tgt{1, 2, 3, 4}; + checkLabeling(src, tgt); +} + +BOOST_AUTO_TEST_CASE(simple_test_2) { + Vi src{0, 1, 2, 4, 5, 6}; + Vi tgt{1, 2, 3, 5, 6, 7}; + checkLabeling(src, tgt); +} + +BOOST_AUTO_TEST_CASE(simple_test_3) { + Vi src{4, 3, 2, 1}; + Vi tgt{3, 2, 1, 0}; + checkLabeling(src, tgt); +} + +void testRelabeling(const Vi &labels, const Vi &refLabelMask, + const Vi &refPrefixSum, const Vi &refLabels) { + dim3 blockDim = 32; + dim3 gridDim = (labels.size() + blockDim.x - 1) / blockDim.x; + + // Copy labels to device + int *cudaLabels; + BOOST_REQUIRE_EQUAL(cudaMalloc(&cudaLabels, labels.size() * sizeof(int)), + cudaSuccess); + BOOST_REQUIRE_EQUAL( + cudaMemcpy(cudaLabels, labels.data(), labels.size() * sizeof(int), + cudaMemcpyHostToDevice), + cudaSuccess); + + // Init label mask + int *cudaLabelMask; + BOOST_REQUIRE_EQUAL(cudaMalloc(&cudaLabelMask, labels.size() * sizeof(int)), + cudaSuccess); + BOOST_REQUIRE_EQUAL(cudaMemset(cudaLabelMask, 0, labels.size() * sizeof(int)), + cudaSuccess); + + makeLabelMask<<<1, 256>>>(labels.size(), cudaLabels, cudaLabelMask); + BOOST_REQUIRE_EQUAL(cudaDeviceSynchronize(), cudaSuccess); + + std::vector labelMask(labels.size()); + BOOST_REQUIRE_EQUAL( + cudaMemcpy(labelMask.data(), cudaLabelMask, + labelMask.size() * sizeof(int), cudaMemcpyDeviceToHost), + cudaSuccess); + + BOOST_CHECK_EQUAL_COLLECTIONS(labelMask.begin(), labelMask.end(), + refLabelMask.begin(), refLabelMask.end()); + + // Prefix sum + int *cudaPrefixSum; + BOOST_REQUIRE_EQUAL(cudaMalloc(&cudaPrefixSum, labels.size() * sizeof(int)), + cudaSuccess); + thrust::exclusive_scan(thrust::device.on(0), cudaLabelMask, + cudaLabelMask + labels.size(), cudaPrefixSum); + + Vi prefixSum(labels.size()); + BOOST_REQUIRE_EQUAL( + cudaMemcpy(prefixSum.data(), cudaPrefixSum, labels.size() * sizeof(int), + cudaMemcpyDeviceToHost), + cudaSuccess); + BOOST_CHECK_EQUAL_COLLECTIONS(prefixSum.begin(), prefixSum.end(), + refPrefixSum.begin(), refPrefixSum.end()); + + // Relabel + mapEdgeLabels<<<1, 256>>>(labels.size(), cudaLabels, cudaPrefixSum); + BOOST_REQUIRE_EQUAL(cudaDeviceSynchronize(), cudaSuccess); + + std::vector labelsFromCuda(labels.size()); + BOOST_REQUIRE_EQUAL( + cudaMemcpy(labelsFromCuda.data(), cudaLabels, labels.size() * sizeof(int), + cudaMemcpyDeviceToHost), + cudaSuccess); + + BOOST_CHECK_EQUAL_COLLECTIONS(labelsFromCuda.begin(), labelsFromCuda.end(), + refLabels.begin(), refLabels.end()); +} + +BOOST_AUTO_TEST_CASE(test_relabeling) { + // clang-format off + Vi labels {0, 3, 5, 3, 0, 0}; + Vi refLabelMask{1, 0, 0, 1, 0, 1}; + Vi refPrefixSum{0, 1, 1, 1, 2, 2}; + Vi refLabels {0, 1, 2, 1, 0, 0}; + // clang-format on + + testRelabeling(labels, refLabelMask, refPrefixSum, refLabels); +} + +BOOST_AUTO_TEST_CASE(test_relabeling_2) { + // clang-format off + Vi labels {1, 3, 5, 3, 1, 1}; + Vi refLabelMask{0, 1, 0, 1, 0, 1}; + Vi refPrefixSum{0, 0, 1, 1, 2, 2}; + Vi refLabels {0, 1, 2, 1, 0, 0}; + // clang-format on + + testRelabeling(labels, refLabelMask, refPrefixSum, refLabels); +} + +auto makeRandomGraph(std::size_t nodes, std::size_t edges) { + std::default_random_engine rng(2345); + std::uniform_int_distribution<> dist(0, nodes); + std::set> set; + Vi src(edges), tgt(edges); + for (auto n = 0ul; n < edges; ++n) { + auto a = dist(rng); + auto b = dist(rng); + if (a == b) { + continue; + } + auto s = std::min(a, b); + auto t = std::max(a, b); + auto [it, success] = set.insert({s, t}); + if (success) { + src.at(n) = s; + tgt.at(n) = t; + } + } + + return std::make_pair(src, tgt); +} + +BOOST_AUTO_TEST_CASE(test_random_graph) { + auto [src, tgt] = makeRandomGraph(5, 10); + checkLabeling(src, tgt); +} + +void testFullConnectedComponents(const Vi &src, const Vi &tgt) { + const auto nNodes = std::max(*std::max_element(src.begin(), src.end()), + *std::max_element(tgt.begin(), tgt.end())) + + 1; + + // print src and tgt + /* + std::cout << "src: "; + for (int i = 0; i < src.size(); ++i) { + std::cout << src[i] << " "; + } + std::cout << std::endl; + std::cout << "tgt: "; + for (int i = 0; i < tgt.size(); ++i) { + std::cout << tgt[i] << " "; + } + std::cout << std::endl; + */ + cudaStream_t stream; + BOOST_REQUIRE_EQUAL(cudaStreamCreate(&stream), cudaSuccess); + + // copy src and tgt to device + int *cudaSrc, *cudaTgt; + BOOST_REQUIRE_EQUAL( + cudaMallocAsync(&cudaSrc, src.size() * sizeof(int), stream), cudaSuccess); + BOOST_REQUIRE_EQUAL( + cudaMallocAsync(&cudaTgt, tgt.size() * sizeof(int), stream), cudaSuccess); + BOOST_REQUIRE_EQUAL( + cudaMemcpyAsync(cudaSrc, src.data(), src.size() * sizeof(int), + cudaMemcpyHostToDevice, stream), + cudaSuccess); + BOOST_REQUIRE_EQUAL( + cudaMemcpyAsync(cudaTgt, tgt.data(), src.size() * sizeof(int), + cudaMemcpyHostToDevice, stream), + cudaSuccess); + + // init label array + int *cudaLabels; + BOOST_REQUIRE_EQUAL( + cudaMallocAsync(&cudaLabels, nNodes * sizeof(int), stream), cudaSuccess); + + // run connected components + int cudaNumLabels = connectedComponentsCuda(src.size(), cudaSrc, cudaTgt, + nNodes, cudaLabels, stream); + BOOST_REQUIRE_EQUAL(cudaStreamSynchronize(stream), cudaSuccess); + + // print message from last cuda error code + std::cout << "CUDA Error msg: " << cudaGetErrorString(cudaPeekAtLastError()) + << std::endl; + BOOST_REQUIRE_EQUAL(cudaGetLastError(), cudaSuccess); + + // copy labels back + std::vector labelsFromCuda(nNodes); + BOOST_REQUIRE_EQUAL( + cudaMemcpyAsync(labelsFromCuda.data(), cudaLabels, nNodes * sizeof(int), + cudaMemcpyDeviceToHost, stream), + cudaSuccess); + + BOOST_REQUIRE_EQUAL(cudaFreeAsync(cudaSrc, stream), cudaSuccess); + BOOST_REQUIRE_EQUAL(cudaFreeAsync(cudaTgt, stream), cudaSuccess); + BOOST_REQUIRE_EQUAL(cudaFreeAsync(cudaLabels, stream), cudaSuccess); + + // sync + BOOST_REQUIRE_EQUAL(cudaStreamSynchronize(stream), cudaSuccess); + BOOST_REQUIRE_EQUAL(cudaStreamDestroy(stream), cudaSuccess); + + // print labelsFromCuda + /* + std::cout << "CUDA labels: "; + for (int i = 0; i < nNodes; ++i) { + std::cout << labelsFromCuda[i] << " "; + } + std::cout << std::endl; + */ + // run boost graph for comparison + + BoostGraph G(nNodes); + + for (auto i = 0ul; i < src.size(); ++i) { + boost::add_edge(src[i], tgt[i], G); + } + + std::vector cpuLabels(boost::num_vertices(G)); + int cpuNumLabels = boost::connected_components(G, &cpuLabels[0]); + + // check + BOOST_CHECK_EQUAL(cudaNumLabels, cpuNumLabels); + BOOST_CHECK_EQUAL_COLLECTIONS(labelsFromCuda.begin(), labelsFromCuda.end(), + cpuLabels.begin(), cpuLabels.end()); +} + +BOOST_AUTO_TEST_CASE(full_test_tiny_graph) { + auto [src, tgt] = makeRandomGraph(5, 10); + testFullConnectedComponents(src, tgt); +} + +BOOST_AUTO_TEST_CASE(full_test_small_graph) { + auto [src, tgt] = makeRandomGraph(100, 500); + testFullConnectedComponents(src, tgt); +} + +BOOST_AUTO_TEST_CASE(full_test_big_graph) { + for (int i = 0; i < 3; ++i) { + std::cout << "Test graph " << i << std::endl; + auto [src, tgt] = makeRandomGraph(100'000, 500'000); + testFullConnectedComponents(src, tgt); + } +} + +BOOST_AUTO_TEST_CASE(test_from_file) { + if (!std::filesystem::exists("edges_cuda_trackbuilding.txt")) { + std::cout << "File edges_cuda_trackbuilding.txt not found" << std::endl; + return; + } + + std::ifstream file("edges_cuda_trackbuilding.txt"); + std::vector src, tgt; + int a, b; + while (file >> a >> b) { + src.push_back(a); + tgt.push_back(b); + } + + testFullConnectedComponents(src, tgt); +} + +// try this pathologic case +BOOST_AUTO_TEST_CASE(special_1) { + testFullConnectedComponents({1, 2}, {4, 7}); +} + +BOOST_AUTO_TEST_CASE(special_2) { + Vi src{1, 2}; + Vi tgt{4, 7}; + checkLabeling(src, tgt); +} + +BOOST_AUTO_TEST_CASE(special_3) { + // clang-format off + Vi labels {0, 1, 2, 3, 1, 5, 6, 2}; + Vi refLabelMask{1, 1, 1, 1, 0, 1, 1, 0}; + Vi refPrefixSum{0, 1, 2, 3, 4, 4, 5, 6}; + Vi refLabels {0, 1, 2, 3, 1, 4, 5, 2}; + // clang-format on + + testRelabeling(labels, refLabelMask, refPrefixSum, refLabels); +} + +BOOST_AUTO_TEST_CASE(special_4) { + Vi src{1, 2}; + Vi tgt{4, 7}; + + auto labelsFromCuda = checkLabeling(src, tgt); + + Vi refLabelMask{1, 1, 1, 1, 0, 1, 1, 0}; + Vi refPrefixSum{0, 1, 2, 3, 4, 4, 5, 6}; + Vi refLabels{0, 1, 2, 3, 1, 4, 5, 2}; + + testRelabeling(labelsFromCuda, refLabelMask, refPrefixSum, refLabels); +} diff --git a/Tests/UnitTests/Plugins/Geant4/Geant4SurfaceProviderTests.cpp b/Tests/UnitTests/Plugins/Geant4/Geant4SurfaceProviderTests.cpp index 7508fe9a148..e1846e108c7 100644 --- a/Tests/UnitTests/Plugins/Geant4/Geant4SurfaceProviderTests.cpp +++ b/Tests/UnitTests/Plugins/Geant4/Geant4SurfaceProviderTests.cpp @@ -32,17 +32,17 @@ /// @brief Convert Acts binning value to Geant4 axis /// as Geant4 uses a different axis convention /// @param bv the Acts binning value -EAxis binToGeant4Axis(const Acts::BinningValue& bv) { +EAxis binToGeant4Axis(const Acts::AxisDirection& bv) { switch (bv) { - case Acts::BinningValue::binX: + case Acts::AxisDirection::AxisX: return EAxis::kXAxis; - case Acts::BinningValue::binY: + case Acts::AxisDirection::AxisY: return EAxis::kYAxis; - case Acts::BinningValue::binZ: + case Acts::AxisDirection::AxisZ: return EAxis::kZAxis; - case Acts::BinningValue::binR: + case Acts::AxisDirection::AxisR: return EAxis::kRho; - case Acts::BinningValue::binPhi: + case Acts::AxisDirection::AxisPhi: return EAxis::kPhi; default: throw std::invalid_argument( @@ -225,7 +225,7 @@ BOOST_AUTO_TEST_CASE(Geant4SurfaceProviderRanges) { auto kdt1DOpt = Acts::Experimental::Geant4SurfaceProvider<1>::kdtOptions(); kdt1DOpt.range = Acts::RangeXD<1, double>(); kdt1DOpt.range[0].set(8, 12); - kdt1DOpt.binningValues = {Acts::BinningValue::binZ}; + kdt1DOpt.binningValues = {Acts::AxisDirection::AxisZ}; auto sp1D = std::make_shared>( sp1DCfg, kdt1DOpt); @@ -260,7 +260,7 @@ BOOST_AUTO_TEST_CASE(Geant4SurfaceProviderRanges) { kdt2DOpt.range = Acts::RangeXD<2, double>(); kdt2DOpt.range[0].set(8, 12); kdt2DOpt.range[1].set(armOffset - 5, armOffset + 100); - kdt2DOpt.binningValues = {Acts::BinningValue::binZ}; + kdt2DOpt.binningValues = {Acts::AxisDirection::AxisZ}; auto sp2D = std::make_shared>( sp2DCfg, kdt2DOpt); @@ -289,8 +289,8 @@ BOOST_AUTO_TEST_CASE(Geant4SurfaceProviderRanges) { std::map> ranges; std::array g4Axes{0}; - for (auto& bv : {Acts::BinningValue::binX, Acts::BinningValue::binY, - Acts::BinningValue::binZ}) { + for (auto& bv : {Acts::AxisDirection::AxisX, Acts::AxisDirection::AxisY, + Acts::AxisDirection::AxisZ}) { g4Axes[toUnderlying(bv)] = binToGeant4Axis(bv); } @@ -390,7 +390,7 @@ BOOST_AUTO_TEST_CASE(Geant4RectangleFromGDML) { auto kdt1DOpt = Acts::Experimental::Geant4SurfaceProvider<1>::kdtOptions(); kdt1DOpt.range = Acts::RangeXD<1, double>(); kdt1DOpt.range[0].set(-100, 100); - kdt1DOpt.binningValues = {Acts::BinningValue::binZ}; + kdt1DOpt.binningValues = {Acts::AxisDirection::AxisZ}; auto tContext = Acts::GeometryContext(); diff --git a/Tests/UnitTests/Plugins/Json/CMakeLists.txt b/Tests/UnitTests/Plugins/Json/CMakeLists.txt index 82ad95611ed..a7e12eeefd8 100644 --- a/Tests/UnitTests/Plugins/Json/CMakeLists.txt +++ b/Tests/UnitTests/Plugins/Json/CMakeLists.txt @@ -10,6 +10,7 @@ add_unittest(GridJsonConverter GridJsonConverterTests.cpp) add_unittest(MaterialJsonConverter MaterialJsonConverterTests.cpp) add_unittest(MaterialMapJsonConverter MaterialMapJsonConverterTests.cpp) add_unittest(PortalJsonConverter PortalJsonConverterTests.cpp) +add_unittest(ProtoAxisJsonConverter ProtoAxisJsonConverterTests.cpp) add_unittest(ProtoDetectorJsonConverter ProtoDetectorJsonConverterTests.cpp) add_unittest(UtilitiesJsonConverter UtilitiesJsonConverterTests.cpp) add_unittest(SurfaceBoundsJsonConverter SurfaceBoundsJsonConverterTests.cpp) diff --git a/Tests/UnitTests/Plugins/Json/DetectorJsonConverterTests.cpp b/Tests/UnitTests/Plugins/Json/DetectorJsonConverterTests.cpp index 7195c38eb9a..9a9cbcccb67 100644 --- a/Tests/UnitTests/Plugins/Json/DetectorJsonConverterTests.cpp +++ b/Tests/UnitTests/Plugins/Json/DetectorJsonConverterTests.cpp @@ -169,7 +169,7 @@ BOOST_AUTO_TEST_CASE(BeamPipeEndcapBarrelDetector) { lsConfig.auxiliary = "*** Endcap with 22 surfaces ***"; lsConfig.surfacesProvider = endcapSurfaces; lsConfig.binnings = {Acts::Experimental::ProtoBinning( - Acts::BinningValue::binPhi, Acts::AxisBoundaryType::Closed, + Acts::AxisDirection::AxisPhi, Acts::AxisBoundaryType::Closed, -std::numbers::pi, std::numbers::pi, 22u, 1u)}; auto layerBuilder = @@ -231,11 +231,11 @@ BOOST_AUTO_TEST_CASE(BeamPipeEndcapBarrelDetector) { lsConfig.auxiliary = "*** Barrel with 448 surfaces ***"; lsConfig.surfacesProvider = barrelSurfaces; lsConfig.binnings = { - Acts::Experimental::ProtoBinning{Acts::BinningValue::binZ, + Acts::Experimental::ProtoBinning{Acts::AxisDirection::AxisZ, Acts::AxisBoundaryType::Bound, -480., 480., 14u, 1u}, Acts::Experimental::ProtoBinning( - Acts::BinningValue::binPhi, Acts::AxisBoundaryType::Closed, + Acts::AxisDirection::AxisPhi, Acts::AxisBoundaryType::Closed, -std::numbers::pi, std::numbers::pi, 32u, 1u)}; auto barrelBuilder = @@ -280,7 +280,7 @@ BOOST_AUTO_TEST_CASE(BeamPipeEndcapBarrelDetector) { // Build the combined barrel Acts::Experimental::CylindricalContainerBuilder::Config ccBarrelBuilderCfg; ccBarrelBuilderCfg.builders = {ivBuilder, dvBuilder, ovBuilder}; - ccBarrelBuilderCfg.binning = {Acts::BinningValue::binR}; + ccBarrelBuilderCfg.binning = {Acts::AxisDirection::AxisR}; auto ccBarrelBuilder = std::make_shared( @@ -291,7 +291,7 @@ BOOST_AUTO_TEST_CASE(BeamPipeEndcapBarrelDetector) { Acts::Experimental::CylindricalContainerBuilder::Config ccBarrelEcBuilderCfg; ccBarrelEcBuilderCfg.builders = {endcapBuilders[0u], ccBarrelBuilder, endcapBuilders[1u]}; - ccBarrelEcBuilderCfg.binning = {Acts::BinningValue::binZ}; + ccBarrelEcBuilderCfg.binning = {Acts::AxisDirection::AxisZ}; auto ccBarrelEndcapBuilder = std::make_shared( @@ -318,7 +318,7 @@ BOOST_AUTO_TEST_CASE(BeamPipeEndcapBarrelDetector) { // Full detector Acts::Experimental::CylindricalContainerBuilder::Config detCompBuilderCfg; detCompBuilderCfg.builders = {bpBuilder, ccBarrelEndcapBuilder}; - detCompBuilderCfg.binning = {Acts::BinningValue::binR}; + detCompBuilderCfg.binning = {Acts::AxisDirection::AxisR}; auto detCompBuilder = std::make_shared( diff --git a/Tests/UnitTests/Plugins/Json/DetectorVolumeFinderJsonConverterTests.cpp b/Tests/UnitTests/Plugins/Json/DetectorVolumeFinderJsonConverterTests.cpp index 1d4aca927d9..88cfc784059 100644 --- a/Tests/UnitTests/Plugins/Json/DetectorVolumeFinderJsonConverterTests.cpp +++ b/Tests/UnitTests/Plugins/Json/DetectorVolumeFinderJsonConverterTests.cpp @@ -51,8 +51,8 @@ BOOST_AUTO_TEST_CASE(RzVolumes) { grid.atPosition(p22) = 22u; grid.atPosition(p23) = 23u; - auto casts = std::array{Acts::BinningValue::binZ, - Acts::BinningValue::binR}; + auto casts = std::array{Acts::AxisDirection::AxisZ, + Acts::AxisDirection::AxisR}; using IndexedDetectorVolumesImpl = Acts::Experimental::IndexedGridNavigation< Acts::Experimental::IExternalNavigation, GridType, diff --git a/Tests/UnitTests/Plugins/Json/DetectorVolumeJsonConverterTests.cpp b/Tests/UnitTests/Plugins/Json/DetectorVolumeJsonConverterTests.cpp index b1701f06128..3713cc46f90 100644 --- a/Tests/UnitTests/Plugins/Json/DetectorVolumeJsonConverterTests.cpp +++ b/Tests/UnitTests/Plugins/Json/DetectorVolumeJsonConverterTests.cpp @@ -149,7 +149,7 @@ BOOST_AUTO_TEST_CASE(EndcapVolumeWithSurfaces) { lsConfig.auxiliary = "*** Endcap with 22 surfaces ***"; lsConfig.surfacesProvider = endcapSurfaces; lsConfig.binnings = {Acts::Experimental::ProtoBinning( - Acts::BinningValue::binPhi, Acts::AxisBoundaryType::Closed, + Acts::AxisDirection::AxisPhi, Acts::AxisBoundaryType::Closed, -std::numbers::pi, std::numbers::pi, 22u, 1u)}; auto layerBuilder = @@ -228,11 +228,11 @@ BOOST_AUTO_TEST_CASE(BarrelVolumeWithSurfaces) { lsConfig.auxiliary = "*** Barrel with 448 surfaces ***"; lsConfig.surfacesProvider = barrelSurfaces; lsConfig.binnings = { - Acts::Experimental::ProtoBinning{Acts::BinningValue::binZ, + Acts::Experimental::ProtoBinning{Acts::AxisDirection::AxisZ, Acts::AxisBoundaryType::Bound, -480., 480., 14u, 1u}, Acts::Experimental::ProtoBinning( - Acts::BinningValue::binPhi, Acts::AxisBoundaryType::Closed, + Acts::AxisDirection::AxisPhi, Acts::AxisBoundaryType::Closed, -std::numbers::pi, std::numbers::pi, 32u, 1u)}; auto barrelBuilder = diff --git a/Tests/UnitTests/Plugins/Json/EqualityHelpers.hpp b/Tests/UnitTests/Plugins/Json/EqualityHelpers.hpp index 1544941002d..1a8286aa05c 100644 --- a/Tests/UnitTests/Plugins/Json/EqualityHelpers.hpp +++ b/Tests/UnitTests/Plugins/Json/EqualityHelpers.hpp @@ -91,7 +91,7 @@ inline static bool isEqual(const Acts::Extent& ea, const Acts::Extent& eb, double tolerance = 0.) { bool equalConstrains = true; bool equalRange = true; - for (auto& bVal : allBinningValues()) { + for (auto& bVal : allAxisDirections()) { equalConstrains = equalConstrains && (ea.constrains(bVal) == eb.constrains(bVal)); BOOST_CHECK(equalConstrains); diff --git a/Tests/UnitTests/Plugins/Json/ExtentJsonConverterTests.cpp b/Tests/UnitTests/Plugins/Json/ExtentJsonConverterTests.cpp index 3fc16ad0ccf..7c1884d5a3a 100644 --- a/Tests/UnitTests/Plugins/Json/ExtentJsonConverterTests.cpp +++ b/Tests/UnitTests/Plugins/Json/ExtentJsonConverterTests.cpp @@ -22,8 +22,8 @@ BOOST_AUTO_TEST_SUITE(ExtentJsonConverter) BOOST_AUTO_TEST_CASE(ExtentRoundtripTests) { Extent e; - e.set(BinningValue::binR, 0, 200); - e.set(BinningValue::binZ, -50, 50); + e.set(AxisDirection::AxisR, 0, 200); + e.set(AxisDirection::AxisZ, -50, 50); nlohmann::json j; j["extent"] = e; @@ -32,13 +32,13 @@ BOOST_AUTO_TEST_CASE(ExtentRoundtripTests) { Extent eIn = j["extent"]; - CHECK_CLOSE_ABS(eIn.min(BinningValue::binR), e.min(BinningValue::binR), + CHECK_CLOSE_ABS(eIn.min(AxisDirection::AxisR), e.min(AxisDirection::AxisR), 10e-5); - CHECK_CLOSE_ABS(eIn.max(BinningValue::binR), e.max(BinningValue::binR), + CHECK_CLOSE_ABS(eIn.max(AxisDirection::AxisR), e.max(AxisDirection::AxisR), 10e-5); - CHECK_CLOSE_ABS(eIn.min(BinningValue::binZ), e.min(BinningValue::binZ), + CHECK_CLOSE_ABS(eIn.min(AxisDirection::AxisZ), e.min(AxisDirection::AxisZ), 10e-5); - CHECK_CLOSE_ABS(eIn.max(BinningValue::binZ), e.max(BinningValue::binZ), + CHECK_CLOSE_ABS(eIn.max(AxisDirection::AxisZ), e.max(AxisDirection::AxisZ), 10e-5); } diff --git a/Tests/UnitTests/Plugins/Json/GridJsonConverterTests.cpp b/Tests/UnitTests/Plugins/Json/GridJsonConverterTests.cpp index cac514a18ac..98c0c731021 100644 --- a/Tests/UnitTests/Plugins/Json/GridJsonConverterTests.cpp +++ b/Tests/UnitTests/Plugins/Json/GridJsonConverterTests.cpp @@ -363,12 +363,13 @@ void checkGlobalSubspaceTuple(const SubspactTuple& sstuple) { BOOST_AUTO_TEST_CASE(GlobalSubSpaceTests1D) { // One dimensional sub spaces - const std::tuple, - Acts::GridAccess::GlobalSubspace, - Acts::GridAccess::GlobalSubspace, - Acts::GridAccess::GlobalSubspace, - Acts::GridAccess::GlobalSubspace, - Acts::GridAccess::GlobalSubspace> + const std::tuple< + Acts::GridAccess::GlobalSubspace, + Acts::GridAccess::GlobalSubspace, + Acts::GridAccess::GlobalSubspace, + Acts::GridAccess::GlobalSubspace, + Acts::GridAccess::GlobalSubspace, + Acts::GridAccess::GlobalSubspace> sspace1D; // Check the tuple for 1D @@ -377,26 +378,27 @@ BOOST_AUTO_TEST_CASE(GlobalSubSpaceTests1D) { BOOST_AUTO_TEST_CASE(GlobalSubSpaceTests2D) { // Two dimensional sub spaces - const std::tuple, - Acts::GridAccess::GlobalSubspace, - Acts::GridAccess::GlobalSubspace, - Acts::GridAccess::GlobalSubspace, - Acts::GridAccess::GlobalSubspace, - Acts::GridAccess::GlobalSubspace, - Acts::GridAccess::GlobalSubspace, - Acts::GridAccess::GlobalSubspace, - Acts::GridAccess::GlobalSubspace, - Acts::GridAccess::GlobalSubspace> + const std::tuple< + Acts::GridAccess::GlobalSubspace, + Acts::GridAccess::GlobalSubspace, + Acts::GridAccess::GlobalSubspace, + Acts::GridAccess::GlobalSubspace, + Acts::GridAccess::GlobalSubspace, + Acts::GridAccess::GlobalSubspace, + Acts::GridAccess::GlobalSubspace, + Acts::GridAccess::GlobalSubspace, + Acts::GridAccess::GlobalSubspace, + Acts::GridAccess::GlobalSubspace> sspace2D = {}; // Check the tuple for 2D diff --git a/Tests/UnitTests/Plugins/Json/MaterialJsonConverterTests.cpp b/Tests/UnitTests/Plugins/Json/MaterialJsonConverterTests.cpp index 6647ee69fe4..b7f982de739 100644 --- a/Tests/UnitTests/Plugins/Json/MaterialJsonConverterTests.cpp +++ b/Tests/UnitTests/Plugins/Json/MaterialJsonConverterTests.cpp @@ -55,11 +55,10 @@ BOOST_AUTO_TEST_CASE(IndexedSurfaceMaterial1DTests) { std::move(localX)); auto globalX = std::make_unique< - const Acts::GridAccess::GlobalSubspace>(); + const Acts::GridAccess::GlobalSubspace>(); Acts::IndexedSurfaceMaterial::GlobalToGridLocalDelegate gToX; - gToX.connect< - &Acts::GridAccess::GlobalSubspace::toGridLocal>( - std::move(globalX)); + gToX.connect<&Acts::GridAccess::GlobalSubspace< + Acts::AxisDirection::AxisX>::toGridLocal>(std::move(globalX)); Acts::IndexedSurfaceMaterial ism( std::move(eqGrid), Acts::IndexedMaterialAccessor{std::move(material)}, @@ -132,10 +131,10 @@ BOOST_AUTO_TEST_CASE(IndexedSurfaceMaterial2DTests) { // With z shift 10 auto globalToGrid = std::make_unique>(); + Acts::AxisDirection::AxisZ, Acts::AxisDirection::AxisPhi>>(); Acts::IndexedSurfaceMaterial::GlobalToGridLocalDelegate gToZphi; gToZphi.connect<&Acts::GridAccess::GlobalSubspace< - Acts::BinningValue::binZ, Acts::BinningValue::binPhi>::toGridLocal>( + Acts::AxisDirection::AxisZ, Acts::AxisDirection::AxisPhi>::toGridLocal>( std::move(globalToGrid)); // Create the indexed material grid diff --git a/Tests/UnitTests/Plugins/Json/PortalJsonConverterTests.cpp b/Tests/UnitTests/Plugins/Json/PortalJsonConverterTests.cpp index 770076c1a0e..ecdb602a4e2 100644 --- a/Tests/UnitTests/Plugins/Json/PortalJsonConverterTests.cpp +++ b/Tests/UnitTests/Plugins/Json/PortalJsonConverterTests.cpp @@ -77,9 +77,9 @@ BOOST_AUTO_TEST_CASE(PortalSingleConnected) { BOOST_CHECK_NE(portal, nullptr); // Attaching the portals Acts::Experimental::detail::PortalHelper::attachExternalNavigationDelegate( - *portal, forwardVolume, Acts::Direction::Forward); + *portal, forwardVolume, Acts::Direction::Forward()); Acts::Experimental::detail::PortalHelper::attachExternalNavigationDelegate( - *portal, backwardVolume, Acts::Direction::Backward); + *portal, backwardVolume, Acts::Direction::Backward()); std::vector detectorVolumes = { forwardVolume.get(), backwardVolume.get()}; @@ -125,11 +125,12 @@ BOOST_AUTO_TEST_CASE(PortalMultiConnected) { // Attaching the portals Acts::Experimental::detail::PortalHelper::attachExternalNavigationDelegate( - *portal, backwardVolume, Acts::Direction::Backward); + *portal, backwardVolume, Acts::Direction::Backward()); Acts::Experimental::detail::PortalHelper::attachDetectorVolumesUpdater( tContext, *portal, {forwardVolumeA, forwardVolumeB, forwardVolumeC}, - Acts::Direction::Forward, {-100, 10, 20, 200}, Acts::BinningValue::binX); + Acts::Direction::Forward(), {-100, 10, 20, 200}, + Acts::AxisDirection::AxisX); std::vector detectorVolumes = { forwardVolumeA.get(), forwardVolumeB.get(), forwardVolumeC.get(), diff --git a/Tests/UnitTests/Plugins/Json/ProtoAxisJsonConverterTests.cpp b/Tests/UnitTests/Plugins/Json/ProtoAxisJsonConverterTests.cpp new file mode 100644 index 00000000000..de7f78f23e3 --- /dev/null +++ b/Tests/UnitTests/Plugins/Json/ProtoAxisJsonConverterTests.cpp @@ -0,0 +1,155 @@ +// 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 + +#include "Acts/Plugins/Json/ActsJson.hpp" +#include "Acts/Plugins/Json/ProtoAxisJsonConverter.hpp" +#include "Acts/Tests/CommonHelpers/FloatComparisons.hpp" +#include "Acts/Utilities/Axis.hpp" +#include "Acts/Utilities/AxisDefinitions.hpp" +#include "Acts/Utilities/ProtoAxis.hpp" + +BOOST_AUTO_TEST_SUITE(ProtoAxisJsonConversion) + +BOOST_AUTO_TEST_CASE(EquidistantProtoAxisJsonConversion) { + using enum Acts::AxisBoundaryType; + using enum Acts::AxisDirection; + using enum Acts::AxisType; + + // Bound, equidistant axis + Acts::ProtoAxis epab(AxisX, Bound, 0.0, 1.0, 10); + + nlohmann::json jProtoAxis = Acts::ProtoAxisJsonConverter::toJson(epab); + + BOOST_CHECK(jProtoAxis.contains("axis")); + BOOST_CHECK(jProtoAxis.contains("axis_dir")); + BOOST_CHECK(jProtoAxis.contains("autorange")); + + Acts::ProtoAxis epabRead = Acts::ProtoAxisJsonConverter::fromJson(jProtoAxis); + + BOOST_CHECK_EQUAL(epabRead.getAxisDirection(), epab.getAxisDirection()); + BOOST_CHECK_EQUAL(epabRead.getAxis(), epab.getAxis()); + BOOST_CHECK_EQUAL(epabRead.isAutorange(), epab.isAutorange()); + BOOST_CHECK_EQUAL(epabRead.toString(), epab.toString()); +} + +BOOST_AUTO_TEST_CASE(AutorangeProtoAxisJsonConversion) { + using enum Acts::AxisBoundaryType; + using enum Acts::AxisDirection; + using enum Acts::AxisType; + + // Bound, equidistant axis, autorange + Acts::ProtoAxis epa(AxisX, Bound, 10); + + nlohmann::json jProtoAxis = Acts::ProtoAxisJsonConverter::toJson(epa); + + BOOST_CHECK(jProtoAxis.contains("axis")); + BOOST_CHECK(jProtoAxis.contains("axis_dir")); + BOOST_CHECK(jProtoAxis.contains("autorange")); + + Acts::ProtoAxis epaRead = Acts::ProtoAxisJsonConverter::fromJson(jProtoAxis); + + BOOST_CHECK_EQUAL(epaRead.getAxisDirection(), epa.getAxisDirection()); + BOOST_CHECK_EQUAL(epaRead.getAxis(), epa.getAxis()); + BOOST_CHECK_EQUAL(epaRead.isAutorange(), epa.isAutorange()); + BOOST_CHECK_EQUAL(epaRead.toString(), epa.toString()); +} + +BOOST_AUTO_TEST_CASE(VariableProtoAxisJsonConversion) { + using enum Acts::AxisBoundaryType; + using enum Acts::AxisDirection; + using enum Acts::AxisType; + + // Bound, variable axis + Acts::ProtoAxis vpab(AxisX, Bound, {0.0, 1.0, 10}); + + nlohmann::json jProtoAxis = Acts::ProtoAxisJsonConverter::toJson(vpab); + BOOST_CHECK(jProtoAxis.contains("axis")); + BOOST_CHECK(jProtoAxis.contains("axis_dir")); + BOOST_CHECK(jProtoAxis.contains("autorange")); + + Acts::ProtoAxis vpabRead = Acts::ProtoAxisJsonConverter::fromJson(jProtoAxis); + + BOOST_CHECK_EQUAL(vpabRead.getAxisDirection(), vpab.getAxisDirection()); + BOOST_CHECK_EQUAL(vpabRead.getAxis(), vpab.getAxis()); + BOOST_CHECK_EQUAL(vpabRead.isAutorange(), vpab.isAutorange()); + BOOST_CHECK_EQUAL(vpabRead.toString(), vpab.toString()); +} + +BOOST_AUTO_TEST_CASE(InvalidAndValidInputJson) { + // valid eq axis input + nlohmann::json jValidEqAxis = {{"bins", 10}, + {"boundary_type", "Bound"}, + {"range", std::array{0.0, 1.0}}, + {"type", "Equidistant"}}; + + // Valid input first + nlohmann::json jValidEq = { + {"axis", jValidEqAxis}, {"axis_dir", "AxisX"}, {"autorange", false}}; + + BOOST_CHECK_NO_THROW(Acts::ProtoAxisJsonConverter::fromJson(jValidEq)); + + // Invalid input - zero bins + nlohmann::json jInvalidEqAxis = jValidEqAxis; + jInvalidEqAxis["bins"] = 0; + + nlohmann::json jInvalidEq = { + {"axis", jInvalidEqAxis}, {"axis_dir", "AxisX"}, {"autorange", false}}; + + BOOST_CHECK_THROW(Acts::ProtoAxisJsonConverter::fromJson(jInvalidEq), + std::invalid_argument); + + // Invalid input - auto range without bins + jInvalidEq = { + {"axis", jInvalidEqAxis}, {"axis_dir", "AxisX"}, {"autorange", true}}; + BOOST_CHECK_THROW(Acts::ProtoAxisJsonConverter::fromJson(jInvalidEq), + std::invalid_argument); + + // Invalid input - min >= max + jInvalidEqAxis = jValidEqAxis; + jInvalidEqAxis["range"] = std::array{1.0, 0.0}; + + jInvalidEq = { + {"axis", jInvalidEqAxis}, {"axis_dir", "AxisX"}, {"autorange", false}}; + + BOOST_CHECK_THROW(Acts::ProtoAxisJsonConverter::fromJson(jInvalidEq), + std::invalid_argument); + + nlohmann::json jValidVarAxis = { + {"boundary_type", "Bound"}, + {"boundaries", std::vector{0.0, 0.25, 0.75, 1.0}}, + {"type", "Variable"}}; + + // Valid input first + nlohmann::json jValidVar = { + {"axis", jValidVarAxis}, {"axis_dir", "AxisX"}, {"autorange", false}}; + BOOST_CHECK_NO_THROW(Acts::ProtoAxisJsonConverter::fromJson(jValidVar)); + + // Invalid input - less than two edges + nlohmann::json jInvalidVarAxis = jValidVarAxis; + jInvalidVarAxis["boundaries"] = std::vector{0.0}; + + nlohmann::json jInvalidVar = { + {"axis", jInvalidVarAxis}, {"axis_dir", "AxisX"}, {"autorange", false}}; + BOOST_CHECK_THROW(Acts::ProtoAxisJsonConverter::fromJson(jInvalidVar), + std::invalid_argument); + + // Invalid input - non-increasing edges + jInvalidVarAxis = jValidVarAxis; + jInvalidVarAxis["boundaries"] = std::vector{0.0, 0.75, 0.25, 1.0}; + + jInvalidVar = { + {"axis", jInvalidVarAxis}, {"axis_dir", "AxisX"}, {"autorange", false}}; + + BOOST_CHECK_THROW(Acts::ProtoAxisJsonConverter::fromJson(jInvalidVar), + std::invalid_argument); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/Tests/UnitTests/Plugins/Json/ProtoDetectorJsonConverterTests.cpp b/Tests/UnitTests/Plugins/Json/ProtoDetectorJsonConverterTests.cpp index 5cf5f75ce58..1e97184801b 100644 --- a/Tests/UnitTests/Plugins/Json/ProtoDetectorJsonConverterTests.cpp +++ b/Tests/UnitTests/Plugins/Json/ProtoDetectorJsonConverterTests.cpp @@ -117,66 +117,66 @@ BOOST_AUTO_TEST_SUITE(ProtoDetectorJsonConverter) BOOST_AUTO_TEST_CASE(ProtoDetectorRoundTrip) { Acts::ExtentEnvelope cylinderLayerEnvelope = ExtentEnvelope::Zero(); - cylinderLayerEnvelope[Acts::BinningValue::binR] = {1., 1.}; - cylinderLayerEnvelope[Acts::BinningValue::binZ] = {2., 2.}; + cylinderLayerEnvelope[Acts::AxisDirection::AxisR] = {1., 1.}; + cylinderLayerEnvelope[Acts::AxisDirection::AxisZ] = {2., 2.}; Acts::ExtentEnvelope discLayerEnvelope = ExtentEnvelope::Zero(); - discLayerEnvelope[Acts::BinningValue::binR] = {1., 1.}; - discLayerEnvelope[Acts::BinningValue::binZ] = {1., 1.}; + discLayerEnvelope[Acts::AxisDirection::AxisR] = {1., 1.}; + discLayerEnvelope[Acts::AxisDirection::AxisZ] = {1., 1.}; // Beam Pipe container Acts::ProtoVolume beamPipeContainer; beamPipeContainer.name = "odd-beam-pipe"; - beamPipeContainer.extent.set(Acts::BinningValue::binR, 0., 25); + beamPipeContainer.extent.set(Acts::AxisDirection::AxisR, 0., 25); Acts::ProtoVolume beamPipe; beamPipe.name = "odd-beam-pipe-l"; - beamPipe.extent.set(Acts::BinningValue::binR, 2., 24.); + beamPipe.extent.set(Acts::AxisDirection::AxisR, 2., 24.); beamPipe.internal = Acts::ProtoVolume::InternalStructure{ Acts::Surface::SurfaceType::Cylinder}; beamPipeContainer.container = Acts::ProtoVolume::ContainerStructure{ {beamPipe}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binR, {0., 1.})}, + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisR, {0., 1.})}, true}; // Pixel section Acts::ProtoVolume pixelContainer; pixelContainer.name = "odd-pixel"; - pixelContainer.extent.set(Acts::BinningValue::binR, 25., 200); + pixelContainer.extent.set(Acts::AxisDirection::AxisR, 25., 200); Acts::ProtoVolume pixelNec; pixelNec.name = "odd-pixel-nec"; - pixelNec.extent.set(Acts::BinningValue::binZ, -3100., -580); + pixelNec.extent.set(Acts::AxisDirection::AxisZ, -3100., -580); Acts::ProtoVolume pixNecD6; pixNecD6.name = "odd-pixel-nec-d6"; - pixNecD6.extent.set(Acts::BinningValue::binZ, -1540., -1500); + pixNecD6.extent.set(Acts::AxisDirection::AxisZ, -1540., -1500); Acts::ProtoVolume pixNecD5; pixNecD5.name = "odd-pixel-nec-d5"; - pixNecD5.extent.set(Acts::BinningValue::binZ, -1340., -1300); + pixNecD5.extent.set(Acts::AxisDirection::AxisZ, -1340., -1300); Acts::ProtoVolume pixNecD4; pixNecD4.name = "odd-pixel-nec-d4"; - pixNecD4.extent.set(Acts::BinningValue::binZ, -1140., -1100); + pixNecD4.extent.set(Acts::AxisDirection::AxisZ, -1140., -1100); Acts::ProtoVolume pixNecD3; pixNecD3.name = "odd-pixel-nec-d3"; - pixNecD3.extent.set(Acts::BinningValue::binZ, -1000., -960.); + pixNecD3.extent.set(Acts::AxisDirection::AxisZ, -1000., -960.); Acts::ProtoVolume pixNecD2; pixNecD2.name = "odd-pixel-nec-d2"; - pixNecD2.extent.set(Acts::BinningValue::binZ, -860., -820); + pixNecD2.extent.set(Acts::AxisDirection::AxisZ, -860., -820); Acts::ProtoVolume pixNecD1; pixNecD1.name = "odd-pixel-nec-d1"; - pixNecD1.extent.set(Acts::BinningValue::binZ, -740., -700); + pixNecD1.extent.set(Acts::AxisDirection::AxisZ, -740., -700); Acts::ProtoVolume pixNecD0; pixNecD0.name = "odd-pixel-nec-d0"; - pixNecD0.extent.set(Acts::BinningValue::binZ, -640., -600); + pixNecD0.extent.set(Acts::AxisDirection::AxisZ, -640., -600); pixelNec.container = Acts::ProtoVolume::ContainerStructure{ {pixNecD6, pixNecD5, pixNecD4, pixNecD3, pixNecD2, pixNecD1, pixNecD0}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binZ, {0., 1.})}, + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisZ, {0., 1.})}, true}; Acts::BinningData pixEcBinningR = - Acts::BinningData(Acts::open, Acts::BinningValue::binR, 2., 0., 1.); + Acts::BinningData(Acts::open, Acts::AxisDirection::AxisR, 2., 0., 1.); Acts::BinningData pixEcBinningPhi = - Acts::BinningData(Acts::closed, Acts::BinningValue::binPhi, 30., + Acts::BinningData(Acts::closed, Acts::AxisDirection::AxisPhi, 30., -std::numbers::pi, std::numbers::pi); for (auto& cv : pixelNec.container.value().constituentVolumes) { @@ -187,28 +187,28 @@ BOOST_AUTO_TEST_CASE(ProtoDetectorRoundTrip) { Acts::ProtoVolume pixelBarrel; pixelBarrel.name = "odd-pixel-barrel"; - pixelBarrel.extent.set(Acts::BinningValue::binZ, -580., 580); + pixelBarrel.extent.set(Acts::AxisDirection::AxisZ, -580., 580); Acts::ProtoVolume pixBarrelL0; pixBarrelL0.name = "odd-pixel-barrel-l0"; - pixBarrelL0.extent.set(Acts::BinningValue::binR, 28., 48.); - pixBarrelL0.extent.set(Acts::BinningValue::binZ, -580., 580); + pixBarrelL0.extent.set(Acts::AxisDirection::AxisR, 28., 48.); + pixBarrelL0.extent.set(Acts::AxisDirection::AxisZ, -580., 580); Acts::ProtoVolume pixBarrelL1; pixBarrelL1.name = "odd-pixel-barrel-l1"; - pixBarrelL1.extent.set(Acts::BinningValue::binR, 62., 76); - pixBarrelL1.extent.set(Acts::BinningValue::binZ, -580., 580); + pixBarrelL1.extent.set(Acts::AxisDirection::AxisR, 62., 76); + pixBarrelL1.extent.set(Acts::AxisDirection::AxisZ, -580., 580); Acts::ProtoVolume pixBarrelL2; pixBarrelL2.name = "odd-pixel-barrel-l2"; - pixBarrelL2.extent.set(Acts::BinningValue::binR, 100., 120.); - pixBarrelL2.extent.set(Acts::BinningValue::binZ, -580., 580); + pixBarrelL2.extent.set(Acts::AxisDirection::AxisR, 100., 120.); + pixBarrelL2.extent.set(Acts::AxisDirection::AxisZ, -580., 580); Acts::ProtoVolume pixBarrelL3; pixBarrelL3.name = "odd-pixel-barrel-l3"; - pixBarrelL3.extent.set(Acts::BinningValue::binR, 160., 180.); - pixBarrelL3.extent.set(Acts::BinningValue::binZ, -580., 580); + pixBarrelL3.extent.set(Acts::AxisDirection::AxisR, 160., 180.); + pixBarrelL3.extent.set(Acts::AxisDirection::AxisZ, -580., 580); pixelBarrel.container = Acts::ProtoVolume::ContainerStructure{ {pixBarrelL0, pixBarrelL1, pixBarrelL2, pixBarrelL3}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binR, {0., 1})}, + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisR, {0., 1})}, true}; for (auto& cv : pixelBarrel.container.value().constituentVolumes) { @@ -219,33 +219,33 @@ BOOST_AUTO_TEST_CASE(ProtoDetectorRoundTrip) { Acts::ProtoVolume pixelPec; pixelPec.name = "odd-pixel-pec"; - pixelPec.extent.set(Acts::BinningValue::binZ, 580., 3100.); + pixelPec.extent.set(Acts::AxisDirection::AxisZ, 580., 3100.); Acts::ProtoVolume pixPecD0; pixPecD0.name = "odd-pixel-pec-d0"; - pixPecD0.extent.set(Acts::BinningValue::binZ, 600., 640); + pixPecD0.extent.set(Acts::AxisDirection::AxisZ, 600., 640); Acts::ProtoVolume pixPecD1; pixPecD1.name = "odd-pixel-pec-d1"; - pixPecD1.extent.set(Acts::BinningValue::binZ, 700., 740); + pixPecD1.extent.set(Acts::AxisDirection::AxisZ, 700., 740); Acts::ProtoVolume pixPecD2; pixPecD2.name = "odd-pixel-pec-d2"; - pixPecD2.extent.set(Acts::BinningValue::binZ, 820., 860.); + pixPecD2.extent.set(Acts::AxisDirection::AxisZ, 820., 860.); Acts::ProtoVolume pixPecD3; pixPecD3.name = "odd-pixel-pec-d3"; - pixPecD3.extent.set(Acts::BinningValue::binZ, 960., 1000.); + pixPecD3.extent.set(Acts::AxisDirection::AxisZ, 960., 1000.); Acts::ProtoVolume pixPecD4; pixPecD4.name = "odd-pixel-pec-d4"; - pixPecD4.extent.set(Acts::BinningValue::binZ, 1100., 1140); + pixPecD4.extent.set(Acts::AxisDirection::AxisZ, 1100., 1140); Acts::ProtoVolume pixPecD5; pixPecD5.name = "odd-pixel-pec-d5"; - pixPecD5.extent.set(Acts::BinningValue::binZ, 1300., 1340.); + pixPecD5.extent.set(Acts::AxisDirection::AxisZ, 1300., 1340.); Acts::ProtoVolume pixPecD6; pixPecD6.name = "odd-pixel-pec-d6"; - pixPecD6.extent.set(Acts::BinningValue::binZ, 1500., 1540.); + pixPecD6.extent.set(Acts::AxisDirection::AxisZ, 1500., 1540.); pixelPec.container = Acts::ProtoVolume::ContainerStructure{ {pixPecD0, pixPecD1, pixPecD2, pixPecD3, pixPecD4, pixPecD5, pixPecD6}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binZ, {0., 1})}, + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisZ, {0., 1})}, true}; for (auto& cv : pixelPec.container.value().constituentVolumes) { @@ -256,60 +256,60 @@ BOOST_AUTO_TEST_CASE(ProtoDetectorRoundTrip) { pixelContainer.container = Acts::ProtoVolume::ContainerStructure{ {pixelNec, pixelBarrel, pixelPec}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binZ, + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisZ, {-3100., -580., 580., 3100.})}}; // Short Strip section Acts::ProtoVolume pstContainer; pstContainer.name = "odd-pst"; - pstContainer.extent.set(Acts::BinningValue::binR, 200., 210.); + pstContainer.extent.set(Acts::AxisDirection::AxisR, 200., 210.); Acts::ProtoVolume pst; pst.name = "odd-pst-l"; - pst.extent.set(Acts::BinningValue::binR, 201., 209.); + pst.extent.set(Acts::AxisDirection::AxisR, 201., 209.); pst.internal = Acts::ProtoVolume::InternalStructure{ Acts::Surface::SurfaceType::Cylinder}; pstContainer.container = Acts::ProtoVolume::ContainerStructure{ {pst}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binR, {0., 1.})}, + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisR, {0., 1.})}, true}; // Short Strip section Acts::ProtoVolume sstripContainer; sstripContainer.name = "odd-sstrip"; - sstripContainer.extent.set(Acts::BinningValue::binR, 210., 720); + sstripContainer.extent.set(Acts::AxisDirection::AxisR, 210., 720); Acts::BinningData sstripEcBinningR = - Acts::BinningData(Acts::open, Acts::BinningValue::binR, 3., 0., 1.); + Acts::BinningData(Acts::open, Acts::AxisDirection::AxisR, 3., 0., 1.); Acts::BinningData sstripEcBinningPhi = - Acts::BinningData(Acts::closed, Acts::BinningValue::binPhi, 42., + Acts::BinningData(Acts::closed, Acts::AxisDirection::AxisPhi, 42., -std::numbers::pi, std::numbers::pi); Acts::ProtoVolume sstripNec; sstripNec.name = "odd-sstrip-nec"; - sstripNec.extent.set(Acts::BinningValue::binZ, -3100., -1200); + sstripNec.extent.set(Acts::AxisDirection::AxisZ, -3100., -1200); Acts::ProtoVolume sstripNecD5; sstripNecD5.name = "odd-sstrip-nec-d5"; - sstripNecD5.extent.set(Acts::BinningValue::binZ, -3000, -2900.); + sstripNecD5.extent.set(Acts::AxisDirection::AxisZ, -3000, -2900.); Acts::ProtoVolume sstripNecD4; sstripNecD4.name = "odd-sstrip-nec-d4"; - sstripNecD4.extent.set(Acts::BinningValue::binZ, -2600., -2500.); + sstripNecD4.extent.set(Acts::AxisDirection::AxisZ, -2600., -2500.); Acts::ProtoVolume sstripNecD3; sstripNecD3.name = "odd-sstrip-nec-d3"; - sstripNecD3.extent.set(Acts::BinningValue::binZ, -2250, -2150.); + sstripNecD3.extent.set(Acts::AxisDirection::AxisZ, -2250, -2150.); Acts::ProtoVolume sstripNecD2; sstripNecD2.name = "odd-sstrip-nec-d2"; - sstripNecD2.extent.set(Acts::BinningValue::binZ, -1900, -1800.); + sstripNecD2.extent.set(Acts::AxisDirection::AxisZ, -1900, -1800.); Acts::ProtoVolume sstripNecD1; sstripNecD1.name = "odd-sstrip-nec-d1"; - sstripNecD1.extent.set(Acts::BinningValue::binZ, -1600., -1500.); + sstripNecD1.extent.set(Acts::AxisDirection::AxisZ, -1600., -1500.); Acts::ProtoVolume sstripNecD0; sstripNecD0.name = "odd-sstrip-nec-d0"; - sstripNecD0.extent.set(Acts::BinningValue::binZ, -1350., -1250.); + sstripNecD0.extent.set(Acts::AxisDirection::AxisZ, -1350., -1250.); sstripNec.container = Acts::ProtoVolume::ContainerStructure{ {sstripNecD5, sstripNecD4, sstripNecD3, sstripNecD2, sstripNecD1, sstripNecD0}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binZ, {0., 1})}, + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisZ, {0., 1})}, true}; for (auto& cv : sstripNec.container.value().constituentVolumes) { @@ -321,24 +321,24 @@ BOOST_AUTO_TEST_CASE(ProtoDetectorRoundTrip) { Acts::ProtoVolume sstripBarrel; sstripBarrel.name = "odd-sstrip-barrel"; - sstripBarrel.extent.set(Acts::BinningValue::binZ, -1200., 1200); + sstripBarrel.extent.set(Acts::AxisDirection::AxisZ, -1200., 1200); Acts::ProtoVolume sstripBarrelL0; sstripBarrelL0.name = "odd-sstrip-barrel-l0"; - sstripBarrelL0.extent.set(Acts::BinningValue::binR, 240., 280.); + sstripBarrelL0.extent.set(Acts::AxisDirection::AxisR, 240., 280.); Acts::ProtoVolume sstripBarrelL1; sstripBarrelL1.name = "odd-sstrip-barrel-l1"; - sstripBarrelL1.extent.set(Acts::BinningValue::binR, 340., 380.); + sstripBarrelL1.extent.set(Acts::AxisDirection::AxisR, 340., 380.); Acts::ProtoVolume sstripBarrelL2; sstripBarrelL2.name = "odd-sstrip-barrel-l2"; - sstripBarrelL2.extent.set(Acts::BinningValue::binR, 480., 520.); + sstripBarrelL2.extent.set(Acts::AxisDirection::AxisR, 480., 520.); Acts::ProtoVolume sstripBarrelL3; sstripBarrelL3.name = "odd-sstrip-barrel-l3"; - sstripBarrelL3.extent.set(Acts::BinningValue::binR, 640., 680.); + sstripBarrelL3.extent.set(Acts::AxisDirection::AxisR, 640., 680.); sstripBarrel.container = Acts::ProtoVolume::ContainerStructure{ {sstripBarrelL0, sstripBarrelL1, sstripBarrelL2, sstripBarrelL3}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binR, {0., 1})}, + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisR, {0., 1})}, true}; for (auto& cv : sstripBarrel.container.value().constituentVolumes) { @@ -349,31 +349,31 @@ BOOST_AUTO_TEST_CASE(ProtoDetectorRoundTrip) { Acts::ProtoVolume sstripPec; sstripPec.name = "odd-sstrip-pec"; - sstripPec.extent.set(Acts::BinningValue::binZ, 1200., 3100); + sstripPec.extent.set(Acts::AxisDirection::AxisZ, 1200., 3100); Acts::ProtoVolume sstripPecD0; sstripPecD0.name = "odd-sstrip-pec-d0"; - sstripPecD0.extent.set(Acts::BinningValue::binZ, 1250., 1350); + sstripPecD0.extent.set(Acts::AxisDirection::AxisZ, 1250., 1350); Acts::ProtoVolume sstripPecD1; sstripPecD1.name = "odd-sstrip-pec-d1"; - sstripPecD1.extent.set(Acts::BinningValue::binZ, 1500., 1600.); + sstripPecD1.extent.set(Acts::AxisDirection::AxisZ, 1500., 1600.); Acts::ProtoVolume sstripPecD2; sstripPecD2.name = "odd-sstrip-pec-d2"; - sstripPecD2.extent.set(Acts::BinningValue::binZ, 1800., 1900.); + sstripPecD2.extent.set(Acts::AxisDirection::AxisZ, 1800., 1900.); Acts::ProtoVolume sstripPecD3; sstripPecD3.name = "odd-sstrip-pec-d3"; - sstripPecD3.extent.set(Acts::BinningValue::binZ, 2150., 2250.); + sstripPecD3.extent.set(Acts::AxisDirection::AxisZ, 2150., 2250.); Acts::ProtoVolume sstripPecD4; sstripPecD4.name = "odd-sstrip-pec-d4"; - sstripPecD4.extent.set(Acts::BinningValue::binZ, 2500., 2600.); + sstripPecD4.extent.set(Acts::AxisDirection::AxisZ, 2500., 2600.); Acts::ProtoVolume sstripPecD5; sstripPecD5.name = "odd-sstrip-pec-d5"; - sstripPecD5.extent.set(Acts::BinningValue::binZ, 2900., 3000.); + sstripPecD5.extent.set(Acts::AxisDirection::AxisZ, 2900., 3000.); sstripPec.container = Acts::ProtoVolume::ContainerStructure{ {sstripPecD0, sstripPecD1, sstripPecD2, sstripPecD3, sstripPecD4, sstripPecD5}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binZ, {0., 1})}, + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisZ, {0., 1})}, true}; for (auto& cv : sstripPec.container.value().constituentVolumes) { cv.extent.setEnvelope(discLayerEnvelope); @@ -384,40 +384,40 @@ BOOST_AUTO_TEST_CASE(ProtoDetectorRoundTrip) { sstripContainer.container = Acts::ProtoVolume::ContainerStructure{ {sstripNec, sstripBarrel, sstripPec}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binZ, + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisZ, {-3100., -1200., 1200., 3100.})}}; // Long Strip section Acts::ProtoVolume lstripContainer; lstripContainer.name = "odd-lstrip"; - lstripContainer.extent.set(Acts::BinningValue::binR, 720, 1100.); + lstripContainer.extent.set(Acts::AxisDirection::AxisR, 720, 1100.); Acts::ProtoVolume lstripNec; lstripNec.name = "odd-lstrip-nec"; - lstripNec.extent.set(Acts::BinningValue::binZ, -3100., -1200); + lstripNec.extent.set(Acts::AxisDirection::AxisZ, -3100., -1200); Acts::ProtoVolume lstripNecD5; lstripNecD5.name = "odd-lstrip-nec-d5"; - lstripNecD5.extent.set(Acts::BinningValue::binZ, -3050, -2900.); + lstripNecD5.extent.set(Acts::AxisDirection::AxisZ, -3050, -2900.); Acts::ProtoVolume lstripNecD4; lstripNecD4.name = "odd-lstrip-nec-d4"; - lstripNecD4.extent.set(Acts::BinningValue::binZ, -2650., -2500.); + lstripNecD4.extent.set(Acts::AxisDirection::AxisZ, -2650., -2500.); Acts::ProtoVolume lstripNecD3; lstripNecD3.name = "odd-lstrip-nec-d3"; - lstripNecD3.extent.set(Acts::BinningValue::binZ, -2300, -2150.); + lstripNecD3.extent.set(Acts::AxisDirection::AxisZ, -2300, -2150.); Acts::ProtoVolume lstripNecD2; lstripNecD2.name = "odd-lstrip-nec-d2"; - lstripNecD2.extent.set(Acts::BinningValue::binZ, -1950, -1800.); + lstripNecD2.extent.set(Acts::AxisDirection::AxisZ, -1950, -1800.); Acts::ProtoVolume lstripNecD1; lstripNecD1.name = "odd-lstrip-nec-d1"; - lstripNecD1.extent.set(Acts::BinningValue::binZ, -1650., -1500.); + lstripNecD1.extent.set(Acts::AxisDirection::AxisZ, -1650., -1500.); Acts::ProtoVolume lstripNecD0; lstripNecD0.name = "odd-lstrip-nec-d0"; - lstripNecD0.extent.set(Acts::BinningValue::binZ, -1400., -1250.); + lstripNecD0.extent.set(Acts::AxisDirection::AxisZ, -1400., -1250.); lstripNec.container = Acts::ProtoVolume::ContainerStructure{ {lstripNecD5, lstripNecD4, lstripNecD3, lstripNecD2, lstripNecD1, lstripNecD0}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binZ, {0., 1})}, + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisZ, {0., 1})}, true}; for (auto& cv : lstripNec.container.value().constituentVolumes) { @@ -428,18 +428,18 @@ BOOST_AUTO_TEST_CASE(ProtoDetectorRoundTrip) { Acts::ProtoVolume lstripBarrel; lstripBarrel.name = "odd-lstrip-barrel"; - lstripBarrel.extent.set(Acts::BinningValue::binZ, -1200., 1200); + lstripBarrel.extent.set(Acts::AxisDirection::AxisZ, -1200., 1200); Acts::ProtoVolume lstripBarrelL0; lstripBarrelL0.name = "odd-lstrip-barrel-l0"; - lstripBarrelL0.extent.set(Acts::BinningValue::binR, 800., 840.); + lstripBarrelL0.extent.set(Acts::AxisDirection::AxisR, 800., 840.); Acts::ProtoVolume lstripBarrelL1; lstripBarrelL1.name = "odd-lstrip-barrel-l1"; - lstripBarrelL1.extent.set(Acts::BinningValue::binR, 1000., 1050.); + lstripBarrelL1.extent.set(Acts::AxisDirection::AxisR, 1000., 1050.); lstripBarrel.container = Acts::ProtoVolume::ContainerStructure{ {lstripBarrelL0, lstripBarrelL1}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binR, {0., 1})}, + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisR, {0., 1})}, true}; for (auto& cv : lstripBarrel.container.value().constituentVolumes) { @@ -450,31 +450,31 @@ BOOST_AUTO_TEST_CASE(ProtoDetectorRoundTrip) { Acts::ProtoVolume lstripPec; lstripPec.name = "odd-lstrip-pec"; - lstripPec.extent.set(Acts::BinningValue::binZ, 1200., 3100); + lstripPec.extent.set(Acts::AxisDirection::AxisZ, 1200., 3100); Acts::ProtoVolume lstripPecD0; lstripPecD0.name = "odd-lstrip-pec-d0"; - lstripPecD0.extent.set(Acts::BinningValue::binZ, 1250., 1400); + lstripPecD0.extent.set(Acts::AxisDirection::AxisZ, 1250., 1400); Acts::ProtoVolume lstripPecD1; lstripPecD1.name = "odd-lstrip-pec-d1"; - lstripPecD1.extent.set(Acts::BinningValue::binZ, 1500., 1650.); + lstripPecD1.extent.set(Acts::AxisDirection::AxisZ, 1500., 1650.); Acts::ProtoVolume lstripPecD2; lstripPecD2.name = "odd-lstrip-pec-d2"; - lstripPecD2.extent.set(Acts::BinningValue::binZ, 1800., 1950.); + lstripPecD2.extent.set(Acts::AxisDirection::AxisZ, 1800., 1950.); Acts::ProtoVolume lstripPecD3; lstripPecD3.name = "odd-lstrip-pec-d3"; - lstripPecD3.extent.set(Acts::BinningValue::binZ, 2150., 2300.); + lstripPecD3.extent.set(Acts::AxisDirection::AxisZ, 2150., 2300.); Acts::ProtoVolume lstripPecD4; lstripPecD4.name = "odd-lstrip-pec-d4"; - lstripPecD4.extent.set(Acts::BinningValue::binZ, 2500., 2650.); + lstripPecD4.extent.set(Acts::AxisDirection::AxisZ, 2500., 2650.); Acts::ProtoVolume lstripPecD5; lstripPecD5.name = "odd-lstrip-pec-d5"; - lstripPecD5.extent.set(Acts::BinningValue::binZ, 2900., 3050.); + lstripPecD5.extent.set(Acts::AxisDirection::AxisZ, 2900., 3050.); lstripPec.container = Acts::ProtoVolume::ContainerStructure{ {lstripPecD0, lstripPecD1, lstripPecD2, lstripPecD3, lstripPecD4, lstripPecD5}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binZ, {0., 1})}, + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisZ, {0., 1})}, true}; for (auto& cv : lstripPec.container.value().constituentVolumes) { cv.internal = @@ -483,18 +483,18 @@ BOOST_AUTO_TEST_CASE(ProtoDetectorRoundTrip) { } lstripContainer.container = Acts::ProtoVolume::ContainerStructure{ {lstripNec, lstripBarrel, lstripPec}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binZ, + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisZ, {-3100., -1200., 1200., 3100.})}}; // The overall container Acts::ProtoVolume detectorContainer; detectorContainer.name = "odd-light-world"; - detectorContainer.extent.set(Acts::BinningValue::binR, 0., 1100.); - detectorContainer.extent.set(Acts::BinningValue::binZ, -3100., 3100.); + detectorContainer.extent.set(Acts::AxisDirection::AxisR, 0., 1100.); + detectorContainer.extent.set(Acts::AxisDirection::AxisZ, -3100., 3100.); detectorContainer.container = Acts::ProtoVolume::ContainerStructure{ {beamPipeContainer, pixelContainer, pstContainer, sstripContainer, lstripContainer}, - {Acts::BinningData(Acts::open, Acts::BinningValue::binR, + {Acts::BinningData(Acts::open, Acts::AxisDirection::AxisR, {0., 25., 200., 210., 720., 1100.})}}; // ---------------------------------------------------------- diff --git a/Tests/UnitTests/Plugins/Json/UtilitiesJsonConverterTests.cpp b/Tests/UnitTests/Plugins/Json/UtilitiesJsonConverterTests.cpp index 41f080db7f5..db6d314df7f 100644 --- a/Tests/UnitTests/Plugins/Json/UtilitiesJsonConverterTests.cpp +++ b/Tests/UnitTests/Plugins/Json/UtilitiesJsonConverterTests.cpp @@ -31,7 +31,7 @@ using namespace Acts; BOOST_AUTO_TEST_SUITE(UtilitiesJsonConverter) BOOST_AUTO_TEST_CASE(BinUtilityRoundTripTests) { - BinUtility reference(2, 0., 4., open, BinningValue::binR); + BinUtility reference(2, 0., 4., open, AxisDirection::AxisR); std::ofstream out; @@ -56,7 +56,7 @@ BOOST_AUTO_TEST_CASE(BinUtilityRoundTripTests) { // Increase to two dimensions reference += BinUtility(10., -std::numbers::pi, std::numbers::pi, closed, - BinningValue::binPhi); + AxisDirection::AxisPhi); nlohmann::json jtwoDimOut; to_json(jtwoDimOut, reference); out.open("BinUtility_2D.json"); @@ -77,7 +77,7 @@ BOOST_AUTO_TEST_CASE(BinUtilityRoundTripTests) { // Increase to three dimensions std::vector boundaries = {-4., -1.5, 0., 10.}; - reference += BinUtility(boundaries, open, BinningValue::binZ); + reference += BinUtility(boundaries, open, AxisDirection::AxisZ); nlohmann::json jthreeDimOut; to_json(jthreeDimOut, reference); out.open("BinUtility_3D.json"); diff --git a/Tests/UnitTests/Plugins/TGeo/TGeoLayerBuilderTests.cpp b/Tests/UnitTests/Plugins/TGeo/TGeoLayerBuilderTests.cpp index b45e188f9ec..abfe5461fc9 100644 --- a/Tests/UnitTests/Plugins/TGeo/TGeoLayerBuilderTests.cpp +++ b/Tests/UnitTests/Plugins/TGeo/TGeoLayerBuilderTests.cpp @@ -56,8 +56,8 @@ BOOST_AUTO_TEST_CASE(TGeoLayerBuilderTests) { b0Config.sensorNames = {"PixelActiveo2", "PixelActiveo4", "PixelActiveo5", "PixelActiveo6"}; b0Config.localAxes = "XYZ"; - b0Config.parseRanges = {{BinningValue::binR, {0., 40_mm}}, - {BinningValue::binZ, {-60_mm, 15_mm}}}; + b0Config.parseRanges = {{AxisDirection::AxisR, {0., 40_mm}}, + {AxisDirection::AxisZ, {-60_mm, 15_mm}}}; b0Config.envelope = {0_mm, 0_mm}; TglConfig eAllConfig; @@ -65,9 +65,9 @@ BOOST_AUTO_TEST_CASE(TGeoLayerBuilderTests) { eAllConfig.sensorNames = {"PixelActiveo2", "PixelActiveo4", "PixelActiveo5", "PixelActiveo6"}; eAllConfig.localAxes = "XYZ"; - eAllConfig.parseRanges = {{BinningValue::binR, {0., 40_mm}}, - {BinningValue::binZ, {16_mm, 60_mm}}}; - eAllConfig.splitConfigs = {{BinningValue::binZ, 5_mm}}; + eAllConfig.parseRanges = {{AxisDirection::AxisR, {0., 40_mm}}, + {AxisDirection::AxisZ, {16_mm, 60_mm}}}; + eAllConfig.splitConfigs = {{AxisDirection::AxisZ, 5_mm}}; eAllConfig.envelope = {0_mm, 0_mm}; std::vector cConfigs = {b0Config}; diff --git a/Tests/UnitTests/Plugins/TGeo/TGeoParserTests.cpp b/Tests/UnitTests/Plugins/TGeo/TGeoParserTests.cpp index 1292d311b84..78fd673d0bf 100644 --- a/Tests/UnitTests/Plugins/TGeo/TGeoParserTests.cpp +++ b/Tests/UnitTests/Plugins/TGeo/TGeoParserTests.cpp @@ -78,8 +78,8 @@ BOOST_AUTO_TEST_CASE(TGeoParser_Pixel_SelectInnermost) { tgpOptions.volumeNames = {volumeName}; tgpOptions.targetNames = {"PixelActiveo2", "PixelActiveo4", "PixelActiveo5", "PixelActiveo6"}; - tgpOptions.parseRanges.push_back({BinningValue::binR, {0., 40.}}); - tgpOptions.parseRanges.push_back({BinningValue::binZ, {-60., 15.}}); + tgpOptions.parseRanges.push_back({AxisDirection::AxisR, {0., 40.}}); + tgpOptions.parseRanges.push_back({AxisDirection::AxisZ, {-60., 15.}}); tgpOptions.unit = 10.; std::string axes = "XYZ"; diff --git a/docs/_extensions/lazy_autodoc.py b/docs/_extensions/lazy_autodoc.py index 3c9513c4268..dfc259e50fc 100644 --- a/docs/_extensions/lazy_autodoc.py +++ b/docs/_extensions/lazy_autodoc.py @@ -76,6 +76,7 @@ def run() -> None: "Acts::Geant4PhysicalVolumeSelectors::NameSelector", "Acts::Geant4PhysicalVolumeSelectors::PositionSelector", "Acts::OrientedSurface", + "Acts::TrackStateCreator", } role_instances["class"] |= { @@ -96,6 +97,7 @@ def run() -> None: "Acts::GenericCuboidVolumeBounds", "Acts::TrapezoidVolumeBounds", "Acts::CylinderVolumeStack", + "Acts::CuboidVolumeStack", "Acts::GeometryObject", "Acts::TrackContainer", "Acts::ConeLayer", @@ -131,9 +133,8 @@ def run() -> None: } role_instances["enum"] = { - "Acts::BinningValue", + "Acts::AxisDirection", "Acts::BinningType", - "Acts::BinningValue", "Acts::BoundIndices", "Acts::FreeIndices", "Acts::MagneticFieldError", diff --git a/docs/getting_started.md b/docs/getting_started.md index 03365dd9f40..2b99227a1e7 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -41,7 +41,6 @@ components: - [Pythia8](https://pythia.org) for some examples - [ROOT](https://root.cern.ch) >= 6.20 for the TGeo plugin and the examples - [Sphinx](https://www.sphinx-doc.org) >= 2.0 with [Breathe](https://breathe.readthedocs.io/en/latest/), [Exhale](https://exhale.readthedocs.io/en/latest/), and [recommonmark](https://recommonmark.readthedocs.io/en/latest/index.html) extensions for the documentation -- [cugraph](https://github.com/rapidsai/cugraph) for the Exa.TrkX plugin - [libtorch](https://pytorch.org/cppdocs/installing.html) for the Exa.TrkX plugin - [Pybind11](https://github.com/pybind/pybind11) for the Python bindings of the examples diff --git a/thirdparty/Annoy/CMakeLists.txt b/thirdparty/Annoy/CMakeLists.txt index adc28862843..e8291a1db48 100644 --- a/thirdparty/Annoy/CMakeLists.txt +++ b/thirdparty/Annoy/CMakeLists.txt @@ -6,6 +6,8 @@ # 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/. +cmake_minimum_required(VERSION 3.25) + # CMake include(s). include(FetchContent) @@ -18,6 +20,7 @@ set(ANNOY_VERSION "v${_acts_annoy_version}") # Declare the fetching of the Annoy library. FetchContent_Declare( Annoy + SYSTEM ${ACTS_ANNOY_SOURCE} PATCH_COMMAND patch -p1 < ${CMAKE_CURRENT_SOURCE_DIR}/0001-Modify-annoy.patch @@ -26,8 +29,3 @@ FetchContent_Declare( # Make the fetched content available. # Annoy contains a CMakeLists.txt file, so it will be added as a subdirectory. FetchContent_MakeAvailable(Annoy) - -target_compile_options( - Annoy - INTERFACE "-Wno-old-style-cast" "-Wno-zero-as-null-pointer-constant" -) diff --git a/thirdparty/FRNN/CMakeLists.txt b/thirdparty/FRNN/CMakeLists.txt index 25bcfb10f2b..d5a7018e796 100644 --- a/thirdparty/FRNN/CMakeLists.txt +++ b/thirdparty/FRNN/CMakeLists.txt @@ -5,12 +5,15 @@ # 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/. + +cmake_minimum_required(VERSION 3.25) + include(FetchContent) message(STATUS "Building FRNN as part of the ACTS project") # Declare where to get frnncontent from -FetchContent_Declare(frnncontent ${ACTS_FRNN_SOURCE}) +FetchContent_Declare(frnncontent SYSTEM ${ACTS_FRNN_SOURCE}) # FRNN does not provide a CMakeLists.txt, so we use a custom one. Because of this, # we have to implement the populate step manually diff --git a/thirdparty/actsvg/CMakeLists.txt b/thirdparty/actsvg/CMakeLists.txt index 8d57b9ba764..ad56606c936 100644 --- a/thirdparty/actsvg/CMakeLists.txt +++ b/thirdparty/actsvg/CMakeLists.txt @@ -6,13 +6,15 @@ # 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/. +cmake_minimum_required(VERSION 3.25) + # CMake include(s). include(FetchContent) # Tell the user what's happening. message(STATUS "Building actsvg as part of the ACTS project") -FetchContent_Declare(actsvg ${ACTS_ACTSVG_SOURCE}) +FetchContent_Declare(actsvg SYSTEM ${ACTS_ACTSVG_SOURCE}) set(ACTSVG_BUILD_PYTHON_BINDINGS OFF diff --git a/thirdparty/algebra-plugins/CMakeLists.txt b/thirdparty/algebra-plugins/CMakeLists.txt index ef0fc005afb..da579a29552 100644 --- a/thirdparty/algebra-plugins/CMakeLists.txt +++ b/thirdparty/algebra-plugins/CMakeLists.txt @@ -6,13 +6,15 @@ # 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/. +cmake_minimum_required(VERSION 3.25) + # CMake include(s). include(FetchContent) # Tell the user what's happening. message(STATUS "Building algebra-plugins as part of the Acts project") -FetchContent_Declare(AlgebraPlugins ${ACTS_ALGEBRAPLUGINS_SOURCE}) +FetchContent_Declare(AlgebraPlugins SYSTEM ${ACTS_ALGEBRAPLUGINS_SOURCE}) # Options used in the build of Algebra Plugins. set(ALGEBRA_PLUGINS_BUILD_TESTING diff --git a/thirdparty/covfie/CMakeLists.txt b/thirdparty/covfie/CMakeLists.txt index fe86e7e0e47..7999bfe75b9 100644 --- a/thirdparty/covfie/CMakeLists.txt +++ b/thirdparty/covfie/CMakeLists.txt @@ -6,6 +6,8 @@ # 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/. +cmake_minimum_required(VERSION 3.25) + # CMake include(s). include(FetchContent) @@ -15,7 +17,7 @@ message(STATUS "Building Covfie as part of the Acts project") set(COVFIE_VERSION "v${_acts_covfie_version}") # Declare where to get covfie from. -FetchContent_Declare(covfie ${ACTS_COVFIE_SOURCE}) +FetchContent_Declare(covfie SYSTEM ${ACTS_COVFIE_SOURCE}) # Options used for covfie. set(COVFIE_BUILD_EXAMPLES OFF CACHE BOOL "Build covfie examples") diff --git a/thirdparty/detray/CMakeLists.txt b/thirdparty/detray/CMakeLists.txt index 201fddb02f3..d801f8cb010 100644 --- a/thirdparty/detray/CMakeLists.txt +++ b/thirdparty/detray/CMakeLists.txt @@ -6,6 +6,8 @@ # 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/. +cmake_minimum_required(VERSION 3.25) + # CMake include(s). include(FetchContent) @@ -15,7 +17,7 @@ message(STATUS "Building Detray as part of the Acts project") set(DETRAY_VERSION "v${_acts_detray_version}") # Declare where to get Detray from. -FetchContent_Declare(Detray ${ACTS_DETRAY_SOURCE}) +FetchContent_Declare(Detray SYSTEM ${ACTS_DETRAY_SOURCE}) # Options used in the build of Detray. set(ACTS_DETRAY_SCALARTYPE "double") diff --git a/thirdparty/eigen3/CMakeLists.txt b/thirdparty/eigen3/CMakeLists.txt index cd4fe4837c0..3d1d653a4a3 100644 --- a/thirdparty/eigen3/CMakeLists.txt +++ b/thirdparty/eigen3/CMakeLists.txt @@ -1,18 +1,11 @@ -message(STATUS "Building Eigen ${_acts_eigen3_version}") +cmake_minimum_required(VERSION 3.25) -include(ExternalProject) +# CMake include(s). +include(FetchContent) -set(Eigen3_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/eigen3-prefix/src/eigen3) +# Tell the user what's happening. +message(STATUS "Building Eigen3 as part of the Acts project") -ExternalProject_Add( - eigen3 - "${ACTS_EIGEN3_SOURCE};CONFIGURE_COMMAND;;BUILD_COMMAND;;INSTALL_COMMAND;" -) - -add_library(Eigen3::Eigen INTERFACE IMPORTED GLOBAL) -add_dependencies(Eigen3::Eigen eigen3) -target_include_directories(Eigen3::Eigen INTERFACE ${Eigen3_INCLUDE_DIR}) -install( - DIRECTORY ${Eigen3_INCLUDE_DIR}/Eigen - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} -) +# Declare where to get Eigen from. +FetchContent_Declare(Eigen SYSTEM ${ACTS_EIGEN3_SOURCE}) +FetchContent_MakeAvailable(Eigen) diff --git a/thirdparty/nlohmann_json/CMakeLists.txt b/thirdparty/nlohmann_json/CMakeLists.txt index 2e8be353c21..61b60bf2937 100644 --- a/thirdparty/nlohmann_json/CMakeLists.txt +++ b/thirdparty/nlohmann_json/CMakeLists.txt @@ -1,10 +1,12 @@ +cmake_minimum_required(VERSION 3.25) + include(FetchContent) # Tell the user what's happening. message(STATUS "Building nlohmann_json as part of the ACTS project") # Declare where to get nlohmann json from. -FetchContent_Declare(nlohmann_json ${ACTS_NLOHMANNJSON_SOURCE}) +FetchContent_Declare(nlohmann_json SYSTEM ${ACTS_NLOHMANNJSON_SOURCE}) # Now set up its build. set(JSON_BuildTests OFF CACHE INTERNAL "") diff --git a/thirdparty/pybind11/CMakeLists.txt b/thirdparty/pybind11/CMakeLists.txt index 525c56d6c80..12dd002fcf4 100644 --- a/thirdparty/pybind11/CMakeLists.txt +++ b/thirdparty/pybind11/CMakeLists.txt @@ -1,10 +1,12 @@ +cmake_minimum_required(VERSION 3.25) + include(FetchContent) # Tell the user what's happening. message(STATUS "Building pybind11 as part of the ACTS project") # Declare where to get pybind from. -FetchContent_Declare(pybind11 ${ACTS_PYBIND11_SOURCE}) +FetchContent_Declare(pybind11 SYSTEM ${ACTS_PYBIND11_SOURCE}) # Now set up its build. set(PYBIND11_TEST OFF) diff --git a/thirdparty/traccc/CMakeLists.txt b/thirdparty/traccc/CMakeLists.txt index 2974ac1eea5..b877061a2ab 100644 --- a/thirdparty/traccc/CMakeLists.txt +++ b/thirdparty/traccc/CMakeLists.txt @@ -6,6 +6,8 @@ # 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/. +cmake_minimum_required(VERSION 3.25) + # CMake include(s). include(FetchContent) @@ -15,7 +17,7 @@ message(STATUS "Building traccc as part of the Acts project") set(TRACCC_VERSION "${_acts_traccc_version}") # Declare where to get traccc from. -FetchContent_Declare(traccc ${ACTS_TRACCC_SOURCE}) +FetchContent_Declare(traccc SYSTEM ${ACTS_TRACCC_SOURCE}) set(ACTS_TRACCC_SCALARTYPE "double") diff --git a/thirdparty/vecmem/CMakeLists.txt b/thirdparty/vecmem/CMakeLists.txt index e0fbf07b143..76974e9916d 100644 --- a/thirdparty/vecmem/CMakeLists.txt +++ b/thirdparty/vecmem/CMakeLists.txt @@ -6,6 +6,8 @@ # 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/. +cmake_minimum_required(VERSION 3.25) + # CMake include(s). include(FetchContent) @@ -15,7 +17,7 @@ message(STATUS "Building VecMem as part of the Acts project") set(VECMEM_VERSION "v${_acts_vecmem_version}") # Declare where to get VecMem from. -FetchContent_Declare(VecMem ${ACTS_VECMEM_SOURCE}) +FetchContent_Declare(VecMem SYSTEM ${ACTS_VECMEM_SOURCE}) # Options used in the build of VecMem. set(VECMEM_BUILD_TESTING