diff --git a/.github/workflows/analysis.yml b/.github/workflows/analysis.yml index 2ce3bfdc278..c946b38cd66 100644 --- a/.github/workflows/analysis.yml +++ b/.github/workflows/analysis.yml @@ -20,8 +20,9 @@ env: CTEST_OUTPUT_ON_FAILURE: 1 CCACHE_DIR: ${{ github.workspace }}/ccache CCACHE_MAXSIZE: 1.25G - CCACHE_KEY_SUFFIX: r1 + CCACHE_KEY_SUFFIX: r2 ACTS_LOG_FAILURE_THRESHOLD: WARNING + DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/ubuntu-24.04/deps.v4.tar.zst # NOTE this only builds core unittests to reduce the output size. if we # found a way to have Github actions not fail regularly with this job @@ -29,18 +30,21 @@ env: jobs: build_debug: runs-on: ubuntu-latest - container: ghcr.io/acts-project/ubuntu2404:58 + container: ghcr.io/acts-project/ubuntu2404:63 steps: - uses: actions/checkout@v4 + - name: Install dependencies + run: CI/dependencies.sh + - name: Cache build uses: actions/cache@v4 with: - path: ${{ github.workspace }}/ccache - key: ${{ runner.os }}-ccache-linux_ubuntu_debug_${{ env.CCACHE_KEY_SUFFIX }}_${{ github.sha }} + path: ${{ env.CCACHE_DIR }} + key: ccache-${{ runner.os }}-${{ github.job }}-${{ env.CCACHE_KEY_SUFFIX }}-${{ github.sha }} restore-keys: | - ${{ runner.os }}-ccache-linux_ubuntu_debug_${{ env.CCACHE_KEY_SUFFIX }}_ + ccache-${{ runner.os }}-${{ github.job }}-${{ env.CCACHE_KEY_SUFFIX }}- - name: Configure run: > @@ -49,6 +53,7 @@ jobs: --preset=github-ci -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="-Werror --coverage -g -gz -g1" + -DPython_EXECUTABLE=$(which python3) -DACTS_BUILD_ODD=OFF - name: Build run: cmake --build build @@ -86,10 +91,14 @@ jobs: build_performance: runs-on: ubuntu-latest - container: ghcr.io/acts-project/ubuntu2404:58 + container: ghcr.io/acts-project/ubuntu2404:63 if: github.ref == 'refs/heads/main' steps: - uses: actions/checkout@v4 + + - name: Install dependencies + run: CI/dependencies.sh + - name: Install dependencies run: pip3 install git+https://github.com/paulgessinger/cmakeperf.git@2a409b5 - name: Configure @@ -98,6 +107,7 @@ jobs: --preset=github-ci -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_CXX_FLAGS="-Werror" + -DPython_EXECUTABLE=$(which python3) -DACTS_BUILD_ODD=OFF - name: Measure run: cmakeperf collect build/compile_commands.json -o perf.csv diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index 06312a6b339..010b7ff8963 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -19,32 +19,34 @@ env: HOMEBREW_NO_INSTALL_CLEANUP: 1 CCACHE_DIR: ${{ github.workspace }}/ccache CCACHE_MAXSIZE: 500M - CCACHE_KEY_SUFFIX: r1 + CCACHE_KEY_SUFFIX: r2 jobs: linux_ubuntu: runs-on: ubuntu-latest - container: ghcr.io/acts-project/ubuntu2404:58 + container: ghcr.io/acts-project/ubuntu2404:63 env: INSTALL_DIR: ${{ github.workspace }}/install ACTS_LOG_FAILURE_THRESHOLD: WARNING - steps: - - name: Install git lfs - run: apt-get update && apt-get install -y git-lfs + DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/ubuntu-24.04/deps.v4.tar.zst + steps: - uses: actions/checkout@v4 with: submodules: true lfs: true + - name: Install dependencies + run: CI/dependencies.sh + - name: Restore ccache uses: actions/cache/restore@v4 id: ccache-restore with: - path: ${{ github.workspace }}/ccache - key: ${{ runner.os }}-ccache-linux_ubuntu_${{ env.CCACHE_KEY_SUFFIX }}_${{ github.sha }} + path: ${{ env.CCACHE_DIR }} + key: ccache-${{ runner.os }}-${{ github.job }}-${{ env.CCACHE_KEY_SUFFIX }}-${{ github.sha }} restore-keys: | - ${{ runner.os }}-ccache-linux_ubuntu_${{ env.CCACHE_KEY_SUFFIX }}_ + ccache-${{ runner.os }}-${{ github.job }}-${{ env.CCACHE_KEY_SUFFIX }}- - name: Configure # setting CMAKE_CXX_STANDARD=20 is a workaround for a bug in the @@ -58,6 +60,7 @@ jobs: cmake -B build -S . --preset=github-ci -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" + -DPython_EXECUTABLE=$(which python3) -DACTS_BUILD_PLUGIN_ONNX=ON - name: Build @@ -82,7 +85,6 @@ jobs: - name: Install run: cmake --build build --target install - - name: Package build run: tar czf build.tar.gz -C build --exclude "*.o" --exclude "bin/ActsUnitTest*" --exclude "bin/ActsIntegrationTest*" . @@ -108,20 +110,21 @@ jobs: linux_examples_test: runs-on: ubuntu-latest - container: ghcr.io/acts-project/ubuntu2404:58 + container: ghcr.io/acts-project/ubuntu2404:63 needs: [linux_ubuntu] env: ACTS_SEQUENCER_DISABLE_FPEMON: true + DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/ubuntu-24.04/deps.v4.tar.zst steps: - - name: Install git lfs - run: apt-get update && apt-get install -y git-lfs - - uses: actions/checkout@v4 with: submodules: true lfs: true + - name: Install dependencies + run: CI/dependencies.sh + - uses: actions/download-artifact@v4 with: name: acts-linux-ubuntu @@ -136,29 +139,31 @@ jobs: PYTEST_MD_REPORT_VERBOSE: 0 PYTEST_MD_REPORT_OUTPUT: pytest.md run: > - /usr/local/bin/geant4-config --install-datasets + geant4-config --install-datasets && source build/this_acts_withdeps.sh - && pip3 install -r Examples/Python/tests/requirements.txt - && pip3 install pytest-md-report + && python3 -m pip install -r Examples/Python/tests/requirements.txt + && python3 -m pip install pytest-md-report && pytest -rFsv -k "not exatrkx" -v && cat ${PYTEST_MD_REPORT_OUTPUT} >> $GITHUB_STEP_SUMMARY linux_physmon: runs-on: ubuntu-latest - container: ghcr.io/acts-project/ubuntu2404:58 + container: ghcr.io/acts-project/ubuntu2404:63 needs: [linux_ubuntu] env: ACTS_SEQUENCER_DISABLE_FPEMON: true + DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/ubuntu-24.04/deps.v4.tar.zst steps: - - name: Install git lfs - run: apt-get update && apt-get install -y git-lfs time - - uses: actions/checkout@v4 with: submodules: true lfs: true + - run: apt-get update && apt-get install -y time + - name: Install dependencies + run: CI/dependencies.sh + - uses: actions/download-artifact@v4 with: name: acts-linux-ubuntu @@ -178,10 +183,15 @@ jobs: run: > echo "::group::Dependencies" && git config --global safe.directory "$GITHUB_WORKSPACE" - && pip3 install histcmp==0.6.7 matplotlib - && pip3 install -r Examples/Scripts/requirements.txt - && /usr/local/bin/geant4-config --install-datasets + && python3 -m pip install histcmp==0.6.8 matplotlib + && python3 -m pip install -r Examples/Scripts/requirements.txt + && geant4-config --install-datasets + && venv_python=$(which python3) + && echo $venv_python && source build/this_acts_withdeps.sh + && export PATH=$(dirname $venv_python):$PATH + && echo $PATH + && which python3 && echo "::endgroup::" && CI/physmon/phys_perf_mon.sh all physmon @@ -232,27 +242,28 @@ jobs: std: 20 - image: ubuntu2204_clang std: 20 - container: ghcr.io/acts-project/${{ matrix.image }}:58 + container: ghcr.io/acts-project/${{ matrix.image }}:63 env: INSTALL_DIR: ${{ github.workspace }}/install ACTS_LOG_FAILURE_THRESHOLD: WARNING + DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/ubuntu-22.04/deps.v4.tar.zst steps: - - name: Install git lfs - run: apt-get update && apt-get install -y git-lfs - - uses: actions/checkout@v4 with: submodules: true lfs: true + - name: Install dependencies + run: CI/dependencies.sh + - name: Restore ccache uses: actions/cache/restore@v4 id: ccache-restore with: - path: ${{ github.workspace }}/ccache - key: ${{ runner.os }}-ccache-linux_${{ matrix.image }}_${{ env.CCACHE_KEY_SUFFIX }}_${{ github.sha }} + path: ${{ env.CCACHE_DIR }} + key: ccache-${{ runner.os }}-${{ github.job }}-${{ env.CCACHE_KEY_SUFFIX }}-${{ github.sha }} restore-keys: | - ${{ runner.os }}-ccache-linux_${{ matrix.image }}_${{ env.CCACHE_KEY_SUFFIX }}_ + ccache-${{ runner.os }}-${{ github.job }}-${{ env.CCACHE_KEY_SUFFIX }}- - name: Configure @@ -265,6 +276,7 @@ jobs: --preset=github-ci -DCMAKE_CXX_STANDARD=${{ matrix.std }} -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" + -DPython_EXECUTABLE=$(which python3) - name: Build run: cmake --build build @@ -307,11 +319,8 @@ jobs: runs-on: macos-14 env: INSTALL_DIR: ${{ github.workspace }}/install_acts - DEPENDENCY_DIR: ${{ github.workspace }}/install ACTS_LOG_FAILURE_THRESHOLD: WARNING - DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/macos-14/deps.v2.tar.zst - # Works around an issue where root's RPATH is wrong for tbb, thus won't find it - DYLD_LIBRARY_PATH: "${{ github.workspace }}/install/tbb/2021.11.0/lib" + DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/macos-14/deps.v4.tar.zst steps: - uses: actions/checkout@v4 with: @@ -324,61 +333,65 @@ jobs: - name: Install dependencies run: > brew install cmake ninja ccache xerces-c - && wget --verbose --progress=dot:giga --continue --retry-connrefused --tries=5 --timeout=2 -O deps.tar.zst ${{ env.DEPENDENCY_URL }} - && mkdir ${{ env.DEPENDENCY_DIR }} - && tar -xf deps.tar.zst -C ${{ env.DEPENDENCY_DIR }} - && PATH="${{ env.DEPENDENCY_DIR }}/bin:$PATH" - && python3 -m pip install pyyaml jinja2 + && CI/dependencies.sh - name: Restore ccache uses: actions/cache/restore@v4 id: ccache-restore with: - path: ${{ github.workspace }}/ccache - key: ${{ runner.os }}-ccache_${{ env.CCACHE_KEY_SUFFIX }}_${{ github.sha }} + path: ${{ env.CCACHE_DIR }} + key: ccache-${{ runner.os }}-${{ github.job }}-${{ env.CCACHE_KEY_SUFFIX }}-${{ github.sha }} restore-keys: | - ${{ runner.os }}-ccache_${{ env.CCACHE_KEY_SUFFIX }}_ + ccache-${{ runner.os }}-${{ github.job }}-${{ env.CCACHE_KEY_SUFFIX }}- - name: Configure run: > ccache -z - && PATH="${{ env.DEPENDENCY_DIR }}/bin:$PATH" && cmake -B build -S . --preset=github-ci -DCMAKE_PREFIX_PATH="${{ env.DEPENDENCY_DIR }}" - -DPython_EXECUTABLE=${{ env.DEPENDENCY_DIR }}/bin/python3 -DCMAKE_INSTALL_PREFIX="${{ env.INSTALL_DIR }}" + -DPython_EXECUTABLE=$(which python3) + - name: Build run: cmake --build build + - name: ccache stats run: ccache -s + - name: Save ccache uses: actions/cache/save@v4 if: always() with: path: ${{ github.workspace }}/ccache key: ${{ steps.ccache-restore.outputs.cache-primary-key }} + - name: Unit tests run: cmake --build build --target test + - name: Integration tests run: cmake --build build --target integrationtests + - name: Install run: cmake --build build --target install + - uses: actions/upload-artifact@v4 with: name: acts-macos path: ${{ env.INSTALL_DIR }} + - name: Downstream configure run: > - PATH="${{ env.DEPENDENCY_DIR }}/bin:$PATH" - && cmake -B build-downstream -S Tests/DownstreamProject + cmake -B build-downstream -S Tests/DownstreamProject -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS=-Werror -DCMAKE_CXX_STANDARD=20 -DCMAKE_PREFIX_PATH="${INSTALL_DIR}" + - name: Downstream build run: cmake --build build-downstream + - name: Downstream run run: > PATH="${{ env.DEPENDENCY_DIR }}/bin:$PATH" diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2e6b5f42fa9..a5cbbce542e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,12 +1,14 @@ variables: CCACHE_DIR: ${CI_PROJECT_DIR}/ccache CCACHE_MAXSIZE: 2G - CCACHE_KEY_SUFFIX: r1 + CCACHE_KEY_SUFFIX: r2 CTEST_OUTPUT_ON_FAILURE: 1 + DEPENDENCY_TAG: v4 + clang_tidy: stage: build - image: ghcr.io/acts-project/ubuntu2404:58 + image: ghcr.io/acts-project/ubuntu2404:63 tags: - large artifacts: @@ -14,6 +16,8 @@ clang_tidy: - src/clang-tidy/ when: always expire_in: 1 week + variables: + DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/ubuntu-24.04/deps.$DEPENDENCY_TAG.tar.zst script: - git clone $CLONE_URL src - cd src @@ -24,11 +28,15 @@ clang_tidy: && ln -sf /usr/bin/clang++-18 /usr/bin/clang++ && ln -sf /usr/bin/clang-18 /usr/bin/clang && ln -sf /usr/bin/clang-tidy-18 /usr/bin/clang-tidy + + - source CI/dependencies.sh + - > cmake -B build -S . --preset=gitlab-ci-clangtidy -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang + -DPython_EXECUTABLE=$(which python3) -DACTS_RUN_CLANG_TIDY=ON -DACTS_BUILD_ODD=OFF @@ -36,7 +44,7 @@ clang_tidy: - CI/clang_tidy/run_clang_tidy.sh clang-tidy build # Install dependencies for processing scripts - - pip install -r CI/clang_tidy/requirements.txt + - python3 -m pip install -r CI/clang_tidy/requirements.txt # Parse the main clang-tidy run - > @@ -55,14 +63,19 @@ clang_tidy: build_exatrkx_cpu: stage: build - image: ghcr.io/acts-project/ubuntu2204_exatrkx:58 + image: 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-exatrkx-cpu-$CI_COMMIT_REF_SLUG + 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: - - ${CI_PROJECT_DIR}/ccache + - ${CCACHE_DIR} script: - export PATH=/usr/local/sbin:/usr/sbin:/sbin:$PATH @@ -72,12 +85,14 @@ build_exatrkx_cpu: - git clone $CLONE_URL src - cd src - git checkout $HEAD_SHA + - source CI/dependencies.sh - cd .. - mkdir build # Here we only do a minimal build without examples to save resources - > cmake -B build -S src --preset=gitlab-ci-exatrkx + -DPython_EXECUTABLE=$(which python3) -DACTS_EXATRKX_ENABLE_CUDA=OFF - ccache -z @@ -86,14 +101,19 @@ build_exatrkx_cpu: build_exatrkx: stage: build - image: ghcr.io/acts-project/ubuntu2204_exatrkx:58 + image: 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-exatrkx-$CI_COMMIT_REF_SLUG + 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: - - ${CI_PROJECT_DIR}/ccache + - ${CCACHE_DIR} artifacts: paths: @@ -111,11 +131,13 @@ build_exatrkx: - git clone $CLONE_URL src - cd src - git checkout $HEAD_SHA + - source CI/dependencies.sh - cd .. - mkdir build - > cmake -B build -S src --preset=gitlab-ci-exatrkx + -DPython_EXECUTABLE=$(which python3) -DCMAKE_CUDA_ARCHITECTURES="75;86" - ccache -z @@ -126,7 +148,7 @@ build_exatrkx: # stage: test # needs: # - build_exatrkx -# image: ghcr.io/acts-project/ubuntu2204_exatrkx:58 +# image: ghcr.io/acts-project/ubuntu2204_exatrkx:63 # tags: # - docker-gpu-nvidia # script: @@ -136,7 +158,7 @@ build_exatrkx: # stage: test # needs: # - build_exatrkx -# image: ghcr.io/acts-project/ubuntu2204_exatrkx:58 +# image: ghcr.io/acts-project/ubuntu2204_exatrkx:63 # tags: # - docker-gpu-nvidia # script: @@ -152,13 +174,17 @@ build_exatrkx: build_linux_ubuntu: stage: build - image: ghcr.io/acts-project/ubuntu2404:58 + image: 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_SLUG}-${HEAD_REF}-${CCACHE_KEY_SUFFIX} - when: 'always' + 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: - - ${CI_PROJECT_DIR}/ccache + - ${CCACHE_DIR} artifacts: paths: @@ -177,12 +203,14 @@ build_linux_ubuntu: - git checkout $HEAD_SHA - git submodule init - git submodule update + - source CI/dependencies.sh - cd .. - mkdir build - > cmake -B build -S src --preset=gitlab-ci + -DPython_EXECUTABLE=$(which python3) -DACTS_BUILD_PLUGIN_ONNX=ON - ccache -z @@ -191,7 +219,9 @@ build_linux_ubuntu: linux_test_examples: stage: test - image: ghcr.io/acts-project/ubuntu2404:58 + image: 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] script: @@ -202,17 +232,20 @@ linux_test_examples: - git checkout $HEAD_SHA - git submodule init - git submodule update + - source CI/dependencies.sh - cd .. - - /usr/local/bin/geant4-config --install-datasets + - geant4-config --install-datasets - source build/this_acts_withdeps.sh - cd src - - pip3 install -r Examples/Python/tests/requirements.txt + - python3 -m pip install -r Examples/Python/tests/requirements.txt - pytest -rFsv -k "not exatrkx" -v -s linux_physmon: stage: test - image: ghcr.io/acts-project/ubuntu2404:58 + image: 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] artifacts: @@ -229,13 +262,19 @@ linux_physmon: - git checkout $HEAD_SHA - git submodule init - git submodule update + - source CI/dependencies.sh - cd .. - git config --global safe.directory "$GITHUB_WORKSPACE" - - pip3 install histcmp==0.6.7 matplotlib - - pip3 install -r src/Examples/Scripts/requirements.txt - - /usr/local/bin/geant4-config --install-datasets + - python3 -m pip install histcmp==0.6.8 matplotlib + - python3 -m pip install -r src/Examples/Scripts/requirements.txt + - geant4-config --install-datasets + - venv_python=$(which python3) + - echo $venv_python - source build/this_acts_withdeps.sh + - export PATH=$(dirname $venv_python):$PATH + - echo $PATH + - which python3 - cd src - CI/physmon/phys_perf_mon.sh all physmon @@ -243,17 +282,19 @@ linux_physmon: ### UBUNTU EXTRA JOB MATRIX ### ############################### -.linux_ubuntu_extra: &linux_ubuntu_extra +.linux_ubuntu_extra: variables: INSTALL_DIR: ${CI_PROJECT_DIR}/install stage: build cache: - key: ccache-${CI_JOB_NAME_SLUG}-${HEAD_REF}-${CCACHE_KEY_SUFFIX} - when: 'always' + 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: - - ${CI_PROJECT_DIR}/ccache + - ${CCACHE_DIR} script: - git clone $CLONE_URL src @@ -262,12 +303,14 @@ linux_physmon: - git checkout $HEAD_SHA - git submodule init - git submodule update + - source CI/dependencies.sh - cd .. - mkdir build - > cmake -B build -S src --preset=gitlab-ci + -DPython_EXECUTABLE=$(which python3) -DCMAKE_CXX_STANDARD=${CXXSTD} - ccache -z @@ -295,25 +338,27 @@ linux_physmon: # Downstream run - ./build-downstream/bin/ShowActsVersion -linux_ubuntu_2404: - <<: *linux_ubuntu_extra +linux_ubuntu_2204: + extends: .linux_ubuntu_extra variables: CXXSTD: 20 - image: ghcr.io/acts-project/ubuntu2404:58 + DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/ubuntu-22.04/deps.$DEPENDENCY_TAG.tar.zst + image: ghcr.io/acts-project/ubuntu2204:63 linux_ubuntu_2204_clang: - <<: *linux_ubuntu_extra + extends: .linux_ubuntu_extra variables: CXXSTD: 20 - image: ghcr.io/acts-project/ubuntu2204_clang:58 + 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 ###################### ### LCG JOB MATRIX ### ###################### -.lcg: &lcg_base_job - image: ghcr.io/acts-project/${OS}-base:58 +.lcg_base_job: + image: ghcr.io/acts-project/${OS}-base:63 stage: build tags: - cvmfs @@ -325,10 +370,12 @@ linux_ubuntu_2204_clang: SETUP: cache: - key: ccache-${CI_JOB_NAME_SLUG}-${HEAD_REF}-${CCACHE_KEY_SUFFIX} - when: 'always' + 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: - - ${CI_PROJECT_DIR}/ccache + - ${CCACHE_DIR} before_script: - 'echo "LCG_VERSION: ${LCG_VERSION}"' @@ -364,6 +411,7 @@ linux_ubuntu_2204_clang: cmake -B build -S src --preset=gitlab-ci -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" + -DPython_EXECUTABLE=$(which python3) -DACTS_BUILD_PLUGIN_GEOMODEL=OFF # GeoModel is not in LCG at this point - ccache -z @@ -374,7 +422,7 @@ linux_ubuntu_2204_clang: lcg_105: - <<: *lcg_base_job + extends: .lcg_base_job variables: LCG_VERSION: "105" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ea1ef7ec79a..76af4847b7f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -44,7 +44,7 @@ repos: - id: license name: license language: system - entry: CI/check_license.py + entry: CI/check_license.py --fix files: \.(cpp|hpp|ipp|cu|cuh)$ - repo: local diff --git a/CI/dependencies.sh b/CI/dependencies.sh new file mode 100755 index 00000000000..7c8879b499e --- /dev/null +++ b/CI/dependencies.sh @@ -0,0 +1,103 @@ +#!/bin/bash + +function run() { + set -x + "$@" + { set +x; } 2> /dev/null +} + +function set_env { + key="$1" + value="$2" + + echo "=> ${key}=${value}" + + if [ -n "${GITHUB_ACTIONS:-}" ]; then + echo "${key}=${value}" >> $GITHUB_ENV + else + export ${key}=${value} + fi +} + +url=${1:-${DEPENDENCY_URL:-}} + +if [ -n "${GITHUB_ACTIONS:-}" ]; then + destination="${GITHUB_WORKSPACE}/dependencies" +elif [ -n "${GITLAB_CI:-}" ];then + destination="${CI_PROJECT_DIR}/dependencies" +else + destination=${2} +fi + +set_env DEPENDENCY_DIR "${destination}" + +if [ -z "${url}" ]; then + echo "url is not set" + exit 1 +fi + +echo "URL: $url" +echo "DESTINATION: $destination" + +# check curl location +CURL=$(command -v curl) +if [ -z "$CURL" ]; then + echo "curl is not available" + exit 1 +fi + +UNZSTD=$(command -v unzstd) +if [ -z "$UNZSTD" ]; then + echo "unzstd is not available" + exit 1 +fi + +TAR=$(command -v tar) +if [ -z "$TAR" ]; then + echo "tar is not available" + exit 1 +fi + +run mkdir -p "${destination}" + +run $CURL \ + --retry 5 \ + --connect-timeout 2 \ + --location $url \ + | unzstd \ + | tar \ + -x \ + --strip-components=1 \ + --directory "${destination}" + +# Patch up geant4-config data install script +out=$(${destination}/bin/geant4-config --datasets) +line=$(echo "$out" | head -n1) +orig_share=$(echo "$line" | perl -pe 's|.*?(\/.*)\/share.*|\1|') +orig_share_escaped=$(echo $orig_share|perl -pe 's|/|\\/|g') +destination_escaped=$(echo "$destination"|perl -pe 's|/|\\/|g') +perl -pi.bak -e "s/$orig_share_escaped/$destination_escaped/g" ${destination}/bin/geant4-config + +if [ -n "${GITHUB_ACTIONS:-}" ]; then + echo "Running in GitHub Actions" + venv="${GITHUB_WORKSPACE}/venv" +fi + +if [ -n "${GITLAB_CI:-}" ];then + echo "Running in GitLab CI" + venv="${CI_PROJECT_DIR}/venv" +fi + +if [ -n "${CI:-}" ];then + run "${destination}/bin/python3" -m venv "${venv}" + run "${venv}/bin/python3" -m pip install pyyaml jinja2 + set_env PATH "${venv}/bin:${destination}/bin/:${PATH}" +fi + +set_env CMAKE_PREFIX_PATH "${destination}" +set_env LD_LIBRARY_PATH "${destination}/lib" +set_env ROOT_INCLUDE_PATH "${destination}/include" +# Geant4 puts CLHEP in a subdirectory +set_env ROOT_INCLUDE_PATH "${destination}/include/Geant4" +# Pythia8 looks for settings in this directory +set_env PYTHIA8DATA "${destination}/share/Pythia8/xmldoc" diff --git a/CI/physmon/phys_perf_mon.sh b/CI/physmon/phys_perf_mon.sh index 841fad5c376..c2944f0dd06 100755 --- a/CI/physmon/phys_perf_mon.sh +++ b/CI/physmon/phys_perf_mon.sh @@ -15,7 +15,7 @@ function run() { export run - +run which python3 shopt -s extglob @@ -223,13 +223,22 @@ function trackfinding() { fi run_histcmp \ - $outdir/data/$path/performance_ckf.root \ - $refdir/$path/performance_ckf.root \ - "CKF | ${name}" \ - $path/performance_ckf.html \ - $path/performance_ckf_plots \ + $outdir/data/$path/performance_finding_ckf.root \ + $refdir/$path/performance_finding_ckf.root \ + "CKF finding performance | ${name}" \ + $path/performance_finding_ckf.html \ + $path/performance_finding_ckf_plots \ --config $default_config + run_histcmp \ + $outdir/data/$path/performance_fitting_ckf.root \ + $refdir/$path/performance_fitting_ckf.root \ + "CKF fitting performance | ${name}" \ + $path/performance_fitting_ckf.html \ + $path/performance_fitting_ckf_plots \ + --config $default_config + + run Examples/Scripts/generic_plotter.py \ $outdir/data/$path/tracksummary_ckf.root \ tracksummary \ @@ -244,17 +253,17 @@ function trackfinding() { run_histcmp \ $outdir/data/$path/tracksummary_ckf_hist.root \ $refdir/$path/tracksummary_ckf_hist.root \ - "Track Summary CKF | ${name}" \ + "CKF track summary | ${name}" \ $path/tracksummary_ckf.html \ $path/tracksummary_ckf_plots - if [ -f $refdir/$path/performance_ckf_ambi.root ]; then + if [ -f $refdir/$path/performance_finding_ckf_ambi.root ]; then run_histcmp \ - $outdir/data/$path/performance_ckf_ambi.root \ - $refdir/$path/performance_ckf_ambi.root \ - "Ambisolver | ${name}" \ - $path/performance_ckf_ambi.html \ - $path/performance_ckf_ambi + $outdir/data/$path/performance_finding_ckf_ambi.root \ + $refdir/$path/performance_finding_ckf_ambi.root \ + "Ambisolver finding performance | ${name}" \ + $path/performance_finding_ckf_ambi.html \ + $path/performance_finding_ckf_ambi fi } diff --git a/CI/physmon/reference/simulation/particles_ttbar_hist.root b/CI/physmon/reference/simulation/particles_ttbar_hist.root index 9100c71418a..4b8b8c552e0 100644 Binary files a/CI/physmon/reference/simulation/particles_ttbar_hist.root and b/CI/physmon/reference/simulation/particles_ttbar_hist.root differ diff --git a/CI/physmon/reference/simulation/vertices_ttbar_hist.root b/CI/physmon/reference/simulation/vertices_ttbar_hist.root index 9e54eaed90e..7dc8182b96a 100644 Binary files a/CI/physmon/reference/simulation/vertices_ttbar_hist.root and b/CI/physmon/reference/simulation/vertices_ttbar_hist.root differ diff --git a/CI/physmon/reference/trackfinding_1muon/orthogonal/performance_ckf.root b/CI/physmon/reference/trackfinding_1muon/orthogonal/performance_ckf.root deleted file mode 100644 index 305a3bf724f..00000000000 Binary files a/CI/physmon/reference/trackfinding_1muon/orthogonal/performance_ckf.root and /dev/null differ diff --git a/CI/physmon/reference/trackfinding_1muon/orthogonal/performance_finding_ckf.root b/CI/physmon/reference/trackfinding_1muon/orthogonal/performance_finding_ckf.root new file mode 100644 index 00000000000..b2e59570e85 Binary files /dev/null and b/CI/physmon/reference/trackfinding_1muon/orthogonal/performance_finding_ckf.root differ diff --git a/CI/physmon/reference/trackfinding_1muon/orthogonal/performance_fitting_ckf.root b/CI/physmon/reference/trackfinding_1muon/orthogonal/performance_fitting_ckf.root new file mode 100644 index 00000000000..36c779d4846 Binary files /dev/null and b/CI/physmon/reference/trackfinding_1muon/orthogonal/performance_fitting_ckf.root differ diff --git a/CI/physmon/reference/trackfinding_1muon/orthogonal/performance_seeding.root b/CI/physmon/reference/trackfinding_1muon/orthogonal/performance_seeding.root index d55d3833570..1049ad5b18b 100644 Binary files a/CI/physmon/reference/trackfinding_1muon/orthogonal/performance_seeding.root and b/CI/physmon/reference/trackfinding_1muon/orthogonal/performance_seeding.root differ diff --git a/CI/physmon/reference/trackfinding_1muon/seeded/performance_ckf.root b/CI/physmon/reference/trackfinding_1muon/seeded/performance_ckf.root deleted file mode 100644 index a9a127efa07..00000000000 Binary files a/CI/physmon/reference/trackfinding_1muon/seeded/performance_ckf.root and /dev/null differ diff --git a/CI/physmon/reference/trackfinding_1muon/seeded/performance_finding_ckf.root b/CI/physmon/reference/trackfinding_1muon/seeded/performance_finding_ckf.root new file mode 100644 index 00000000000..7f59b99cf7e Binary files /dev/null and b/CI/physmon/reference/trackfinding_1muon/seeded/performance_finding_ckf.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 new file mode 100644 index 00000000000..5ba97ecd168 Binary files /dev/null and b/CI/physmon/reference/trackfinding_1muon/seeded/performance_fitting_ckf.root differ diff --git a/CI/physmon/reference/trackfinding_1muon/seeded/performance_seeding.root b/CI/physmon/reference/trackfinding_1muon/seeded/performance_seeding.root index 0c64e9fe631..d91320f3d9a 100644 Binary files a/CI/physmon/reference/trackfinding_1muon/seeded/performance_seeding.root and b/CI/physmon/reference/trackfinding_1muon/seeded/performance_seeding.root differ diff --git a/CI/physmon/reference/trackfinding_1muon/truth_estimated/performance_ckf.root b/CI/physmon/reference/trackfinding_1muon/truth_estimated/performance_ckf.root deleted file mode 100644 index 8b9f8ae4d1d..00000000000 Binary files a/CI/physmon/reference/trackfinding_1muon/truth_estimated/performance_ckf.root and /dev/null differ diff --git a/CI/physmon/reference/trackfinding_1muon/truth_estimated/performance_finding_ckf.root b/CI/physmon/reference/trackfinding_1muon/truth_estimated/performance_finding_ckf.root new file mode 100644 index 00000000000..b4def41bfb5 Binary files /dev/null and b/CI/physmon/reference/trackfinding_1muon/truth_estimated/performance_finding_ckf.root differ diff --git a/CI/physmon/reference/trackfinding_1muon/truth_estimated/performance_fitting_ckf.root b/CI/physmon/reference/trackfinding_1muon/truth_estimated/performance_fitting_ckf.root new file mode 100644 index 00000000000..3fcdb6021d1 Binary files /dev/null and b/CI/physmon/reference/trackfinding_1muon/truth_estimated/performance_fitting_ckf.root differ diff --git a/CI/physmon/reference/trackfinding_1muon/truth_estimated/performance_seeding.root b/CI/physmon/reference/trackfinding_1muon/truth_estimated/performance_seeding.root index 06abee42be7..4d134bc87d3 100644 Binary files a/CI/physmon/reference/trackfinding_1muon/truth_estimated/performance_seeding.root and b/CI/physmon/reference/trackfinding_1muon/truth_estimated/performance_seeding.root differ diff --git a/CI/physmon/reference/trackfinding_1muon/truth_smeared/performance_ckf.root b/CI/physmon/reference/trackfinding_1muon/truth_smeared/performance_ckf.root deleted file mode 100644 index e38e388edce..00000000000 Binary files a/CI/physmon/reference/trackfinding_1muon/truth_smeared/performance_ckf.root and /dev/null differ diff --git a/CI/physmon/reference/trackfinding_1muon/truth_smeared/performance_finding_ckf.root b/CI/physmon/reference/trackfinding_1muon/truth_smeared/performance_finding_ckf.root new file mode 100644 index 00000000000..10f10907b8d Binary files /dev/null and b/CI/physmon/reference/trackfinding_1muon/truth_smeared/performance_finding_ckf.root differ diff --git a/CI/physmon/reference/trackfinding_1muon/truth_smeared/performance_fitting_ckf.root b/CI/physmon/reference/trackfinding_1muon/truth_smeared/performance_fitting_ckf.root new file mode 100644 index 00000000000..1ca5e629d35 Binary files /dev/null and b/CI/physmon/reference/trackfinding_1muon/truth_smeared/performance_fitting_ckf.root differ diff --git a/CI/physmon/reference/trackfinding_4muon_50vertices/performance_ckf.root b/CI/physmon/reference/trackfinding_4muon_50vertices/performance_ckf.root deleted file mode 100644 index c4507b9636a..00000000000 Binary files a/CI/physmon/reference/trackfinding_4muon_50vertices/performance_ckf.root and /dev/null differ diff --git a/CI/physmon/reference/trackfinding_4muon_50vertices/performance_ckf_ambi.root b/CI/physmon/reference/trackfinding_4muon_50vertices/performance_ckf_ambi.root deleted file mode 100644 index 35b860dcb8e..00000000000 Binary files a/CI/physmon/reference/trackfinding_4muon_50vertices/performance_ckf_ambi.root and /dev/null differ diff --git a/CI/physmon/reference/trackfinding_4muon_50vertices/performance_finding_ckf.root b/CI/physmon/reference/trackfinding_4muon_50vertices/performance_finding_ckf.root new file mode 100644 index 00000000000..71bfd26dfb8 Binary files /dev/null and b/CI/physmon/reference/trackfinding_4muon_50vertices/performance_finding_ckf.root differ diff --git a/CI/physmon/reference/trackfinding_4muon_50vertices/performance_finding_ckf_ambi.root b/CI/physmon/reference/trackfinding_4muon_50vertices/performance_finding_ckf_ambi.root new file mode 100644 index 00000000000..39d7dc1a31f Binary files /dev/null and b/CI/physmon/reference/trackfinding_4muon_50vertices/performance_finding_ckf_ambi.root differ diff --git a/CI/physmon/reference/trackfinding_4muon_50vertices/performance_fitting_ckf.root b/CI/physmon/reference/trackfinding_4muon_50vertices/performance_fitting_ckf.root new file mode 100644 index 00000000000..b90f40313eb Binary files /dev/null and b/CI/physmon/reference/trackfinding_4muon_50vertices/performance_fitting_ckf.root differ diff --git a/CI/physmon/reference/trackfinding_4muon_50vertices/performance_fitting_ckf_ambi.root b/CI/physmon/reference/trackfinding_4muon_50vertices/performance_fitting_ckf_ambi.root new file mode 100644 index 00000000000..ff59dc310eb Binary files /dev/null and b/CI/physmon/reference/trackfinding_4muon_50vertices/performance_fitting_ckf_ambi.root differ diff --git a/CI/physmon/reference/trackfinding_4muon_50vertices/performance_seeding.root b/CI/physmon/reference/trackfinding_4muon_50vertices/performance_seeding.root index 0a59b0fba85..e79e159caa2 100644 Binary files a/CI/physmon/reference/trackfinding_4muon_50vertices/performance_seeding.root and b/CI/physmon/reference/trackfinding_4muon_50vertices/performance_seeding.root differ diff --git a/CI/physmon/reference/trackfinding_ttbar_pu200/performance_ckf.root b/CI/physmon/reference/trackfinding_ttbar_pu200/performance_ckf.root deleted file mode 100644 index 2c7626e0516..00000000000 Binary files a/CI/physmon/reference/trackfinding_ttbar_pu200/performance_ckf.root and /dev/null differ diff --git a/CI/physmon/reference/trackfinding_ttbar_pu200/performance_ckf_ambi.root b/CI/physmon/reference/trackfinding_ttbar_pu200/performance_ckf_ambi.root deleted file mode 100644 index c5d08a93db0..00000000000 Binary files a/CI/physmon/reference/trackfinding_ttbar_pu200/performance_ckf_ambi.root and /dev/null 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 new file mode 100644 index 00000000000..d4b5a8b9dde Binary files /dev/null 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 new file mode 100644 index 00000000000..a083efffaff Binary files /dev/null and b/CI/physmon/reference/trackfinding_ttbar_pu200/performance_finding_ckf_ambi.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 new file mode 100644 index 00000000000..09d2dc033af Binary files /dev/null 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 new file mode 100644 index 00000000000..949d8cebfc3 Binary files /dev/null and b/CI/physmon/reference/trackfinding_ttbar_pu200/performance_fitting_ckf_ambi.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 5e072e1393c..500783b48a4 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 64abc1fadaf..8d1bf337631 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 8181f0608c4..25110c369be 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 e964b96fcab..f803f21ee8f 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 3d2eaa11044..b3543963d9f 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/reference/trackfitting_gx2f/performance_trackfitting.root b/CI/physmon/reference/trackfitting_gx2f/performance_trackfitting.root index 8fae64cd735..21533ce8076 100644 Binary files a/CI/physmon/reference/trackfitting_gx2f/performance_trackfitting.root and b/CI/physmon/reference/trackfitting_gx2f/performance_trackfitting.root differ diff --git a/CI/physmon/reference/trackfitting_kf/performance_trackfitting.root b/CI/physmon/reference/trackfitting_kf/performance_trackfitting.root index aade25ba5a2..4e3f44e2b34 100644 Binary files a/CI/physmon/reference/trackfitting_kf/performance_trackfitting.root and b/CI/physmon/reference/trackfitting_kf/performance_trackfitting.root differ diff --git a/CI/physmon/reference/trackrefitting_gsf/performance_trackrefitting.root b/CI/physmon/reference/trackrefitting_gsf/performance_trackrefitting.root index d888ad406d8..b6b8d6fd126 100644 Binary files a/CI/physmon/reference/trackrefitting_gsf/performance_trackrefitting.root and b/CI/physmon/reference/trackrefitting_gsf/performance_trackrefitting.root differ diff --git a/CI/physmon/reference/trackrefitting_kf/performance_trackrefitting.root b/CI/physmon/reference/trackrefitting_kf/performance_trackrefitting.root index aade25ba5a2..99385589d48 100644 Binary files a/CI/physmon/reference/trackrefitting_kf/performance_trackrefitting.root and b/CI/physmon/reference/trackrefitting_kf/performance_trackrefitting.root differ diff --git a/CI/physmon/workflows/physmon_trackfinding_1muon.py b/CI/physmon/workflows/physmon_trackfinding_1muon.py index 3c87bdee32d..aaa4bc9f71d 100755 --- a/CI/physmon/workflows/physmon_trackfinding_1muon.py +++ b/CI/physmon/workflows/physmon_trackfinding_1muon.py @@ -112,7 +112,7 @@ def run_ckf_tracking(label, seeding): maxSeedsPerSpM=1, sigmaScattering=5, radLengthPerSeed=0.1, - minPt=500 * u.MeV, + minPt=0.5 * u.GeV, impactMax=3 * u.mm, ), SeedFinderOptionsArg(bFieldInZ=2 * u.T), @@ -163,8 +163,9 @@ def run_ckf_tracking(label, seeding): if seeding != SeedingAlgorithm.TruthSmeared else [] ) + [ - "performance_ckf.root", "tracksummary_ckf.root", + "performance_finding_ckf.root", + "performance_fitting_ckf.root", ]: perf_file = tp / file assert perf_file.exists(), f"Performance file not found {perf_file}" diff --git a/CI/physmon/workflows/physmon_trackfinding_4muon_50vertices.py b/CI/physmon/workflows/physmon_trackfinding_4muon_50vertices.py index f6c3fe110fd..1a119c8ed6c 100755 --- a/CI/physmon/workflows/physmon_trackfinding_4muon_50vertices.py +++ b/CI/physmon/workflows/physmon_trackfinding_4muon_50vertices.py @@ -96,7 +96,7 @@ maxSeedsPerSpM=1, sigmaScattering=5, radLengthPerSeed=0.1, - minPt=500 * u.MeV, + minPt=0.5 * u.GeV, impactMax=3 * u.mm, ), SeedFinderOptionsArg(bFieldInZ=2 * u.T, beamPos=(0.0, 0.0)), @@ -196,8 +196,12 @@ s.run() shutil.move( - tp / "performance_ambi.root", - tp / "performance_ckf_ambi.root", + tp / "performance_finding_ambi.root", + tp / "performance_finding_ckf_ambi.root", + ) + shutil.move( + tp / "performance_fitting_ambi.root", + tp / "performance_fitting_ckf_ambi.root", ) for vertexing in ["ivf_notime", "amvf_gauss_notime", "amvf_grid_time"]: shutil.move( @@ -208,8 +212,10 @@ for file in [ "performance_seeding.root", "tracksummary_ckf.root", - "performance_ckf.root", - "performance_ckf_ambi.root", + "performance_finding_ckf.root", + "performance_fitting_ckf.root", + "performance_finding_ckf_ambi.root", + "performance_fitting_ckf_ambi.root", "performance_vertexing_ivf_notime.root", "performance_vertexing_amvf_gauss_notime.root", "performance_vertexing_amvf_grid_time.root", diff --git a/CI/physmon/workflows/physmon_trackfinding_ttbar_pu200.py b/CI/physmon/workflows/physmon_trackfinding_ttbar_pu200.py index c8b163c9022..99f12d0170d 100755 --- a/CI/physmon/workflows/physmon_trackfinding_ttbar_pu200.py +++ b/CI/physmon/workflows/physmon_trackfinding_ttbar_pu200.py @@ -94,7 +94,7 @@ maxSeedsPerSpM=1, sigmaScattering=5, radLengthPerSeed=0.1, - minPt=500 * u.MeV, + minPt=0.5 * u.GeV, impactMax=3 * u.mm, ), SeedFinderOptionsArg(bFieldInZ=2 * u.T, beamPos=(0.0, 0.0)), @@ -118,7 +118,7 @@ setup.trackingGeometry, setup.field, TrackSelectorConfig( - pt=(500 * u.MeV, None), + pt=(0.5 * u.GeV, None), loc0=(-4.0 * u.mm, 4.0 * u.mm), nMeasurementsMin=6, maxHoles=2, @@ -180,8 +180,12 @@ s.run() shutil.move( - tp / "performance_ambi.root", - tp / "performance_ckf_ambi.root", + tp / "performance_finding_ambi.root", + tp / "performance_finding_ckf_ambi.root", + ) + shutil.move( + tp / "performance_fitting_ambi.root", + tp / "performance_fitting_ckf_ambi.root", ) for vertexing in ["amvf_gauss_notime", "amvf_grid_time"]: shutil.move( @@ -192,8 +196,10 @@ for file in [ "performance_seeding.root", "tracksummary_ckf.root", - "performance_ckf.root", - "performance_ckf_ambi.root", + "performance_finding_ckf.root", + "performance_fitting_ckf.root", + "performance_finding_ckf_ambi.root", + "performance_fitting_ckf_ambi.root", "performance_vertexing_amvf_gauss_notime.root", "performance_vertexing_amvf_grid_time.root", ]: diff --git a/CMakeLists.txt b/CMakeLists.txt index e8e9ab3f583..f81002cab83 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -227,6 +227,7 @@ endif() set(_acts_actsvg_version 0.4.50) set(_acts_boost_version 1.71.0) set(_acts_dd4hep_version 1.21) +set(_acts_geant4_version 11.1.3) set(_acts_edm4hep_version 0.7) set(_acts_eigen3_version 3.4.0) set(_acts_podio_version 1.0.1) # will try this first @@ -453,7 +454,7 @@ if(ACTS_BUILD_PLUGIN_EDM4HEP) find_package(EDM4HEP ${_acts_edm4hep_version} REQUIRED CONFIG) endif() if(ACTS_BUILD_PLUGIN_GEANT4) - find_package(Geant4 REQUIRED CONFIG COMPONENTS gdml) + find_package(Geant4 ${_acts_geant4_version} REQUIRED CONFIG COMPONENTS gdml) endif() if(ACTS_BUILD_PLUGIN_TRACCC) diff --git a/Core/include/Acts/EventData/TrackParameterHelpers.hpp b/Core/include/Acts/EventData/TrackParameterHelpers.hpp new file mode 100644 index 00000000000..cd68b5ae6a4 --- /dev/null +++ b/Core/include/Acts/EventData/TrackParameterHelpers.hpp @@ -0,0 +1,44 @@ +// 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/Definitions/TrackParametrization.hpp" +#include "Acts/Utilities/detail/periodic.hpp" + +namespace Acts { + +/// Normalize the bound parameter angles +/// +/// @param boundParams The bound parameters to normalize +/// +/// @return The normalized bound parameters +inline BoundVector normalizeBoundParameters(const BoundVector& boundParams) { + BoundVector result = boundParams; + std::tie(result[eBoundPhi], result[eBoundTheta]) = + detail::normalizePhiTheta(result[eBoundPhi], result[eBoundTheta]); + return result; +} + +/// Subtract bound parameters and take care of angle periodicity for phi and +/// theta. +/// +/// @param lhs The left hand side bound parameters +/// @param rhs The right hand side bound parameters +/// +/// @return The difference of the bound parameters +inline BoundVector subtractBoundParameters(const BoundVector& lhs, + const BoundVector& rhs) { + BoundVector result = lhs - rhs; + result[eBoundPhi] = + detail::difference_periodic(lhs[eBoundPhi], rhs[eBoundPhi], 2 * M_PI); + return result; +} + +} // namespace Acts diff --git a/Core/include/Acts/Seeding/PathSeeder.hpp b/Core/include/Acts/Seeding/PathSeeder.hpp index 1d3fd49f66b..d4475c022df 100644 --- a/Core/include/Acts/Seeding/PathSeeder.hpp +++ b/Core/include/Acts/Seeding/PathSeeder.hpp @@ -9,10 +9,13 @@ #pragma once #include "Acts/EventData/SourceLink.hpp" +#include "Acts/EventData/TrackParameters.hpp" +#include "Acts/Seeding/detail/UtilityFunctions.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Utilities/Delegate.hpp" +#include "Acts/Utilities/GridIterator.hpp" -namespace Acts::Experimental { +namespace Acts { /// @brief Seeding algorigthm that extracts /// the IP parameters and sorts the source links @@ -23,7 +26,7 @@ namespace Acts::Experimental { /// source links -- as follows: First the source links /// are sorted into a user-defined grid. Then, iteration over the source links /// is performed. If a source link is attached to a surface that is -/// in the first tracking layer, as defined by the user, the IP parameters +/// in the reference tracking layer, as defined by the user, the IP parameters /// are estimated and the tracking layers are intersected to construct the /// core of the "Path". The source links in the subsequent layers are then /// added to the seed if they lie within the path width of the core. @@ -39,84 +42,34 @@ namespace Acts::Experimental { /// /// @note Handling of the rotated surfaces has to happen /// in the user-defined delegate functions. - -template class PathSeeder { public: - using GridType = grid_t; - - /// @brief The seed struct - /// - /// The seed struct contains the IP parameters - /// and the source links that are associated with - /// the seed. - struct Seed { - /// The IP momentum magnitude - ActsScalar ipP; - - /// The IP momentum direction - Vector3 ipDir; - - /// The IP vertex position - Vector3 ipVertex; - - /// The source links associated with the seed - std::vector sourceLinks; - - Seed() = delete; - Seed(ActsScalar ipPmag, Vector3 ipPdir, Vector3 ipPos, - std::vector sls) - : ipP(ipPmag), - ipDir(std::move(ipPdir)), - ipVertex(std::move(ipPos)), - sourceLinks(std::move(sls)) {}; - }; - - /// @brief Delegate to provide the relevant grid - /// filled with source links for the given geometry - /// member - /// - /// @arg The geometry identifier to use - /// - /// @return The grid filled with source links - using SourceLinkGridLookup = Delegate; + using PathSeed = + std::pair>; /// @brief Delegate to estimate the IP parameters - /// and the momentum direction at the first tracking layer - /// - /// @arg The geometry context to use - /// @arg The global position of the pivot source link - /// - /// @return Particle charge, the IP momentum magnitude, the IP vertex position, - /// the IP momentum direction, the momentum direction at the - /// first tracking layer - using TrackEstimator = - Delegate( - const GeometryContext&, const Vector3&)>; - - /// @brief Delegate to transform the source link to the - /// appropriate global frame. + /// and the momentum direction at the reference tracking layer /// - /// @arg The geometry context to use - /// @arg The source link to calibrate + /// @arg Geometry context to use + /// @arg Pivot source link /// - /// @return The global position of the source link measurement - using SourceLinkCalibrator = - Delegate; + /// @return Pair of the track parameters at the IP and + /// the reference tracking layer + using TrackEstimator = Delegate< + std::pair( + const GeometryContext&, const SourceLink&)>; /// @brief Delegate to find the intersections for the given pivot /// source link /// /// @arg The geometry context to use - /// @arg The global position of the pivot source link - /// @arg The momentum direction of the pivot source link - /// at the first tracking layer - /// @arg The IP momentum magnitude - /// @arg The particle charge + /// @arg Track parameters at the reference tracking layer + /// + /// @return Vector of pairs of the geometry identifier + /// and the local intersection point using IntersectionLookup = - Delegate>( - const GeometryContext&, const Vector3&, const Vector3&, - const ActsScalar&, const ActsScalar&)>; + Delegate>( + const GeometryContext&, const CurvilinearTrackParameters&)>; /// @brief Delegate to provide the path width around /// the intersection point to pull the source links @@ -133,24 +86,18 @@ class PathSeeder { /// @brief The nested configuration struct struct Config { - /// Binned SourceLink provider - SourceLinkGridLookup sourceLinkGridLookup; /// Parameters estimator TrackEstimator trackEstimator; - /// SourceLink calibrator - SourceLinkCalibrator sourceLinkCalibrator; /// Intersection finder IntersectionLookup intersectionFinder; /// Path width provider PathWidthLookup pathWidthProvider; - /// First layer extent - Extent firstLayerExtent; - /// Direction of the telescope extent - BinningValue orientation = BinningValue::binX; + /// Reference layer IDs + std::vector refLayerIds; }; /// @brief Constructor - PathSeeder(const Config& config) : m_cfg(std::move(config)) {}; + PathSeeder(const Config& config) : m_cfg(config) {}; /// @brief Destructor ~PathSeeder() = default; @@ -159,101 +106,86 @@ class PathSeeder { /// sort the source links into the seeds /// /// @param gctx The geometry context - /// @param sourceLinks The source links to seed + /// @param sourceLinkGridLookup The lookup table for the source links + /// @param seedCollection The collection of seeds to fill /// /// @return The vector of seeds - std::vector getSeeds(const GeometryContext& gctx, - const std::vector& sourceLinks) const { - // Get plane of the telescope - // sensitive surfaces - int bin0 = static_cast(BinningValue::binX); - int bin1 = static_cast(BinningValue::binY); - if (m_cfg.orientation == BinningValue::binX) { - bin0 = static_cast(BinningValue::binY); - bin1 = static_cast(BinningValue::binZ); - } else if (m_cfg.orientation == BinningValue::binY) { - bin0 = static_cast(BinningValue::binX); - bin1 = static_cast(BinningValue::binZ); - } - + template + void findSeeds(const GeometryContext& gctx, + const std::unordered_map& + sourceLinkGridLookup, + container_t& seedCollection) const { // Create the seeds - std::vector seeds; - for (const auto& sl : sourceLinks) { - Vector3 globalPos = m_cfg.sourceLinkCalibrator(gctx, sl); - - // Check if the hit is in the - // first tracking layer - if (!m_cfg.firstLayerExtent.contains(globalPos)) { - continue; - } - - // Get the IP parameters - auto [q, ipP, ipVertex, ipDir, flDir] = - m_cfg.trackEstimator(gctx, globalPos); - - // Intersect with the surfaces - std::vector> intersections = - m_cfg.intersectionFinder(gctx, globalPos, flDir, ipP, q); - - // Continue if no intersections - if (intersections.empty()) { - continue; - } - // Vector to store the source links - std::vector seedSourceLinks; - - // Store the pivot source link - seedSourceLinks.push_back(sl); + for (auto& refGeoId : m_cfg.refLayerIds) { + auto refGrid = sourceLinkGridLookup.at(refGeoId); - // Iterate over the intersections - // and get the source links - // in the subsequent layers - for (auto& [geoId, refPoint] : intersections) { - // Get the path width - auto [pathWidth0, pathWidth1] = m_cfg.pathWidthProvider(gctx, geoId); + for (auto it = refGrid.begin(); it != refGrid.end(); it++) { + std::vector pivotSourceLinks = *it; - // Get the bounds of the path - ActsScalar top0 = refPoint[bin0] + pathWidth0; - ActsScalar bot0 = refPoint[bin0] - pathWidth0; - ActsScalar top1 = refPoint[bin1] + pathWidth1; - ActsScalar bot1 = refPoint[bin1] - pathWidth1; + for (const auto& pivot : pivotSourceLinks) { + // Get the IP parameters + auto [ipParameters, refLayerParameters] = + m_cfg.trackEstimator(gctx, pivot); - // Get the lookup table for the source links - auto grid = m_cfg.sourceLinkGridLookup(geoId); + // Intersect with the surfaces + std::vector> intersections = + m_cfg.intersectionFinder(gctx, refLayerParameters); - // Get the range of bins to search for source links - auto botLeftBin = grid.localBinsFromPosition(Vector2(bot0, bot1)); - auto topRightBin = grid.localBinsFromPosition(Vector2(top0, top1)); - - // Get the source links from the lookup table - // by iterating over the bin ranges - auto currentBin = botLeftBin; - while (currentBin.at(1) <= topRightBin.at(1)) { - while (currentBin.at(0) <= topRightBin.at(0)) { - auto sourceLinksToAdd = grid.atLocalBins(currentBin); + // Continue if no intersections + if (intersections.empty()) { + continue; + } - seedSourceLinks.insert(seedSourceLinks.end(), - sourceLinksToAdd.begin(), - sourceLinksToAdd.end()); - currentBin.at(0)++; + // Iterate over the intersections + // and get the source links + // in the subsequent layers + std::vector seedSourceLinks; + for (auto& [geoId, refPoint] : intersections) { + // Get the path width + auto [pathWidth0, pathWidth1] = + m_cfg.pathWidthProvider(gctx, geoId); + + // Get the bounds of the path + ActsScalar top0 = refPoint[0] + pathWidth0; + ActsScalar bot0 = refPoint[0] - pathWidth0; + ActsScalar top1 = refPoint[1] + pathWidth1; + ActsScalar bot1 = refPoint[1] - pathWidth1; + + // Get the lookup table for the source links + auto grid = sourceLinkGridLookup.at(geoId); + + // Get the range of bins to search for source links + auto botLeftBin = grid.localBinsFromPosition(Vector2(bot0, bot1)); + auto topRightBin = grid.localBinsFromPosition(Vector2(top0, top1)); + + // Get the source links from the lookup table + // by iterating over the bin ranges + auto currentBin = botLeftBin; + while (currentBin.at(1) <= topRightBin.at(1)) { + while (currentBin.at(0) <= topRightBin.at(0)) { + auto sourceLinksToAdd = grid.atLocalBins(currentBin); + + seedSourceLinks.insert(seedSourceLinks.end(), + sourceLinksToAdd.begin(), + sourceLinksToAdd.end()); + + currentBin.at(0)++; + } + currentBin.at(1)++; + currentBin.at(0) = botLeftBin.at(0); + } } - currentBin.at(1)++; - currentBin.at(0) = botLeftBin.at(0); + PathSeed seed = {ipParameters, seedSourceLinks}; + + // Add the seed to the collection + Acts::detail::pushBackOrInsertAtEnd(seedCollection, seed); } } - - // Store the IP parameters and - // add the source links to the seed - Seed seed{ipP, ipDir, ipVertex, seedSourceLinks}; - - // Add the seed to the list - seeds.push_back(seed); } - return seeds; - }; + } private: Config m_cfg; }; -} // namespace Acts::Experimental +} // namespace Acts diff --git a/Core/include/Acts/Seeding/detail/UtilityFunctions.hpp b/Core/include/Acts/Seeding/detail/UtilityFunctions.hpp index 9cc61c4fe3f..b4fa190fa37 100644 --- a/Core/include/Acts/Seeding/detail/UtilityFunctions.hpp +++ b/Core/include/Acts/Seeding/detail/UtilityFunctions.hpp @@ -8,6 +8,8 @@ #pragma once +#include "Acts/EventData/SourceLink.hpp" + #include namespace Acts::detail { @@ -29,6 +31,10 @@ concept isCollectionThatSupportsInsert = coll.insert(std::ranges::end(coll), val); }; +template +concept SourceLinkGrid = + std::same_as>; + // Define some functions template diff --git a/Core/include/Acts/TrackFinding/TrackSelector.hpp b/Core/include/Acts/TrackFinding/TrackSelector.hpp index e782b7feb9d..bca7fa8d2a0 100644 --- a/Core/include/Acts/TrackFinding/TrackSelector.hpp +++ b/Core/include/Acts/TrackFinding/TrackSelector.hpp @@ -12,11 +12,11 @@ #include "Acts/EventData/TrackStateType.hpp" #include "Acts/Geometry/GeometryHierarchyMap.hpp" #include "Acts/Geometry/GeometryIdentifier.hpp" +#include "Acts/Utilities/AngleHelpers.hpp" #include #include #include -#include #include #include @@ -419,7 +419,7 @@ bool TrackSelector::isValidTrack(const track_proxy_t& track) const { auto absEta = [&]() { if (_absEta == kUnset) { - _eta = -std::log(std::tan(theta / 2)); + _eta = AngleHelpers::etaFromTheta(theta); _absEta = std::abs(_eta); } return _absEta; diff --git a/Core/include/Acts/TrackFitting/detail/GainMatrixUpdaterImpl.hpp b/Core/include/Acts/TrackFitting/detail/GainMatrixUpdaterImpl.hpp index 7a6e1ec6434..0dce3c2ba21 100644 --- a/Core/include/Acts/TrackFitting/detail/GainMatrixUpdaterImpl.hpp +++ b/Core/include/Acts/TrackFitting/detail/GainMatrixUpdaterImpl.hpp @@ -8,6 +8,7 @@ #pragma once +#include "Acts/EventData/TrackParameterHelpers.hpp" #include "Acts/TrackFitting/GainMatrixUpdater.hpp" #include "Acts/Utilities/Logger.hpp" @@ -60,6 +61,8 @@ std::tuple GainMatrixUpdater::visitMeasurementImpl( trackState.filtered = trackState.predicted + K * (calibrated - H * trackState.predicted); + // Normalize phi and theta + trackState.filtered = normalizeBoundParameters(trackState.filtered); trackState.filteredCovariance = (BoundSquareMatrix::Identity() - K * H) * trackState.predictedCovariance; ACTS_VERBOSE("Filtered parameters: " << trackState.filtered.transpose()); diff --git a/Core/include/Acts/Utilities/AngleHelpers.hpp b/Core/include/Acts/Utilities/AngleHelpers.hpp new file mode 100644 index 00000000000..02feec2323e --- /dev/null +++ b/Core/include/Acts/Utilities/AngleHelpers.hpp @@ -0,0 +1,35 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 CERN for the benefit of the ACTS project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +#pragma once + +#include + +namespace Acts::AngleHelpers { + +/// Calculate the pseudorapidity from the polar angle theta. +/// +/// @param theta is the polar angle in radian towards the z-axis. +/// +/// @return the pseudorapidity towards the z-axis. +template +Scalar etaFromTheta(Scalar theta) { + return -std::log(std::tan(0.5 * theta)); +} + +/// Calculate the polar angle theta from the pseudorapidity. +/// +/// @param eta is the pseudorapidity towards the z-axis. +/// +/// @return the polar angle in radian towards the z-axis. +template +Scalar thetaFromEta(Scalar eta) { + return 2 * std::atan(std::exp(-eta)); +} + +} // namespace Acts::AngleHelpers diff --git a/Core/include/Acts/Utilities/BoundingBox.ipp b/Core/include/Acts/Utilities/BoundingBox.ipp index 330353014fa..d989507fa85 100644 --- a/Core/include/Acts/Utilities/BoundingBox.ipp +++ b/Core/include/Acts/Utilities/BoundingBox.ipp @@ -346,8 +346,7 @@ template Acts::AxisAlignedBoundingBox Acts::AxisAlignedBoundingBox::transformed( const transform_type& trf) const { - VertexType vmin, vmax; - std::tie(vmin, vmax) = transformVertices(trf); + const auto [vmin, vmax] = transformVertices(trf); return self_t(m_entity, vmin, vmax); } @@ -463,8 +462,7 @@ box_t* octree_inner(std::vector>& store, std::array, 8> octants; // calc center of boxes - VertexType vmin, vmax; - std::tie(vmin, vmax) = box_t::wrap(lprims); + const auto [vmin, vmax] = box_t::wrap(lprims); VertexType glob_ctr = (vmin + vmax) / 2.; for (auto* box : lprims) { diff --git a/Core/include/Acts/Utilities/GridAxisGenerators.hpp b/Core/include/Acts/Utilities/GridAxisGenerators.hpp index 2ebeb78406f..18e6a1cdd2e 100644 --- a/Core/include/Acts/Utilities/GridAxisGenerators.hpp +++ b/Core/include/Acts/Utilities/GridAxisGenerators.hpp @@ -110,7 +110,7 @@ struct EqEq { nBins0); Acts::Axis bEq(range1[0u], range1[1u], nBins1); - return std::tie(aEq, bEq); + return {aEq, bEq}; } }; @@ -160,7 +160,7 @@ struct EqVar { Acts::Axis eqA(range[0u], range[1u], nBins); Acts::Axis varB(edges); - return std::tie(eqA, varB); + return {eqA, varB}; } }; @@ -210,7 +210,7 @@ struct VarEq { Acts::Axis varA(edges); Acts::Axis eqB(range[0u], range[1u], nBins); - return std::tie(varA, eqB); + return {varA, eqB}; } }; @@ -257,7 +257,7 @@ struct VarVar { return_type operator()() const { Acts::Axis varA(edges0); Acts::Axis varB(edges1); - return std::tie(varA, varB); + return {varA, varB}; } }; diff --git a/Core/include/Acts/Utilities/Helpers.hpp b/Core/include/Acts/Utilities/Helpers.hpp index 2308d2a3014..4bf9d1c89c3 100644 --- a/Core/include/Acts/Utilities/Helpers.hpp +++ b/Core/include/Acts/Utilities/Helpers.hpp @@ -179,7 +179,7 @@ std::tuple range_medium(const T& tseries) { auto [minIt, maxIt] = std::ranges::minmax_element(tseries); typename T::value_type range = (*maxIt - *minIt); ActsScalar medium = static_cast((*maxIt + *minIt) * 0.5); - return std::tie(range, medium); + return {range, medium}; } template diff --git a/Core/include/Acts/Vertexing/detail/KalmanVertexUpdaterImpl.hpp b/Core/include/Acts/Vertexing/detail/KalmanVertexUpdaterImpl.hpp index 4c08820e693..f8f99b98f20 100644 --- a/Core/include/Acts/Vertexing/detail/KalmanVertexUpdaterImpl.hpp +++ b/Core/include/Acts/Vertexing/detail/KalmanVertexUpdaterImpl.hpp @@ -254,9 +254,7 @@ void updateVertexWithTrackImpl(Vertex& vtx, TrackAtVertex& trk, int sign) { calculateUpdate(vtx, trk.linearizedState, trackWeight, sign, cache); // Get fit quality parameters wrt to old vertex - double chi2 = 0.; - double ndf = 0.; - std::tie(chi2, ndf) = vtx.fitQuality(); + auto [chi2, ndf] = vtx.fitQuality(); // Chi2 of the track parameters double trkChi2 = trackParametersChi2(trk.linearizedState, cache); diff --git a/Core/src/Detector/detail/CuboidalDetectorHelper.cpp b/Core/src/Detector/detail/CuboidalDetectorHelper.cpp index 114b8512e7f..ac2acd2482a 100644 --- a/Core/src/Detector/detail/CuboidalDetectorHelper.cpp +++ b/Core/src/Detector/detail/CuboidalDetectorHelper.cpp @@ -373,7 +373,7 @@ Acts::Experimental::detail::CuboidalDetectorHelper::xyzBoundaries( } for (auto [im, map] : enumerate(valueMaps)) { - for (auto [key, value] : map) { + for (auto [key, _] : map) { boundaries[im].push_back(key); } std::ranges::sort(boundaries[im]); diff --git a/Core/src/MagneticField/BFieldMapUtils.cpp b/Core/src/MagneticField/BFieldMapUtils.cpp index 14bc273966b..e7216aa3bf9 100644 --- a/Core/src/MagneticField/BFieldMapUtils.cpp +++ b/Core/src/MagneticField/BFieldMapUtils.cpp @@ -254,12 +254,9 @@ Acts::solenoidFieldMap(std::pair rlim, std::pair zlim, std::pair nbins, const SolenoidBField& field) { - double rMin = 0, rMax = 0, zMin = 0, zMax = 0; - std::tie(rMin, rMax) = rlim; - std::tie(zMin, zMax) = zlim; - - std::size_t nBinsR = 0, nBinsZ = 0; - std::tie(nBinsR, nBinsZ) = nbins; + auto [rMin, rMax] = rlim; + auto [zMin, zMax] = zlim; + const auto [nBinsR, nBinsZ] = nbins; double stepZ = std::abs(zMax - zMin) / (nBinsZ - 1); double stepR = std::abs(rMax - rMin) / (nBinsR - 1); diff --git a/Core/src/Material/BinnedSurfaceMaterialAccumulater.cpp b/Core/src/Material/BinnedSurfaceMaterialAccumulater.cpp index ca2a460d4d2..a4d2366b743 100644 --- a/Core/src/Material/BinnedSurfaceMaterialAccumulater.cpp +++ b/Core/src/Material/BinnedSurfaceMaterialAccumulater.cpp @@ -119,9 +119,9 @@ void Acts::BinnedSurfaceMaterialAccumulater::accumulate( } // After mapping this track, average the touched bins - for (auto tmapBin : touchedMapBins) { - std::vector> trackBins = {tmapBin.second}; - tmapBin.first->trackAverage(trackBins, true); + for (const auto& [key, value] : touchedMapBins) { + std::vector> trackBins = {value}; + key->trackAverage(trackBins, true); } // Empty bin correction diff --git a/Core/src/Material/SurfaceMaterialMapper.cpp b/Core/src/Material/SurfaceMaterialMapper.cpp index 4890354217a..f4ad7ecc6f9 100644 --- a/Core/src/Material/SurfaceMaterialMapper.cpp +++ b/Core/src/Material/SurfaceMaterialMapper.cpp @@ -416,19 +416,19 @@ void Acts::SurfaceMaterialMapper::mapInteraction( } // After mapping this track, average the touched bins - for (auto tmapBin : touchedMapBins) { - std::vector> trackBins = {tmapBin.second}; + for (const auto& [key, value] : touchedMapBins) { + std::vector> trackBins = {value}; if (m_cfg.computeVariance) { // This only makes sense for the binned material auto binnedMaterial = dynamic_cast( - touchedMaterialBin[tmapBin.first].get()); + touchedMaterialBin[key].get()); if (binnedMaterial != nullptr) { - tmapBin.first->trackVariance( + key->trackVariance( trackBins, binnedMaterial->fullMaterial()[trackBins[0][1]][trackBins[0][0]]); } } - tmapBin.first->trackAverage(trackBins); + key->trackAverage(trackBins); } // After mapping this track, average the untouched but intersected bins @@ -493,14 +493,14 @@ void Acts::SurfaceMaterialMapper::mapSurfaceInteraction( } // After mapping this track, average the touched bins - for (auto tmapBin : touchedMapBins) { - std::vector> trackBins = {tmapBin.second}; + for (const auto& [key, value] : touchedMapBins) { + std::vector> trackBins = {value}; if (m_cfg.computeVariance) { // This only makes sense for the binned material auto binnedMaterial = dynamic_cast( - touchedMaterialBin[tmapBin.first].get()); + touchedMaterialBin[key].get()); if (binnedMaterial != nullptr) { - tmapBin.first->trackVariance( + key->trackVariance( trackBins, binnedMaterial->fullMaterial()[trackBins[0][1]][trackBins[0][0]], true); @@ -508,6 +508,6 @@ void Acts::SurfaceMaterialMapper::mapSurfaceInteraction( } // No need to do an extra pass for untouched surfaces they would have been // added to the material interaction in the initial mapping - tmapBin.first->trackAverage(trackBins, true); + key->trackAverage(trackBins, true); } } diff --git a/Core/src/TrackFinding/AmbiguityTrackClustering.cpp b/Core/src/TrackFinding/AmbiguityTrackClustering.cpp index ca6b39571af..ff0e95cbb3d 100644 --- a/Core/src/TrackFinding/AmbiguityTrackClustering.cpp +++ b/Core/src/TrackFinding/AmbiguityTrackClustering.cpp @@ -22,26 +22,26 @@ Acts::detail::clusterDuplicateTracks( std::unordered_map hitToTrack; // Loop over all the tracks - for (auto track = trackMap.rbegin(); track != trackMap.rend(); ++track) { - std::vector hits = track->second.second; + for (const auto& [_, trackValue] : trackMap) { + std::vector hits = trackValue.second; auto matchedTrack = hitToTrack.end(); // Loop over all the hits in the track - for (auto hit = hits.begin(); hit != hits.end(); hit++) { + for (const auto& hit : hits) { // Check if the hit is already associated to a track - matchedTrack = hitToTrack.find(*hit); + matchedTrack = hitToTrack.find(hit); if (matchedTrack != hitToTrack.end()) { // Add the track to the cluster associated to the matched track - cluster.at(matchedTrack->second).push_back(track->second.first); + cluster.at(matchedTrack->second).push_back(trackValue.first); break; } } // None of the hits have been matched to a track create a new cluster if (matchedTrack == hitToTrack.end()) { - cluster.emplace(track->second.first, - std::vector(1, track->second.first)); + cluster.emplace(trackValue.first, + std::vector(1, trackValue.first)); for (const auto& hit : hits) { // Add the hits of the new cluster to the hitToTrack - hitToTrack.emplace(hit, track->second.first); + hitToTrack.emplace(hit, trackValue.first); } } } diff --git a/Core/src/TrackFinding/GbtsConnector.cpp b/Core/src/TrackFinding/GbtsConnector.cpp index acebffa9f74..d947894871c 100644 --- a/Core/src/TrackFinding/GbtsConnector.cpp +++ b/Core/src/TrackFinding/GbtsConnector.cpp @@ -9,6 +9,7 @@ // TODO: update to C++17 style #include "Acts/TrackFinding/GbtsConnector.hpp" +#include #include #include #include @@ -57,15 +58,8 @@ GbtsConnector::GbtsConnector(std::ifstream &inFile) { continue; } - std::map>::iterator it = - m_connMap.find(stage); - - if (it == m_connMap.end()) { - std::vector v(1, pC); - m_connMap.insert(std::make_pair(stage, v)); - } else { - (*it).second.push_back(pC); - } + auto &connections = m_connMap[stage]; + connections.push_back(pC); } // re-arrange the connection stages @@ -74,9 +68,8 @@ GbtsConnector::GbtsConnector(std::ifstream &inFile) { std::map> newConnMap; - for (const auto &conn : m_connMap) { - std::copy(conn.second.begin(), conn.second.end(), - std::back_inserter(lConns)); + for (const auto &[_, value] : m_connMap) { + std::ranges::copy(value, std::back_inserter(lConns)); } int stageCounter = 0; @@ -111,19 +104,19 @@ GbtsConnector::GbtsConnector(std::ifstream &inFile) { std::set zeroLayers; - for (const auto &layerCounts : mCounter) { - if (layerCounts.second.second != 0) { + for (const auto &[key, value] : mCounter) { + if (value.second != 0) { continue; } - zeroLayers.insert(layerCounts.first); + zeroLayers.insert(key); } // remove connections which use zeroLayer as destination std::vector theStage; - std::list::iterator cIt = lConns.begin(); + auto cIt = lConns.begin(); while (cIt != lConns.end()) { if (zeroLayers.contains((*cIt)->m_dst)) { @@ -144,10 +137,9 @@ GbtsConnector::GbtsConnector(std::ifstream &inFile) { // the doublet making is done using "outside-in" approach hence the reverse // iterations - for (std::map>::reverse_iterator it = - newConnMap.rbegin(); - it != newConnMap.rend(); ++it, currentStage++) { - const std::vector &vConn = (*it).second; + for (auto it = newConnMap.rbegin(); it != newConnMap.rend(); + it++, currentStage++) { + const auto &[_, vConn] = *it; // loop over links, extract all connections for the stage, group sources by // L1 (dst) index @@ -157,8 +149,7 @@ GbtsConnector::GbtsConnector(std::ifstream &inFile) { for (const auto *conn : vConn) { unsigned int dst = conn->m_dst; - std::map>::iterator - l1MapIt = l1ConnMap.find(dst); + auto l1MapIt = l1ConnMap.find(dst); if (l1MapIt != l1ConnMap.end()) { (*l1MapIt).second.push_back(conn); } else { @@ -171,8 +162,8 @@ GbtsConnector::GbtsConnector(std::ifstream &inFile) { lgv.reserve(l1ConnMap.size()); - for (const auto &l1Group : l1ConnMap) { - lgv.push_back(LayerGroup(l1Group.first, l1Group.second)); + for (const auto &[key, value] : l1ConnMap) { + lgv.emplace_back(LayerGroup(key, value)); } m_layerGroups.insert(std::make_pair(currentStage, lgv)); @@ -183,12 +174,9 @@ GbtsConnector::GbtsConnector(std::ifstream &inFile) { GbtsConnector::~GbtsConnector() { m_layerGroups.clear(); - for (std::map>::iterator it = - m_connMap.begin(); - it != m_connMap.end(); ++it) { - for (std::vector::iterator cIt = (*it).second.begin(); - cIt != (*it).second.end(); ++cIt) { - delete (*cIt); + for (const auto &[_, connections] : m_connMap) { + for (auto *conn : connections) { + delete conn; } } } diff --git a/Core/src/TrackFitting/GainMatrixSmoother.cpp b/Core/src/TrackFitting/GainMatrixSmoother.cpp index 19d54bdcf4b..711540ff0bf 100644 --- a/Core/src/TrackFitting/GainMatrixSmoother.cpp +++ b/Core/src/TrackFitting/GainMatrixSmoother.cpp @@ -9,6 +9,7 @@ #include "Acts/TrackFitting/GainMatrixSmoother.hpp" #include "Acts/Definitions/TrackParametrization.hpp" +#include "Acts/EventData/TrackParameterHelpers.hpp" #include "Acts/EventData/detail/CovarianceHelper.hpp" #include "Acts/TrackFitting/KalmanFitterError.hpp" @@ -57,7 +58,10 @@ Result GainMatrixSmoother::calculate( "Prev. predicted parameters: " << predicted(prev_ts).transpose()); // Calculate the smoothed parameters - smoothed(ts) = filtered(ts) + G * (smoothed(prev_ts) - predicted(prev_ts)); + smoothed(ts) = filtered(ts) + G * subtractBoundParameters(smoothed(prev_ts), + predicted(prev_ts)); + // Normalize phi and theta + smoothed(ts) = normalizeBoundParameters(smoothed(ts)); ACTS_VERBOSE("Smoothed parameters are: " << smoothed(ts).transpose()); ACTS_VERBOSE("Calculate smoothed covariance:"); diff --git a/Core/src/TrackFitting/MbfSmoother.cpp b/Core/src/TrackFitting/MbfSmoother.cpp index 8ed74106bfb..2614834aadb 100644 --- a/Core/src/TrackFitting/MbfSmoother.cpp +++ b/Core/src/TrackFitting/MbfSmoother.cpp @@ -8,6 +8,8 @@ #include "Acts/TrackFitting/MbfSmoother.hpp" +#include "Acts/EventData/TrackParameterHelpers.hpp" + namespace Acts { void MbfSmoother::calculateSmoothed(InternalTrackState& ts, @@ -17,6 +19,8 @@ void MbfSmoother::calculateSmoothed(InternalTrackState& ts, bigLambdaHat * ts.filteredCovariance; ts.smoothed = ts.filtered - ts.filteredCovariance * smallLambdaHat; + // Normalize phi and theta + ts.smoothed = normalizeBoundParameters(ts.smoothed); } void MbfSmoother::visitNonMeasurement(const InternalTrackState& ts, diff --git a/Core/src/Vertexing/AdaptiveMultiVertexFinder.cpp b/Core/src/Vertexing/AdaptiveMultiVertexFinder.cpp index 34d20e32e0a..dddd49e715a 100644 --- a/Core/src/Vertexing/AdaptiveMultiVertexFinder.cpp +++ b/Core/src/Vertexing/AdaptiveMultiVertexFinder.cpp @@ -589,10 +589,10 @@ Result AdaptiveMultiVertexFinder::deleteLastVertex( return removeResult.error(); } - for (auto& entry : fitterState.tracksAtVerticesMap) { + for (auto& [key, value] : fitterState.tracksAtVerticesMap) { // Delete all linearized tracks for current (bad) vertex - if (entry.first.second == &vtx) { - entry.second.isLinearized = false; + if (key.second == &vtx) { + value.isLinearized = false; } } diff --git a/Core/src/Vertexing/ImpactPointEstimator.cpp b/Core/src/Vertexing/ImpactPointEstimator.cpp index 53e19277c85..3caac09b57b 100644 --- a/Core/src/Vertexing/ImpactPointEstimator.cpp +++ b/Core/src/Vertexing/ImpactPointEstimator.cpp @@ -9,10 +9,10 @@ #include "Acts/Vertexing/ImpactPointEstimator.hpp" #include "Acts/Definitions/Algebra.hpp" -#include "Acts/Propagator/Propagator.hpp" #include "Acts/Propagator/PropagatorOptions.hpp" #include "Acts/Surfaces/PerigeeSurface.hpp" #include "Acts/Surfaces/PlaneSurface.hpp" +#include "Acts/Utilities/AngleHelpers.hpp" #include "Acts/Utilities/MathHelpers.hpp" #include "Acts/Vertexing/VertexingError.hpp" @@ -526,7 +526,7 @@ Result> ImpactPointEstimator::getLifetimeSignOfTrack( const double theta = params[BoundIndices::eBoundTheta]; double vs = std::sin(std::atan2(direction[1], direction[0]) - phi) * d0; - double eta = -std::log(std::tan(theta / 2.)); + double eta = AngleHelpers::etaFromTheta(theta); double dir_eta = VectorHelpers::eta(direction); double zs = (dir_eta - eta) * z0; diff --git a/Examples/Algorithms/Alignment/src/AlignmentAlgorithmFunction.cpp b/Examples/Algorithms/Alignment/src/AlignmentAlgorithmFunction.cpp index d36a6df9b95..de6780d817b 100644 --- a/Examples/Algorithms/Alignment/src/AlignmentAlgorithmFunction.cpp +++ b/Examples/Algorithms/Alignment/src/AlignmentAlgorithmFunction.cpp @@ -31,7 +31,7 @@ struct AlignmentFunctionImpl : public ActsExamples::AlignmentAlgorithm::AlignmentFunction { Alignment align; - AlignmentFunctionImpl(Alignment&& a) : align(std::move(a)) {} + explicit AlignmentFunctionImpl(Alignment&& a) : align(std::move(a)) {} ActsExamples::AlignmentAlgorithm::AlignmentResult operator()( const std::vector>& diff --git a/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationConfig.hpp b/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationConfig.hpp index 3521d0bef7d..6a933f50075 100644 --- a/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationConfig.hpp +++ b/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationConfig.hpp @@ -130,7 +130,7 @@ class DigitizationConfig { bool doMerge, double mergeNsigma, bool mergeCommonCorner, Acts::GeometryHierarchyMap &&digiCfgs); - DigitizationConfig( + explicit DigitizationConfig( Acts::GeometryHierarchyMap &&digiCfgs); /// Input collection of simulated hits. diff --git a/Examples/Algorithms/Digitization/src/MeasurementCreation.cpp b/Examples/Algorithms/Digitization/src/MeasurementCreation.cpp index 9d5169ca6c9..066901cc0cf 100644 --- a/Examples/Algorithms/Digitization/src/MeasurementCreation.cpp +++ b/Examples/Algorithms/Digitization/src/MeasurementCreation.cpp @@ -30,6 +30,7 @@ ActsExamples::VariableBoundMeasurementProxy ActsExamples::createMeasurement( return Acts::visit_measurement( dParams.indices.size(), [&](auto dim) -> VariableBoundMeasurementProxy { auto [indices, par, cov] = measurementConstituents(dParams); - return container.emplaceMeasurement(geometryId, indices, par, cov); + return VariableBoundMeasurementProxy{ + container.emplaceMeasurement(geometryId, indices, par, cov)}; }); } diff --git a/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/MaterialPhysicsList.hpp b/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/MaterialPhysicsList.hpp index b53567b77a0..9cfb45d0453 100644 --- a/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/MaterialPhysicsList.hpp +++ b/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/MaterialPhysicsList.hpp @@ -29,9 +29,9 @@ class MaterialPhysicsList final : public G4VUserPhysicsList { /// /// @param cfg the configuration struct for this Stepping action /// @param logger is an Acts::Logger for unique logging - MaterialPhysicsList(std::unique_ptr logger = - Acts::getDefaultLogger("MaterialPhysicsList", - Acts::Logging::INFO)); + explicit MaterialPhysicsList(std::unique_ptr logger = + Acts::getDefaultLogger("MaterialPhysicsList", + Acts::Logging::INFO)); ~MaterialPhysicsList() override = default; /// @brief Interface particle construction method diff --git a/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/PhysicsListFactory.hpp b/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/PhysicsListFactory.hpp index d3c4b9f33c2..6bbc39b4f04 100644 --- a/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/PhysicsListFactory.hpp +++ b/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/PhysicsListFactory.hpp @@ -28,7 +28,7 @@ class PhysicsListFactoryFunction final : public PhysicsListFactory { public: using Function = std::function()>; - PhysicsListFactoryFunction(Function function); + explicit PhysicsListFactoryFunction(Function function); std::unique_ptr factorize() const final; diff --git a/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/SteppingActionList.hpp b/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/SteppingActionList.hpp index 569914007d8..b4a6d7e5d68 100644 --- a/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/SteppingActionList.hpp +++ b/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/SteppingActionList.hpp @@ -28,7 +28,7 @@ class SteppingActionList : public G4UserSteppingAction { std::vector> actions; }; - SteppingActionList(const Config &cfg) : m_cfg(cfg) {} + explicit SteppingActionList(const Config &cfg) : m_cfg(cfg) {} void UserSteppingAction(const G4Step *step) override { for (const auto &action : m_cfg.actions) { diff --git a/Examples/Algorithms/Geant4HepMC/src/EventAction.hpp b/Examples/Algorithms/Geant4HepMC/src/EventAction.hpp index 5c078e21cf8..dcf82b9543f 100644 --- a/Examples/Algorithms/Geant4HepMC/src/EventAction.hpp +++ b/Examples/Algorithms/Geant4HepMC/src/EventAction.hpp @@ -28,7 +28,7 @@ class EventAction final : public G4UserEventAction { static EventAction* instance(); /// Construct the action and ensure singleton usage. - EventAction(std::vector processFilter); + explicit EventAction(std::vector processFilter); ~EventAction() override; /// Interface method for begin of the event diff --git a/Examples/Algorithms/Geant4HepMC/src/SteppingAction.hpp b/Examples/Algorithms/Geant4HepMC/src/SteppingAction.hpp index 51144f3e83c..c19ed0a8560 100644 --- a/Examples/Algorithms/Geant4HepMC/src/SteppingAction.hpp +++ b/Examples/Algorithms/Geant4HepMC/src/SteppingAction.hpp @@ -20,7 +20,7 @@ namespace ActsExamples::Geant4::HepMC3 { /// Collects the particles history. class SteppingAction : public G4UserSteppingAction { public: - SteppingAction(std::vector eventRejectionProcess); + explicit SteppingAction(std::vector eventRejectionProcess); ~SteppingAction() override; /// Static access method to the instance diff --git a/Examples/Algorithms/Generators/ActsExamples/Generators/MultiplicityGenerators.hpp b/Examples/Algorithms/Generators/ActsExamples/Generators/MultiplicityGenerators.hpp index 42290a5e471..32c6d708235 100644 --- a/Examples/Algorithms/Generators/ActsExamples/Generators/MultiplicityGenerators.hpp +++ b/Examples/Algorithms/Generators/ActsExamples/Generators/MultiplicityGenerators.hpp @@ -19,7 +19,7 @@ struct FixedMultiplicityGenerator : public EventGenerator::MultiplicityGenerator { std::size_t n = 1; - FixedMultiplicityGenerator(std::size_t _n) : n{_n} {} + explicit FixedMultiplicityGenerator(std::size_t _n) : n{_n} {} FixedMultiplicityGenerator() = default; std::size_t operator()(RandomEngine& /*rng*/) const override { return n; } @@ -28,7 +28,7 @@ struct FixedMultiplicityGenerator struct PoissonMultiplicityGenerator : public EventGenerator::MultiplicityGenerator { double mean = 1; - PoissonMultiplicityGenerator(double _mean) : mean{_mean} {} + explicit PoissonMultiplicityGenerator(double _mean) : mean{_mean} {} PoissonMultiplicityGenerator() = default; std::size_t operator()(RandomEngine& rng) const override { diff --git a/Examples/Algorithms/Generators/ActsExamples/Generators/ParametricParticleGenerator.cpp b/Examples/Algorithms/Generators/ActsExamples/Generators/ParametricParticleGenerator.cpp index 104c8c0f04d..d6b6bb9eb30 100644 --- a/Examples/Algorithms/Generators/ActsExamples/Generators/ParametricParticleGenerator.cpp +++ b/Examples/Algorithms/Generators/ActsExamples/Generators/ParametricParticleGenerator.cpp @@ -11,7 +11,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/Common.hpp" #include "Acts/Definitions/ParticleData.hpp" -#include "ActsExamples/EventData/SimHit.hpp" +#include "Acts/Utilities/AngleHelpers.hpp" #include "ActsFatras/EventData/Barcode.hpp" #include "ActsFatras/EventData/Particle.hpp" @@ -35,8 +35,8 @@ ParametricParticleGenerator::ParametricParticleGenerator(const Config& cfg) m_cosThetaMax(std::nextafter(std::cos(m_cfg.thetaMax), std::numeric_limits::max())), // in case we force uniform eta generation - m_etaMin(-std::log(std::tan(0.5 * m_cfg.thetaMin))), - m_etaMax(-std::log(std::tan(0.5 * m_cfg.thetaMax))) {} + m_etaMin(Acts::AngleHelpers::etaFromTheta(m_cfg.thetaMin)), + m_etaMax(Acts::AngleHelpers::etaFromTheta(m_cfg.thetaMax)) {} std::pair ParametricParticleGenerator::operator()(RandomEngine& rng) { @@ -64,8 +64,8 @@ ParametricParticleGenerator::operator()(RandomEngine& rng) { SimParticleContainer::sequence_type particles; // create the primary vertex - auto& primaryVertex = - vertices.emplace_back(0, SimVertex::Vector4(0., 0., 0., 0.)); + auto& primaryVertex = vertices.emplace_back( + SimVertexBarcode{0}, SimVertex::Vector4(0., 0., 0., 0.)); // counter will be reused as barcode particle number which must be non-zero. for (std::size_t ip = 1; ip <= m_cfg.numParticles; ++ip) { diff --git a/Examples/Algorithms/Generators/ActsExamples/Generators/ParametricParticleGenerator.hpp b/Examples/Algorithms/Generators/ActsExamples/Generators/ParametricParticleGenerator.hpp index 3bb8ff9d836..a7d9bfe3e08 100644 --- a/Examples/Algorithms/Generators/ActsExamples/Generators/ParametricParticleGenerator.hpp +++ b/Examples/Algorithms/Generators/ActsExamples/Generators/ParametricParticleGenerator.hpp @@ -64,7 +64,7 @@ class ParametricParticleGenerator : public EventGenerator::ParticlesGenerator { std::optional mass; }; - ParametricParticleGenerator(const Config& cfg); + explicit ParametricParticleGenerator(const Config& cfg); /// Generate a single primary vertex with the given number of particles. std::pair operator()( diff --git a/Examples/Algorithms/GeneratorsPythia8/ActsExamples/Generators/Pythia8ProcessGenerator.cpp b/Examples/Algorithms/GeneratorsPythia8/ActsExamples/Generators/Pythia8ProcessGenerator.cpp index e19e785ac5c..ae7c2b85403 100644 --- a/Examples/Algorithms/GeneratorsPythia8/ActsExamples/Generators/Pythia8ProcessGenerator.cpp +++ b/Examples/Algorithms/GeneratorsPythia8/ActsExamples/Generators/Pythia8ProcessGenerator.cpp @@ -121,7 +121,8 @@ Pythia8Generator::operator()(RandomEngine& rng) { } // create the primary vertex - vertices.emplace_back(0, SimVertex::Vector4(0., 0., 0., 0.)); + vertices.emplace_back(SimVertexBarcode{0}, + SimVertex::Vector4(0., 0., 0., 0.)); // convert generated final state particles into internal format for (int ip = 0; ip < m_pythia8->event.size(); ++ip) { @@ -166,7 +167,8 @@ Pythia8Generator::operator()(RandomEngine& rng) { } else { // no matching secondary vertex exists -> create new one particleId.setVertexSecondary(vertices.size()); - auto& vertex = vertices.emplace_back(particleId.vertexId(), pos4); + auto& vertex = vertices.emplace_back( + static_cast(particleId.vertexId()), pos4); vertex.outgoing.insert(particleId); ACTS_VERBOSE("created new secondary vertex " << pos4.transpose()); } diff --git a/Examples/Algorithms/Propagation/include/ActsExamples/Propagation/PropagatorInterface.hpp b/Examples/Algorithms/Propagation/include/ActsExamples/Propagation/PropagatorInterface.hpp index c063a2a1a48..2aa3b2292ac 100644 --- a/Examples/Algorithms/Propagation/include/ActsExamples/Propagation/PropagatorInterface.hpp +++ b/Examples/Algorithms/Propagation/include/ActsExamples/Propagation/PropagatorInterface.hpp @@ -50,7 +50,7 @@ class PropagatorInterface { template class ConcretePropagator : public PropagatorInterface { public: - ConcretePropagator(propagator_t propagator) + explicit ConcretePropagator(propagator_t propagator) : m_propagator{std::move(propagator)} {} Acts::Result execute( diff --git a/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp b/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp index f2a5104e2b0..b1ef900c5b9 100644 --- a/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp +++ b/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp @@ -203,7 +203,7 @@ class BranchStopper { } else if constexpr (std::is_same_v< T, Acts::TrackSelector::EtaBinnedConfig>) { double theta = trackState.parameters()[Acts::eBoundTheta]; - double eta = -std::log(std::tan(0.5 * theta)); + double eta = Acts::AngleHelpers::etaFromTheta(theta); return config.hasCuts(eta) ? &config.getCuts(eta) : nullptr; } }, diff --git a/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithmFunction.cpp b/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithmFunction.cpp index 65e0cf41970..e9f6ae315f3 100644 --- a/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithmFunction.cpp +++ b/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithmFunction.cpp @@ -35,7 +35,7 @@ struct TrackFinderFunctionImpl : public ActsExamples::TrackFindingAlgorithm::TrackFinderFunction { CKF trackFinder; - TrackFinderFunctionImpl(CKF&& f) : trackFinder(std::move(f)) {} + explicit TrackFinderFunctionImpl(CKF&& f) : trackFinder(std::move(f)) {} ActsExamples::TrackFindingAlgorithm::TrackFinderResult operator()( const ActsExamples::TrackParameters& initialParameters, diff --git a/Examples/Algorithms/TrackFindingExaTrkX/src/TrackFindingAlgorithmExaTrkX.cpp b/Examples/Algorithms/TrackFindingExaTrkX/src/TrackFindingAlgorithmExaTrkX.cpp index 05fe35a6ea0..df4b8998540 100644 --- a/Examples/Algorithms/TrackFindingExaTrkX/src/TrackFindingAlgorithmExaTrkX.cpp +++ b/Examples/Algorithms/TrackFindingExaTrkX/src/TrackFindingAlgorithmExaTrkX.cpp @@ -40,14 +40,6 @@ struct LoopHook : public Acts::ExaTrkXHook { } }; -// TODO do we have these function in the repo somewhere? -float theta(float r, float z) { - return std::atan2(r, z); -} -float eta(float r, float z) { - return -std::log(std::tan(0.5 * theta(r, z))); -} - } // namespace ActsExamples::TrackFindingAlgorithmExaTrkX::TrackFindingAlgorithmExaTrkX( @@ -187,7 +179,7 @@ ActsExamples::ProcessCode ActsExamples::TrackFindingAlgorithmExaTrkX::execute( break; case NF::eZ: f[ift] = sp.z(); break; case NF::eX: f[ift] = sp.x(); break; case NF::eY: f[ift] = sp.y(); - break; case NF::eEta: f[ift] = eta(std::hypot(sp.x(), sp.y()), sp.z()); + break; case NF::eEta: f[ift] = Acts::VectorHelpers::eta(Acts::Vector3{sp.x(), sp.y(), sp.z()}); break; case NF::eClusterX: f[ift] = cl1->sizeLoc0; break; case NF::eClusterY: f[ift] = cl1->sizeLoc1; break; case NF::eCellSum: f[ift] = cl1->sumActivations(); @@ -198,8 +190,8 @@ ActsExamples::ProcessCode ActsExamples::TrackFindingAlgorithmExaTrkX::execute( break; case NF::eCluster2Phi: f[ift] = std::atan2(cl2->globalPosition[Acts::ePos1], cl2->globalPosition[Acts::ePos0]); break; case NF::eCluster1Z: f[ift] = cl1->globalPosition[Acts::ePos2]; break; case NF::eCluster2Z: f[ift] = cl2->globalPosition[Acts::ePos2]; - break; case NF::eCluster1Eta: f[ift] = eta(std::hypot(cl1->globalPosition[Acts::ePos0], cl1->globalPosition[Acts::ePos1]), cl1->globalPosition[Acts::ePos2]); - break; case NF::eCluster2Eta: f[ift] = eta(std::hypot(cl2->globalPosition[Acts::ePos0], cl2->globalPosition[Acts::ePos1]), cl2->globalPosition[Acts::ePos2]); + break; case NF::eCluster1Eta: f[ift] = Acts::VectorHelpers::eta(Acts::Vector3{cl1->globalPosition[Acts::ePos0], cl1->globalPosition[Acts::ePos1], cl1->globalPosition[Acts::ePos2]}); + break; case NF::eCluster2Eta: f[ift] = Acts::VectorHelpers::eta(Acts::Vector3{cl2->globalPosition[Acts::ePos0], cl2->globalPosition[Acts::ePos1], cl2->globalPosition[Acts::ePos2]}); } // clang-format on diff --git a/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/TrackParameterSelector.cpp b/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/TrackParameterSelector.cpp index 13b0481e178..18b9cf9090c 100644 --- a/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/TrackParameterSelector.cpp +++ b/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/TrackParameterSelector.cpp @@ -9,6 +9,7 @@ #include "ActsExamples/TruthTracking/TrackParameterSelector.hpp" #include "Acts/Definitions/TrackParametrization.hpp" +#include "Acts/Utilities/AngleHelpers.hpp" #include "ActsExamples/EventData/Track.hpp" #include "ActsExamples/Framework/AlgorithmContext.hpp" @@ -41,7 +42,7 @@ ActsExamples::ProcessCode ActsExamples::TrackParameterSelector::execute( }; auto isValidTrack = [&](const auto& trk) { const auto theta = trk.template get(); - const auto eta = -std::log(std::tan(theta / 2)); + const auto eta = Acts::AngleHelpers::etaFromTheta(theta); // define charge selection return within(trk.transverseMomentum(), m_cfg.ptMin, m_cfg.ptMax) && within(std::abs(eta), m_cfg.absEtaMin, m_cfg.absEtaMax) && diff --git a/Examples/Algorithms/Vertexing/src/AdaptiveMultiVertexFinderAlgorithm.cpp b/Examples/Algorithms/Vertexing/src/AdaptiveMultiVertexFinderAlgorithm.cpp index 9ef72913e37..5330e55c76c 100644 --- a/Examples/Algorithms/Vertexing/src/AdaptiveMultiVertexFinderAlgorithm.cpp +++ b/Examples/Algorithms/Vertexing/src/AdaptiveMultiVertexFinderAlgorithm.cpp @@ -249,7 +249,8 @@ ProcessCode AdaptiveMultiVertexFinderAlgorithm::execute( // Count the number of particles associated with each vertex std::size_t particleCount = 0; for (const auto& particle : truthParticles) { - if (particle.particleId().vertexId() == truthVertex.vertexId()) { + if (static_cast(particle.particleId().vertexId()) == + truthVertex.vertexId()) { ++particleCount; } } diff --git a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp index fec8cfdd052..015b511825f 100644 --- a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp +++ b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp @@ -52,7 +52,8 @@ struct DD4hepDetector { DD4hepDetector() = default; /// @brief Constructor from geometry service /// @param _geometryService the geometry service - DD4hepDetector(std::shared_ptr _geometryService); + explicit DD4hepDetector( + std::shared_ptr _geometryService); /// @brief Default destructor ~DD4hepDetector() = default; diff --git a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp index 6fb17141814..9ce1ca5f2e9 100644 --- a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp +++ b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp @@ -87,7 +87,7 @@ class DD4hepGeometryService { std::make_shared(); }; - DD4hepGeometryService(const Config& cfg); + explicit DD4hepGeometryService(const Config& cfg); DD4hepGeometryService(const DD4hepGeometryService&) = delete; DD4hepGeometryService(DD4hepGeometryService&&) = delete; ~DD4hepGeometryService(); diff --git a/Examples/Detectors/MagneticField/include/ActsExamples/MagneticField/ScalableBField.hpp b/Examples/Detectors/MagneticField/include/ActsExamples/MagneticField/ScalableBField.hpp index bd7f7af38df..5def5740fa4 100644 --- a/Examples/Detectors/MagneticField/include/ActsExamples/MagneticField/ScalableBField.hpp +++ b/Examples/Detectors/MagneticField/include/ActsExamples/MagneticField/ScalableBField.hpp @@ -26,7 +26,7 @@ class ScalableBField final : public Acts::MagneticFieldProvider { Acts::ActsScalar scalor = 1.; /// @brief constructor with context - Cache(const Acts::MagneticFieldContext& mctx) { + explicit Cache(const Acts::MagneticFieldContext& mctx) { scalor = mctx.get().scalor; } }; diff --git a/Examples/Detectors/MuonSpectrometerMockupDetector/include/ActsExamples/MuonSpectrometerMockupDetector/MockupSectorBuilder.hpp b/Examples/Detectors/MuonSpectrometerMockupDetector/include/ActsExamples/MuonSpectrometerMockupDetector/MockupSectorBuilder.hpp index 62ae610224e..5b349bec9af 100644 --- a/Examples/Detectors/MuonSpectrometerMockupDetector/include/ActsExamples/MuonSpectrometerMockupDetector/MockupSectorBuilder.hpp +++ b/Examples/Detectors/MuonSpectrometerMockupDetector/include/ActsExamples/MuonSpectrometerMockupDetector/MockupSectorBuilder.hpp @@ -55,7 +55,7 @@ class MockupSectorBuilder { /// Constructor ///@param config The configuration struct - MockupSectorBuilder(const Config& config); + explicit MockupSectorBuilder(const Config& config); /// Destructor ~MockupSectorBuilder() = default; diff --git a/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/TGeoDetector.hpp b/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/TGeoDetector.hpp index 8982e3dbfb9..0fae0df1c5a 100644 --- a/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/TGeoDetector.hpp +++ b/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/TGeoDetector.hpp @@ -75,7 +75,7 @@ struct TGeoDetector { struct LayerTriplet { LayerTriplet() = default; - LayerTriplet(T value) + explicit LayerTriplet(T value) : negative{value}, central{value}, positive{value} {} LayerTriplet(T _negative, T _central, T _positive) diff --git a/Examples/Framework/CMakeLists.txt b/Examples/Framework/CMakeLists.txt index 692db8f2f15..efe06302800 100644 --- a/Examples/Framework/CMakeLists.txt +++ b/Examples/Framework/CMakeLists.txt @@ -13,6 +13,7 @@ add_library( src/Framework/WhiteBoard.cpp src/Framework/RandomNumbers.cpp src/Framework/Sequencer.cpp + src/Framework/DataHandle.cpp src/Utilities/EventDataTransforms.cpp src/Utilities/Paths.cpp src/Utilities/Options.cpp diff --git a/Examples/Framework/ML/src/NeuralCalibrator.cpp b/Examples/Framework/ML/src/NeuralCalibrator.cpp index 68d24d35468..67c6e76db57 100644 --- a/Examples/Framework/ML/src/NeuralCalibrator.cpp +++ b/Examples/Framework/ML/src/NeuralCalibrator.cpp @@ -176,7 +176,8 @@ void ActsExamples::NeuralCalibrator::calibrate( Acts::visit_measurement(measurement.size(), [&](auto N) -> void { constexpr std::size_t kMeasurementSize = decltype(N)::value; const ConstFixedBoundMeasurementProxy fixedMeasurement = - measurement; + static_cast>( + measurement); Acts::ActsVector calibratedParameters = fixedMeasurement.parameters(); diff --git a/Examples/Framework/include/ActsExamples/EventData/Measurement.hpp b/Examples/Framework/include/ActsExamples/EventData/Measurement.hpp index 12286417c61..a0bf4559509 100644 --- a/Examples/Framework/include/ActsExamples/EventData/Measurement.hpp +++ b/Examples/Framework/include/ActsExamples/EventData/Measurement.hpp @@ -205,7 +205,7 @@ class MeasurementProxyBase { MeasurementProxyBase(Container& container_, Index index_) : m_container(&container_), m_index(index_) {} template - MeasurementProxyBase( + explicit MeasurementProxyBase( const MeasurementProxyBase& other) requires(ReadOnly == OtherReadOnly || ReadOnly) : m_container(&other.container()), m_index(other.index()) {} @@ -358,7 +358,7 @@ class FixedMeasurementProxy assert(container().m_entries.at(index()).size == Size && "Size mismatch"); } template - FixedMeasurementProxy( + explicit FixedMeasurementProxy( const MeasurementProxyBase& other) requires(ReadOnly == OtherReadOnly || ReadOnly) : Base(other) { @@ -450,7 +450,7 @@ class VariableMeasurementProxy VariableMeasurementProxy(Container& container_, Index index_) : Base(container_, index_) {} template - VariableMeasurementProxy( + explicit VariableMeasurementProxy( const MeasurementProxyBase& other) requires(ReadOnly == OtherReadOnly || ReadOnly) : Base(other) {} diff --git a/Examples/Framework/include/ActsExamples/EventData/ScalingCalibrator.hpp b/Examples/Framework/include/ActsExamples/EventData/ScalingCalibrator.hpp index 706ef5291cd..a91b6d840cb 100644 --- a/Examples/Framework/include/ActsExamples/EventData/ScalingCalibrator.hpp +++ b/Examples/Framework/include/ActsExamples/EventData/ScalingCalibrator.hpp @@ -47,7 +47,7 @@ class ScalingCalibrator : public MeasurementCalibrator { } }; - ScalingCalibrator(const std::filesystem::path& path); + explicit ScalingCalibrator(const std::filesystem::path& path); void calibrate( const MeasurementContainer& measurements, diff --git a/Examples/Framework/include/ActsExamples/EventData/SimVertex.hpp b/Examples/Framework/include/ActsExamples/EventData/SimVertex.hpp index d012ac3eb80..0bdfbb4925c 100644 --- a/Examples/Framework/include/ActsExamples/EventData/SimVertex.hpp +++ b/Examples/Framework/include/ActsExamples/EventData/SimVertex.hpp @@ -21,8 +21,9 @@ class SimVertexBarcode { using Value = SimBarcode::Value; constexpr SimVertexBarcode() = default; - constexpr SimVertexBarcode(Value encoded) : m_id(SimBarcode(encoded)) {} - constexpr SimVertexBarcode(SimBarcode vertexId) + explicit constexpr SimVertexBarcode(Value encoded) + : m_id(SimBarcode(encoded)) {} + explicit constexpr SimVertexBarcode(SimBarcode vertexId) : m_id(vertexId.setParticle(0).setSubParticle(0)) { if (vertexId != vertexId.vertexId()) { throw std::invalid_argument("SimVertexBarcode: invalid vertexId"); diff --git a/Examples/Framework/include/ActsExamples/EventData/SpacePointContainer.hpp b/Examples/Framework/include/ActsExamples/EventData/SpacePointContainer.hpp index 14f50ff249a..dbf94345f0a 100644 --- a/Examples/Framework/include/ActsExamples/EventData/SpacePointContainer.hpp +++ b/Examples/Framework/include/ActsExamples/EventData/SpacePointContainer.hpp @@ -31,8 +31,10 @@ class SpacePointContainer { // the memory backend is independetly handled. This is only interfacing it to // ACTS SpacePointContainer(CollectionType&& container) = delete; - SpacePointContainer(CollectionType& container) : m_storage(container) {} - SpacePointContainer(CollectionType* container) : m_storage(container) {} + explicit SpacePointContainer(CollectionType& container) + : m_storage(container) {} + explicit SpacePointContainer(CollectionType* container) + : m_storage(container) {} // No copy constructor or copy operation allowed SpacePointContainer(const SpacePointContainer&) = delete; diff --git a/Examples/Framework/include/ActsExamples/Framework/DataHandle.hpp b/Examples/Framework/include/ActsExamples/Framework/DataHandle.hpp index 2aaa469446c..eebe8cae749 100644 --- a/Examples/Framework/include/ActsExamples/Framework/DataHandle.hpp +++ b/Examples/Framework/include/ActsExamples/Framework/DataHandle.hpp @@ -8,11 +8,9 @@ #pragma once -#include "Acts/Utilities/ThrowAssert.hpp" #include "ActsExamples/Framework/SequenceElement.hpp" #include "ActsExamples/Framework/WhiteBoard.hpp" -#include #include #include @@ -54,14 +52,33 @@ class DataHandleBase { std::optional m_key{}; }; -template -class ReadDataHandle; +class WriteDataHandleBase : public DataHandleBase { + protected: + WriteDataHandleBase(SequenceElement* parent, const std::string& name) + : DataHandleBase{parent, name} {} + + public: + void initialize(const std::string& key); + + bool isCompatible(const DataHandleBase& other) const final; +}; + +class ReadDataHandleBase : public DataHandleBase { + protected: + ReadDataHandleBase(SequenceElement* parent, const std::string& name) + : DataHandleBase{parent, name} {} + + public: + void initialize(const std::string& key); + + bool isCompatible(const DataHandleBase& other) const final; +}; template -class WriteDataHandle final : public DataHandleBase { +class WriteDataHandle final : public WriteDataHandleBase { public: WriteDataHandle(SequenceElement* parent, const std::string& name) - : DataHandleBase{parent, name} { + : WriteDataHandleBase{parent, name} { m_parent->registerWriteHandle(*this); } @@ -77,37 +94,17 @@ class WriteDataHandle final : public DataHandleBase { wb.add(m_key.value(), std::move(value)); } - void initialize(const std::string& key) { - if (key.empty()) { - throw std::invalid_argument{"Write handle '" + fullName() + - "' cannot receive empty key"}; - } - m_key = key; - } - - bool isCompatible(const DataHandleBase& other) const override { - return dynamic_cast*>(&other) != nullptr; - } - const std::type_info& typeInfo() const override { return typeid(T); }; }; template -class ReadDataHandle final : public DataHandleBase { +class ReadDataHandle final : public ReadDataHandleBase { public: ReadDataHandle(SequenceElement* parent, const std::string& name) - : DataHandleBase{parent, name} { + : ReadDataHandleBase{parent, name} { m_parent->registerReadHandle(*this); } - void initialize(const std::string& key) { - if (key.empty()) { - throw std::invalid_argument{"Read handle '" + fullName() + - "' cannot receive empty key"}; - } - m_key = key; - } - const T& operator()(const AlgorithmContext& ctx) const { return (*this)(ctx.eventStore); } @@ -120,10 +117,6 @@ class ReadDataHandle final : public DataHandleBase { return wb.get(m_key.value()); } - bool isCompatible(const DataHandleBase& other) const override { - return dynamic_cast*>(&other) != nullptr; - } - const std::type_info& typeInfo() const override { return typeid(T); }; }; diff --git a/Examples/Framework/include/ActsExamples/Framework/RandomNumbers.hpp b/Examples/Framework/include/ActsExamples/Framework/RandomNumbers.hpp index 5389ae5a8b6..6f9f9abbcd6 100644 --- a/Examples/Framework/include/ActsExamples/Framework/RandomNumbers.hpp +++ b/Examples/Framework/include/ActsExamples/Framework/RandomNumbers.hpp @@ -44,7 +44,7 @@ class RandomNumbers { std::uint64_t seed = 1234567890u; ///< random seed }; - RandomNumbers(const Config& cfg); + explicit RandomNumbers(const Config& cfg); /// Spawn an algorithm-local random number generator. To avoid inefficiencies /// and multiple uses of a given RNG seed, this should only be done once per diff --git a/Examples/Framework/include/ActsExamples/Framework/Sequencer.hpp b/Examples/Framework/include/ActsExamples/Framework/Sequencer.hpp index fa1c53618a0..a8f2ad27950 100644 --- a/Examples/Framework/include/ActsExamples/Framework/Sequencer.hpp +++ b/Examples/Framework/include/ActsExamples/Framework/Sequencer.hpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -89,7 +88,7 @@ class Sequencer { std::size_t fpeStackTraceLength = 8; }; - Sequencer(const Config &cfg); + explicit Sequencer(const Config &cfg); /// Add a context decorator to the set of context decorators. /// diff --git a/Examples/Framework/include/ActsExamples/Framework/WhiteBoard.hpp b/Examples/Framework/include/ActsExamples/Framework/WhiteBoard.hpp index ca5e1904879..777d27fe898 100644 --- a/Examples/Framework/include/ActsExamples/Framework/WhiteBoard.hpp +++ b/Examples/Framework/include/ActsExamples/Framework/WhiteBoard.hpp @@ -76,7 +76,7 @@ class WhiteBoard { struct HolderT : public IHolder { T value; - HolderT(T&& v) : value(std::move(v)) {} + explicit HolderT(T&& v) : value(std::move(v)) {} const std::type_info& type() const override { return typeid(T); } }; diff --git a/Examples/Framework/include/ActsExamples/Utilities/tbbWrap.hpp b/Examples/Framework/include/ActsExamples/Utilities/tbbWrap.hpp index 985cbb2180b..84784c55d31 100644 --- a/Examples/Framework/include/ActsExamples/Utilities/tbbWrap.hpp +++ b/Examples/Framework/include/ActsExamples/Utilities/tbbWrap.hpp @@ -161,7 +161,7 @@ class queuing_mutex { #endif } - scoped_lock(queuing_mutex& ACTS_EXAMPLES_WITH_TBB(m)) { + explicit scoped_lock(queuing_mutex& ACTS_EXAMPLES_WITH_TBB(m)) { #ifndef ACTS_EXAMPLES_NO_TBB if (enableTBB()) { tbb.emplace(*m.tbb); diff --git a/Examples/Framework/include/ActsExamples/Validation/EffPlotTool.hpp b/Examples/Framework/include/ActsExamples/Validation/EffPlotTool.hpp index 534549fbaa4..7ac49098a0a 100644 --- a/Examples/Framework/include/ActsExamples/Validation/EffPlotTool.hpp +++ b/Examples/Framework/include/ActsExamples/Validation/EffPlotTool.hpp @@ -34,6 +34,7 @@ class EffPlotTool { {"Eta", PlotHelpers::Binning("#eta", 40, -4, 4)}, {"Phi", PlotHelpers::Binning("#phi", 100, -3.15, 3.15)}, {"Pt", PlotHelpers::Binning("pT [GeV/c]", 40, 0, 100)}, + {"Z0", PlotHelpers::Binning("z_0 [mm]", 50, -200, 200)}, {"DeltaR", PlotHelpers::Binning("#Delta R", 100, 0, 0.3)}}; }; @@ -42,6 +43,7 @@ class EffPlotTool { TEfficiency* trackEff_vs_pT{nullptr}; ///< Tracking efficiency vs pT TEfficiency* trackEff_vs_eta{nullptr}; ///< Tracking efficiency vs eta TEfficiency* trackEff_vs_phi{nullptr}; ///< Tracking efficiency vs phi + TEfficiency* trackEff_vs_z0{nullptr}; ///< Tracking efficiency vs z0 TEfficiency* trackEff_vs_DeltaR{ nullptr}; ///< Tracking efficiency vs distance to the closest truth ///< particle diff --git a/Examples/Framework/src/EventData/MeasurementCalibration.cpp b/Examples/Framework/src/EventData/MeasurementCalibration.cpp index 963ef57ea24..b4764844770 100644 --- a/Examples/Framework/src/EventData/MeasurementCalibration.cpp +++ b/Examples/Framework/src/EventData/MeasurementCalibration.cpp @@ -38,7 +38,8 @@ void ActsExamples::PassThroughCalibrator::calibrate( Acts::visit_measurement(measurement.size(), [&](auto N) -> void { constexpr std::size_t kMeasurementSize = decltype(N)::value; const ConstFixedBoundMeasurementProxy fixedMeasurement = - measurement; + static_cast>( + measurement); trackState.allocateCalibrated(kMeasurementSize); trackState.calibrated() = fixedMeasurement.parameters(); diff --git a/Examples/Framework/src/EventData/ScalingCalibrator.cpp b/Examples/Framework/src/EventData/ScalingCalibrator.cpp index 12da0078659..ae5c1eca4fe 100644 --- a/Examples/Framework/src/EventData/ScalingCalibrator.cpp +++ b/Examples/Framework/src/EventData/ScalingCalibrator.cpp @@ -165,7 +165,8 @@ void ActsExamples::ScalingCalibrator::calibrate( Acts::visit_measurement(measurement.size(), [&](auto N) -> void { constexpr std::size_t kMeasurementSize = decltype(N)::value; const ConstFixedBoundMeasurementProxy fixedMeasurement = - measurement; + static_cast>( + measurement); Acts::ActsVector calibratedParameters = fixedMeasurement.parameters(); diff --git a/Examples/Framework/src/Framework/DataHandle.cpp b/Examples/Framework/src/Framework/DataHandle.cpp new file mode 100644 index 00000000000..621b6201d0f --- /dev/null +++ b/Examples/Framework/src/Framework/DataHandle.cpp @@ -0,0 +1,39 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 CERN for the benefit of the ACTS project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +#include "ActsExamples/Framework/DataHandle.hpp" + +namespace ActsExamples { + +void WriteDataHandleBase::initialize(const std::string& key) { + if (key.empty()) { + throw std::invalid_argument{"Write handle '" + fullName() + + "' cannot receive empty key"}; + } + m_key = key; +} + +bool WriteDataHandleBase::isCompatible(const DataHandleBase& other) const { + return dynamic_cast(&other) != nullptr && + typeInfo() == other.typeInfo(); +} + +void ReadDataHandleBase::initialize(const std::string& key) { + if (key.empty()) { + throw std::invalid_argument{"Read handle '" + fullName() + + "' cannot receive empty key"}; + } + m_key = key; +} + +bool ReadDataHandleBase::isCompatible(const DataHandleBase& other) const { + return dynamic_cast(&other) != nullptr && + typeInfo() == other.typeInfo(); +} + +} // namespace ActsExamples diff --git a/Examples/Framework/src/Framework/Sequencer.cpp b/Examples/Framework/src/Framework/Sequencer.cpp index f6bb69d44c0..5c1a76b5bd4 100644 --- a/Examples/Framework/src/Framework/Sequencer.cpp +++ b/Examples/Framework/src/Framework/Sequencer.cpp @@ -367,7 +367,7 @@ struct StopWatch { Timepoint start; Duration& store; - StopWatch(Duration& s) : start(Clock::now()), store(s) {} + explicit StopWatch(Duration& s) : start(Clock::now()), store(s) {} ~StopWatch() { store += Clock::now() - start; } }; diff --git a/Examples/Framework/src/Validation/EffPlotTool.cpp b/Examples/Framework/src/Validation/EffPlotTool.cpp index a30c1499796..eb92cfa7b63 100644 --- a/Examples/Framework/src/Validation/EffPlotTool.cpp +++ b/Examples/Framework/src/Validation/EffPlotTool.cpp @@ -27,6 +27,7 @@ void ActsExamples::EffPlotTool::book( PlotHelpers::Binning bEta = m_cfg.varBinning.at("Eta"); PlotHelpers::Binning bPt = m_cfg.varBinning.at("Pt"); PlotHelpers::Binning bDeltaR = m_cfg.varBinning.at("DeltaR"); + PlotHelpers::Binning bZ0 = m_cfg.varBinning.at("Z0"); ACTS_DEBUG("Initialize the histograms for efficiency plots"); // efficiency vs pT effPlotCache.trackEff_vs_pT = PlotHelpers::bookEff( @@ -37,6 +38,9 @@ void ActsExamples::EffPlotTool::book( // efficiency vs phi effPlotCache.trackEff_vs_phi = PlotHelpers::bookEff( "trackeff_vs_phi", "Tracking efficiency;Truth #phi;Efficiency", bPhi); + // efficiency vs z0 + effPlotCache.trackEff_vs_z0 = PlotHelpers::bookEff( + "trackeff_vs_z0", "Tracking efficiency;Truth z_0 [mm];Efficiency", bZ0); // efficiancy vs distance to the closest truth particle effPlotCache.trackEff_vs_DeltaR = PlotHelpers::bookEff( "trackeff_vs_DeltaR", @@ -47,6 +51,7 @@ void ActsExamples::EffPlotTool::clear(EffPlotCache& effPlotCache) const { delete effPlotCache.trackEff_vs_pT; delete effPlotCache.trackEff_vs_eta; delete effPlotCache.trackEff_vs_phi; + delete effPlotCache.trackEff_vs_z0; delete effPlotCache.trackEff_vs_DeltaR; } @@ -56,6 +61,7 @@ void ActsExamples::EffPlotTool::write( effPlotCache.trackEff_vs_pT->Write(); effPlotCache.trackEff_vs_eta->Write(); effPlotCache.trackEff_vs_phi->Write(); + effPlotCache.trackEff_vs_z0->Write(); effPlotCache.trackEff_vs_DeltaR->Write(); } @@ -65,10 +71,12 @@ void ActsExamples::EffPlotTool::fill(EffPlotTool::EffPlotCache& effPlotCache, const auto t_phi = phi(truthParticle.direction()); const auto t_eta = eta(truthParticle.direction()); const auto t_pT = truthParticle.transverseMomentum(); + const auto t_z0 = truthParticle.position().z(); const auto t_deltaR = deltaR; PlotHelpers::fillEff(effPlotCache.trackEff_vs_pT, t_pT, status); PlotHelpers::fillEff(effPlotCache.trackEff_vs_eta, t_eta, status); PlotHelpers::fillEff(effPlotCache.trackEff_vs_phi, t_phi, status); + PlotHelpers::fillEff(effPlotCache.trackEff_vs_z0, t_z0, status); PlotHelpers::fillEff(effPlotCache.trackEff_vs_DeltaR, t_deltaR, status); } diff --git a/Examples/Framework/src/Validation/ResPlotTool.cpp b/Examples/Framework/src/Validation/ResPlotTool.cpp index 14321050144..c1e3e4a6c1b 100644 --- a/Examples/Framework/src/Validation/ResPlotTool.cpp +++ b/Examples/Framework/src/Validation/ResPlotTool.cpp @@ -158,21 +158,27 @@ void ActsExamples::ResPlotTool::fill( auto trackParameter = fittedParamters.parameters(); // get the perigee surface - auto pSurface = &fittedParamters.referenceSurface(); + const auto& pSurface = fittedParamters.referenceSurface(); // get the truth position and momentum ParametersVector truthParameter = ParametersVector::Zero(); // get the truth perigee parameter - auto lpResult = pSurface->globalToLocal(gctx, truthParticle.position(), - truthParticle.direction()); - if (lpResult.ok()) { + auto intersection = + pSurface + .intersect(gctx, truthParticle.position(), truthParticle.direction()) + .closest(); + if (intersection.isValid()) { + auto lpResult = pSurface.globalToLocal(gctx, intersection.position(), + truthParticle.direction()); + assert(lpResult.ok()); + truthParameter[Acts::BoundIndices::eBoundLoc0] = lpResult.value()[Acts::BoundIndices::eBoundLoc0]; truthParameter[Acts::BoundIndices::eBoundLoc1] = lpResult.value()[Acts::BoundIndices::eBoundLoc1]; } else { - ACTS_ERROR("Global to local transformation did not succeed."); + ACTS_ERROR("Cannot get the truth perigee parameter"); } truthParameter[Acts::BoundIndices::eBoundPhi] = phi(truthParticle.direction()); diff --git a/Examples/Framework/src/Validation/TrackClassification.cpp b/Examples/Framework/src/Validation/TrackClassification.cpp index a89f7c2a07a..d1e79d15835 100644 --- a/Examples/Framework/src/Validation/TrackClassification.cpp +++ b/Examples/Framework/src/Validation/TrackClassification.cpp @@ -53,8 +53,9 @@ void ActsExamples::identifyContributingParticles( for (auto hitIndex : protoTrack) { // register all particles that generated this hit - for (auto hitParticle : makeRange(hitParticlesMap.equal_range(hitIndex))) { - increaseHitCount(particleHitCounts, hitParticle.second); + for (const auto& [_, value] : + makeRange(hitParticlesMap.equal_range(hitIndex))) { + increaseHitCount(particleHitCounts, value); } } sortHitCount(particleHitCounts); @@ -79,8 +80,9 @@ void ActsExamples::identifyContributingParticles( IndexSourceLink sl = state.getUncalibratedSourceLink().template get(); auto hitIndex = sl.index(); - for (auto hitParticle : makeRange(hitParticlesMap.equal_range(hitIndex))) { - increaseHitCount(particleHitCounts, hitParticle.second); + for (const auto& [_, value] : + makeRange(hitParticlesMap.equal_range(hitIndex))) { + increaseHitCount(particleHitCounts, value); } return true; }); @@ -102,8 +104,9 @@ void ActsExamples::identifyContributingParticles( IndexSourceLink sl = state.getUncalibratedSourceLink().template get(); auto hitIndex = sl.index(); - for (auto hitParticle : makeRange(hitParticlesMap.equal_range(hitIndex))) { - increaseHitCount(particleHitCounts, hitParticle.second); + for (const auto& [_, value] : + makeRange(hitParticlesMap.equal_range(hitIndex))) { + increaseHitCount(particleHitCounts, value); } } sortHitCount(particleHitCounts); diff --git a/Examples/HelloWorld/HelloLoggerAlgorithm.hpp b/Examples/HelloWorld/HelloLoggerAlgorithm.hpp index 934c0b67f5c..3cafd2c4f55 100644 --- a/Examples/HelloWorld/HelloLoggerAlgorithm.hpp +++ b/Examples/HelloWorld/HelloLoggerAlgorithm.hpp @@ -17,7 +17,7 @@ namespace ActsExamples { /// A simple algorithm that just prints hello world. class HelloLoggerAlgorithm : public ActsExamples::IAlgorithm { public: - HelloLoggerAlgorithm(Acts::Logging::Level level); + explicit HelloLoggerAlgorithm(Acts::Logging::Level level); // Log a few messages. ActsExamples::ProcessCode execute(const AlgorithmContext& ctx) const override; diff --git a/Examples/Io/Csv/include/ActsExamples/Io/Csv/CsvInputOutput.hpp b/Examples/Io/Csv/include/ActsExamples/Io/Csv/CsvInputOutput.hpp index 7f4e7b894c3..e141f470988 100644 --- a/Examples/Io/Csv/include/ActsExamples/Io/Csv/CsvInputOutput.hpp +++ b/Examples/Io/Csv/include/ActsExamples/Io/Csv/CsvInputOutput.hpp @@ -236,7 +236,7 @@ class DsvReader { /// Open a file at the given path. /// /// \param path Path to the input file - DsvReader(const std::string& path); + explicit DsvReader(const std::string& path); /// Read the next line from the file. /// diff --git a/Examples/Io/Performance/CMakeLists.txt b/Examples/Io/Performance/CMakeLists.txt deleted file mode 100644 index b41bf76ea07..00000000000 --- a/Examples/Io/Performance/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -add_library( - ActsExamplesIoPerformance - SHARED - ActsExamples/Io/Performance/CKFPerformanceWriter.cpp - ActsExamples/Io/Performance/SeedingPerformanceWriter.cpp - ActsExamples/Io/Performance/TrackFinderPerformanceWriter.cpp - ActsExamples/Io/Performance/TrackFitterPerformanceWriter.cpp - ActsExamples/Io/Performance/VertexPerformanceWriter.cpp -) -target_include_directories( - ActsExamplesIoPerformance - PUBLIC $ -) -target_link_libraries( - ActsExamplesIoPerformance - PUBLIC ActsExamplesFramework - PRIVATE ActsCore ROOT::Core ROOT::Tree -) - -install( - TARGETS ActsExamplesIoPerformance - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} -) diff --git a/Examples/Io/Root/CMakeLists.txt b/Examples/Io/Root/CMakeLists.txt index f384c291bc1..353d68debab 100644 --- a/Examples/Io/Root/CMakeLists.txt +++ b/Examples/Io/Root/CMakeLists.txt @@ -25,11 +25,11 @@ add_library( src/RootAthenaDumpReader.cpp src/RootNuclearInteractionParametersWriter.cpp src/detail/NuclearInteractionParametrisation.cpp - src/CKFPerformanceWriter.cpp - src/SeedingPerformanceWriter.cpp src/TrackFinderPerformanceWriter.cpp + src/SeedingPerformanceWriter.cpp + src/TrackFinderNTupleWriter.cpp src/TrackFitterPerformanceWriter.cpp - src/VertexPerformanceWriter.cpp + src/VertexNTupleWriter.cpp ) target_include_directories( ActsExamplesIoRoot diff --git a/Examples/Io/Root/include/ActsExamples/Io/Root/CKFPerformanceWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/CKFPerformanceWriter.hpp deleted file mode 100644 index 0d9e4c96feb..00000000000 --- a/Examples/Io/Root/include/ActsExamples/Io/Root/CKFPerformanceWriter.hpp +++ /dev/null @@ -1,126 +0,0 @@ -// This file is part of the ACTS project. -// -// Copyright (C) 2016 CERN for the benefit of the ACTS project -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -#pragma once - -#include "Acts/Utilities/Logger.hpp" -#include "ActsExamples/EventData/Track.hpp" -#include "ActsExamples/EventData/TruthMatching.hpp" -#include "ActsExamples/Framework/DataHandle.hpp" -#include "ActsExamples/Framework/ProcessCode.hpp" -#include "ActsExamples/Framework/WriterT.hpp" -#include "ActsExamples/Validation/DuplicationPlotTool.hpp" -#include "ActsExamples/Validation/EffPlotTool.hpp" -#include "ActsExamples/Validation/FakeRatePlotTool.hpp" -#include "ActsExamples/Validation/TrackSummaryPlotTool.hpp" - -#include -#include -#include - -class TFile; -class TTree; -namespace ActsFatras { -class Barcode; -} // namespace ActsFatras - -namespace ActsExamples { -struct AlgorithmContext; - -/// Write out the performance of CombinatorialKalmanFilter (CKF), e.g. track -/// efficiency, fake rate etc. -/// -/// @TODO: add duplication plots -/// -/// A common file can be provided for the writer to attach his TTree, this is -/// done by setting the Config::rootFile pointer to an existing file. -/// -/// Safe to use from multiple writer threads - uses a std::mutex lock. -class CKFPerformanceWriter final : public WriterT { - public: - struct Config { - /// Input (found) tracks collection. - std::string inputTracks; - /// Input particles collection. - std::string inputParticles; - /// Input track-particle matching. - std::string inputTrackParticleMatching; - /// Input track-particle matching. - std::string inputParticleTrackMatching; - /// Output filename. - std::string filePath = "performance_ckf.root"; - /// Output filemode - std::string fileMode = "RECREATE"; - - /// Plot tool configurations. - EffPlotTool::Config effPlotToolConfig; - FakeRatePlotTool::Config fakeRatePlotToolConfig; - DuplicationPlotTool::Config duplicationPlotToolConfig; - TrackSummaryPlotTool::Config trackSummaryPlotToolConfig; - - /// Write additional matching details to a TTree - bool writeMatchingDetails = false; - }; - - /// Construct from configuration and log level. - CKFPerformanceWriter(Config cfg, Acts::Logging::Level lvl); - ~CKFPerformanceWriter() override; - - /// Finalize plots. - ProcessCode finalize() override; - - /// Get readonly access to the config parameters - const Config& config() const { return m_cfg; } - - private: - ProcessCode writeT(const AlgorithmContext& ctx, - const ConstTrackContainer& tracks) override; - - Config m_cfg; - /// Mutex used to protect multi-threaded writes. - std::mutex m_writeMutex; - TFile* m_outputFile{nullptr}; - /// Plot tool for efficiency - EffPlotTool m_effPlotTool; - EffPlotTool::EffPlotCache m_effPlotCache; - /// Plot tool for fake rate - FakeRatePlotTool m_fakeRatePlotTool; - FakeRatePlotTool::FakeRatePlotCache m_fakeRatePlotCache{}; - /// Plot tool for duplication rate - DuplicationPlotTool m_duplicationPlotTool; - DuplicationPlotTool::DuplicationPlotCache m_duplicationPlotCache{}; - /// Plot tool for track hit info - TrackSummaryPlotTool m_trackSummaryPlotTool; - TrackSummaryPlotTool::TrackSummaryPlotCache m_trackSummaryPlotCache{}; - - /// For optional output of the matching details - TTree* m_matchingTree{nullptr}; - - /// Variables to fill in the TTree - std::uint32_t m_treeEventNr{}; - std::uint64_t m_treeParticleId{}; - bool m_treeIsMatched{}; - - // Adding numbers for efficiency, fake, duplicate calculations - std::size_t m_nTotalTracks = 0; - std::size_t m_nTotalMatchedTracks = 0; - std::size_t m_nTotalFakeTracks = 0; - std::size_t m_nTotalDuplicateTracks = 0; - std::size_t m_nTotalParticles = 0; - std::size_t m_nTotalMatchedParticles = 0; - std::size_t m_nTotalDuplicateParticles = 0; - std::size_t m_nTotalFakeParticles = 0; - - ReadDataHandle m_inputParticles{this, "InputParticles"}; - ReadDataHandle m_inputTrackParticleMatching{ - this, "InputTrackParticleMatching"}; - ReadDataHandle m_inputParticleTrackMatching{ - this, "InputParticleTrackMatching"}; -}; - -} // namespace ActsExamples diff --git a/Examples/Io/Root/include/ActsExamples/Io/Root/TrackFinderNTupleWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/TrackFinderNTupleWriter.hpp new file mode 100644 index 00000000000..799471be784 --- /dev/null +++ b/Examples/Io/Root/include/ActsExamples/Io/Root/TrackFinderNTupleWriter.hpp @@ -0,0 +1,69 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 CERN for the benefit of the ACTS project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +#pragma once + +#include "Acts/Utilities/Logger.hpp" +#include "ActsExamples/EventData/ProtoTrack.hpp" +#include "ActsExamples/EventData/TruthMatching.hpp" +#include "ActsExamples/Framework/ProcessCode.hpp" +#include "ActsExamples/Framework/WriterT.hpp" + +#include +#include + +namespace ActsExamples { +struct AlgorithmContext; + +/// Write track finder performance measures. +/// +/// Only considers the track finding itself, i.e. grouping of hits into tracks, +/// and computes relevant per-track and per-particles statistics. +class TrackFinderNTupleWriter final : public WriterT { + public: + struct Config { + /// Input reconstructed track collection. + std::string inputTracks; + /// Input particles collection. + std::string inputParticles; + /// Input hit-particles map collection. + std::string inputMeasurementParticlesMap; + /// Input proto track-particle matching. + std::string inputTrackParticleMatching; + /// Output filename. + std::string filePath = "performance_track_finder.root"; + /// Output file mode + std::string fileMode = "RECREATE"; + /// Output tree name for the tracks + std::string treeNameTracks = "track_finder_tracks"; + /// Output tree name for the particles + std::string treeNameParticles = "track_finder_particles"; + }; + + /// Constructor + /// @param config the configuration + /// @param level The log level + TrackFinderNTupleWriter(Config config, Acts::Logging::Level level); + + ~TrackFinderNTupleWriter() override; + + ProcessCode finalize() override; + + /// Get readonly access to the config parameters + const Config& config() const; + + private: + ProcessCode writeT(const AlgorithmContext& ctx, + const ConstTrackContainer& tracks) override; + + struct Impl; + + std::unique_ptr m_impl; +}; + +} // namespace ActsExamples diff --git a/Examples/Io/Root/include/ActsExamples/Io/Root/TrackFinderPerformanceWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/TrackFinderPerformanceWriter.hpp index 287cf361999..b3b6c36436c 100644 --- a/Examples/Io/Root/include/ActsExamples/Io/Root/TrackFinderPerformanceWriter.hpp +++ b/Examples/Io/Root/include/ActsExamples/Io/Root/TrackFinderPerformanceWriter.hpp @@ -9,61 +9,118 @@ #pragma once #include "Acts/Utilities/Logger.hpp" -#include "ActsExamples/EventData/ProtoTrack.hpp" +#include "ActsExamples/EventData/Track.hpp" #include "ActsExamples/EventData/TruthMatching.hpp" +#include "ActsExamples/Framework/DataHandle.hpp" #include "ActsExamples/Framework/ProcessCode.hpp" #include "ActsExamples/Framework/WriterT.hpp" +#include "ActsExamples/Validation/DuplicationPlotTool.hpp" +#include "ActsExamples/Validation/EffPlotTool.hpp" +#include "ActsExamples/Validation/FakeRatePlotTool.hpp" +#include "ActsExamples/Validation/TrackSummaryPlotTool.hpp" -#include +#include +#include #include +class TFile; +class TTree; +namespace ActsFatras { +class Barcode; +} // namespace ActsFatras + namespace ActsExamples { struct AlgorithmContext; -/// Write track finder performance measures. +/// Write out the performance of CombinatorialKalmanFilter (CKF), e.g. track +/// efficiency, fake rate etc. +/// +/// @TODO: add duplication plots +/// +/// A common file can be provided for the writer to attach his TTree, this is +/// done by setting the Config::rootFile pointer to an existing file. /// -/// Only considers the track finding itself, i.e. grouping of hits into tracks, -/// and computes relevant per-track and per-particles statistics. -class TrackFinderPerformanceWriter final : public WriterT { +/// Safe to use from multiple writer threads - uses a std::mutex lock. +class TrackFinderPerformanceWriter final : public WriterT { public: struct Config { - /// Input reconstructed track collection. + /// Input (found) tracks collection. std::string inputTracks; /// Input particles collection. std::string inputParticles; - /// Input hit-particles map collection. - std::string inputMeasurementParticlesMap; - /// Input proto track-particle matching. + /// Input track-particle matching. std::string inputTrackParticleMatching; + /// Input track-particle matching. + std::string inputParticleTrackMatching; /// Output filename. - std::string filePath = "performance_track_finder.root"; - /// Output file mode + std::string filePath = "performance_ckf.root"; + /// Output filemode std::string fileMode = "RECREATE"; - /// Output tree name for the tracks - std::string treeNameTracks = "track_finder_tracks"; - /// Output tree name for the particles - std::string treeNameParticles = "track_finder_particles"; - }; - /// Constructor - /// @param config the configuration - /// @param level The log level - TrackFinderPerformanceWriter(Config config, Acts::Logging::Level level); + /// Plot tool configurations. + EffPlotTool::Config effPlotToolConfig; + FakeRatePlotTool::Config fakeRatePlotToolConfig; + DuplicationPlotTool::Config duplicationPlotToolConfig; + TrackSummaryPlotTool::Config trackSummaryPlotToolConfig; + /// Write additional matching details to a TTree + bool writeMatchingDetails = false; + }; + + /// Construct from configuration and log level. + TrackFinderPerformanceWriter(Config cfg, Acts::Logging::Level lvl); ~TrackFinderPerformanceWriter() override; + /// Finalize plots. ProcessCode finalize() override; /// Get readonly access to the config parameters - const Config& config() const; + const Config& config() const { return m_cfg; } private: ProcessCode writeT(const AlgorithmContext& ctx, - const TrackContainer& tracks) override; + const ConstTrackContainer& tracks) override; + + Config m_cfg; + /// Mutex used to protect multi-threaded writes. + std::mutex m_writeMutex; + TFile* m_outputFile{nullptr}; + /// Plot tool for efficiency + EffPlotTool m_effPlotTool; + EffPlotTool::EffPlotCache m_effPlotCache; + /// Plot tool for fake rate + FakeRatePlotTool m_fakeRatePlotTool; + FakeRatePlotTool::FakeRatePlotCache m_fakeRatePlotCache{}; + /// Plot tool for duplication rate + DuplicationPlotTool m_duplicationPlotTool; + DuplicationPlotTool::DuplicationPlotCache m_duplicationPlotCache{}; + /// Plot tool for track hit info + TrackSummaryPlotTool m_trackSummaryPlotTool; + TrackSummaryPlotTool::TrackSummaryPlotCache m_trackSummaryPlotCache{}; + + /// For optional output of the matching details + TTree* m_matchingTree{nullptr}; + + /// Variables to fill in the TTree + std::uint32_t m_treeEventNr{}; + std::uint64_t m_treeParticleId{}; + bool m_treeIsMatched{}; - struct Impl; + // Adding numbers for efficiency, fake, duplicate calculations + std::size_t m_nTotalTracks = 0; + std::size_t m_nTotalMatchedTracks = 0; + std::size_t m_nTotalFakeTracks = 0; + std::size_t m_nTotalDuplicateTracks = 0; + std::size_t m_nTotalParticles = 0; + std::size_t m_nTotalMatchedParticles = 0; + std::size_t m_nTotalDuplicateParticles = 0; + std::size_t m_nTotalFakeParticles = 0; - std::unique_ptr m_impl; + ReadDataHandle m_inputParticles{this, "InputParticles"}; + ReadDataHandle m_inputTrackParticleMatching{ + this, "InputTrackParticleMatching"}; + ReadDataHandle m_inputParticleTrackMatching{ + this, "InputParticleTrackMatching"}; }; } // namespace ActsExamples diff --git a/Examples/Io/Root/include/ActsExamples/Io/Root/VertexPerformanceWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/VertexNTupleWriter.hpp similarity index 97% rename from Examples/Io/Root/include/ActsExamples/Io/Root/VertexPerformanceWriter.hpp rename to Examples/Io/Root/include/ActsExamples/Io/Root/VertexNTupleWriter.hpp index 8043dd1cac0..514dbfc8850 100644 --- a/Examples/Io/Root/include/ActsExamples/Io/Root/VertexPerformanceWriter.hpp +++ b/Examples/Io/Root/include/ActsExamples/Io/Root/VertexNTupleWriter.hpp @@ -38,15 +38,14 @@ enum class RecoVertexClassification { Split, }; -/// @class VertexPerformanceWriter +/// @class VertexNTupleWriter /// /// Writes out the number of reconstructed primary vertices along with /// the number of primary vertices in detector acceptance as well as /// reconstructable primary vertices after track fitting. /// Additionally it matches the reco vertices to their truth vertices /// and write out the difference in x,y and z position. -class VertexPerformanceWriter final - : public WriterT> { +class VertexNTupleWriter final : public WriterT> { public: struct Config { /// Input vertex collection. @@ -90,9 +89,9 @@ class VertexPerformanceWriter final /// /// @param config Configuration struct /// @param level Message level declaration - VertexPerformanceWriter(const Config& config, Acts::Logging::Level level); + VertexNTupleWriter(const Config& config, Acts::Logging::Level level); - ~VertexPerformanceWriter() override; + ~VertexNTupleWriter() override; /// End-of-run hook ProcessCode finalize() override; diff --git a/Examples/Io/Root/include/ActsExamples/Io/Root/detail/NuclearInteractionParametrisation.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/detail/NuclearInteractionParametrisation.hpp index b0a6174a0d6..e00fb79c63a 100644 --- a/Examples/Io/Root/include/ActsExamples/Io/Root/detail/NuclearInteractionParametrisation.hpp +++ b/Examples/Io/Root/include/ActsExamples/Io/Root/detail/NuclearInteractionParametrisation.hpp @@ -34,7 +34,7 @@ struct EventFraction { /// /// @param [in] event Tuple containing the initial particle, the particle /// before the interaction and all final state particles after the interaction - EventFraction(const ActsExamples::ExtractedSimulationProcess& event) + explicit EventFraction(const ActsExamples::ExtractedSimulationProcess& event) : initialParticle(event.initial), interactingParticle(event.before), finalParticles(event.after) {} diff --git a/Examples/Io/Root/src/CKFPerformanceWriter.cpp b/Examples/Io/Root/src/CKFPerformanceWriter.cpp deleted file mode 100644 index 7b5b5aaf291..00000000000 --- a/Examples/Io/Root/src/CKFPerformanceWriter.cpp +++ /dev/null @@ -1,296 +0,0 @@ -// This file is part of the ACTS project. -// -// Copyright (C) 2016 CERN for the benefit of the ACTS project -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -#include "ActsExamples/Io/Root/CKFPerformanceWriter.hpp" - -#include "Acts/EventData/TrackParameters.hpp" -#include "Acts/Utilities/VectorHelpers.hpp" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -using Acts::VectorHelpers::eta; -using Acts::VectorHelpers::phi; - -namespace ActsExamples { - -CKFPerformanceWriter::CKFPerformanceWriter(CKFPerformanceWriter::Config cfg, - Acts::Logging::Level lvl) - : WriterT(cfg.inputTracks, "CKFPerformanceWriter", lvl), - m_cfg(std::move(cfg)), - m_effPlotTool(m_cfg.effPlotToolConfig, lvl), - m_fakeRatePlotTool(m_cfg.fakeRatePlotToolConfig, lvl), - m_duplicationPlotTool(m_cfg.duplicationPlotToolConfig, lvl), - m_trackSummaryPlotTool(m_cfg.trackSummaryPlotToolConfig, lvl) { - // tracks collection name is already checked by base ctor - if (m_cfg.inputParticles.empty()) { - throw std::invalid_argument("Missing particles input collection"); - } - if (m_cfg.inputTrackParticleMatching.empty()) { - throw std::invalid_argument("Missing input track particles matching"); - } - if (m_cfg.inputParticleTrackMatching.empty()) { - throw std::invalid_argument("Missing input particle track matching"); - } - if (m_cfg.filePath.empty()) { - throw std::invalid_argument("Missing output filename"); - } - - m_inputParticles.initialize(m_cfg.inputParticles); - m_inputTrackParticleMatching.initialize(m_cfg.inputTrackParticleMatching); - m_inputParticleTrackMatching.initialize(m_cfg.inputParticleTrackMatching); - - // the output file can not be given externally since TFile accesses to the - // same file from multiple threads are unsafe. - // must always be opened internally - m_outputFile = TFile::Open(m_cfg.filePath.c_str(), m_cfg.fileMode.c_str()); - if (m_outputFile == nullptr) { - throw std::invalid_argument("Could not open '" + m_cfg.filePath + "'"); - } - - if (m_cfg.writeMatchingDetails) { - m_matchingTree = new TTree("matchingdetails", "matchingdetails"); - - m_matchingTree->Branch("event_nr", &m_treeEventNr); - m_matchingTree->Branch("particle_id", &m_treeParticleId); - m_matchingTree->Branch("matched", &m_treeIsMatched); - } - - // initialize the plot tools - m_effPlotTool.book(m_effPlotCache); - m_fakeRatePlotTool.book(m_fakeRatePlotCache); - m_duplicationPlotTool.book(m_duplicationPlotCache); - m_trackSummaryPlotTool.book(m_trackSummaryPlotCache); -} - -CKFPerformanceWriter::~CKFPerformanceWriter() { - m_effPlotTool.clear(m_effPlotCache); - m_fakeRatePlotTool.clear(m_fakeRatePlotCache); - m_duplicationPlotTool.clear(m_duplicationPlotCache); - m_trackSummaryPlotTool.clear(m_trackSummaryPlotCache); - if (m_outputFile != nullptr) { - m_outputFile->Close(); - } -} - -ProcessCode CKFPerformanceWriter::finalize() { - float eff_tracks = static_cast(m_nTotalMatchedTracks) / m_nTotalTracks; - float fakeRate_tracks = - static_cast(m_nTotalFakeTracks) / m_nTotalTracks; - float duplicationRate_tracks = - static_cast(m_nTotalDuplicateTracks) / m_nTotalTracks; - - float eff_particle = - static_cast(m_nTotalMatchedParticles) / m_nTotalParticles; - float fakeRate_particle = - static_cast(m_nTotalFakeParticles) / m_nTotalParticles; - float duplicationRate_particle = - static_cast(m_nTotalDuplicateParticles) / m_nTotalParticles; - - ACTS_DEBUG("nTotalTracks = " << m_nTotalTracks); - ACTS_DEBUG("nTotalMatchedTracks = " << m_nTotalMatchedTracks); - ACTS_DEBUG("nTotalDuplicateTracks = " << m_nTotalDuplicateTracks); - ACTS_DEBUG("nTotalFakeTracks = " << m_nTotalFakeTracks); - - ACTS_INFO( - "Efficiency with tracks (nMatchedTracks/ nAllTracks) = " << eff_tracks); - ACTS_INFO( - "Fake rate with tracks (nFakeTracks/nAllTracks) = " << fakeRate_tracks); - ACTS_INFO("Duplicate rate with tracks (nDuplicateTracks/nAllTracks) = " - << duplicationRate_tracks); - ACTS_INFO("Efficiency with particles (nMatchedParticles/nTrueParticles) = " - << eff_particle); - ACTS_INFO("Fake rate with particles (nFakeParticles/nTrueParticles) = " - << fakeRate_particle); - ACTS_INFO( - "Duplicate rate with particles (nDuplicateParticles/nTrueParticles) = " - << duplicationRate_particle); - - auto writeFloat = [&](float f, const char* name) { - TVectorF v(1); - v[0] = f; - m_outputFile->WriteObject(&v, name); - }; - - if (m_outputFile != nullptr) { - m_outputFile->cd(); - m_effPlotTool.write(m_effPlotCache); - m_fakeRatePlotTool.write(m_fakeRatePlotCache); - m_duplicationPlotTool.write(m_duplicationPlotCache); - m_trackSummaryPlotTool.write(m_trackSummaryPlotCache); - writeFloat(eff_tracks, "eff_tracks"); - writeFloat(fakeRate_tracks, "fakerate_tracks"); - writeFloat(duplicationRate_tracks, "duplicaterate_tracks"); - writeFloat(eff_particle, "eff_particles"); - writeFloat(fakeRate_particle, "fakerate_particles"); - writeFloat(duplicationRate_particle, "duplicaterate_particles"); - - if (m_matchingTree != nullptr) { - m_matchingTree->Write(); - } - - ACTS_INFO("Wrote performance plots to '" << m_outputFile->GetPath() << "'"); - } - return ProcessCode::SUCCESS; -} - -ProcessCode CKFPerformanceWriter::writeT(const AlgorithmContext& ctx, - const ConstTrackContainer& tracks) { - // The number of majority particle hits and fitted track parameters - using Acts::VectorHelpers::perp; - - // Read truth input collections - const auto& particles = m_inputParticles(ctx); - const auto& trackParticleMatching = m_inputTrackParticleMatching(ctx); - const auto& particleTrackMatching = m_inputParticleTrackMatching(ctx); - - // Exclusive access to the tree while writing - std::lock_guard lock(m_writeMutex); - - // Vector of input features for neural network classification - std::vector inputFeatures(3); - - for (const auto& track : tracks) { - // Counting number of total trajectories - m_nTotalTracks++; - - // Check if the reco track has fitted track parameters - if (!track.hasReferenceSurface()) { - ACTS_WARNING("No fitted track parameters for track, index = " - << track.index() << " tip index = " << track.tipIndex()); - continue; - } - - Acts::BoundTrackParameters fittedParameters = - track.createParametersAtReference(); - - // Fill the trajectory summary info - m_trackSummaryPlotTool.fill(m_trackSummaryPlotCache, fittedParameters, - track.nTrackStates(), track.nMeasurements(), - track.nOutliers(), track.nHoles(), - track.nSharedHits()); - - // Get the truth matching information - auto imatched = trackParticleMatching.find(track.index()); - if (imatched == trackParticleMatching.end()) { - ACTS_DEBUG("No truth matching information for this track, index = " - << track.index() << " tip index = " << track.tipIndex()); - continue; - } - - const auto& particleMatch = imatched->second; - - if (particleMatch.classification == TrackMatchClassification::Fake) { - m_nTotalFakeTracks++; - } - - if (particleMatch.classification == TrackMatchClassification::Duplicate) { - m_nTotalDuplicateTracks++; - } - - // Fill fake rate plots - m_fakeRatePlotTool.fill( - m_fakeRatePlotCache, fittedParameters, - particleMatch.classification == TrackMatchClassification::Fake); - - // Fill the duplication rate - m_duplicationPlotTool.fill( - m_duplicationPlotCache, fittedParameters, - particleMatch.classification == TrackMatchClassification::Duplicate); - } - - // Loop over all truth particles for efficiency plots and reco details. - for (const auto& particle : particles) { - auto particleId = particle.particleId(); - - // Investigate the truth-matched tracks - std::size_t nMatchedTracks = 0; - std::size_t nFakeTracks = 0; - bool isReconstructed = false; - if (auto imatched = particleTrackMatching.find(particleId); - imatched != particleTrackMatching.end()) { - nMatchedTracks = (imatched->second.track.has_value() ? 1 : 0) + - imatched->second.duplicates; - - // Add number for total matched tracks here - m_nTotalMatchedTracks += nMatchedTracks; - m_nTotalMatchedParticles += 1; - - // Check if the particle has more than one matched track for the duplicate - // rate - if (nMatchedTracks > 1) { - m_nTotalDuplicateParticles += 1; - } - isReconstructed = imatched->second.track.has_value(); - - nFakeTracks = imatched->second.fakes; - if (nFakeTracks > 0) { - m_nTotalFakeParticles += 1; - } - } - - // Loop over all the other truth particle and find the distance to the - // closest one - double minDeltaR = -1; - for (const auto& closeParticle : particles) { - if (closeParticle.particleId() == particleId) { - continue; - } - double p_phi = phi(particle.direction()); - double p_eta = eta(particle.direction()); - double c_phi = phi(closeParticle.direction()); - double c_eta = eta(closeParticle.direction()); - double distance = sqrt(pow(p_phi - c_phi, 2) + pow(p_eta - c_eta, 2)); - if (minDeltaR == -1 || distance < minDeltaR) { - minDeltaR = distance; - } - } - - // Fill efficiency plots - m_effPlotTool.fill(m_effPlotCache, particle, minDeltaR, isReconstructed); - // Fill number of duplicated tracks for this particle - m_duplicationPlotTool.fill(m_duplicationPlotCache, particle, - nMatchedTracks - 1); - - // Fill number of reconstructed/truth-matched/fake tracks for this particle - m_fakeRatePlotTool.fill(m_fakeRatePlotCache, particle, nMatchedTracks, - nFakeTracks); - - m_nTotalParticles += 1; - } - - // Write additional stuff to TTree - if (m_cfg.writeMatchingDetails && m_matchingTree != nullptr) { - for (const auto& particle : particles) { - auto particleId = particle.particleId(); - - m_treeEventNr = ctx.eventNumber; - m_treeParticleId = particleId.value(); - - m_treeIsMatched = false; - if (auto imatched = particleTrackMatching.find(particleId); - imatched != particleTrackMatching.end()) { - m_treeIsMatched = imatched->second.track.has_value(); - } - - m_matchingTree->Fill(); - } - } - - return ProcessCode::SUCCESS; -} - -} // namespace ActsExamples diff --git a/Examples/Io/Root/src/RootNuclearInteractionParametersWriter.cpp b/Examples/Io/Root/src/RootNuclearInteractionParametersWriter.cpp index e0d635443e5..995f7bdf57d 100644 --- a/Examples/Io/Root/src/RootNuclearInteractionParametersWriter.cpp +++ b/Examples/Io/Root/src/RootNuclearInteractionParametersWriter.cpp @@ -227,7 +227,7 @@ std::pair, std::vector> buildMap( } /// @brief This method builds decomposed cumulative probability distributions -/// out of a vector of proability distributions +/// out of a vector of probability distributions /// /// @param [in] histos Vector of probability distributions /// @@ -410,27 +410,27 @@ ActsExamples::RootNuclearInteractionParametersWriter::finalize() { gDirectory->WriteObject(&mapNIprob.second, "NuclearInteractionBinContents"); ACTS_DEBUG("Nuclear interaction probability parametrised"); - ACTS_DEBUG("Starting calulcation of probability of interaction type"); - // Write the interaction type proability + ACTS_DEBUG("Starting calculation of probability of interaction type"); + // Write the interaction type probability const auto softProbability = Parametrisation::softProbability(m_eventFractionCollection); gDirectory->WriteObject(&softProbability, "SoftInteraction"); - ACTS_DEBUG("Calulcation of probability of interaction type finished"); + ACTS_DEBUG("Calculation of probability of interaction type finished"); // Write the PDG id production distribution ACTS_DEBUG( - "Starting calulcation of transition probabilities between PDG IDs"); + "Starting calculation of transition probabilities between PDG IDs"); const auto pdgIdMap = Parametrisation::cumulativePDGprobability(m_eventFractionCollection); std::vector branchingPdgIds; std::vector targetPdgIds; std::vector targetPdgProbability; - for (const auto& targetPdgIdMap : pdgIdMap) { - for (const auto& producedPdgIdMap : targetPdgIdMap.second) { - branchingPdgIds.push_back(targetPdgIdMap.first); - targetPdgIds.push_back(producedPdgIdMap.first); - targetPdgProbability.push_back(producedPdgIdMap.second); + for (const auto& [targetKey, targetValue] : pdgIdMap) { + for (const auto& [producedKey, producedValue] : targetValue) { + branchingPdgIds.push_back(targetKey); + targetPdgIds.push_back(producedKey); + targetPdgProbability.push_back(producedValue); } } @@ -438,7 +438,7 @@ ActsExamples::RootNuclearInteractionParametersWriter::finalize() { gDirectory->WriteObject(&targetPdgIds, "TargetPdgIds"); gDirectory->WriteObject(&targetPdgProbability, "TargetPdgProbability"); ACTS_DEBUG( - "Calulcation of transition probabilities between PDG IDs finished"); + "Calculation of transition probabilities between PDG IDs finished"); // Write the multiplicity and kinematics distribution ACTS_DEBUG("Starting parametrisation of multiplicity probabilities"); diff --git a/Examples/Io/Root/src/RootVertexReader.cpp b/Examples/Io/Root/src/RootVertexReader.cpp index 93a986a6c04..336e0364f9b 100644 --- a/Examples/Io/Root/src/RootVertexReader.cpp +++ b/Examples/Io/Root/src/RootVertexReader.cpp @@ -114,7 +114,7 @@ ProcessCode RootVertexReader::read(const AlgorithmContext& context) { for (unsigned int i = 0; i < nVertices; i++) { SimVertex v; - v.id = (*m_vertexId)[i]; + v.id = SimVertexBarcode{(*m_vertexId)[i]}; v.process = static_cast((*m_process)[i]); v.position4 = Acts::Vector4((*m_vx)[i] * Acts::UnitConstants::mm, (*m_vy)[i] * Acts::UnitConstants::mm, diff --git a/Examples/Io/Root/src/TrackFinderNTupleWriter.cpp b/Examples/Io/Root/src/TrackFinderNTupleWriter.cpp new file mode 100644 index 00000000000..3ddfc2b6f84 --- /dev/null +++ b/Examples/Io/Root/src/TrackFinderNTupleWriter.cpp @@ -0,0 +1,295 @@ +// 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/Io/Root/TrackFinderNTupleWriter.hpp" + +#include "Acts/Definitions/Units.hpp" +#include "ActsExamples/EventData/Index.hpp" +#include "ActsExamples/EventData/SimHit.hpp" +#include "ActsExamples/EventData/SimParticle.hpp" +#include "ActsExamples/EventData/TruthMatching.hpp" +#include "ActsExamples/Framework/AlgorithmContext.hpp" +#include "ActsExamples/Framework/DataHandle.hpp" +#include "ActsExamples/Utilities/Range.hpp" +#include "ActsExamples/Validation/TrackClassification.hpp" +#include "ActsFatras/EventData/Barcode.hpp" +#include "ActsFatras/EventData/Particle.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +struct ActsExamples::TrackFinderNTupleWriter::Impl { + Config cfg; + + ReadDataHandle inputParticles; + ReadDataHandle inputMeasurementParticlesMap; + ReadDataHandle inputTrackParticleMatching; + + TFile* file = nullptr; + + // per-track tree + TTree* trkTree = nullptr; + std::mutex trkMutex; + // track identification + ULong64_t trkEventId = 0; + ULong64_t trkTrackId = 0; + // track content + // number of hits on track + UShort_t trkNumHits = 0; + // number of particles contained in the track + UShort_t trkNumParticles = 0; + // track particle content; for each contributing particle, largest first + std::vector trkParticleId; + // total number of hits generated by this particle + std::vector trkParticleNumHitsTotal; + // number of hits within this track + std::vector trkParticleNumHitsOnTrack; + + // per-particle tree + TTree* prtTree = nullptr; + std::mutex prtMutex; + // particle identification + ULong64_t prtEventId = 0; + ULong64_t prtParticleId = 0; + Int_t prtParticleType = 0; + // particle kinematics + // vertex position in mm + float prtVx = 0, prtVy = 0, prtVz = 0; + // vertex time in ns + float prtVt = 0; + // particle momentum at production in GeV + float prtPx = 0, prtPy = 0, prtPz = 0; + // particle mass in GeV + float prtM = 0; + // particle charge in e + float prtQ = 0; + // particle reconstruction + UShort_t prtNumHits = 0; // number of hits for this particle + UShort_t prtNumTracks = + 0; // number of tracks this particle was reconstructed in + UShort_t prtNumTracksMajority = + 0; // number of tracks reconstructed as majority + // extra logger reference for the logging macros + const Acts::Logger& _logger; + + Impl(TrackFinderNTupleWriter* parent, Config&& c, const Acts::Logger& l) + : cfg(std::move(c)), + inputParticles{parent, "InputParticles"}, + inputMeasurementParticlesMap{parent, "InputMeasurementParticlesMap"}, + inputTrackParticleMatching{parent, "InputTrackParticleMatching"}, + _logger(l) { + if (cfg.inputTracks.empty()) { + throw std::invalid_argument("Missing track input collection"); + } + if (cfg.inputParticles.empty()) { + throw std::invalid_argument("Missing particles input collection"); + } + if (cfg.inputMeasurementParticlesMap.empty()) { + throw std::invalid_argument("Missing hit-particles map input collection"); + } + if (cfg.inputTrackParticleMatching.empty()) { + throw std::invalid_argument( + "Missing proto track-particle matching input collection"); + } + if (cfg.filePath.empty()) { + throw std::invalid_argument("Missing output filename"); + } + + inputParticles.initialize(cfg.inputParticles); + inputMeasurementParticlesMap.initialize(cfg.inputMeasurementParticlesMap); + inputTrackParticleMatching.initialize(cfg.inputTrackParticleMatching); + + // the output file can not be given externally since TFile accesses to the + // same file from multiple threads are unsafe. + // must always be opened internally + file = TFile::Open(cfg.filePath.c_str(), cfg.fileMode.c_str()); + if (file == nullptr) { + throw std::invalid_argument("Could not open '" + cfg.filePath + "'"); + } + + // construct trees + trkTree = new TTree(cfg.treeNameTracks.c_str(), cfg.treeNameTracks.c_str()); + trkTree->SetDirectory(file); + trkTree->Branch("event_id", &trkEventId); + trkTree->Branch("track_id", &trkTrackId); + trkTree->Branch("size", &trkNumHits); + trkTree->Branch("nparticles", &trkNumParticles); + trkTree->Branch("particle_id", &trkParticleId); + trkTree->Branch("particle_nhits_total", &trkParticleNumHitsTotal); + trkTree->Branch("particle_nhits_on_track", &trkParticleNumHitsOnTrack); + prtTree = + new TTree(cfg.treeNameParticles.c_str(), cfg.treeNameParticles.c_str()); + prtTree->SetDirectory(file); + prtTree->Branch("event_id", &prtEventId); + prtTree->Branch("particle_id", &prtParticleId); + prtTree->Branch("particle_type", &prtParticleType); + prtTree->Branch("vx", &prtVx); + prtTree->Branch("vy", &prtVy); + prtTree->Branch("vz", &prtVz); + prtTree->Branch("vt", &prtVt); + prtTree->Branch("px", &prtPx); + prtTree->Branch("py", &prtPy); + prtTree->Branch("pz", &prtPz); + prtTree->Branch("m", &prtM); + prtTree->Branch("q", &prtQ); + prtTree->Branch("nhits", &prtNumHits); + prtTree->Branch("ntracks", &prtNumTracks); + prtTree->Branch("ntracks_majority", &prtNumTracksMajority); + } + + const Acts::Logger& logger() const { return _logger; } + + void write(std::uint64_t eventId, const ConstTrackContainer& tracks, + const SimParticleContainer& particles, + const HitParticlesMap& hitParticlesMap, + const TrackParticleMatching& trackParticleMatching) { + const auto& particleHitsMap = invertIndexMultimap(hitParticlesMap); + + // How often a particle was reconstructed. + std::unordered_map reconCount; + reconCount.reserve(particles.size()); + // How often a particle was reconstructed as the majority particle. + std::unordered_map majorityCount; + majorityCount.reserve(particles.size()); + + // write per-track performance measures + { + std::lock_guard guardTrk(trkMutex); + for (auto track : tracks) { + // Get the truth-matched particle + auto imatched = trackParticleMatching.find(track.index()); + if (imatched == trackParticleMatching.end()) { + ACTS_DEBUG( + "No truth particle associated with this proto track, index = " + << track.index()); + continue; + } + const auto& particleMatch = imatched->second; + + if (particleMatch.particle.has_value()) { + SimBarcode majorityParticleId = particleMatch.particle.value(); + + auto it = majorityCount.try_emplace(majorityParticleId, 0u).first; + it->second += 1; + + // Find the truth particle via the barcode + if (auto ip = particles.find(majorityParticleId); + ip == particles.end()) { + ACTS_WARNING( + "Majority particle not found in the particles collection."); + } + } + + for (const auto& hc : particleMatch.contributingParticles) { + auto it = reconCount.try_emplace(hc.particleId, 0u).first; + it->second += 1; + } + + trkEventId = eventId; + trkTrackId = track.index(); + trkNumHits = track.nMeasurements(); + trkNumParticles = particleMatch.contributingParticles.size(); + trkParticleId.clear(); + trkParticleNumHitsTotal.clear(); + trkParticleNumHitsOnTrack.clear(); + for (const auto& phc : particleMatch.contributingParticles) { + trkParticleId.push_back(phc.particleId.value()); + // count total number of hits for this particle + auto trueParticleHits = + makeRange(particleHitsMap.equal_range(phc.particleId.value())); + trkParticleNumHitsTotal.push_back(trueParticleHits.size()); + trkParticleNumHitsOnTrack.push_back(phc.hitCount); + } + + trkTree->Fill(); + } + } + + // write per-particle performance measures + { + std::lock_guard guardPrt(trkMutex); + for (const auto& particle : particles) { + // find all hits for this particle + auto hits = + makeRange(particleHitsMap.equal_range(particle.particleId())); + + // identification + prtEventId = eventId; + prtParticleId = particle.particleId().value(); + prtParticleType = particle.pdg(); + // kinematics + prtVx = particle.position().x() / Acts::UnitConstants::mm; + prtVy = particle.position().y() / Acts::UnitConstants::mm; + prtVz = particle.position().z() / Acts::UnitConstants::mm; + prtVt = particle.time() / Acts::UnitConstants::mm; + const auto p = particle.absoluteMomentum() / Acts::UnitConstants::GeV; + prtPx = p * particle.direction().x(); + prtPy = p * particle.direction().y(); + prtPz = p * particle.direction().z(); + prtM = particle.mass() / Acts::UnitConstants::GeV; + prtQ = particle.charge() / Acts::UnitConstants::e; + // reconstruction + prtNumHits = hits.size(); + auto nt = reconCount.find(particle.particleId()); + prtNumTracks = (nt != reconCount.end()) ? nt->second : 0u; + auto nm = majorityCount.find(particle.particleId()); + prtNumTracksMajority = (nm != majorityCount.end()) ? nm->second : 0u; + + prtTree->Fill(); + } + } + } + + /// Write everything to disk and close the file. + void close() { + if (file == nullptr) { + ACTS_ERROR("Output file is not available"); + return; + } + file->Write(); + file->Close(); + } +}; + +ActsExamples::TrackFinderNTupleWriter::TrackFinderNTupleWriter( + ActsExamples::TrackFinderNTupleWriter::Config config, + Acts::Logging::Level level) + : WriterT(config.inputTracks, "TrackFinderNTupleWriter", level), + m_impl(std::make_unique(this, std::move(config), logger())) {} + +ActsExamples::TrackFinderNTupleWriter::~TrackFinderNTupleWriter() = default; + +ActsExamples::ProcessCode ActsExamples::TrackFinderNTupleWriter::writeT( + const ActsExamples::AlgorithmContext& ctx, + const ActsExamples::ConstTrackContainer& tracks) { + const auto& particles = m_impl->inputParticles(ctx); + const auto& hitParticlesMap = m_impl->inputMeasurementParticlesMap(ctx); + const auto& trackParticleMatching = m_impl->inputTrackParticleMatching(ctx); + m_impl->write(ctx.eventNumber, tracks, particles, hitParticlesMap, + trackParticleMatching); + return ProcessCode::SUCCESS; +} + +ActsExamples::ProcessCode ActsExamples::TrackFinderNTupleWriter::finalize() { + m_impl->close(); + return ProcessCode::SUCCESS; +} + +const ActsExamples::TrackFinderNTupleWriter::Config& +ActsExamples::TrackFinderNTupleWriter::config() const { + return m_impl->cfg; +} diff --git a/Examples/Io/Root/src/TrackFinderPerformanceWriter.cpp b/Examples/Io/Root/src/TrackFinderPerformanceWriter.cpp index 14e04252283..ecec2fd59ce 100644 --- a/Examples/Io/Root/src/TrackFinderPerformanceWriter.cpp +++ b/Examples/Io/Root/src/TrackFinderPerformanceWriter.cpp @@ -8,290 +8,289 @@ #include "ActsExamples/Io/Root/TrackFinderPerformanceWriter.hpp" -#include "Acts/Definitions/Units.hpp" -#include "ActsExamples/EventData/Index.hpp" -#include "ActsExamples/EventData/SimHit.hpp" -#include "ActsExamples/EventData/SimParticle.hpp" -#include "ActsExamples/EventData/TruthMatching.hpp" -#include "ActsExamples/Framework/AlgorithmContext.hpp" -#include "ActsExamples/Framework/DataHandle.hpp" -#include "ActsExamples/Utilities/Range.hpp" -#include "ActsExamples/Validation/TrackClassification.hpp" -#include "ActsFatras/EventData/Barcode.hpp" -#include "ActsFatras/EventData/Particle.hpp" +#include "Acts/EventData/TrackParameters.hpp" +#include "Acts/Utilities/VectorHelpers.hpp" #include -#include -#include +#include +#include #include -#include #include -#include -#include #include #include +#include +#include + +using Acts::VectorHelpers::eta; +using Acts::VectorHelpers::phi; + +namespace ActsExamples { + +TrackFinderPerformanceWriter::TrackFinderPerformanceWriter( + TrackFinderPerformanceWriter::Config cfg, Acts::Logging::Level lvl) + : WriterT(cfg.inputTracks, "TrackFinderPerformanceWriter", lvl), + m_cfg(std::move(cfg)), + m_effPlotTool(m_cfg.effPlotToolConfig, lvl), + m_fakeRatePlotTool(m_cfg.fakeRatePlotToolConfig, lvl), + m_duplicationPlotTool(m_cfg.duplicationPlotToolConfig, lvl), + m_trackSummaryPlotTool(m_cfg.trackSummaryPlotToolConfig, lvl) { + // tracks collection name is already checked by base ctor + if (m_cfg.inputParticles.empty()) { + throw std::invalid_argument("Missing particles input collection"); + } + if (m_cfg.inputTrackParticleMatching.empty()) { + throw std::invalid_argument("Missing input track particles matching"); + } + if (m_cfg.inputParticleTrackMatching.empty()) { + throw std::invalid_argument("Missing input particle track matching"); + } + if (m_cfg.filePath.empty()) { + throw std::invalid_argument("Missing output filename"); + } -struct ActsExamples::TrackFinderPerformanceWriter::Impl { - Config cfg; - - ReadDataHandle inputParticles; - ReadDataHandle inputMeasurementParticlesMap; - ReadDataHandle inputTrackParticleMatching; - - TFile* file = nullptr; - - // per-track tree - TTree* trkTree = nullptr; - std::mutex trkMutex; - // track identification - ULong64_t trkEventId = 0; - ULong64_t trkTrackId = 0; - // track content - // number of hits on track - UShort_t trkNumHits = 0; - // number of particles contained in the track - UShort_t trkNumParticles = 0; - // track particle content; for each contributing particle, largest first - std::vector trkParticleId; - // total number of hits generated by this particle - std::vector trkParticleNumHitsTotal; - // number of hits within this track - std::vector trkParticleNumHitsOnTrack; - - // per-particle tree - TTree* prtTree = nullptr; - std::mutex prtMutex; - // particle identification - ULong64_t prtEventId = 0; - ULong64_t prtParticleId = 0; - Int_t prtParticleType = 0; - // particle kinematics - // vertex position in mm - float prtVx = 0, prtVy = 0, prtVz = 0; - // vertex time in ns - float prtVt = 0; - // particle momentum at production in GeV - float prtPx = 0, prtPy = 0, prtPz = 0; - // particle mass in GeV - float prtM = 0; - // particle charge in e - float prtQ = 0; - // particle reconstruction - UShort_t prtNumHits = 0; // number of hits for this particle - UShort_t prtNumTracks = - 0; // number of tracks this particle was reconstructed in - UShort_t prtNumTracksMajority = - 0; // number of tracks reconstructed as majority - // extra logger reference for the logging macros - const Acts::Logger& _logger; - - Impl(TrackFinderPerformanceWriter* parent, Config&& c, const Acts::Logger& l) - : cfg(std::move(c)), - inputParticles{parent, "InputParticles"}, - inputMeasurementParticlesMap{parent, "InputMeasurementParticlesMap"}, - inputTrackParticleMatching{parent, "InputTrackParticleMatching"}, - _logger(l) { - if (cfg.inputTracks.empty()) { - throw std::invalid_argument("Missing track input collection"); - } - if (cfg.inputParticles.empty()) { - throw std::invalid_argument("Missing particles input collection"); - } - if (cfg.inputMeasurementParticlesMap.empty()) { - throw std::invalid_argument("Missing hit-particles map input collection"); + m_inputParticles.initialize(m_cfg.inputParticles); + m_inputTrackParticleMatching.initialize(m_cfg.inputTrackParticleMatching); + m_inputParticleTrackMatching.initialize(m_cfg.inputParticleTrackMatching); + + // the output file can not be given externally since TFile accesses to the + // same file from multiple threads are unsafe. + // must always be opened internally + m_outputFile = TFile::Open(m_cfg.filePath.c_str(), m_cfg.fileMode.c_str()); + if (m_outputFile == nullptr) { + throw std::invalid_argument("Could not open '" + m_cfg.filePath + "'"); + } + + if (m_cfg.writeMatchingDetails) { + m_matchingTree = new TTree("matchingdetails", "matchingdetails"); + + m_matchingTree->Branch("event_nr", &m_treeEventNr); + m_matchingTree->Branch("particle_id", &m_treeParticleId); + m_matchingTree->Branch("matched", &m_treeIsMatched); + } + + // initialize the plot tools + m_effPlotTool.book(m_effPlotCache); + m_fakeRatePlotTool.book(m_fakeRatePlotCache); + m_duplicationPlotTool.book(m_duplicationPlotCache); + m_trackSummaryPlotTool.book(m_trackSummaryPlotCache); +} + +TrackFinderPerformanceWriter::~TrackFinderPerformanceWriter() { + m_effPlotTool.clear(m_effPlotCache); + m_fakeRatePlotTool.clear(m_fakeRatePlotCache); + m_duplicationPlotTool.clear(m_duplicationPlotCache); + m_trackSummaryPlotTool.clear(m_trackSummaryPlotCache); + if (m_outputFile != nullptr) { + m_outputFile->Close(); + } +} + +ProcessCode TrackFinderPerformanceWriter::finalize() { + float eff_tracks = static_cast(m_nTotalMatchedTracks) / m_nTotalTracks; + float fakeRate_tracks = + static_cast(m_nTotalFakeTracks) / m_nTotalTracks; + float duplicationRate_tracks = + static_cast(m_nTotalDuplicateTracks) / m_nTotalTracks; + + float eff_particle = + static_cast(m_nTotalMatchedParticles) / m_nTotalParticles; + float fakeRate_particle = + static_cast(m_nTotalFakeParticles) / m_nTotalParticles; + float duplicationRate_particle = + static_cast(m_nTotalDuplicateParticles) / m_nTotalParticles; + + ACTS_DEBUG("nTotalTracks = " << m_nTotalTracks); + ACTS_DEBUG("nTotalMatchedTracks = " << m_nTotalMatchedTracks); + ACTS_DEBUG("nTotalDuplicateTracks = " << m_nTotalDuplicateTracks); + ACTS_DEBUG("nTotalFakeTracks = " << m_nTotalFakeTracks); + + ACTS_INFO( + "Efficiency with tracks (nMatchedTracks/ nAllTracks) = " << eff_tracks); + ACTS_INFO( + "Fake rate with tracks (nFakeTracks/nAllTracks) = " << fakeRate_tracks); + ACTS_INFO("Duplicate rate with tracks (nDuplicateTracks/nAllTracks) = " + << duplicationRate_tracks); + ACTS_INFO("Efficiency with particles (nMatchedParticles/nTrueParticles) = " + << eff_particle); + ACTS_INFO("Fake rate with particles (nFakeParticles/nTrueParticles) = " + << fakeRate_particle); + ACTS_INFO( + "Duplicate rate with particles (nDuplicateParticles/nTrueParticles) = " + << duplicationRate_particle); + + auto writeFloat = [&](float f, const char* name) { + TVectorF v(1); + v[0] = f; + m_outputFile->WriteObject(&v, name); + }; + + if (m_outputFile != nullptr) { + m_outputFile->cd(); + m_effPlotTool.write(m_effPlotCache); + m_fakeRatePlotTool.write(m_fakeRatePlotCache); + m_duplicationPlotTool.write(m_duplicationPlotCache); + m_trackSummaryPlotTool.write(m_trackSummaryPlotCache); + writeFloat(eff_tracks, "eff_tracks"); + writeFloat(fakeRate_tracks, "fakerate_tracks"); + writeFloat(duplicationRate_tracks, "duplicaterate_tracks"); + writeFloat(eff_particle, "eff_particles"); + writeFloat(fakeRate_particle, "fakerate_particles"); + writeFloat(duplicationRate_particle, "duplicaterate_particles"); + + if (m_matchingTree != nullptr) { + m_matchingTree->Write(); } - if (cfg.inputTrackParticleMatching.empty()) { - throw std::invalid_argument( - "Missing proto track-particle matching input collection"); + + ACTS_INFO("Wrote performance plots to '" << m_outputFile->GetPath() << "'"); + } + return ProcessCode::SUCCESS; +} + +ProcessCode TrackFinderPerformanceWriter::writeT( + const AlgorithmContext& ctx, const ConstTrackContainer& tracks) { + // The number of majority particle hits and fitted track parameters + using Acts::VectorHelpers::perp; + + // Read truth input collections + const auto& particles = m_inputParticles(ctx); + const auto& trackParticleMatching = m_inputTrackParticleMatching(ctx); + const auto& particleTrackMatching = m_inputParticleTrackMatching(ctx); + + // Exclusive access to the tree while writing + std::lock_guard lock(m_writeMutex); + + // Vector of input features for neural network classification + std::vector inputFeatures(3); + + for (const auto& track : tracks) { + // Counting number of total trajectories + m_nTotalTracks++; + + // Check if the reco track has fitted track parameters + if (!track.hasReferenceSurface()) { + ACTS_WARNING("No fitted track parameters for track, index = " + << track.index() << " tip index = " << track.tipIndex()); + continue; } - if (cfg.filePath.empty()) { - throw std::invalid_argument("Missing output filename"); + + Acts::BoundTrackParameters fittedParameters = + track.createParametersAtReference(); + + // Fill the trajectory summary info + m_trackSummaryPlotTool.fill(m_trackSummaryPlotCache, fittedParameters, + track.nTrackStates(), track.nMeasurements(), + track.nOutliers(), track.nHoles(), + track.nSharedHits()); + + // Get the truth matching information + auto imatched = trackParticleMatching.find(track.index()); + if (imatched == trackParticleMatching.end()) { + ACTS_DEBUG("No truth matching information for this track, index = " + << track.index() << " tip index = " << track.tipIndex()); + continue; } - inputParticles.initialize(cfg.inputParticles); - inputMeasurementParticlesMap.initialize(cfg.inputMeasurementParticlesMap); - inputTrackParticleMatching.initialize(cfg.inputTrackParticleMatching); + const auto& particleMatch = imatched->second; - // the output file can not be given externally since TFile accesses to the - // same file from multiple threads are unsafe. - // must always be opened internally - file = TFile::Open(cfg.filePath.c_str(), cfg.fileMode.c_str()); - if (file == nullptr) { - throw std::invalid_argument("Could not open '" + cfg.filePath + "'"); + if (particleMatch.classification == TrackMatchClassification::Fake) { + m_nTotalFakeTracks++; } - // construct trees - trkTree = new TTree(cfg.treeNameTracks.c_str(), cfg.treeNameTracks.c_str()); - trkTree->SetDirectory(file); - trkTree->Branch("event_id", &trkEventId); - trkTree->Branch("track_id", &trkTrackId); - trkTree->Branch("size", &trkNumHits); - trkTree->Branch("nparticles", &trkNumParticles); - trkTree->Branch("particle_id", &trkParticleId); - trkTree->Branch("particle_nhits_total", &trkParticleNumHitsTotal); - trkTree->Branch("particle_nhits_on_track", &trkParticleNumHitsOnTrack); - prtTree = - new TTree(cfg.treeNameParticles.c_str(), cfg.treeNameParticles.c_str()); - prtTree->SetDirectory(file); - prtTree->Branch("event_id", &prtEventId); - prtTree->Branch("particle_id", &prtParticleId); - prtTree->Branch("particle_type", &prtParticleType); - prtTree->Branch("vx", &prtVx); - prtTree->Branch("vy", &prtVy); - prtTree->Branch("vz", &prtVz); - prtTree->Branch("vt", &prtVt); - prtTree->Branch("px", &prtPx); - prtTree->Branch("py", &prtPy); - prtTree->Branch("pz", &prtPz); - prtTree->Branch("m", &prtM); - prtTree->Branch("q", &prtQ); - prtTree->Branch("nhits", &prtNumHits); - prtTree->Branch("ntracks", &prtNumTracks); - prtTree->Branch("ntracks_majority", &prtNumTracksMajority); + if (particleMatch.classification == TrackMatchClassification::Duplicate) { + m_nTotalDuplicateTracks++; + } + + // Fill fake rate plots + m_fakeRatePlotTool.fill( + m_fakeRatePlotCache, fittedParameters, + particleMatch.classification == TrackMatchClassification::Fake); + + // Fill the duplication rate + m_duplicationPlotTool.fill( + m_duplicationPlotCache, fittedParameters, + particleMatch.classification == TrackMatchClassification::Duplicate); } - const Acts::Logger& logger() const { return _logger; } - - void write(std::uint64_t eventId, const TrackContainer& tracks, - const SimParticleContainer& particles, - const HitParticlesMap& hitParticlesMap, - const TrackParticleMatching& trackParticleMatching) { - const auto& particleHitsMap = invertIndexMultimap(hitParticlesMap); - - // How often a particle was reconstructed. - std::unordered_map reconCount; - reconCount.reserve(particles.size()); - // How often a particle was reconstructed as the majority particle. - std::unordered_map majorityCount; - majorityCount.reserve(particles.size()); - - // write per-track performance measures - { - std::lock_guard guardTrk(trkMutex); - for (auto track : tracks) { - // Get the truth-matched particle - auto imatched = trackParticleMatching.find(track.index()); - if (imatched == trackParticleMatching.end()) { - ACTS_DEBUG( - "No truth particle associated with this proto track, index = " - << track.index()); - continue; - } - const auto& particleMatch = imatched->second; - - if (particleMatch.particle.has_value()) { - SimBarcode majorityParticleId = particleMatch.particle.value(); - - auto it = majorityCount.try_emplace(majorityParticleId, 0u).first; - it->second += 1; - - // Find the truth particle via the barcode - if (auto ip = particles.find(majorityParticleId); - ip == particles.end()) { - ACTS_WARNING( - "Majority particle not found in the particles collection."); - } - } - - for (const auto& hc : particleMatch.contributingParticles) { - auto it = reconCount.try_emplace(hc.particleId, 0u).first; - it->second += 1; - } - - trkEventId = eventId; - trkTrackId = track.index(); - trkNumHits = track.nMeasurements(); - trkNumParticles = particleMatch.contributingParticles.size(); - trkParticleId.clear(); - trkParticleNumHitsTotal.clear(); - trkParticleNumHitsOnTrack.clear(); - for (const auto& phc : particleMatch.contributingParticles) { - trkParticleId.push_back(phc.particleId.value()); - // count total number of hits for this particle - auto trueParticleHits = - makeRange(particleHitsMap.equal_range(phc.particleId.value())); - trkParticleNumHitsTotal.push_back(trueParticleHits.size()); - trkParticleNumHitsOnTrack.push_back(phc.hitCount); - } - - trkTree->Fill(); + // Loop over all truth particles for efficiency plots and reco details. + for (const auto& particle : particles) { + auto particleId = particle.particleId(); + + // Investigate the truth-matched tracks + std::size_t nMatchedTracks = 0; + std::size_t nFakeTracks = 0; + bool isReconstructed = false; + if (auto imatched = particleTrackMatching.find(particleId); + imatched != particleTrackMatching.end()) { + nMatchedTracks = (imatched->second.track.has_value() ? 1 : 0) + + imatched->second.duplicates; + + // Add number for total matched tracks here + m_nTotalMatchedTracks += nMatchedTracks; + m_nTotalMatchedParticles += 1; + + // Check if the particle has more than one matched track for the duplicate + // rate + if (nMatchedTracks > 1) { + m_nTotalDuplicateParticles += 1; + } + isReconstructed = imatched->second.track.has_value(); + + nFakeTracks = imatched->second.fakes; + if (nFakeTracks > 0) { + m_nTotalFakeParticles += 1; } } - // write per-particle performance measures - { - std::lock_guard guardPrt(trkMutex); - for (const auto& particle : particles) { - // find all hits for this particle - auto hits = - makeRange(particleHitsMap.equal_range(particle.particleId())); - - // identification - prtEventId = eventId; - prtParticleId = particle.particleId().value(); - prtParticleType = particle.pdg(); - // kinematics - prtVx = particle.position().x() / Acts::UnitConstants::mm; - prtVy = particle.position().y() / Acts::UnitConstants::mm; - prtVz = particle.position().z() / Acts::UnitConstants::mm; - prtVt = particle.time() / Acts::UnitConstants::mm; - const auto p = particle.absoluteMomentum() / Acts::UnitConstants::GeV; - prtPx = p * particle.direction().x(); - prtPy = p * particle.direction().y(); - prtPz = p * particle.direction().z(); - prtM = particle.mass() / Acts::UnitConstants::GeV; - prtQ = particle.charge() / Acts::UnitConstants::e; - // reconstruction - prtNumHits = hits.size(); - auto nt = reconCount.find(particle.particleId()); - prtNumTracks = (nt != reconCount.end()) ? nt->second : 0u; - auto nm = majorityCount.find(particle.particleId()); - prtNumTracksMajority = (nm != majorityCount.end()) ? nm->second : 0u; - - prtTree->Fill(); + // Loop over all the other truth particle and find the distance to the + // closest one + double minDeltaR = -1; + for (const auto& closeParticle : particles) { + if (closeParticle.particleId() == particleId) { + continue; + } + double p_phi = phi(particle.direction()); + double p_eta = eta(particle.direction()); + double c_phi = phi(closeParticle.direction()); + double c_eta = eta(closeParticle.direction()); + double distance = sqrt(pow(p_phi - c_phi, 2) + pow(p_eta - c_eta, 2)); + if (minDeltaR == -1 || distance < minDeltaR) { + minDeltaR = distance; } } + + // Fill efficiency plots + m_effPlotTool.fill(m_effPlotCache, particle, minDeltaR, isReconstructed); + // Fill number of duplicated tracks for this particle + m_duplicationPlotTool.fill(m_duplicationPlotCache, particle, + nMatchedTracks - 1); + + // Fill number of reconstructed/truth-matched/fake tracks for this particle + m_fakeRatePlotTool.fill(m_fakeRatePlotCache, particle, nMatchedTracks, + nFakeTracks); + + m_nTotalParticles += 1; } - /// Write everything to disk and close the file. - void close() { - if (file == nullptr) { - ACTS_ERROR("Output file is not available"); - return; + // Write additional stuff to TTree + if (m_cfg.writeMatchingDetails && m_matchingTree != nullptr) { + for (const auto& particle : particles) { + auto particleId = particle.particleId(); + + m_treeEventNr = ctx.eventNumber; + m_treeParticleId = particleId.value(); + + m_treeIsMatched = false; + if (auto imatched = particleTrackMatching.find(particleId); + imatched != particleTrackMatching.end()) { + m_treeIsMatched = imatched->second.track.has_value(); + } + + m_matchingTree->Fill(); } - file->Write(); - file->Close(); } -}; - -ActsExamples::TrackFinderPerformanceWriter::TrackFinderPerformanceWriter( - ActsExamples::TrackFinderPerformanceWriter::Config config, - Acts::Logging::Level level) - : WriterT(config.inputTracks, "TrackFinderPerformanceWriter", level), - m_impl(std::make_unique(this, std::move(config), logger())) {} - -ActsExamples::TrackFinderPerformanceWriter::~TrackFinderPerformanceWriter() = - default; - -ActsExamples::ProcessCode ActsExamples::TrackFinderPerformanceWriter::writeT( - const ActsExamples::AlgorithmContext& ctx, - const ActsExamples::TrackContainer& tracks) { - const auto& particles = m_impl->inputParticles(ctx); - const auto& hitParticlesMap = m_impl->inputMeasurementParticlesMap(ctx); - const auto& trackParticleMatching = m_impl->inputTrackParticleMatching(ctx); - m_impl->write(ctx.eventNumber, tracks, particles, hitParticlesMap, - trackParticleMatching); - return ProcessCode::SUCCESS; -} -ActsExamples::ProcessCode -ActsExamples::TrackFinderPerformanceWriter::finalize() { - m_impl->close(); return ProcessCode::SUCCESS; } -const ActsExamples::TrackFinderPerformanceWriter::Config& -ActsExamples::TrackFinderPerformanceWriter::config() const { - return m_impl->cfg; -} +} // namespace ActsExamples diff --git a/Examples/Io/Root/src/VertexPerformanceWriter.cpp b/Examples/Io/Root/src/VertexNTupleWriter.cpp similarity index 98% rename from Examples/Io/Root/src/VertexPerformanceWriter.cpp rename to Examples/Io/Root/src/VertexNTupleWriter.cpp index f032e39af35..c5a800741d3 100644 --- a/Examples/Io/Root/src/VertexPerformanceWriter.cpp +++ b/Examples/Io/Root/src/VertexNTupleWriter.cpp @@ -6,7 +6,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -#include "ActsExamples/Io/Root/VertexPerformanceWriter.hpp" +#include "ActsExamples/Io/Root/VertexNTupleWriter.hpp" #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/TrackParametrization.hpp" @@ -106,9 +106,9 @@ std::uint32_t getNumberOfTruePriVertices( } // namespace -VertexPerformanceWriter::VertexPerformanceWriter( - const VertexPerformanceWriter::Config& config, Acts::Logging::Level level) - : WriterT(config.inputVertices, "VertexPerformanceWriter", level), +VertexNTupleWriter::VertexNTupleWriter(const VertexNTupleWriter::Config& config, + Acts::Logging::Level level) + : WriterT(config.inputVertices, "VertexNTupleWriter", level), m_cfg(config) { if (m_cfg.filePath.empty()) { throw std::invalid_argument("Missing output filename"); @@ -253,13 +253,13 @@ VertexPerformanceWriter::VertexPerformanceWriter( m_outputTree->Branch("trk_pullQOverPFitted", &m_pullQOverPFitted); } -VertexPerformanceWriter::~VertexPerformanceWriter() { +VertexNTupleWriter::~VertexNTupleWriter() { if (m_outputFile != nullptr) { m_outputFile->Close(); } } -ProcessCode VertexPerformanceWriter::finalize() { +ProcessCode VertexNTupleWriter::finalize() { m_outputFile->cd(); m_outputTree->Write(); m_outputFile->Close(); @@ -267,7 +267,7 @@ ProcessCode VertexPerformanceWriter::finalize() { return ProcessCode::SUCCESS; } -ProcessCode VertexPerformanceWriter::writeT( +ProcessCode VertexNTupleWriter::writeT( const AlgorithmContext& ctx, const std::vector& vertices) { const double nan = std::numeric_limits::quiet_NaN(); @@ -497,7 +497,7 @@ ProcessCode VertexPerformanceWriter::writeT( fmap[vtxId].second += weight; } double truthMajorityVertexTrackWeights = 0; - SimVertexBarcode truthMajorityVertexId = 0; + SimVertexBarcode truthMajorityVertexId{0}; for (const auto& [vtxId, counter] : fmap) { if (counter.second > truthMajorityVertexTrackWeights) { truthMajorityVertexId = vtxId; @@ -629,7 +629,8 @@ ProcessCode VertexPerformanceWriter::writeT( // Count number of reconstructible tracks on truth vertex int nTracksOnTruthVertex = 0; for (const auto& particle : selectedParticles) { - if (particle.particleId().vertexId() == truthVertex.vertexId()) { + if (static_cast(particle.particleId().vertexId()) == + truthVertex.vertexId()) { ++nTracksOnTruthVertex; } } diff --git a/Examples/Python/CMakeLists.txt b/Examples/Python/CMakeLists.txt index c932b3ef081..0a834ae546f 100644 --- a/Examples/Python/CMakeLists.txt +++ b/Examples/Python/CMakeLists.txt @@ -66,6 +66,10 @@ target_link_libraries( ActsExamplesDetectorTelescope ActsExamplesUtilities ActsExamplesAmbiguityResolution + ActsExamplesTruthTracking + ActsExamplesDigitization + ActsExamplesPropagation + ActsExamplesMaterialMapping ) set(py_files diff --git a/Examples/Python/python/acts/examples/reconstruction.py b/Examples/Python/python/acts/examples/reconstruction.py index 38d64100fd3..fd02c6bddac 100644 --- a/Examples/Python/python/acts/examples/reconstruction.py +++ b/Examples/Python/python/acts/examples/reconstruction.py @@ -2,7 +2,6 @@ from typing import Optional, Union, List from enum import Enum from collections import namedtuple -import math import acts import acts.examples @@ -1382,9 +1381,11 @@ def addCKFTracks( reverseSearch: bool = False, outputDirCsv: Optional[Union[Path, str]] = None, outputDirRoot: Optional[Union[Path, str]] = None, - writeTrajectories: bool = True, - logLevel: Optional[acts.logging.Level] = None, + writeTrackSummary: bool = True, + writeTrackStates: bool = False, + writePerformance: bool = True, writeCovMat=False, + logLevel: Optional[acts.logging.Level] = None, ) -> None: """This function steers the seeding @@ -1528,11 +1529,12 @@ def addCKFTracks( tracks=trackFinder.config.outputTracks, outputDirCsv=outputDirCsv, outputDirRoot=outputDirRoot, - writeStates=writeTrajectories, - writeSummary=writeTrajectories, - writeCKFperformance=True, - logLevel=logLevel, + writeSummary=writeTrackSummary, + writeStates=writeTrackStates, + writeFitterPerformance=writePerformance, + writeFinderPerformance=writePerformance, writeCovMat=writeCovMat, + logLevel=logLevel, ) return s @@ -1604,9 +1606,10 @@ def addTrackWriters( tracks: str = "tracks", outputDirCsv: Optional[Union[Path, str]] = None, outputDirRoot: Optional[Union[Path, str]] = None, - writeStates: bool = True, writeSummary: bool = True, - writeCKFperformance: bool = True, + writeStates: bool = False, + writeFitterPerformance: bool = False, + writeFinderPerformance: bool = False, logLevel: Optional[acts.logging.Level] = None, writeCovMat=False, ): @@ -1617,8 +1620,19 @@ def addTrackWriters( if not outputDirRoot.exists(): outputDirRoot.mkdir() + if writeSummary: + trackSummaryWriter = acts.examples.RootTrackSummaryWriter( + level=customLogLevel(), + inputTracks=tracks, + inputParticles="particles_selected", + inputTrackParticleMatching="track_particle_matching", + filePath=str(outputDirRoot / f"tracksummary_{name}.root"), + treeName="tracksummary", + writeCovMat=writeCovMat, + ) + s.addWriter(trackSummaryWriter) + if writeStates: - # write track states from CKF trackStatesWriter = acts.examples.RootTrackStatesWriter( level=customLogLevel(), inputTracks=tracks, @@ -1631,30 +1645,26 @@ def addTrackWriters( ) s.addWriter(trackStatesWriter) - if writeSummary: - # write track summary from CKF - trackSummaryWriter = acts.examples.RootTrackSummaryWriter( + if writeFitterPerformance: + trackFitterPerformanceWriter = acts.examples.TrackFitterPerformanceWriter( level=customLogLevel(), inputTracks=tracks, inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", - filePath=str(outputDirRoot / f"tracksummary_{name}.root"), - treeName="tracksummary", - writeCovMat=writeCovMat, + filePath=str(outputDirRoot / f"performance_fitting_{name}.root"), ) - s.addWriter(trackSummaryWriter) + s.addWriter(trackFitterPerformanceWriter) - if writeCKFperformance: - # Write CKF performance data - ckfPerfWriter = acts.examples.CKFPerformanceWriter( + if writeFinderPerformance: + trackFinderPerfWriter = acts.examples.TrackFinderPerformanceWriter( level=customLogLevel(), inputTracks=tracks, inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", inputParticleTrackMatching="particle_track_matching", - filePath=str(outputDirRoot / f"performance_{name}.root"), + filePath=str(outputDirRoot / f"performance_finding_{name}.root"), ) - s.addWriter(ckfPerfWriter) + s.addWriter(trackFinderPerfWriter) if outputDirCsv is not None: outputDirCsv = Path(outputDirCsv) @@ -1838,7 +1848,7 @@ def addExaTrkX( # Write truth track finding / seeding performance if outputDirRoot is not None: s.addWriter( - acts.examples.TrackFinderPerformanceWriter( + acts.examples.TrackFinderNTupleWriter( level=customLogLevel(), inputProtoTracks=findingAlg.config.outputProtoTracks, # the original selected particles after digitization @@ -1861,9 +1871,11 @@ def addAmbiguityResolution( tracks: str = "tracks", outputDirCsv: Optional[Union[Path, str]] = None, outputDirRoot: Optional[Union[Path, str]] = None, - writeTrajectories: bool = True, - logLevel: Optional[acts.logging.Level] = None, + writeTrackSummary: bool = True, + writeTrackStates: bool = False, + writePerformance: bool = True, writeCovMat=False, + logLevel: Optional[acts.logging.Level] = None, ) -> None: from acts.examples import GreedyAmbiguityResolutionAlgorithm @@ -1905,11 +1917,12 @@ def addAmbiguityResolution( tracks=alg.config.outputTracks, outputDirCsv=outputDirCsv, outputDirRoot=outputDirRoot, - writeStates=writeTrajectories, - writeSummary=writeTrajectories, - writeCKFperformance=True, - logLevel=logLevel, + writeSummary=writeTrackStates, + writeStates=writeTrackSummary, + writeFitterPerformance=writePerformance, + writeFinderPerformance=writePerformance, writeCovMat=writeCovMat, + logLevel=logLevel, ) return s @@ -1925,9 +1938,11 @@ def addScoreBasedAmbiguityResolution( outputDirCsv: Optional[Union[Path, str]] = None, outputDirRoot: Optional[Union[Path, str]] = None, ambiVolumeFile: Optional[Union[Path, str]] = None, - writeTrajectories: bool = True, - logLevel: Optional[acts.logging.Level] = None, + writeTrackSummary: bool = True, + writeTrackStates: bool = False, + writePerformance: bool = True, writeCovMat=False, + logLevel: Optional[acts.logging.Level] = None, ) -> None: from acts.examples import ScoreBasedAmbiguityResolutionAlgorithm @@ -1959,11 +1974,12 @@ def addScoreBasedAmbiguityResolution( tracks=algScoreBased.config.outputTracks, outputDirCsv=outputDirCsv, outputDirRoot=outputDirRoot, - writeStates=writeTrajectories, - writeSummary=writeTrajectories, - writeCKFperformance=True, - logLevel=logLevel, + writeSummary=writeTrackStates, + writeStates=writeTrackSummary, + writeFitterPerformance=writePerformance, + writeFinderPerformance=writePerformance, writeCovMat=writeCovMat, + logLevel=logLevel, ) return s @@ -1978,7 +1994,10 @@ def addAmbiguityResolutionML( onnxModelFile: Optional[Union[Path, str]] = None, outputDirCsv: Optional[Union[Path, str]] = None, outputDirRoot: Optional[Union[Path, str]] = None, - writeTrajectories: bool = True, + writeTrackSummary: bool = True, + writeTrackStates: bool = False, + writePerformance: bool = True, + writeCovMat=False, logLevel: Optional[acts.logging.Level] = None, ) -> None: from acts.examples.onnx import AmbiguityResolutionMLAlgorithm @@ -2016,9 +2035,11 @@ def addAmbiguityResolutionML( tracks=algGreedy.config.outputTracks, outputDirCsv=outputDirCsv, outputDirRoot=outputDirRoot, - writeStates=writeTrajectories, - writeSummary=writeTrajectories, - writeCKFperformance=True, + writeSummary=writeTrackStates, + writeStates=writeTrackSummary, + writeFitterPerformance=writePerformance, + writeFinderPerformance=writePerformance, + writeCovMat=writeCovMat, logLevel=logLevel, ) @@ -2034,7 +2055,10 @@ def addAmbiguityResolutionMLDBScan( onnxModelFile: Optional[Union[Path, str]] = None, outputDirCsv: Optional[Union[Path, str]] = None, outputDirRoot: Optional[Union[Path, str]] = None, - writeTrajectories: bool = True, + writeTrackSummary: bool = True, + writeTrackStates: bool = False, + writePerformance: bool = True, + writeCovMat=False, logLevel: Optional[acts.logging.Level] = None, ) -> None: from acts.examples import AmbiguityResolutionMLDBScanAlgorithm @@ -2060,9 +2084,11 @@ def addAmbiguityResolutionMLDBScan( trajectories=alg.config.outputTracks, outputDirRoot=outputDirRoot, outputDirCsv=outputDirCsv, - writeStates=writeTrajectories, - writeSummary=writeTrajectories, - writeCKFperformance=True, + writeSummary=writeTrackStates, + writeStates=writeTrackSummary, + writeFitterPerformance=writePerformance, + writeFinderPerformance=writePerformance, + writeCovMat=writeCovMat, logLevel=logLevel, ) @@ -2121,7 +2147,7 @@ def addVertexFitting( VertexFitterAlgorithm, IterativeVertexFinderAlgorithm, AdaptiveMultiVertexFinderAlgorithm, - VertexPerformanceWriter, + VertexNTupleWriter, ) customLogLevel = acts.examples.defaultLogging(s, logLevel) @@ -2204,7 +2230,7 @@ def addVertexFitting( if not outputDirRoot.exists(): outputDirRoot.mkdir() s.addWriter( - VertexPerformanceWriter( + VertexNTupleWriter( level=customLogLevel(), inputVertices=outputVertices, inputTracks=tracks, @@ -2230,7 +2256,7 @@ def addSingleSeedVertexFinding( ) -> None: from acts.examples import ( SingleSeedVertexFinderAlgorithm, - VertexPerformanceWriter, + VertexNTupleWriter, ) customLogLevel = acts.examples.defaultLogging(s, logLevel) @@ -2251,7 +2277,7 @@ def addSingleSeedVertexFinding( outputDirRoot.mkdir() s.addWriter( - VertexPerformanceWriter( + VertexNTupleWriter( level=customLogLevel(), inputAllTruthParticles=inputParticles, inputSelectedTruthParticles=selectedParticles, diff --git a/Examples/Python/src/Generators.cpp b/Examples/Python/src/Generators.cpp index ad4a7034840..800c912aa89 100644 --- a/Examples/Python/src/Generators.cpp +++ b/Examples/Python/src/Generators.cpp @@ -7,25 +7,21 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. #include "Acts/Definitions/Algebra.hpp" -#include "Acts/Definitions/PdgParticle.hpp" #include "Acts/Plugins/Python/Utilities.hpp" +#include "Acts/Utilities/AngleHelpers.hpp" #include "Acts/Utilities/Logger.hpp" #include "ActsExamples/EventData/SimParticle.hpp" -#include "ActsExamples/Framework/RandomNumbers.hpp" #include "ActsExamples/Generators/EventGenerator.hpp" #include "ActsExamples/Generators/MultiplicityGenerators.hpp" #include "ActsExamples/Generators/ParametricParticleGenerator.hpp" #include "ActsExamples/Generators/VertexGenerators.hpp" -#include #include #include #include #include -#include #include #include -#include #include #include @@ -36,16 +32,6 @@ class IReader; namespace py = pybind11; -namespace { -double thetaToEta(double theta) { - assert(theta != 0); - return -1 * std::log(std::tan(theta / 2.)); -} -double etaToTheta(double eta) { - return 2 * std::atan(std::exp(-eta)); -} -} // namespace - namespace Acts::Python { void addGenerators(Context& ctx) { @@ -218,12 +204,12 @@ void addGenerators(Context& ctx) { .def_property( "eta", [](Config& cfg) { - return std::pair{thetaToEta(cfg.thetaMin), - thetaToEta(cfg.thetaMax)}; + return std::pair{Acts::AngleHelpers::etaFromTheta(cfg.thetaMin), + Acts::AngleHelpers::etaFromTheta(cfg.thetaMax)}; }, [](Config& cfg, std::pair value) { - cfg.thetaMin = etaToTheta(value.first); - cfg.thetaMax = etaToTheta(value.second); + cfg.thetaMin = Acts::AngleHelpers::thetaFromEta(value.first); + cfg.thetaMax = Acts::AngleHelpers::thetaFromEta(value.second); }); } diff --git a/Examples/Python/src/Output.cpp b/Examples/Python/src/Output.cpp index bda45b3cab7..dce56dc681e 100644 --- a/Examples/Python/src/Output.cpp +++ b/Examples/Python/src/Output.cpp @@ -26,7 +26,6 @@ #include "ActsExamples/Io/Csv/CsvTrackParameterWriter.hpp" #include "ActsExamples/Io/Csv/CsvTrackWriter.hpp" #include "ActsExamples/Io/Csv/CsvTrackingGeometryWriter.hpp" -#include "ActsExamples/Io/Root/CKFPerformanceWriter.hpp" #include "ActsExamples/Io/Root/RootBFieldWriter.hpp" #include "ActsExamples/Io/Root/RootMaterialTrackWriter.hpp" #include "ActsExamples/Io/Root/RootMaterialWriter.hpp" @@ -43,9 +42,10 @@ #include "ActsExamples/Io/Root/RootTrackSummaryWriter.hpp" #include "ActsExamples/Io/Root/RootVertexWriter.hpp" #include "ActsExamples/Io/Root/SeedingPerformanceWriter.hpp" +#include "ActsExamples/Io/Root/TrackFinderNTupleWriter.hpp" #include "ActsExamples/Io/Root/TrackFinderPerformanceWriter.hpp" #include "ActsExamples/Io/Root/TrackFitterPerformanceWriter.hpp" -#include "ActsExamples/Io/Root/VertexPerformanceWriter.hpp" +#include "ActsExamples/Io/Root/VertexNTupleWriter.hpp" #include "ActsExamples/MaterialMapping/IMaterialWriter.hpp" #include "ActsExamples/Plugins/Obj/ObjPropagationStepsWriter.hpp" #include "ActsExamples/Plugins/Obj/ObjTrackingGeometryWriter.hpp" @@ -163,7 +163,7 @@ void addOutput(Context& ctx) { ACTS_PYTHON_STRUCT_END(); } - // Bindings for the binning in e.g., CKFPerformanceWriter + // Bindings for the binning in e.g., TrackFinderPerformanceWriter { py::class_(mex, "Binning") .def(py::init(), "title"_a, "bins"_a, @@ -200,8 +200,8 @@ void addOutput(Context& ctx) { "RootVertexWriter", inputVertices, filePath, fileMode, treeName); - ACTS_PYTHON_DECLARE_WRITER(ActsExamples::TrackFinderPerformanceWriter, mex, - "TrackFinderPerformanceWriter", inputTracks, + ACTS_PYTHON_DECLARE_WRITER(ActsExamples::TrackFinderNTupleWriter, mex, + "TrackFinderNTupleWriter", inputTracks, inputParticles, inputMeasurementParticlesMap, inputTrackParticleMatching, filePath, fileMode, treeNameTracks, treeNameParticles); @@ -353,7 +353,7 @@ void addOutput(Context& ctx) { treeName, fileMode, writeCovMat, writeGsfSpecific, writeGx2fSpecific); ACTS_PYTHON_DECLARE_WRITER( - ActsExamples::VertexPerformanceWriter, mex, "VertexPerformanceWriter", + ActsExamples::VertexNTupleWriter, mex, "VertexNTupleWriter", inputVertices, inputTracks, inputTruthVertices, inputParticles, inputSelectedParticles, inputTrackParticleMatching, bField, filePath, treeName, fileMode, vertexMatchThreshold, trackMatchThreshold, useTracks); @@ -395,12 +395,13 @@ void addOutput(Context& ctx) { trackingGeometry, outputDir, outputPrecision, writeSensitive, writeBoundary, writeSurfaceGrid, writeLayerVolume, writePerEvent); - ACTS_PYTHON_DECLARE_WRITER( - ActsExamples::CKFPerformanceWriter, mex, "CKFPerformanceWriter", - inputTracks, inputParticles, inputTrackParticleMatching, - inputParticleTrackMatching, filePath, fileMode, effPlotToolConfig, - fakeRatePlotToolConfig, duplicationPlotToolConfig, - trackSummaryPlotToolConfig, writeMatchingDetails); + ACTS_PYTHON_DECLARE_WRITER(ActsExamples::TrackFinderPerformanceWriter, mex, + "TrackFinderPerformanceWriter", inputTracks, + inputParticles, inputTrackParticleMatching, + inputParticleTrackMatching, filePath, fileMode, + effPlotToolConfig, fakeRatePlotToolConfig, + duplicationPlotToolConfig, + trackSummaryPlotToolConfig, writeMatchingDetails); ACTS_PYTHON_DECLARE_WRITER( ActsExamples::RootNuclearInteractionParametersWriter, mex, diff --git a/Examples/Python/tests/root_file_hashes.txt b/Examples/Python/tests/root_file_hashes.txt index 4374b827580..3ade64a68ed 100644 --- a/Examples/Python/tests/root_file_hashes.txt +++ b/Examples/Python/tests/root_file_hashes.txt @@ -1,13 +1,13 @@ -test_pythia8__pythia8_particles.root: a8b53c12e771091bc2f5ace0198e9f6c5ac1909e2e6d0e3e4945e8174048ef62 +test_pythia8__pythia8_particles.root: 91c852f3e0e20bcd382c616a7b643985d092decd42bdd653deae67ed8652e8d8 test_fatras__particles_simulation.root: bc970873fef0c2efd86ed5413623802353d2cd04abea72de14e8cdfc0e40076f test_fatras__hits.root: 6e4beb045fa1712c4d14c280ba33c3fa13e4aff9de88d55c3e32f62ad226f724 -test_geant4__particles_simulation.root: 3c9c6265183b04c9d62ed5f2d0709c6dd74e33fbb53ac0aeb3274f6600257fc1 -test_geant4__hits.root: adf5dcdf000a580412dc5089e17460897d6535c978eafa021584ba4281d0a1ac +test_geant4__particles_simulation.root: 49926c71a9b54e13aa1cc7596d3302baf3c87d8e2c1d0267cb4523f6abdc0ac2 +test_geant4__hits.root: 4c9e704a75f47ed2e61652679a1d6f18fa4d9cf53faa8f8f5bbf7995634207aa test_seeding__estimatedparams.root: 69c0e268f9025a0991a212ea2a7f26f53112fecf614b475605bd1cb08415ba56 test_seeding__performance_seeding.root: 992f9c611d30dde0d3f3ab676bab19ada61ab6a4442828e27b65ec5e5b7a2880 test_seeding__particles.root: 7855b021f39ad238bca098e4282667be0666f2d1630e5bcb9d51d3b5ee39fa14 test_seeding__particles_simulation.root: f937a4cc474e80cfbb6eac4384e42e9c5c7ac981fcd6870d624cc898d1a0c006 -test_hashing_seeding__estimatedparams.root: 1f43b760e80089b5674e106d00d962d74be564cbf33ae38222052ebb6f9cbf3a +test_hashing_seeding__estimatedparams.root: 1ab38fbedeaff1380fc022e2970e6c74163d770613205100bd34c3e88283e387 test_seeding_orthogonal__estimatedparams.root: ca5896ec325daf5c8012291bc454269c61c32fe3d7e33bd1fa3b812826930299 test_seeding_orthogonal__performance_seeding.root: 60fbedcf5cb2b37cd8e526251940564432890d3a159d231ed819e915a904682c test_seeding_orthogonal__particles.root: 7855b021f39ad238bca098e4282667be0666f2d1630e5bcb9d51d3b5ee39fa14 @@ -20,7 +20,7 @@ test_propagation__propagation_summary.root: 280c1a6fcfe71974ac39587b4afad27a3164 test_material_recording__geant4_material_tracks.root: c022b9362249b29f57a07926b20644e3ab4ab8ebcf03f773fbf46c446fc1a0a1 test_truth_tracking_gsf[generic]__trackstates_gsf.root: 4df2c69d5dd7d5446a547651e4e962daf17924f5c8617165a93a3223c8ba18fd test_truth_tracking_gsf[generic]__tracksummary_gsf.root: 8c01d139cb865afa1959c62dbca76f3a1fb8b684c57ea4c2968baa6ffedadb6f -test_truth_tracking_gsf[odd]__trackstates_gsf.root: 8e6559aaec4fada8b82cfcad5801f3a609c6c905c3172fc044473cef7de77870 +test_truth_tracking_gsf[odd]__trackstates_gsf.root: c7397e53ea093f2432943ae263fc99bc9aa774504ea6152c6907066a06d21caf test_truth_tracking_gsf[odd]__tracksummary_gsf.root: 4562341f12a61ea0d5e25872b6bf466b79a73781dc95fc18ef9c6515f0a47916 test_particle_gun__particles.root: 5fe7dda2933ee6b9615b064d192322fe07831133cd998e5ed99a3b992b713a10 test_material_mapping__material-map_tracks.root: 938b1a855369e9304401cb10d2751df3fd7acf32a2573f2057eb1691cd94edf3 @@ -33,21 +33,21 @@ test_digitization_example_input[smeared]__particles.root: 5fe7dda2933ee6b9615b06 test_digitization_example_input[smeared]__measurements.root: 243c2f69b7b0db9dbeaa7494d4ea0f3dd1691dc90f16e10df6c0491ff4dc7d62 test_digitization_example_input[geometric]__particles.root: 5fe7dda2933ee6b9615b064d192322fe07831133cd998e5ed99a3b992b713a10 test_digitization_example_input[geometric]__measurements.root: 63ec81635979058fb8976f94455bf490cf92b7b142c4a05cc39de6225f5de2fb -test_ckf_tracks_example[generic-full_seeding]__trackstates_ckf.root: 35249a79237804bce337d797986e1082c6987f0700e30877f6f217f9ac91d36a +test_ckf_tracks_example[generic-full_seeding]__trackstates_ckf.root: 7c48ec32a2cb1723416a9791a8067ef09825fcf71a6cf561c1f6d2ab9dc1c1ad test_ckf_tracks_example[generic-full_seeding]__tracksummary_ckf.root: e6b9e539998ba007e9b7d2c8d9d022c47726a39e8ab9b1724c52b1d78234be03 test_ckf_tracks_example[generic-full_seeding]__performance_seeding_trees.root: 0e0676ffafdb27112fbda50d1cf627859fa745760f98073261dcf6db3f2f991e -test_ckf_tracks_example[generic-truth_estimated]__trackstates_ckf.root: a8c5c6f6c1e6303b887d47b509b7f71a2ffa5f38638fe46ce5bce76fd20d64ca +test_ckf_tracks_example[generic-truth_estimated]__trackstates_ckf.root: df730fd00a7e6a0941f5f94c07ea9cffdb763853272d284d25bec0eb2072bb2e test_ckf_tracks_example[generic-truth_estimated]__tracksummary_ckf.root: 417f7326e1e1bb4519f1378145ac733bdda6653eb9871fd69e455e0269d996a6 test_ckf_tracks_example[generic-truth_estimated]__performance_seeding.root: 1facb05c066221f6361b61f015cdf0918e94d9f3fce2269ec7b6a4dffeb2bc7e -test_ckf_tracks_example[generic-truth_smeared]__trackstates_ckf.root: edf0b06ce9ee0e4fcb153e41859af7b5153271de18f49a6842a23ad2d66b7e09 +test_ckf_tracks_example[generic-truth_smeared]__trackstates_ckf.root: 82a6744980553e6274df78eea15f0dec22676b1c04e14afc3828bff9bbf5e1b1 test_ckf_tracks_example[generic-truth_smeared]__tracksummary_ckf.root: 06d6ae1d05cb611b19df3c59531997c9b0108f5ef6027d76c4827bd2d9edb921 -test_ckf_tracks_example[odd-full_seeding]__trackstates_ckf.root: 6411378b31c1612120318773f8b807ce83a76e07c90a5f308ea86c6b34d02661 +test_ckf_tracks_example[odd-full_seeding]__trackstates_ckf.root: 0fb43661cc3a7973c28940a283dc168ceb13bc60badf1f520096edaa5982a039 test_ckf_tracks_example[odd-full_seeding]__tracksummary_ckf.root: c2e029e462d4ca77df2c7f8963093da43be66c8279ca2cc9aee8c0bc35259eec test_ckf_tracks_example[odd-full_seeding]__performance_seeding_trees.root: 43c58577aafe07645e5660c4f43904efadf91d8cda45c5c04c248bbe0f59814f -test_ckf_tracks_example[odd-truth_estimated]__trackstates_ckf.root: 465bb9e982982eb2e79fc97cae9f513ff5937041da546081281f1f959d8173ea +test_ckf_tracks_example[odd-truth_estimated]__trackstates_ckf.root: 39ac67c47f371c576d7094bca987a04e0315bd286dc79503a63a5f568b58ac97 test_ckf_tracks_example[odd-truth_estimated]__tracksummary_ckf.root: 59e2c75e9524653a80a9fd62fe99e958f73f80aa09240dcbb4ea469372e4811d test_ckf_tracks_example[odd-truth_estimated]__performance_seeding.root: 1a36b7017e59f1c08602ef3c2cb0483c51df248f112e3780c66594110719c575 -test_ckf_tracks_example[odd-truth_smeared]__trackstates_ckf.root: 9cbf99353d71ee4e6779bffb231043b41db6219c9544a80fe5172f4a4fe60cbe +test_ckf_tracks_example[odd-truth_smeared]__trackstates_ckf.root: 35a65e15a6f479f628a96f56ee78e1ac371d71a686ee0c974944d681499fe6bd test_ckf_tracks_example[odd-truth_smeared]__tracksummary_ckf.root: 3e257de624674fa9a19dcc72598c78c29a52633821acaa56dc2aa39a1395f1b5 test_vertex_fitting_reading[Truth-False-100]__performance_vertexing.root: 76ef6084d758dfdfc0151ddec2170e12d73394424e3dac4ffe46f0f339ec8293 test_vertex_fitting_reading[Iterative-False-100]__performance_vertexing.root: 60372210c830a04f95ceb78c6c68a9b0de217746ff59e8e73053750c837b57eb @@ -73,7 +73,7 @@ test_root_clusters_writer[kwargsConstructor]__clusters.root: e842df4fe04eefff3df test_exatrkx[cpu-torch]__performance_track_finding.root: 36b3045589c4c17c038dbc87943366f4af4440f7eea6887afb763871ac149b05 test_exatrkx[gpu-onnx]__performance_track_finding.root: 9090de10ffb1489d3f1993e2a3081a3038227e3e5c453e98a9a4f33ea3d6d817 test_exatrkx[gpu-torch]__performance_track_finding.root: 36b3045589c4c17c038dbc87943366f4af4440f7eea6887afb763871ac149b05 -test_ML_Ambiguity_Solver__performance_ambiML.root: 284ff5c3a08c0b810938e4ac2f8ba8fe2babb17d4c202b624ed69fff731a9006 +test_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 diff --git a/Examples/Python/tests/test_examples.py b/Examples/Python/tests/test_examples.py index 9a2c45c7657..26f69f4aa82 100644 --- a/Examples/Python/tests/test_examples.py +++ b/Examples/Python/tests/test_examples.py @@ -1146,7 +1146,7 @@ def test_ckf_tracks_example( root_files = [ ( - "performance_ckf.root", + "performance_finding_ckf.root", None, ), ( @@ -1290,7 +1290,7 @@ def test_full_chain_odd_example_pythia_geant4(tmp_path): def test_ML_Ambiguity_Solver(tmp_path, assert_root_hash): # This test literally only ensures that the full chain example can run without erroring out - root_file = "performance_ambiML.root" + root_file = "performance_finding_ambiML.root" output_dir = "odd_output" assert not (tmp_path / root_file).exists() diff --git a/Examples/Python/tests/test_writer.py b/Examples/Python/tests/test_writer.py index a3098c743c9..95cd67decd1 100644 --- a/Examples/Python/tests/test_writer.py +++ b/Examples/Python/tests/test_writer.py @@ -21,7 +21,7 @@ from acts import UnitConstants as u from acts.examples import ( ObjPropagationStepsWriter, - TrackFinderPerformanceWriter, + TrackFinderNTupleWriter, SeedingPerformanceWriter, RootPropagationStepsWriter, RootParticleWriter, @@ -31,7 +31,7 @@ RootSimHitWriter, RootTrackStatesWriter, RootTrackSummaryWriter, - VertexPerformanceWriter, + VertexNTupleWriter, RootMeasurementWriter, CsvParticleWriter, CsvSimHitWriter, @@ -250,7 +250,7 @@ def test_csv_simhits_writer(tmp_path, fatras, conf_const): [ RootPropagationStepsWriter, RootParticleWriter, - TrackFinderPerformanceWriter, + TrackFinderNTupleWriter, SeedingPerformanceWriter, RootTrackParameterWriter, RootMaterialTrackWriter, @@ -259,7 +259,7 @@ def test_csv_simhits_writer(tmp_path, fatras, conf_const): RootSimHitWriter, RootTrackStatesWriter, RootTrackSummaryWriter, - VertexPerformanceWriter, + VertexNTupleWriter, SeedingPerformanceWriter, ], ) diff --git a/Examples/Scripts/Python/ckf_tracks.py b/Examples/Scripts/Python/ckf_tracks.py index e2b24436c0a..97f56d17ff0 100755 --- a/Examples/Scripts/Python/ckf_tracks.py +++ b/Examples/Scripts/Python/ckf_tracks.py @@ -170,6 +170,7 @@ def runCKFTracks( ), outputDirRoot=outputDir, outputDirCsv=outputDir / "csv" if outputCsv else None, + writeTrackStates=True, ) return s diff --git a/Examples/Scripts/Python/seeding.py b/Examples/Scripts/Python/seeding.py index e50f9390c12..afe8983eec7 100755 --- a/Examples/Scripts/Python/seeding.py +++ b/Examples/Scripts/Python/seeding.py @@ -104,6 +104,7 @@ def runSeeding( / "Examples/Algorithms/Digitization/share/default-smearing-config-generic.json", rnd=rnd, ) + from acts.examples.reconstruction import ( addSeeding, SeedFinderConfigArg, diff --git a/Examples/Scripts/TrackingPerformance/TreeReader.h b/Examples/Scripts/TrackingPerformance/TreeReader.h index 1346d5197ea..4ab47746dc0 100644 --- a/Examples/Scripts/TrackingPerformance/TreeReader.h +++ b/Examples/Scripts/TrackingPerformance/TreeReader.h @@ -36,7 +36,7 @@ struct ParticleInfo { /// struct TreeReader { // The constructor - TreeReader(TTree* tree_) : tree(tree_) {} + explicit TreeReader(TTree* tree_) : tree(tree_) {} // Get entry void getEntry(unsigned int i) const { @@ -400,7 +400,7 @@ struct TrackSummaryReader : public TreeReader { }; /// Struct used for reading particles written out by the -/// TrackFinderPerformanceWriter +/// TrackFinderNTupleWriter /// struct ParticleReader : public TreeReader { // Delete the default constructor diff --git a/Examples/Scripts/fullMaterial.C b/Examples/Scripts/fullMaterial.C index d984a99c675..85ee1092eb5 100644 --- a/Examples/Scripts/fullMaterial.C +++ b/Examples/Scripts/fullMaterial.C @@ -13,6 +13,8 @@ * Author: jhrdinka */ +#include "Acts/Utilities/AngleHelpers.hpp" + #include "TFile.h" #include "TH1F.h" #include "TH2F.h" @@ -111,7 +113,7 @@ fullMaterial(std::string inFile, for (auto& mrecord : mrecords) { std::vector steps = mrecord.materialSteps(); float theta = mrecord.theta(); - float eta = -log(tan(theta * 0.5)); + float eta = Acts::AngleHelpers::etaFromTheta(theta); float phi = VectorHelpers::phi(mrecord); float thickness = 0.; diff --git a/Examples/Scripts/momentumDistributions.C b/Examples/Scripts/momentumDistributions.C index b4aa6e4e3d9..e16a1b709db 100644 --- a/Examples/Scripts/momentumDistributions.C +++ b/Examples/Scripts/momentumDistributions.C @@ -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/. +#include "Acts/Utilities/AngleHelpers.hpp" + #include "TFile.h" #include "TH1F.h" #include "TH2F.h" @@ -106,7 +108,7 @@ void momentumDistributions(std::string inFile, std::string treeName, for (int j = 0; j < x->size(); j++) { float hitTheta = std::atan2(std::hypot(x->at(j), y->at(j)), z->at(j)); - hitsEta->Fill(-log(tan(hitTheta * 0.5))); + hitsEta->Fill(Acts::AngleHelpers::etaFromTheta(hitTheta)); hitsTheta->Fill(hitTheta); hitsZ->Fill(z->at(j)); } diff --git a/Fatras/include/ActsFatras/Utilities/LandauDistribution.hpp b/Fatras/include/ActsFatras/Utilities/LandauDistribution.hpp index 5fe4f57280c..2b29bd89066 100644 --- a/Fatras/include/ActsFatras/Utilities/LandauDistribution.hpp +++ b/Fatras/include/ActsFatras/Utilities/LandauDistribution.hpp @@ -51,7 +51,7 @@ class LandauDistribution { /// Construct directly from the distribution parameters. LandauDistribution(double location, double scale) : m_cfg(location, scale) {} /// Construct from a parameter object. - LandauDistribution(const param_type &cfg) : m_cfg(cfg) {} + explicit LandauDistribution(const param_type &cfg) : m_cfg(cfg) {} // Explicitlely defaulted construction and assignment LandauDistribution() = default; LandauDistribution(const LandauDistribution &) = default; diff --git a/Plugins/ActSVG/include/Acts/Plugins/ActSVG/IndexedSurfacesSvgConverter.hpp b/Plugins/ActSVG/include/Acts/Plugins/ActSVG/IndexedSurfacesSvgConverter.hpp index 79397aba878..788ac36aca5 100644 --- a/Plugins/ActSVG/include/Acts/Plugins/ActSVG/IndexedSurfacesSvgConverter.hpp +++ b/Plugins/ActSVG/include/Acts/Plugins/ActSVG/IndexedSurfacesSvgConverter.hpp @@ -170,7 +170,7 @@ ProtoIndexedSurfaceGrid convertImpl(const GeometryContext& gctx, } } } - return std::tie(pSurfaces, pGrid, highlightIndices); + return {pSurfaces, pGrid, highlightIndices}; } /// @brief Convert the single delegate if it is of the type of the reference diff --git a/Plugins/ActSVG/include/Acts/Plugins/ActSVG/SvgUtils.hpp b/Plugins/ActSVG/include/Acts/Plugins/ActSVG/SvgUtils.hpp index 38189871efb..d2326694b5d 100644 --- a/Plugins/ActSVG/include/Acts/Plugins/ActSVG/SvgUtils.hpp +++ b/Plugins/ActSVG/include/Acts/Plugins/ActSVG/SvgUtils.hpp @@ -59,7 +59,7 @@ struct Style { str._hl_width = highlightStrokeWidth; str._dasharray = strokeDasharray; - return std::tie(fll, str); + return {fll, str}; } /// Conversion to fill, stroke and font diff --git a/Plugins/ActSVG/src/SurfaceArraySvgConverter.cpp b/Plugins/ActSVG/src/SurfaceArraySvgConverter.cpp index 794bb1d43b5..5cffbe73a1a 100644 --- a/Plugins/ActSVG/src/SurfaceArraySvgConverter.cpp +++ b/Plugins/ActSVG/src/SurfaceArraySvgConverter.cpp @@ -206,5 +206,5 @@ Acts::Svg::SurfaceArrayConverter::convert( // Return the surfaces and the grid std::vector pSurfaceBatches = {pSurfaces}; std::vector pAssociationBatchs = {pAssociations}; - return std::tie(pSurfaceBatches, pGrid, pAssociationBatchs); + return {pSurfaceBatches, pGrid, pAssociationBatchs}; } diff --git a/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepDetectorStructure.hpp b/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepDetectorStructure.hpp index a11601b579b..eb69176aa19 100644 --- a/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepDetectorStructure.hpp +++ b/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepDetectorStructure.hpp @@ -55,9 +55,9 @@ class DD4hepDetectorStructure { /// @param logger is the screen output logger /// /// @note this needs to be provided - DD4hepDetectorStructure(std::unique_ptr logger = - getDefaultLogger("DD4hepLayerStructure", - Acts::Logging::INFO)); + explicit DD4hepDetectorStructure(std::unique_ptr logger = + getDefaultLogger("DD4hepLayerStructure", + Acts::Logging::INFO)); DD4hepDetectorStructure() = delete; diff --git a/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepDetectorSurfaceFactory.hpp b/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepDetectorSurfaceFactory.hpp index d6855443af2..b120358d537 100644 --- a/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepDetectorSurfaceFactory.hpp +++ b/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepDetectorSurfaceFactory.hpp @@ -90,7 +90,7 @@ class DD4hepDetectorSurfaceFactory { /// The DD4hep detector element factory /// /// @param mlogger a screen output logger - DD4hepDetectorSurfaceFactory( + explicit DD4hepDetectorSurfaceFactory( std::unique_ptr mlogger = getDefaultLogger( "DD4hepDetectorSurfaceFactory", Acts::Logging::INFO)); diff --git a/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepFieldAdapter.hpp b/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepFieldAdapter.hpp index 9d2007235e5..6f7b8077348 100644 --- a/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepFieldAdapter.hpp +++ b/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepFieldAdapter.hpp @@ -22,7 +22,7 @@ class DD4hepFieldAdapter : public Acts::MagneticFieldProvider { struct Cache {}; public: - DD4hepFieldAdapter(dd4hep::OverlayedField field); + explicit DD4hepFieldAdapter(dd4hep::OverlayedField field); MagneticFieldProvider::Cache makeCache( const Acts::MagneticFieldContext& mctx) const override; diff --git a/Plugins/DD4hep/src/DD4hepDetectorStructure.cpp b/Plugins/DD4hep/src/DD4hepDetectorStructure.cpp index ca4ae439004..00a5017fca9 100644 --- a/Plugins/DD4hep/src/DD4hepDetectorStructure.cpp +++ b/Plugins/DD4hep/src/DD4hepDetectorStructure.cpp @@ -75,7 +75,7 @@ Acts::Experimental::DD4hepDetectorStructure::construct( detail::BlueprintDrawer::dotStream(bpf, *dd4hepBlueprint); bpf.close(); // Return without building - return std::tie(detector, detectorStore); + return {detector, detectorStore}; } // Create a Cylindrical detector builder from this blueprint @@ -100,5 +100,5 @@ Acts::Experimental::DD4hepDetectorStructure::construct( "DD4hepDetectorStructure: Only cylindrical detectors are (currently) " "supported."); } - return std::tie(detector, detectorStore); + return {detector, detectorStore}; } diff --git a/Plugins/Detray/include/Acts/Plugins/Detray/DetrayConverter.hpp b/Plugins/Detray/include/Acts/Plugins/Detray/DetrayConverter.hpp index 441b8f121f0..104c71e1893 100644 --- a/Plugins/Detray/include/Acts/Plugins/Detray/DetrayConverter.hpp +++ b/Plugins/Detray/include/Acts/Plugins/Detray/DetrayConverter.hpp @@ -38,8 +38,9 @@ class DetrayConverter { }; /// Constructor with logger - DetrayConverter(std::unique_ptr logger = - getDefaultLogger("DetrayConverter", Logging::INFO)); + explicit DetrayConverter( + std::unique_ptr logger = getDefaultLogger("DetrayConverter", + Logging::INFO)); /// Convert an Acts::Experimental::Detector to a detray::detector object /// diff --git a/Plugins/Geant4/include/Acts/Plugins/Geant4/Geant4PhysicalVolumeSelectors.hpp b/Plugins/Geant4/include/Acts/Plugins/Geant4/Geant4PhysicalVolumeSelectors.hpp index 1fab98ea834..fd05274a34d 100644 --- a/Plugins/Geant4/include/Acts/Plugins/Geant4/Geant4PhysicalVolumeSelectors.hpp +++ b/Plugins/Geant4/include/Acts/Plugins/Geant4/Geant4PhysicalVolumeSelectors.hpp @@ -70,7 +70,7 @@ struct PositionSelector : public IGeant4PhysicalVolumeSelector { /// Constructor with arguments /// @param ranges the provided map of axes of ranges - PositionSelector( + explicit PositionSelector( const std::map>& ranges) : m_ranges(ranges) {} diff --git a/Plugins/Hashing/include/Acts/Plugins/Hashing/HashingTraining.ipp b/Plugins/Hashing/include/Acts/Plugins/Hashing/HashingTraining.ipp index ff9e35c1149..3e24e828177 100644 --- a/Plugins/Hashing/include/Acts/Plugins/Hashing/HashingTraining.ipp +++ b/Plugins/Hashing/include/Acts/Plugins/Hashing/HashingTraining.ipp @@ -8,7 +8,9 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/Units.hpp" +#include "Acts/Utilities/AngleHelpers.hpp" +#include #include #include @@ -49,7 +51,7 @@ AnnoyModel HashingTrainingAlgorithm::execute( Scalar y = spacePoint->y() / Acts::UnitConstants::mm; // Helix transform - Scalar phi = atan2(y, x); + Scalar phi = std::atan2(y, x); std::vector vec(f); // Avoid potential null pointer dereference @@ -59,9 +61,9 @@ AnnoyModel HashingTrainingAlgorithm::execute( if (f >= 2) { Scalar z = spacePoint->z() / Acts::UnitConstants::mm; Scalar r2 = x * x + y * y; - Scalar rho = sqrt(r2 + z * z); - Scalar theta = acos(z / rho); - Scalar eta = -log(tan(0.5 * theta)); + Scalar rho = std::sqrt(r2 + z * z); + Scalar theta = std::acos(z / rho); + Scalar eta = Acts::AngleHelpers::etaFromTheta(theta); vec[1] = eta; } diff --git a/Plugins/Json/include/Acts/Plugins/Json/GeometryHierarchyMapJsonConverter.hpp b/Plugins/Json/include/Acts/Plugins/Json/GeometryHierarchyMapJsonConverter.hpp index 70f070e9dd7..74ce7109975 100644 --- a/Plugins/Json/include/Acts/Plugins/Json/GeometryHierarchyMapJsonConverter.hpp +++ b/Plugins/Json/include/Acts/Plugins/Json/GeometryHierarchyMapJsonConverter.hpp @@ -42,7 +42,7 @@ class GeometryHierarchyMapJsonConverter { /// Construct the converter. /// /// @param valueIdentifier user-defined identifier for the stored value - GeometryHierarchyMapJsonConverter(std::string valueIdentifier) + explicit GeometryHierarchyMapJsonConverter(std::string valueIdentifier) : m_valueIdentifier(std::move(valueIdentifier)) { if (m_valueIdentifier.empty()) { throw std::invalid_argument("Value identifier must be non-empty"); diff --git a/Plugins/Json/include/Acts/Plugins/Json/IndexedGridJsonHelper.hpp b/Plugins/Json/include/Acts/Plugins/Json/IndexedGridJsonHelper.hpp index b7717073036..581130a8852 100644 --- a/Plugins/Json/include/Acts/Plugins/Json/IndexedGridJsonHelper.hpp +++ b/Plugins/Json/include/Acts/Plugins/Json/IndexedGridJsonHelper.hpp @@ -83,7 +83,7 @@ updator_type generateFromJson(const nlohmann::json& jUpdater, -> std::tuple, std::size_t> { std::array range = jAxis["range"]; std::size_t bins = jAxis["bins"]; - return std::make_tuple(range, bins); + return {range, bins}; }; /// Helper extractor for variable axis diff --git a/Plugins/Json/src/DetrayJsonHelper.cpp b/Plugins/Json/src/DetrayJsonHelper.cpp index aa61a9d8aeb..e902657da21 100644 --- a/Plugins/Json/src/DetrayJsonHelper.cpp +++ b/Plugins/Json/src/DetrayJsonHelper.cpp @@ -50,7 +50,7 @@ std::tuple> maskFromBounds( break; } } - return std::tie(type, boundaries); + return {type, boundaries}; } void addVolumeLink(nlohmann::json& jSurface, int vLink) { diff --git a/Plugins/Json/src/MaterialMapJsonConverter.cpp b/Plugins/Json/src/MaterialMapJsonConverter.cpp index 76fc01f8569..2424156ec1d 100644 --- a/Plugins/Json/src/MaterialMapJsonConverter.cpp +++ b/Plugins/Json/src/MaterialMapJsonConverter.cpp @@ -253,8 +253,8 @@ nlohmann::json Acts::MaterialMapJsonConverter::materialMapsToJson( VolumeMaterialMap volumeMap = maps.second; std::vector> mapVolumeInit; - for (auto it = volumeMap.begin(); it != volumeMap.end(); it++) { - mapVolumeInit.push_back({it->first, it->second.get()}); + for (const auto& [key, value] : volumeMap) { + mapVolumeInit.push_back({key, value.get()}); } GeometryHierarchyMap hierarchyVolumeMap( mapVolumeInit); @@ -263,8 +263,8 @@ nlohmann::json Acts::MaterialMapJsonConverter::materialMapsToJson( SurfaceMaterialMap surfaceMap = maps.first; std::vector> mapSurfaceInit; - for (auto it = surfaceMap.begin(); it != surfaceMap.end(); it++) { - mapSurfaceInit.push_back({it->first, it->second.get()}); + for (const auto& [key, value] : surfaceMap) { + mapSurfaceInit.push_back({key, value.get()}); } GeometryHierarchyMap hierarchySurfaceMap( mapSurfaceInit); diff --git a/Plugins/Podio/include/Acts/Plugins/Podio/PodioDynamicColumns.hpp b/Plugins/Podio/include/Acts/Plugins/Podio/PodioDynamicColumns.hpp index d72e78bd9f2..295937efe7e 100644 --- a/Plugins/Podio/include/Acts/Plugins/Podio/PodioDynamicColumns.hpp +++ b/Plugins/Podio/include/Acts/Plugins/Podio/PodioDynamicColumns.hpp @@ -18,7 +18,7 @@ namespace Acts::podio_detail { struct ConstDynamicColumnBase { - ConstDynamicColumnBase(std::string_view name) : m_name{name} {} + explicit ConstDynamicColumnBase(std::string_view name) : m_name{name} {} virtual ~ConstDynamicColumnBase() = default; @@ -45,7 +45,8 @@ struct ConstDynamicColumn : public ConstDynamicColumnBase { }; struct DynamicColumnBase : public ConstDynamicColumnBase { - DynamicColumnBase(std::string_view name) : ConstDynamicColumnBase{name} {} + explicit DynamicColumnBase(std::string_view name) + : ConstDynamicColumnBase{name} {} virtual std::any get(std::size_t i) = 0; std::any get(std::size_t i) const override = 0; diff --git a/Tests/UnitTests/Core/Seeding/PathSeederTest.cpp b/Tests/UnitTests/Core/Seeding/PathSeederTest.cpp index 70a8f9ebaa0..e8338925747 100644 --- a/Tests/UnitTests/Core/Seeding/PathSeederTest.cpp +++ b/Tests/UnitTests/Core/Seeding/PathSeederTest.cpp @@ -38,6 +38,8 @@ using namespace Acts::UnitLiterals; using Axis = Acts::Axis; using Grid = Acts::Grid, Axis, Axis>; +using TrackParameters = CurvilinearTrackParameters; + GeometryContext gctx; // Parameters for the geometry @@ -46,6 +48,12 @@ const ActsScalar halfZ = 10.; const ActsScalar deltaX = 10.; const ActsScalar deltaYZ = 1.; +const Vector4 trueVertex(-5., 0., 0., 0); +const std::vector truePhis = {-0.15, -0.1, -0.05, 0, + 0.05, 0.1, 0.15}; +const ActsScalar trueTheta = M_PI_2; +const ActsScalar trueQOverP = 1. / 1._GeV; + // Intersection finding to get the // region of interest for seeding class NoFieldIntersectionFinder { @@ -57,11 +65,13 @@ class NoFieldIntersectionFinder { // Find the intersections along the path // and return them in the order of the path // length - std::vector> operator()( - const GeometryContext& geoCtx, const Vector3& position, - const Vector3& direction, [[maybe_unused]] const ActsScalar& Pmag = 0, - [[maybe_unused]] const ActsScalar& Charge = 0) const { - std::vector> sIntersections; + std::vector> operator()( + const GeometryContext& geoCtx, + const TrackParameters& trackParameters) const { + Vector3 position = trackParameters.position(); + Vector3 direction = trackParameters.direction(); + + std::vector> sIntersections; // Intersect the surfaces for (auto& surface : m_surfaces) { // Get the intersection @@ -76,7 +86,11 @@ class NoFieldIntersectionFinder { if (closestForward.status() == IntersectionStatus::reachable && closestForward.pathLength() > 0.0) { sIntersections.push_back( - {closestForward.object()->geometryId(), closestForward.position()}); + {closestForward.object()->geometryId(), + surface + ->globalToLocal(geoCtx, closestForward.position(), + Vector3{0, 1, 0}) + .value()}); continue; } } @@ -84,92 +98,85 @@ class NoFieldIntersectionFinder { } }; -// Grid to store the source links for -// the seeding fast lookup -class SourceLinkGrid { +// A simple path width provider to set +// the grid lookup boundaries around the +// intersection point +class PathWidthProvider { + public: + std::pair width; + + std::pair operator()( + const GeometryContext& /*gctx*/, + const GeometryIdentifier& /*geoId*/) const { + return width; + } +}; + +// Estimator of the particle's energy, +// vertex, momentum direction at the IP +// and the direction at the first hit +class TrackEstimator { public: - using GridType = Grid; + Vector3 m_ip; + SourceLinkSurfaceAccessor m_surfaceAccessor; + + std::pair operator()( + const GeometryContext& geoCtx, const SourceLink& pivot) const { + auto testSourceLink = pivot.get(); + Vector3 pivot3 = m_surfaceAccessor(pivot)->localToGlobal( + geoCtx, testSourceLink.parameters, Vector3{0, 1, 0}); + + Vector3 direction = (pivot3 - m_ip).normalized(); - /// Lookup table collection - std::unordered_map m_lookupTables; + Vector4 ip = {m_ip.x(), m_ip.y(), m_ip.z(), 0}; + ActsScalar qOverP = 1_e / 1._GeV; + ActsScalar phi = Acts::VectorHelpers::phi(direction); + ActsScalar theta = Acts::VectorHelpers::theta(direction); + ParticleHypothesis particle = ParticleHypothesis::electron(); + + TrackParameters ipParams(ip, phi, theta, qOverP, std::nullopt, particle); + TrackParameters firstLayerParams(ip, phi, theta, qOverP, std::nullopt, + particle); + + return {ipParams, firstLayerParams}; + } +}; - /// Surface accessor +// Construct grid with the source links +struct ConstructSourceLinkGrid { SourceLinkSurfaceAccessor m_surfaceAccessor; - void initialize(const GeometryContext& geoCtx, - std::vector sourceLinks) { + std::unordered_map construct( + std::vector sourceLinks) { // Lookup table for each layer - std::unordered_map lookupTable; + std::unordered_map lookupTable; // Construct a binned grid for each layer for (int i : {14, 15, 16, 17}) { - Axis xAxis(-halfY, halfY, 50); - Axis yAxis(-halfZ, halfZ, 50); + Axis xAxis(-halfY, halfY, 100); + Axis yAxis(-halfZ, halfZ, 100); + + Grid grid(std::make_tuple(xAxis, yAxis)); + + GeometryIdentifier geoId; + + geoId.setSensitive(i); - GridType grid(std::make_tuple(xAxis, yAxis)); - lookupTable.insert({i, grid}); + lookupTable.insert({geoId, grid}); } // Fill the grid with source links for (auto& sl : sourceLinks) { - auto ssl = sl.get(); - auto id = ssl.m_geometryId; + auto tsl = sl.get(); + auto id = tsl.m_geometryId; - // Grid works with global positions - Vector3 globalPos = m_surfaceAccessor(sl)->localToGlobal( - geoCtx, ssl.parameters, Vector3{0, 1, 0}); - - auto bin = - lookupTable.at(id.sensitive()) - .localBinsFromPosition(Vector2(globalPos.y(), globalPos.z())); - lookupTable.at(id.sensitive()).atLocalBins(bin).push_back(sl); + auto bin = lookupTable.at(id).localBinsFromPosition(tsl.parameters); + lookupTable.at(id).atLocalBins(bin).push_back(sl); } - m_lookupTables = lookupTable; - }; - - // Get the source link grid for a given geometry id - GridType operator()(const GeometryIdentifier& geoId) const { - return m_lookupTables.at(geoId.sensitive()); - } -}; - -// A simple path width provider to set -// the grid lookup boundaries around the -// intersection point -std::pair getPathWidth( - const GeometryContext& /*gctx*/, const GeometryIdentifier& /*geoId*/) { - return {0.1, 0.1}; -} - -// Calibrator to transform the source links -// to global coordinates -class SourceLinkCalibrator { - public: - SourceLinkSurfaceAccessor m_surfaceAccessor; - - Vector3 operator()(const GeometryContext& geoCtx, - const SourceLink& sourceLink) const { - auto ssl = sourceLink.get(); - auto res = m_surfaceAccessor(sourceLink) - ->localToGlobal(geoCtx, ssl.parameters, Vector3{0, 1, 0}); - return res; + return lookupTable; } }; -// Estimator of the particle's energy, -// vertex, momentum direction at the IP -// and the direction at the first hit -class TrackEstimator { - public: - Vector3 ip; - - std::tuple operator()( - const GeometryContext& /*geoCtx*/, const Vector3& pivot) const { - Vector3 direction = (pivot - ip).normalized(); - return {1_e, 1._GeV, ip, direction, direction}; - }; -}; - // Construct a simple telescope detector std::shared_ptr constructTelescopeDetector() { RotationMatrix3 rotation; @@ -257,7 +264,7 @@ std::shared_ptr constructTelescopeDetector() { // Connect the volumes auto portalContainer = Experimental::detail::CuboidalDetectorHelper::connect( - gctx, volumes, BinningValue::binX, {}, Logging::VERBOSE); + gctx, volumes, BinningValue::binX, {}, Logging::INFO); // Make sure that the geometry ids are // independent of the potential Id generation @@ -302,23 +309,19 @@ std::vector createSourceLinks( } } - Vector3 vertex(-5., 0., 0.); - std::vector phis = {-0.15, -0.1, -0.05, 0, 0.05, 0.1, 0.15}; - std::vector sourceLinks; - for (ActsScalar phi : phis) { - Vector3 direction(cos(phi), sin(phi), 0.); + for (ActsScalar phi : truePhis) { + TrackParameters trackParameters(trueVertex, phi, trueTheta, trueQOverP, + std::nullopt, + ParticleHypothesis::electron()); - auto intersections = intersectionFinder(geoCtx, vertex, direction); + auto intersections = intersectionFinder(geoCtx, trackParameters); SquareMatrix2 cov = SquareMatrix2::Identity(); for (auto& [id, refPoint] : intersections) { - auto surf = *detector.sensitiveHierarchyMap().find(id); - Vector2 val = surf->globalToLocal(geoCtx, refPoint, direction).value(); - - detail::Test::TestSourceLink sourceLink(eBoundLoc0, eBoundLoc1, val, cov, - id, id.value()); + detail::Test::TestSourceLink sourceLink(eBoundLoc0, eBoundLoc1, refPoint, + cov, id, id.value()); SourceLink sl{sourceLink}; sourceLinks.push_back(sl); @@ -339,30 +342,27 @@ BOOST_AUTO_TEST_CASE(PathSeederZeroField) { auto sourceLinks = createSourceLinks(gctx, *detector); // Prepare the PathSeeder - auto pathSeederCfg = Acts::Experimental::PathSeeder::Config(); + auto pathSeederCfg = Acts::PathSeeder::Config(); // Grid to bin the source links SurfaceAccessor surfaceAccessor{*detector}; - SourceLinkGrid sourceLinkGrid; - sourceLinkGrid.m_surfaceAccessor.connect<&SurfaceAccessor::operator()>( - &surfaceAccessor); - pathSeederCfg.sourceLinkGridLookup.connect<&SourceLinkGrid::operator()>( - &sourceLinkGrid); + auto sourceLinkGridConstructor = ConstructSourceLinkGrid(); + sourceLinkGridConstructor.m_surfaceAccessor + .connect<&SurfaceAccessor::operator()>(&surfaceAccessor); + + // Create the grid + std::unordered_map sourceLinkGrid = + sourceLinkGridConstructor.construct(sourceLinks); // Estimator of the IP and first hit // parameters of the track TrackEstimator trackEstimator; - trackEstimator.ip = Vector3(-5., 0., 0.); + trackEstimator.m_ip = Vector3(-5., 0., 0.); + trackEstimator.m_surfaceAccessor.connect<&SurfaceAccessor::operator()>( + &surfaceAccessor); pathSeederCfg.trackEstimator.connect<&TrackEstimator::operator()>( &trackEstimator); - // Transforms the source links to global coordinates - SourceLinkCalibrator sourceLinkCalibrator; - sourceLinkCalibrator.m_surfaceAccessor.connect<&SurfaceAccessor::operator()>( - &surfaceAccessor); - pathSeederCfg.sourceLinkCalibrator.connect<&SourceLinkCalibrator::operator()>( - &sourceLinkCalibrator); - // Intersection finder NoFieldIntersectionFinder intersectionFinder; for (auto volume : detector->volumes()) { @@ -374,29 +374,35 @@ BOOST_AUTO_TEST_CASE(PathSeederZeroField) { .connect<&NoFieldIntersectionFinder::operator()>(&intersectionFinder); // Path width provider - pathSeederCfg.pathWidthProvider.connect<&getPathWidth>(); + PathWidthProvider pathWidthProvider; - // First tracking layer - Extent firstLayerExtent; - firstLayerExtent.set(BinningValue::binX, -0.1, 0.1); - firstLayerExtent.set(BinningValue::binY, -halfY - deltaYZ, halfY + deltaYZ); - firstLayerExtent.set(BinningValue::binZ, -halfZ - deltaYZ, halfZ + deltaYZ); + pathSeederCfg.pathWidthProvider.connect<&PathWidthProvider::operator()>( + &pathWidthProvider); - pathSeederCfg.firstLayerExtent = firstLayerExtent; + GeometryIdentifier geoId; + geoId.setSensitive(14); + pathSeederCfg.refLayerIds.push_back(geoId); // Create the PathSeeder - Acts::Experimental::PathSeeder pathSeeder(pathSeederCfg); + Acts::PathSeeder pathSeeder(pathSeederCfg); // Get the seeds - sourceLinkGrid.initialize(gctx, sourceLinks); - auto seeds = pathSeeder.getSeeds(gctx, sourceLinks); + pathWidthProvider.width = {1e-3, 1e-3}; + + std::vector seeds; + + // SeedTreeContainer seeds; + pathSeeder.findSeeds(gctx, sourceLinkGrid, seeds); // Check the seeds BOOST_CHECK_EQUAL(seeds.size(), 7); - for (auto& seed : seeds) { - BOOST_CHECK_EQUAL(seed.sourceLinks.size(), 4); - BOOST_CHECK_EQUAL(seed.ipVertex, Vector3(-5., 0., 0.)); - BOOST_CHECK_EQUAL(seed.ipP, 1._GeV); + + for (std::size_t i = 0; i < seeds.size(); i++) { + auto seed = seeds.at(i); + BOOST_CHECK_EQUAL(seed.second.size(), 4); + BOOST_CHECK_EQUAL(seed.first.phi(), truePhis.at(i)); + BOOST_CHECK_EQUAL(seed.first.theta(), trueTheta); + BOOST_CHECK_EQUAL(seed.first.qOverP(), trueQOverP); } } diff --git a/Tests/UnitTests/Core/TrackFitting/FitterTestsCommon.hpp b/Tests/UnitTests/Core/TrackFitting/FitterTestsCommon.hpp index 4eb411751bb..6692974ef63 100644 --- a/Tests/UnitTests/Core/TrackFitting/FitterTestsCommon.hpp +++ b/Tests/UnitTests/Core/TrackFitting/FitterTestsCommon.hpp @@ -90,7 +90,7 @@ auto makeStraightPropagator(std::shared_ptr geo) { cfg.resolveMaterial = true; cfg.resolveSensitive = true; Acts::Navigator navigator( - cfg, Acts::getDefaultLogger("Navigator", Acts::Logging::VERBOSE)); + cfg, Acts::getDefaultLogger("Navigator", Acts::Logging::INFO)); Acts::StraightLineStepper stepper; return Acts::Propagator( stepper, std::move(navigator)); @@ -105,7 +105,7 @@ auto makeConstantFieldPropagator( cfg.resolveMaterial = true; cfg.resolveSensitive = true; Acts::Navigator navigator( - cfg, Acts::getDefaultLogger("Navigator", Acts::Logging::VERBOSE)); + cfg, Acts::getDefaultLogger("Navigator", Acts::Logging::INFO)); auto field = std::make_shared(Acts::Vector3(0.0, 0.0, bz)); stepper_t stepper(std::move(field)); diff --git a/Tests/UnitTests/Core/Utilities/AngleHelpersTests.cpp b/Tests/UnitTests/Core/Utilities/AngleHelpersTests.cpp new file mode 100644 index 00000000000..5898986e6d5 --- /dev/null +++ b/Tests/UnitTests/Core/Utilities/AngleHelpersTests.cpp @@ -0,0 +1,29 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 CERN for the benefit of the ACTS project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +#include + +#include "Acts/Tests/CommonHelpers/FloatComparisons.hpp" +#include "Acts/Utilities/AngleHelpers.hpp" + +#include + +using Acts::AngleHelpers::etaFromTheta; +using Acts::AngleHelpers::thetaFromEta; + +BOOST_AUTO_TEST_SUITE(AngleHelpers) + +BOOST_AUTO_TEST_CASE(EtaThetaConversion) { + CHECK_CLOSE_ABS(0.0, etaFromTheta(std::numbers::pi / 2), 1e-6); + + CHECK_CLOSE_ABS(1.0, etaFromTheta(thetaFromEta(1.0)), 1e-6); + + CHECK_CLOSE_ABS(1.0, thetaFromEta(etaFromTheta(1.0)), 1e-6); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/Tests/UnitTests/Core/Utilities/CMakeLists.txt b/Tests/UnitTests/Core/Utilities/CMakeLists.txt index 2c00476c116..cb5249b6be9 100644 --- a/Tests/UnitTests/Core/Utilities/CMakeLists.txt +++ b/Tests/UnitTests/Core/Utilities/CMakeLists.txt @@ -56,6 +56,8 @@ add_unittest(ParticleData ParticleDataTests.cpp) add_unittest(Zip ZipTests.cpp) add_unittest(TransformRange TransformRangeTests.cpp) add_unittest(MathHelpers MathHelpersTests.cpp) +add_unittest(AngleHelpers AngleHelpersTests.cpp) +add_unittest(VectorHelpers VectorHelpersTests.cpp) add_unittest(TrackHelpers TrackHelpersTests.cpp) add_unittest(GraphViz GraphVizTests.cpp) diff --git a/Tests/UnitTests/Core/Utilities/KDTreeTests.cpp b/Tests/UnitTests/Core/Utilities/KDTreeTests.cpp index b1a70c399c7..15146e2eb60 100644 --- a/Tests/UnitTests/Core/Utilities/KDTreeTests.cpp +++ b/Tests/UnitTests/Core/Utilities/KDTreeTests.cpp @@ -482,12 +482,10 @@ BOOST_FIXTURE_TEST_CASE(range_search_combinatorial, TreeFixture3DDoubleInt2) { std::vector valid; - for (const std::pair, int>& i : - test_vector) { - const std::array& c = i.first; + for (const auto& [c, value] : test_vector) { if (xmin <= c[0] && c[0] < xmax && ymin <= c[1] && c[1] < ymax && zmin <= c[2] && c[2] < zmax) { - valid.push_back(i.second); + valid.push_back(value); } } diff --git a/Tests/UnitTests/Core/Utilities/VectorHelpersTests.cpp b/Tests/UnitTests/Core/Utilities/VectorHelpersTests.cpp new file mode 100644 index 00000000000..17ffe9d93a5 --- /dev/null +++ b/Tests/UnitTests/Core/Utilities/VectorHelpersTests.cpp @@ -0,0 +1,30 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 CERN for the benefit of the ACTS project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +#include + +#include "Acts/Definitions/Algebra.hpp" +#include "Acts/Tests/CommonHelpers/FloatComparisons.hpp" +#include "Acts/Utilities/VectorHelpers.hpp" + +#include + +using Acts::VectorHelpers::eta; +using Acts::VectorHelpers::theta; + +BOOST_AUTO_TEST_SUITE(AngleHelpers) + +BOOST_AUTO_TEST_CASE(EtaFromVector) { + CHECK_CLOSE_ABS(0.0, eta(Acts::Vector3{1, 0, 0}), 1e-6); +} + +BOOST_AUTO_TEST_CASE(ThetaFromVector) { + CHECK_CLOSE_ABS(std::numbers::pi / 2, theta(Acts::Vector3{1, 0, 0}), 1e-6); +} + +BOOST_AUTO_TEST_SUITE_END()