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 fa3027bb8f6..c2944f0dd06 100755 --- a/CI/physmon/phys_perf_mon.sh +++ b/CI/physmon/phys_perf_mon.sh @@ -15,13 +15,13 @@ function run() { export run - +run which python3 shopt -s extglob mode=${1:-all} -if ! [[ $mode = @(all|kf|gsf|gx2f|fullchains|simulation) ]]; then - echo "Usage: $0 (outdir)" +if ! [[ $mode = @(all|kf|gsf|gx2f|refit_kf|refit_gsf|fullchains|simulation) ]]; then + echo "Usage: $0 (outdir)" exit 1 fi @@ -152,6 +152,12 @@ fi if [[ "$mode" == "all" || "$mode" == "gx2f" ]]; then run_physmon_gen "Truth Tracking GX2F" "trackfitting_gx2f" fi +if [[ "$mode" == "all" || "$mode" == "refit_kf" ]]; then + run_physmon_gen "Truth Tracking KF refit" "trackrefitting_kf" +fi +if [[ "$mode" == "all" || "$mode" == "refit_gsf" ]]; then + run_physmon_gen "Truth Tracking GSF refit" "trackrefitting_gsf" +fi if [[ "$mode" == "all" || "$mode" == "fullchains" ]]; then run_physmon_gen "CKF single muon" "trackfinding_1muon" run_physmon_gen "CKF muon 50" "trackfinding_4muon_50vertices" @@ -217,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 \ @@ -238,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 } @@ -411,6 +426,26 @@ if [[ "$mode" == "all" || "$mode" == "gx2f" ]]; then --config CI/physmon/config/trackfitting_gx2f.yml fi +if [[ "$mode" == "all" || "$mode" == "kf_refit" ]]; then + run_histcmp \ + $outdir/data/trackrefitting_kf/performance_trackrefitting.root \ + $refdir/trackrefitting_kf/performance_trackrefitting.root \ + "Truth tracking (KF refit)" \ + trackrefitting_kf/performance_trackrefitting.html \ + trackrefitting_kf/performance_trackrefitting_plots \ + --config CI/physmon/config/trackfitting_kf.yml +fi + +if [[ "$mode" == "all" || "$mode" == "gsf_refit" ]]; then + run_histcmp \ + $outdir/data/trackrefitting_gsf/performance_trackrefitting.root \ + $refdir/trackrefitting_gsf/performance_trackrefitting.root \ + "Truth tracking (GSF refit)" \ + trackrefitting_gsf/performance_trackrefitting.html \ + trackrefitting_gsf/performance_trackrefitting_plots \ + --config CI/physmon/config/trackfitting_gsf.yml +fi + if [[ "$mode" == "all" || "$mode" == "fullchains" ]]; then trackfinding "trackfinding | single muon | truth smeared seeding" trackfinding_1muon/truth_smeared trackfinding "trackfinding | single muon | truth estimated seeding" trackfinding_1muon/truth_estimated 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 26472832eeb..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 1a1651abd5c..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 74c3632898b..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 new file mode 100644 index 00000000000..b6b8d6fd126 Binary files /dev/null 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 new file mode 100644 index 00000000000..99385589d48 Binary files /dev/null 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 d06f99fbdb6..aaa4bc9f71d 100755 --- a/CI/physmon/workflows/physmon_trackfinding_1muon.py +++ b/CI/physmon/workflows/physmon_trackfinding_1muon.py @@ -11,13 +11,13 @@ EtaConfig, PhiConfig, ParticleConfig, + ParticleSelectorConfig, addFatras, addDigitization, ) from acts.examples.reconstruction import ( addSeeding, - TruthSeedRanges, ParticleSmearingSigmas, SeedFinderConfigArg, SeedFinderOptionsArg, @@ -72,6 +72,11 @@ def run_ckf_tracking(label, seeding): setup.field, enableInteractions=True, rnd=rnd, + postSelectParticles=ParticleSelectorConfig( + pt=(0.9 * u.GeV, None), + measurements=(9, None), + removeNeutral=True, + ), ) addDigitization( @@ -86,7 +91,6 @@ def run_ckf_tracking(label, seeding): s, setup.trackingGeometry, setup.field, - TruthSeedRanges(pt=(500 * u.MeV, None), nHits=(9, None)), ParticleSmearingSigmas( # only used by SeedingAlgorithm.TruthSmeared # zero eveything so the CKF has a chance to find the measurements d0=0, @@ -108,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), @@ -134,7 +138,7 @@ def run_ckf_tracking(label, seeding): setup.trackingGeometry, setup.field, TrackSelectorConfig( - pt=(500 * u.MeV, None), + pt=(0.9 * u.GeV, None), loc0=(-4.0 * u.mm, 4.0 * u.mm), nMeasurementsMin=6, maxHoles=2, @@ -159,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 e1ece122c45..1a119c8ed6c 100755 --- a/CI/physmon/workflows/physmon_trackfinding_4muon_50vertices.py +++ b/CI/physmon/workflows/physmon_trackfinding_4muon_50vertices.py @@ -11,12 +11,12 @@ EtaConfig, PhiConfig, ParticleConfig, + ParticleSelectorConfig, addFatras, addDigitization, ) from acts.examples.reconstruction import ( addSeeding, - TruthSeedRanges, SeedFinderConfigArg, SeedFinderOptionsArg, SeedingAlgorithm, @@ -69,6 +69,11 @@ setup.trackingGeometry, setup.field, rnd=rnd, + postSelectParticles=ParticleSelectorConfig( + pt=(0.9 * u.GeV, None), + measurements=(9, None), + removeNeutral=True, + ), ) addDigitization( @@ -83,7 +88,6 @@ s, setup.trackingGeometry, setup.field, - TruthSeedRanges(pt=(500.0 * u.MeV, None), nHits=(9, None)), SeedFinderConfigArg( r=(33 * u.mm, 200 * u.mm), deltaR=(1 * u.mm, 60 * u.mm), @@ -92,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)), @@ -116,7 +120,7 @@ setup.trackingGeometry, setup.field, TrackSelectorConfig( - pt=(500 * u.MeV, None), + pt=(0.9 * u.GeV, None), loc0=(-4.0 * u.mm, 4.0 * u.mm), nMeasurementsMin=6, maxHoles=2, @@ -192,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( @@ -204,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 172fa55270a..99f12d0170d 100755 --- a/CI/physmon/workflows/physmon_trackfinding_ttbar_pu200.py +++ b/CI/physmon/workflows/physmon_trackfinding_ttbar_pu200.py @@ -13,7 +13,6 @@ ) from acts.examples.reconstruction import ( addSeeding, - TruthSeedRanges, SeedFinderConfigArg, SeedFinderOptionsArg, SeedingAlgorithm, @@ -68,6 +67,11 @@ rho=(0.0, 24 * u.mm), absZ=(0.0, 1.0 * u.m), ), + postSelectParticles=ParticleSelectorConfig( + pt=(0.5 * u.GeV, None), + measurements=(9, None), + removeNeutral=True, + ), ) addDigitization( @@ -82,7 +86,6 @@ s, setup.trackingGeometry, setup.field, - TruthSeedRanges(pt=(500.0 * u.MeV, None), nHits=(9, None)), SeedFinderConfigArg( r=(33 * u.mm, 200 * u.mm), deltaR=(1 * u.mm, 60 * u.mm), @@ -91,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)), @@ -115,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, @@ -177,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( @@ -189,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/CI/physmon/workflows/physmon_trackrefitting_gsf.py b/CI/physmon/workflows/physmon_trackrefitting_gsf.py new file mode 100755 index 00000000000..5477121942a --- /dev/null +++ b/CI/physmon/workflows/physmon_trackrefitting_gsf.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 + +import tempfile +from pathlib import Path +import shutil + +import acts +from truth_tracking_gsf_refitting import runRefittingGsf + +from physmon_common import makeSetup + +setup = makeSetup() + +with tempfile.TemporaryDirectory() as temp: + s = acts.examples.Sequencer( + events=10000, + numThreads=-1, + logLevel=acts.logging.INFO, + ) + + tp = Path(temp) + runRefittingGsf( + trackingGeometry=setup.trackingGeometry, + field=setup.field, + digiConfigFile=setup.digiConfig, + outputDir=tp, + s=s, + ) + + s.run() + + perf_file = tp / "performance_gsf_refit.root" + assert perf_file.exists(), "Performance file not found" + shutil.copy(perf_file, setup.outdir / "performance_trackrefitting.root") diff --git a/CI/physmon/workflows/physmon_trackrefitting_kf.py b/CI/physmon/workflows/physmon_trackrefitting_kf.py new file mode 100755 index 00000000000..ea82d26c701 --- /dev/null +++ b/CI/physmon/workflows/physmon_trackrefitting_kf.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 + +import tempfile +from pathlib import Path +import shutil + +import acts +from truth_tracking_kalman_refitting import runRefittingKf + +from physmon_common import makeSetup + +setup = makeSetup() + +with tempfile.TemporaryDirectory() as temp: + s = acts.examples.Sequencer( + events=10000, + numThreads=-1, + logLevel=acts.logging.INFO, + ) + + tp = Path(temp) + runRefittingKf( + trackingGeometry=setup.trackingGeometry, + field=setup.field, + digiConfigFile=setup.digiConfig, + outputDir=tp, + s=s, + ) + + s.run() + + perf_file = tp / "performance_kf_refit.root" + assert perf_file.exists(), "Performance file not found" + shutil.copy(perf_file, setup.outdir / "performance_trackrefitting.root") diff --git a/CMakeLists.txt b/CMakeLists.txt index 0bbfae3efa8..f81002cab83 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,6 @@ option(ACTS_FORCE_ASSERTIONS "Force assertions regardless of build type" OFF) option(ACTS_USE_SYSTEM_LIBS "Use system libraries by default" OFF) # plugins related options option(ACTS_USE_SYSTEM_ACTSVG "Use the ActSVG system library" ${ACTS_USE_SYSTEM_LIBS}) -option(ACTS_USE_SYSTEM_GEOMODEL "Use a system-provided GeoModel installation" ${ACTS_USE_SYSTEM_LIBS}) option(ACTS_USE_SYSTEM_COVFIE "Use a system-provided covfie installation" ${ACTS_USE_SYSTEM_LIBS}) option(ACTS_USE_SYSTEM_DETRAY "Use a system-provided detray installation" ${ACTS_USE_SYSTEM_LIBS}) option(ACTS_USE_SYSTEM_TRACCC "Use a system-provided traccc installation" ${ACTS_USE_SYSTEM_LIBS}) @@ -228,8 +227,8 @@ 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_geomodel_version 6.3.0) set(_acts_eigen3_version 3.4.0) set(_acts_podio_version 1.0.1) # will try this first set(_acts_podio_fallback_version 0.16) # if not found, will try this one @@ -374,8 +373,24 @@ if(ACTS_BUILD_PLUGIN_JSON) endif() endif() if(ACTS_BUILD_PLUGIN_GEOMODEL) - find_package(GeoModelCore ${_acts_geomodel_version} REQUIRED CONFIG) - find_package(GeoModelIO ${_acts_geomodel_version} REQUIRED CONFIG) + find_package(GeoModelCore CONFIG) + if(NOT GeoModelCore_FOUND) + message( + FATAL_ERROR + "GeoModel not found. Please install GeoModel or set ACTS_BUILD_PLUGIN_GEOMODEL to OFF." + ) + endif() + + set(_gm_ver_min 6.3.0) + + if(GeoModelCore_VERSION VERSION_LESS _gm_ver_min) + message( + FATAL_ERROR + "GeoModel version ${GeoModelCore_VERSION} is insufficient. Please install GeoModel version ${_gm_ver_min} or newer." + ) + endif() + # find other GeoModel components of EXACT same version + find_package(GeoModelIO ${GeoModelCore_VERSION} REQUIRED EXACT CONFIG) endif() if(ACTS_BUILD_PLUGIN_TGEO) find_package( @@ -439,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/CMakePresets.json b/CMakePresets.json index bee5ab514df..2aef0f3fe94 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -46,7 +46,7 @@ "inherits": "common", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release", - "CMAKE_CXX_FLAGS": "-Werror", + "CMAKE_COMPILE_WARNING_AS_ERROR": "ON", "ACTS_FORCE_ASSERTIONS": "ON", "ACTS_ENABLE_LOG_FAILURE_THRESHOLD": "ON", "ACTS_BUILD_BENCHMARKS": "ON", diff --git a/Core/CMakeLists.txt b/Core/CMakeLists.txt index eeb6bc8b92a..554656f514c 100644 --- a/Core/CMakeLists.txt +++ b/Core/CMakeLists.txt @@ -110,6 +110,7 @@ add_subdirectory(src/MagneticField) add_subdirectory(src/Material) add_subdirectory(src/Navigation) add_subdirectory(src/Propagator) +add_subdirectory(src/Seeding) add_subdirectory(src/Surfaces) add_subdirectory(src/TrackFinding) add_subdirectory(src/TrackFitting) diff --git a/Core/include/Acts/EventData/GenericBoundTrackParameters.hpp b/Core/include/Acts/EventData/GenericBoundTrackParameters.hpp index 27b411a99cc..f624cd88aee 100644 --- a/Core/include/Acts/EventData/GenericBoundTrackParameters.hpp +++ b/Core/include/Acts/EventData/GenericBoundTrackParameters.hpp @@ -250,6 +250,17 @@ class GenericBoundTrackParameters { return m_surface->referenceFrame(geoCtx, position(geoCtx), momentum()); } + /// Reflect the parameters in place. + void reflectInPlace() { m_params = reflectBoundParameters(m_params); } + + /// Reflect the parameters. + /// @return Reflected parameters. + GenericBoundTrackParameters reflect() const { + GenericBoundTrackParameters reflected = *this; + reflected.reflectInPlace(); + return reflected; + } + private: BoundVector m_params; std::optional m_cov; diff --git a/Core/include/Acts/EventData/GenericCurvilinearTrackParameters.hpp b/Core/include/Acts/EventData/GenericCurvilinearTrackParameters.hpp index a42ac2f116f..6e4ed9bae7a 100644 --- a/Core/include/Acts/EventData/GenericCurvilinearTrackParameters.hpp +++ b/Core/include/Acts/EventData/GenericCurvilinearTrackParameters.hpp @@ -111,6 +111,14 @@ class GenericCurvilinearTrackParameters Vector3 position() const { return GenericBoundTrackParameters::position({}); } + + /// Reflect the parameters. + /// @return Reflected parameters. + GenericCurvilinearTrackParameters reflect() const { + GenericCurvilinearTrackParameters reflected = *this; + reflected.reflectInPlace(); + return reflected; + } }; } // namespace Acts diff --git a/Core/include/Acts/EventData/GenericFreeTrackParameters.hpp b/Core/include/Acts/EventData/GenericFreeTrackParameters.hpp index 1e7846318ef..214aa2e1551 100644 --- a/Core/include/Acts/EventData/GenericFreeTrackParameters.hpp +++ b/Core/include/Acts/EventData/GenericFreeTrackParameters.hpp @@ -12,9 +12,11 @@ #include "Acts/Definitions/Common.hpp" #include "Acts/Definitions/TrackParametrization.hpp" #include "Acts/EventData/TrackParametersConcept.hpp" +#include "Acts/EventData/TransformationHelpers.hpp" #include "Acts/EventData/detail/PrintParameters.hpp" #include "Acts/Utilities/MathHelpers.hpp" #include "Acts/Utilities/UnitVectors.hpp" +#include "Acts/Utilities/VectorHelpers.hpp" #include #include @@ -55,6 +57,29 @@ class GenericFreeTrackParameters { m_cov(std::move(cov)), m_particleHypothesis(std::move(particleHypothesis)) {} + /// Construct from four-position, direction, absolute momentum, and charge. + /// + /// @param pos4 Track position/time four-vector + /// @param dir Track direction three-vector; normalization is ignored. + /// @param qOverP Charge over momentum + /// @param cov Free parameters covariance matrix + /// @param particleHypothesis Particle hypothesis + GenericFreeTrackParameters(const Vector4& pos4, const Vector3& dir, + Scalar qOverP, std::optional cov, + ParticleHypothesis particleHypothesis) + : m_params(FreeVector::Zero()), + m_cov(std::move(cov)), + m_particleHypothesis(std::move(particleHypothesis)) { + m_params[eFreePos0] = pos4[ePos0]; + m_params[eFreePos1] = pos4[ePos1]; + m_params[eFreePos2] = pos4[ePos2]; + m_params[eFreeTime] = pos4[eTime]; + m_params[eFreeDir0] = dir[eMom0]; + m_params[eFreeDir1] = dir[eMom1]; + m_params[eFreeDir2] = dir[eMom2]; + m_params[eFreeQOverP] = qOverP; + } + /// Construct from four-position, angles, absolute momentum, and charge. /// /// @param pos4 Track position/time four-vector @@ -135,9 +160,9 @@ class GenericFreeTrackParameters { Scalar time() const { return m_params[eFreeTime]; } /// Phi direction. - Scalar phi() const { return phi(direction()); } + Scalar phi() const { return VectorHelpers::phi(direction()); } /// Theta direction. - Scalar theta() const { return theta(direction()); } + Scalar theta() const { return VectorHelpers::theta(direction()); } /// Charge over momentum. Scalar qOverP() const { return m_params[eFreeQOverP]; } @@ -175,6 +200,17 @@ class GenericFreeTrackParameters { return m_particleHypothesis; } + /// Reflect the parameters in place. + void reflectInPlace() { m_params = reflectFreeParameters(m_params); } + + /// Reflect the parameters. + /// @return Reflected parameters. + GenericFreeTrackParameters reflect() const { + GenericFreeTrackParameters reflected = *this; + reflected.reflectInPlace(); + return reflected; + } + private: FreeVector m_params; std::optional m_cov; diff --git a/Core/include/Acts/EventData/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/EventData/TrackProxy.hpp b/Core/include/Acts/EventData/TrackProxy.hpp index ce674e9cfa4..5939022e2e8 100644 --- a/Core/include/Acts/EventData/TrackProxy.hpp +++ b/Core/include/Acts/EventData/TrackProxy.hpp @@ -324,7 +324,8 @@ class TrackProxy { return std::distance(tsRange.begin(), tsRange.end()); } - /// Return the number of measurements for the track. Const version + /// Return a mutable reference to the number of measurements for the track. + /// Mutable version /// @note Only available if the track proxy is not read-only /// @return The number of measurements unsigned int& nMeasurements() @@ -333,8 +334,7 @@ class TrackProxy { return component(); } - /// Return a mutable reference to the number of measurements for the track. - /// Mutable version + /// Return the number of measurements for the track. Const version /// @return The number of measurements unsigned int nMeasurements() const { return component(); diff --git a/Core/include/Acts/EventData/TransformationHelpers.hpp b/Core/include/Acts/EventData/TransformationHelpers.hpp index 7fa297f4abc..39240bf469e 100644 --- a/Core/include/Acts/EventData/TransformationHelpers.hpp +++ b/Core/include/Acts/EventData/TransformationHelpers.hpp @@ -13,11 +13,39 @@ #include "Acts/Definitions/TrackParametrization.hpp" #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Utilities/Result.hpp" +#include "Acts/Utilities/detail/periodic.hpp" namespace Acts { class Surface; +/// Reflect bound track parameters. +/// +/// @param boundParams Bound track parameters vector +/// @return Reflected bound track parameters vector +inline BoundVector reflectBoundParameters(const BoundVector& boundParams) { + BoundVector reflected = boundParams; + auto [phi, theta] = detail::normalizePhiTheta( + boundParams[eBoundPhi] - M_PI, M_PI - boundParams[eBoundTheta]); + reflected[eBoundPhi] = phi; + reflected[eBoundTheta] = theta; + reflected[eBoundQOverP] = -boundParams[eBoundQOverP]; + return reflected; +} + +/// Reflect free track parameters. +/// +/// @param freeParams Free track parameters vector +/// @return Reflected free track parameters vector +inline FreeVector reflectFreeParameters(const FreeVector& freeParams) { + FreeVector reflected = freeParams; + reflected[eFreeDir0] = -freeParams[eFreeDir0]; + reflected[eFreeDir1] = -freeParams[eFreeDir1]; + reflected[eFreeDir2] = -freeParams[eFreeDir2]; + reflected[eFreeQOverP] = -freeParams[eFreeQOverP]; + return reflected; +} + /// Transform bound track parameters into equivalent free track parameters. /// /// @param surface Surface onto which the input parameters are bound diff --git a/Core/include/Acts/Geometry/CylinderVolumeBounds.hpp b/Core/include/Acts/Geometry/CylinderVolumeBounds.hpp index 1951d96b2da..002af04cd59 100644 --- a/Core/include/Acts/Geometry/CylinderVolumeBounds.hpp +++ b/Core/include/Acts/Geometry/CylinderVolumeBounds.hpp @@ -128,7 +128,7 @@ class CylinderVolumeBounds : public VolumeBounds { /// Copy Constructor /// /// @param cylbo is the source cylinder volume bounds for the copy - CylinderVolumeBounds(const CylinderVolumeBounds& cylbo) = default; + CylinderVolumeBounds(const CylinderVolumeBounds& cylbo); ~CylinderVolumeBounds() override = default; CylinderVolumeBounds& operator=(const CylinderVolumeBounds& cylbo) = default; diff --git a/Core/include/Acts/Propagator/DirectNavigator.hpp b/Core/include/Acts/Propagator/DirectNavigator.hpp index 8df2afdfe8e..eb9db91e71f 100644 --- a/Core/include/Acts/Propagator/DirectNavigator.hpp +++ b/Core/include/Acts/Propagator/DirectNavigator.hpp @@ -8,6 +8,7 @@ #pragma once +#include "Acts/Definitions/Direction.hpp" #include "Acts/Geometry/BoundarySurfaceT.hpp" #include "Acts/Geometry/Layer.hpp" #include "Acts/Geometry/TrackingGeometry.hpp" @@ -17,6 +18,7 @@ #include "Acts/Surfaces/BoundaryTolerance.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Utilities/Intersection.hpp" +#include "Acts/Utilities/Logger.hpp" #include #include @@ -63,7 +65,7 @@ class DirectNavigator { Options options; /// Index of the next surface to try - std::size_t surfaceIndex = 0; + int surfaceIndex = 0; /// Navigation state - external interface: the current surface const Surface* currentSurface = nullptr; @@ -72,6 +74,35 @@ class DirectNavigator { bool targetReached = false; /// Navigation state - external interface: a break has been detected bool navigationBreak = false; + + const Surface* navSurface() const { + return options.surfaces.at(surfaceIndex); + } + + void nextSurface(Direction direction) { + if (direction == Direction::Forward) { + ++surfaceIndex; + } else { + --surfaceIndex; + } + } + + bool endOfSurfaces() const { + return surfaceIndex < 0 || + surfaceIndex >= static_cast(options.surfaces.size()); + } + + int remainingSurfaces(Direction direction) const { + if (direction == Direction::Forward) { + return options.surfaces.size() - surfaceIndex; + } + return surfaceIndex + 1; + } + + void resetSurfaceIndex(Direction direction) { + surfaceIndex = + direction == Direction::Forward ? 0 : options.surfaces.size() - 1; + } }; explicit DirectNavigator(std::unique_ptr _logger = @@ -135,17 +166,41 @@ class DirectNavigator { void initialize(propagator_state_t& state, const stepper_t& /*stepper*/) const { ACTS_VERBOSE("Initialize. Surface sequence for navigation:"); - for (auto surface : state.navigation.options.surfaces) { + for (const Surface* surface : state.navigation.options.surfaces) { ACTS_VERBOSE(surface->geometryId() << " - " << surface->center(state.geoContext).transpose()); } // We set the current surface to the start surface state.navigation.currentSurface = state.navigation.options.startSurface; - if (state.navigation.currentSurface) { + if (state.navigation.currentSurface != nullptr) { ACTS_VERBOSE("Current surface set to start surface " << state.navigation.currentSurface->geometryId()); + } else { + ACTS_VERBOSE("Current surface set to nullptr"); + } + + // Reset the surface index + state.navigation.resetSurfaceIndex(state.options.direction); + for (const Surface* surface : state.navigation.options.surfaces) { + // make sure we skip over the start surface + state.navigation.nextSurface(state.options.direction); + if (surface == state.navigation.currentSurface) { + break; + } + } + ACTS_VERBOSE("Start surface index set to " + << state.navigation.surfaceIndex); + if (state.navigation.endOfSurfaces()) { + ACTS_DEBUG( + "Did not find the start surface in the sequence. Assuming it is not " + "part of the sequence. Trusting the correctness of the input " + "sequence. Resetting the surface index."); + state.navigation.resetSurfaceIndex(state.options.direction); } + + state.navigation.navigationBreak = false; + state.navigation.targetReached = false; } /// @brief Navigator pre step call @@ -157,21 +212,25 @@ class DirectNavigator { /// @param [in] stepper Stepper in use template void preStep(propagator_state_t& state, const stepper_t& stepper) const { + if (state.navigation.navigationBreak) { + return; + } + ACTS_VERBOSE("pre step"); // Navigator target always resets the current surface state.navigation.currentSurface = nullptr; // Output the position in the sequence - ACTS_VERBOSE((state.navigation.options.surfaces.size() - - state.navigation.surfaceIndex) + ACTS_VERBOSE(state.navigation.remainingSurfaces(state.options.direction) << " out of " << state.navigation.options.surfaces.size() << " surfaces remain to try."); - if (state.navigation.surfaceIndex >= - state.navigation.options.surfaces.size()) { + if (state.navigation.endOfSurfaces()) { // Set the navigation break + ACTS_VERBOSE("End of surfaces reached, navigation break."); state.navigation.navigationBreak = true; + stepper.releaseStepSize(state.stepping, ConstrainedStep::actor); // If no externally provided target is given, the target is reached if (state.navigation.options.targetSurface == nullptr) { state.navigation.targetReached = true; @@ -183,8 +242,7 @@ class DirectNavigator { // Establish & update the surface status // TODO we do not know the intersection index - passing the closer one - const auto& surface = - *state.navigation.options.surfaces.at(state.navigation.surfaceIndex); + const auto& surface = *state.navigation.navSurface(); const double farLimit = std::numeric_limits::max(); const auto index = chooseIntersection( @@ -202,7 +260,7 @@ class DirectNavigator { "Surface not reachable anymore, switching to next one in " "sequence"); // Move the sequence to the next surface - ++state.navigation.surfaceIndex; + state.navigation.nextSurface(state.options.direction); } else { ACTS_VERBOSE("Navigation stepSize set to " << stepper.outputStepSize(state.stepping)); @@ -218,26 +276,27 @@ class DirectNavigator { /// @param [in] stepper Stepper in use template void postStep(propagator_state_t& state, const stepper_t& stepper) const { + if (state.navigation.navigationBreak) { + return; + } + ACTS_VERBOSE("post step"); // Navigator post step always resets the current surface state.navigation.currentSurface = nullptr; // Output the position in the sequence - ACTS_VERBOSE((state.navigation.options.surfaces.size() - - state.navigation.surfaceIndex) + ACTS_VERBOSE(state.navigation.remainingSurfaces(state.options.direction) << " out of " << state.navigation.options.surfaces.size() << " surfaces remain to try."); - if (state.navigation.surfaceIndex >= - state.navigation.options.surfaces.size()) { + if (state.navigation.endOfSurfaces()) { return; } // Establish the surface status // TODO we do not know the intersection index - passing the closer one - const auto& surface = - *state.navigation.options.surfaces.at(state.navigation.surfaceIndex); + const auto& surface = *state.navigation.navSurface(); const double farLimit = std::numeric_limits::max(); const auto index = chooseIntersection( @@ -252,14 +311,12 @@ class DirectNavigator { *m_logger); if (surfaceStatus == Intersection3D::Status::onSurface) { // Set the current surface - state.navigation.currentSurface = - state.navigation.options.surfaces.at(state.navigation.surfaceIndex); + state.navigation.currentSurface = state.navigation.navSurface(); ACTS_VERBOSE("Current surface set to " << state.navigation.currentSurface->geometryId()); // Move the sequence to the next surface - ++state.navigation.surfaceIndex; - if (state.navigation.surfaceIndex < - state.navigation.options.surfaces.size()) { + state.navigation.nextSurface(state.options.direction); + if (!state.navigation.endOfSurfaces()) { ACTS_VERBOSE("Next surface candidate is " << state.navigation.options.surfaces .at(state.navigation.surfaceIndex) diff --git a/Core/include/Acts/Propagator/MultiStepperAborters.hpp b/Core/include/Acts/Propagator/MultiStepperAborters.hpp index f675200975e..0e28375df94 100644 --- a/Core/include/Acts/Propagator/MultiStepperAborters.hpp +++ b/Core/include/Acts/Propagator/MultiStepperAborters.hpp @@ -71,8 +71,8 @@ struct MultiStepperSurfaceReached : public SurfaceReached { } ACTS_VERBOSE( - "MultiStepperSurfaceReached aborter | " - "Target intersection not found. Maybe next time?"); + "MultiStepperSurfaceReached aborter | Average distance to target: " + << sIntersection.pathLength()); } bool reached = true; @@ -84,6 +84,7 @@ struct MultiStepperSurfaceReached : public SurfaceReached { if (!SurfaceReached::checkAbort(singleState, singleStepper, navigator, logger)) { + cmp.status() = Acts::Intersection3D::Status::reachable; reached = false; } else { cmp.status() = Acts::Intersection3D::Status::onSurface; diff --git a/Core/include/Acts/Propagator/Navigator.hpp b/Core/include/Acts/Propagator/Navigator.hpp index b2bea757749..c2a9427257c 100644 --- a/Core/include/Acts/Propagator/Navigator.hpp +++ b/Core/include/Acts/Propagator/Navigator.hpp @@ -205,8 +205,6 @@ class Navigator { : m_cfg{std::move(cfg)}, m_logger{std::move(_logger)} {} State makeState(const Options& options) const { - assert(options.startSurface != nullptr && "Start surface must be set"); - State state; state.options = options; state.startSurface = options.startSurface; diff --git a/Core/include/Acts/Propagator/TryAllNavigator.hpp b/Core/include/Acts/Propagator/TryAllNavigator.hpp index 9a3a2d78475..83d7cbc64a4 100644 --- a/Core/include/Acts/Propagator/TryAllNavigator.hpp +++ b/Core/include/Acts/Propagator/TryAllNavigator.hpp @@ -96,8 +96,6 @@ class TryAllNavigatorBase { : m_cfg(std::move(cfg)), m_logger{std::move(_logger)} {} State makeState(const Options& options) const { - assert(options.startSurface != nullptr && "Start surface must be set"); - State state; state.options = options; state.startSurface = options.startSurface; @@ -587,8 +585,6 @@ class TryAllOverstepNavigator : public TryAllNavigatorBase { : TryAllNavigatorBase(std::move(cfg), std::move(logger)) {} State makeState(const Options& options) const { - assert(options.startSurface != nullptr && "Start surface must be set"); - State state; state.options = options; state.startSurface = options.startSurface; diff --git a/Core/include/Acts/Seeding/EstimateTrackParamsFromSeed.hpp b/Core/include/Acts/Seeding/EstimateTrackParamsFromSeed.hpp index 7a5c597f626..f3850e102ce 100644 --- a/Core/include/Acts/Seeding/EstimateTrackParamsFromSeed.hpp +++ b/Core/include/Acts/Seeding/EstimateTrackParamsFromSeed.hpp @@ -287,4 +287,41 @@ std::optional estimateTrackParamsFromSeed( return params; } +/// Configuration for the estimation of the covariance matrix of the track +/// parameters with `estimateTrackParamCovariance`. +struct EstimateTrackParamCovarianceConfig { + /// The initial sigmas for the track parameters + BoundVector initialSigmas = {1. * UnitConstants::mm, + 1. * UnitConstants::mm, + 1. * UnitConstants::degree, + 1. * UnitConstants::degree, + 1. * UnitConstants::e / UnitConstants::GeV, + 1. * UnitConstants::ns}; + + /// The initial relative uncertainty of the q/pt + double initialSigmaPtRel = 0.1; + + /// The inflation factors for the variances of the track parameters + BoundVector initialVarInflation = {1., 1., 1., 1., 1., 1.}; + /// The inflation factor for time uncertainty if the time parameter was not + /// estimated + double noTimeVarInflation = 100.; +}; + +/// Estimate the covariance matrix of the given track parameters based on the +/// provided configuration. The assumption is that we can model the uncertainty +/// of the track parameters as a diagonal matrix with the provided initial +/// sigmas. The inflation factors are used to inflate the initial variances +/// based on the provided configuration. The uncertainty of q/p is estimated +/// based on the relative uncertainty of the q/pt and the theta uncertainty. +/// +/// @param config is the configuration for the estimation +/// @param params is the track parameters +/// @param hasTime is true if the track parameters have time +/// +/// @return the covariance matrix of the track parameters +BoundMatrix estimateTrackParamCovariance( + const EstimateTrackParamCovarianceConfig& config, const BoundVector& params, + bool hasTime); + } // namespace Acts diff --git a/Core/include/Acts/Seeding/HoughTransformUtils.hpp b/Core/include/Acts/Seeding/HoughTransformUtils.hpp index a7a84d8908c..4fcece48034 100644 --- a/Core/include/Acts/Seeding/HoughTransformUtils.hpp +++ b/Core/include/Acts/Seeding/HoughTransformUtils.hpp @@ -14,6 +14,7 @@ #include "Acts/Utilities/Logger.hpp" #include "Acts/Utilities/Result.hpp" +#include #include #include #include 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/SeedFinder.ipp b/Core/include/Acts/Seeding/SeedFinder.ipp index 2896fba925f..45b95ec05d5 100644 --- a/Core/include/Acts/Seeding/SeedFinder.ipp +++ b/Core/include/Acts/Seeding/SeedFinder.ipp @@ -368,8 +368,15 @@ SeedFinder::getCompatibleDoublets( const float uT = xNewFrame * iDeltaR2; const float vT = yNewFrame * iDeltaR2; - // interactionPointCut == true we apply this cut first cuts before - // coordinate transformation to avoid unnecessary calculations + // We check the interaction point by evaluating the minimal distance + // between the origin and the straight line connecting the two points in + // the doublets. Using a geometric similarity, the Im is given by + // yNewFrame * rM / deltaR <= m_config.impactMax + // However, we make here an approximation of the impact parameter + // which is valid under the assumption yNewFrame / xNewFrame is small + // The correct computation would be: + // yNewFrame * yNewFrame * rM * rM <= m_config.impactMax * + // m_config.impactMax * deltaR2 if (std::abs(rM * yNewFrame) <= impactMax * xNewFrame) { // check if duplet cotTheta is within the region of interest // cotTheta is defined as (deltaZ / deltaR) but instead we multiply 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 d0e8526dc35..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 @@ -142,7 +142,7 @@ class TrackSelector { std::vector cutSets = {}; /// Eta bin edges for varying cuts by eta - std::vector absEtaEdges = {}; + std::vector absEtaEdges = {0, inf}; /// Get the number of eta bins /// @return Number of eta bins @@ -150,7 +150,7 @@ class TrackSelector { /// Construct an empty (accepts everything) configuration. /// Results in a single cut set and one abs eta bin from 0 to infinity. - EtaBinnedConfig() : cutSets{{}}, absEtaEdges{{0, inf}} {}; + EtaBinnedConfig() : cutSets{{}} {}; /// Constructor to create a config object that is not upper-bounded. /// This is useful to use the "fluent" API to populate the configuration. @@ -163,13 +163,12 @@ class TrackSelector { /// @param absEtaEdgesIn is the vector of eta bin edges EtaBinnedConfig(std::vector absEtaEdgesIn) : absEtaEdges{std::move(absEtaEdgesIn)} { - cutSets.resize(absEtaEdges.size() - 1); + cutSets.resize(nEtaBins()); } /// Auto-converting constructor from a single cut configuration. /// Results in a single absolute eta bin from 0 to infinity. - EtaBinnedConfig(Config cutSet) - : cutSets{std::move(cutSet)}, absEtaEdges{{0, inf}} {} + EtaBinnedConfig(Config cutSet) : cutSets{std::move(cutSet)} {} /// Add a new eta bin with the given upper bound. /// @param etaMax Upper bound of the new eta bin @@ -195,11 +194,17 @@ class TrackSelector { /// @return True if the configuration has a bin for the given eta bool hasCuts(double eta) const; - /// Get the index of the eta bin for a given eta + /// Get the index of the eta bin for a given eta. + /// throws an exception if Eta is outside the abs eta bin edges. /// @param eta Eta value /// @return Index of the eta bin std::size_t binIndex(double eta) const; + /// Get the index of the eta bin for a given eta + /// @param eta Eta value + /// @return Index of the eta bin, or >= nEtaBins() if Eta is outside the abs eta bin edges. + std::size_t binIndexNoCheck(double eta) const; + /// Get the cuts for a given eta /// @param eta Eta value /// @return Cuts for the given eta @@ -237,8 +242,7 @@ class TrackSelector { private: EtaBinnedConfig m_cfg; - bool m_isUnbinned; - bool m_noEtaCuts; + bool m_isUnbinned = false; }; inline TrackSelector::Config& TrackSelector::Config::loc0(double min, @@ -350,14 +354,22 @@ inline bool TrackSelector::EtaBinnedConfig::hasCuts(double eta) const { } inline std::size_t TrackSelector::EtaBinnedConfig::binIndex(double eta) const { - if (!hasCuts(eta)) { + std::size_t index = binIndexNoCheck(eta); + if (!(index < nEtaBins())) { throw std::invalid_argument{"Eta is outside the abs eta bin edges"}; } + return index; +} +inline std::size_t TrackSelector::EtaBinnedConfig::binIndexNoCheck( + double eta) const { auto binIt = std::upper_bound(absEtaEdges.begin(), absEtaEdges.end(), std::abs(eta)); - std::size_t index = std::distance(absEtaEdges.begin(), binIt) - 1; - return index; + std::size_t index = std::distance(absEtaEdges.begin(), binIt); + if (index == 0) { + index = absEtaEdges.size() + 1; // positive value to check for underflow + } + return index - 1; } inline const TrackSelector::Config& TrackSelector::EtaBinnedConfig::getCuts( @@ -407,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; @@ -428,8 +440,8 @@ bool TrackSelector::isValidTrack(const track_proxy_t& track) const { return track.hasReferenceSurface() && within(track.transverseMomentum(), cuts.ptMin, cuts.ptMax) && - (m_noEtaCuts || (within(absEta(), cuts.absEtaMin, cuts.absEtaMax) && - within(_eta, cuts.etaMin, cuts.etaMax))) && + (!m_isUnbinned || (within(absEta(), cuts.absEtaMin, cuts.absEtaMax) && + within(_eta, cuts.etaMin, cuts.etaMax))) && within(track.phi(), cuts.phiMin, cuts.phiMax) && within(track.loc0(), cuts.loc0Min, cuts.loc0Max) && within(track.loc1(), cuts.loc1Min, cuts.loc1Max) && @@ -452,26 +464,19 @@ inline TrackSelector::TrackSelector( "TrackSelector cut / eta bin configuration is inconsistent"}; } - m_isUnbinned = false; if (m_cfg.nEtaBins() == 1) { static const std::vector infVec = {0, inf}; - bool limitEta = m_cfg.absEtaEdges != infVec; - m_isUnbinned = !limitEta; // single bin, no eta edges given - - const Config& cuts = m_cfg.cutSets[0]; - - if (limitEta && (cuts.etaMin != -inf || cuts.etaMax != inf || - cuts.absEtaMin != 0.0 || cuts.absEtaMax != inf)) { - throw std::invalid_argument{ - "Explicit eta cuts are only valid for single eta bin"}; - } + m_isUnbinned = + m_cfg.absEtaEdges == infVec; // single bin, no eta edges given } - m_noEtaCuts = m_isUnbinned; - for (const auto& cuts : m_cfg.cutSets) { - if (cuts.etaMin != -inf || cuts.etaMax != inf || cuts.absEtaMin != 0.0 || - cuts.absEtaMax != inf) { - m_noEtaCuts = false; + if (!m_isUnbinned) { + for (const auto& cuts : m_cfg.cutSets) { + if (cuts.etaMin != -inf || cuts.etaMax != inf || cuts.absEtaMin != 0.0 || + cuts.absEtaMax != inf) { + throw std::invalid_argument{ + "Explicit eta cuts are only valid for single eta bin"}; + } } } } diff --git a/Core/include/Acts/TrackFitting/BetheHeitlerApprox.hpp b/Core/include/Acts/TrackFitting/BetheHeitlerApprox.hpp index 653bef7e899..666ebf6aa23 100644 --- a/Core/include/Acts/TrackFitting/BetheHeitlerApprox.hpp +++ b/Core/include/Acts/TrackFitting/BetheHeitlerApprox.hpp @@ -125,6 +125,7 @@ class AtlasBetheHeitlerApprox { constexpr static double m_singleGaussianLimit = 0.002; double m_lowLimit = 0.10; double m_highLimit = 0.20; + bool m_clampToRange = false; public: /// Construct the Bethe-Heitler approximation description with two @@ -138,16 +139,19 @@ class AtlasBetheHeitlerApprox { /// @param highTransform whether the high data need to be transformed /// @param lowLimit the upper limit for the low data /// @param highLimit the upper limit for the high data + /// @param clampToRange whether to clamp the input x/x0 to the allowed range constexpr AtlasBetheHeitlerApprox(const Data &lowData, const Data &highData, bool lowTransform, bool highTransform, double lowLimit = 0.1, - double highLimit = 0.2) + double highLimit = 0.2, + bool clampToRange = false) : m_lowData(lowData), m_highData(highData), m_lowTransform(lowTransform), m_highTransform(highTransform), m_lowLimit(lowLimit), - m_highLimit(highLimit) {} + m_highLimit(highLimit), + m_clampToRange(clampToRange) {} /// Returns the number of components the returned mixture will have constexpr auto numComponents() const { return NComponents; } @@ -155,7 +159,13 @@ class AtlasBetheHeitlerApprox { /// Checks if an input is valid for the parameterization /// /// @param x pathlength in terms of the radiation length - constexpr bool validXOverX0(ActsScalar x) const { return x < m_highLimit; } + constexpr bool validXOverX0(ActsScalar x) const { + if (m_clampToRange) { + return true; + } else { + return x < m_highLimit; + } + } /// Generates the mixture from the polynomials and reweights them, so /// that the sum of all weights is 1 @@ -164,6 +174,11 @@ class AtlasBetheHeitlerApprox { auto mixture(ActsScalar x) const { using Array = boost::container::static_vector; + + if (m_clampToRange) { + x = std::clamp(x, 0.0, m_highLimit); + } + // Build a polynom auto poly = [](ActsScalar xx, const std::array &coeffs) { @@ -238,9 +253,11 @@ class AtlasBetheHeitlerApprox { /// the parameterization for high x/x0 /// @param lowLimit the upper limit for the low x/x0-data /// @param highLimit the upper limit for the high x/x0-data + /// @param clampToRange forwarded to constructor static auto loadFromFiles(const std::string &low_parameters_path, const std::string &high_parameters_path, - double lowLimit = 0.1, double highLimit = 0.2) { + double lowLimit = 0.1, double highLimit = 0.2, + bool clampToRange = false) { auto read_file = [](const std::string &filepath) { std::ifstream file(filepath); @@ -284,7 +301,8 @@ class AtlasBetheHeitlerApprox { const auto [highData, highTransform] = read_file(high_parameters_path); return AtlasBetheHeitlerApprox(lowData, highData, lowTransform, - highTransform, lowLimit, highLimit); + highTransform, lowLimit, highLimit, + clampToRange); } }; @@ -292,6 +310,7 @@ class AtlasBetheHeitlerApprox { /// configuration, that are stored as static data in the source code. /// This may not be an optimal configuration, but should allow to run /// the GSF without the need to load files -AtlasBetheHeitlerApprox<6, 5> makeDefaultBetheHeitlerApprox(); +AtlasBetheHeitlerApprox<6, 5> makeDefaultBetheHeitlerApprox( + bool clampToRange = false); } // namespace Acts diff --git a/Core/include/Acts/TrackFitting/GaussianSumFitter.hpp b/Core/include/Acts/TrackFitting/GaussianSumFitter.hpp index efe21b58a60..f6c990a696d 100644 --- a/Core/include/Acts/TrackFitting/GaussianSumFitter.hpp +++ b/Core/include/Acts/TrackFitting/GaussianSumFitter.hpp @@ -123,15 +123,11 @@ struct GaussianSumFitter { using Actors = ActorList; using PropagatorOptions = typename propagator_t::template Options; - std::vector backwardSequence( - std::next(sSequence.rbegin()), sSequence.rend()); - backwardSequence.push_back(opts.referenceSurface); - PropagatorOptions propOptions(opts.geoContext, opts.magFieldContext); propOptions.setPlainOptions(opts.propagatorPlainOptions); - propOptions.navigation.surfaces = backwardSequence; + propOptions.navigation.surfaces = sSequence; propOptions.actorList.template get() .m_cfg.bethe_heitler_approx = &m_betheHeitlerApproximation; 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/Geometry/CylinderVolumeBounds.cpp b/Core/src/Geometry/CylinderVolumeBounds.cpp index c7bb8192f4a..d9af620ea45 100644 --- a/Core/src/Geometry/CylinderVolumeBounds.cpp +++ b/Core/src/Geometry/CylinderVolumeBounds.cpp @@ -309,4 +309,7 @@ void CylinderVolumeBounds::set( } } +CylinderVolumeBounds::CylinderVolumeBounds(const CylinderVolumeBounds& cylbo) = + default; + } // namespace Acts 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/Seeding/CMakeLists.txt b/Core/src/Seeding/CMakeLists.txt new file mode 100644 index 00000000000..770037b1dfd --- /dev/null +++ b/Core/src/Seeding/CMakeLists.txt @@ -0,0 +1 @@ +target_sources(ActsCore PRIVATE EstimateTrackParamsFromSeed.cpp) diff --git a/Core/src/Seeding/EstimateTrackParamsFromSeed.cpp b/Core/src/Seeding/EstimateTrackParamsFromSeed.cpp new file mode 100644 index 00000000000..83d950fc3a1 --- /dev/null +++ b/Core/src/Seeding/EstimateTrackParamsFromSeed.cpp @@ -0,0 +1,50 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 CERN for the benefit of the ACTS project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +#include "Acts/Seeding/EstimateTrackParamsFromSeed.hpp" + +#include "Acts/Definitions/TrackParametrization.hpp" + +Acts::BoundMatrix Acts::estimateTrackParamCovariance( + const EstimateTrackParamCovarianceConfig& config, const BoundVector& params, + bool hasTime) { + assert((params[eBoundTheta] > 0 && params[eBoundTheta] < M_PI) && + "Theta must be in the range (0, pi)"); + + BoundSquareMatrix result = BoundSquareMatrix::Zero(); + + for (std::size_t i = eBoundLoc0; i < eBoundSize; ++i) { + double sigma = config.initialSigmas[i]; + double variance = sigma * sigma; + + if (i == eBoundQOverP) { + // note that we rely on the fact that sigma theta is already computed + double varianceTheta = result(eBoundTheta, eBoundTheta); + + // transverse momentum contribution + variance += std::pow(config.initialSigmaPtRel * params[eBoundQOverP], 2); + + // theta contribution + variance += + varianceTheta * + std::pow(params[eBoundQOverP] / std::tan(params[eBoundTheta]), 2); + } + + if (i == eBoundTime && !hasTime) { + // Inflate the time uncertainty if no time measurement is available + variance *= config.noTimeVarInflation; + } + + // Inflate the initial covariance + variance *= config.initialVarInflation[i]; + + result(i, i) = variance; + } + + return result; +} diff --git a/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/BetheHeitlerApprox.cpp b/Core/src/TrackFitting/BetheHeitlerApprox.cpp index b19b9921902..272d6e08c8d 100644 --- a/Core/src/TrackFitting/BetheHeitlerApprox.cpp +++ b/Core/src/TrackFitting/BetheHeitlerApprox.cpp @@ -8,7 +8,8 @@ #include "Acts/TrackFitting/BetheHeitlerApprox.hpp" -Acts::AtlasBetheHeitlerApprox<6, 5> Acts::makeDefaultBetheHeitlerApprox() { +Acts::AtlasBetheHeitlerApprox<6, 5> Acts::makeDefaultBetheHeitlerApprox( + bool clampToRange) { // Tracking/TrkFitter/TrkGaussianSumFilterUtils/Data/BetheHeitler_cdf_nC6_O5.par // clang-format off constexpr static AtlasBetheHeitlerApprox<6, 5>::Data cdf_cmps6_order5_data = {{ @@ -51,6 +52,7 @@ Acts::AtlasBetheHeitlerApprox<6, 5> Acts::makeDefaultBetheHeitlerApprox() { }}; // clang-format on - return AtlasBetheHeitlerApprox<6, 5>( - cdf_cmps6_order5_data, cdf_cmps6_order5_data, true, true, 0.2, 0.2); + return AtlasBetheHeitlerApprox<6, 5>(cdf_cmps6_order5_data, + cdf_cmps6_order5_data, true, true, 0.2, + 0.2, clampToRange); } diff --git a/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/include/ActsExamples/TrackFinding/TrackFindingAlgorithm.hpp b/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/TrackFindingAlgorithm.hpp index deb15750a5f..c56e9508c9b 100644 --- a/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/TrackFindingAlgorithm.hpp +++ b/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/TrackFindingAlgorithm.hpp @@ -179,6 +179,7 @@ class TrackFindingAlgorithm final : public IAlgorithm { mutable std::atomic m_nFoundTracks{0}; mutable std::atomic m_nSelectedTracks{0}; mutable std::atomic m_nStoppedBranches{0}; + mutable std::atomic m_nSkippedSecondPass{0}; mutable tbb::combinable m_memoryStatistics{[]() { diff --git a/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp b/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp index 2a36701dc3b..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; } }, @@ -532,6 +532,15 @@ ProcessCode TrackFindingAlgorithm::execute(const AlgorithmContext& ctx) const { Acts::BoundTrackParameters secondInitialParameters = trackCandidate.createParametersFromState(firstMeasurement); + if (!secondInitialParameters.referenceSurface().insideBounds( + secondInitialParameters.localPosition())) { + m_nSkippedSecondPass++; + ACTS_DEBUG( + "Smoothing of first pass fit produced out-of-bounds parameters " + "relative to the surface. Skipping second pass."); + continue; + } + auto secondRootBranch = tracksTemp.makeTrack(); secondRootBranch.copyFrom(trackCandidate, false); auto secondResult = @@ -681,6 +690,7 @@ ProcessCode TrackFindingAlgorithm::finalize() { ACTS_INFO("- found tracks: " << m_nFoundTracks); ACTS_INFO("- selected tracks: " << m_nSelectedTracks); ACTS_INFO("- stopped branches: " << m_nStoppedBranches); + ACTS_INFO("- skipped second pass: " << m_nSkippedSecondPass); auto memoryStatistics = m_memoryStatistics.combine([](const auto& a, const auto& b) { 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/TrackFinding/src/TrackParamsEstimationAlgorithm.cpp b/Examples/Algorithms/TrackFinding/src/TrackParamsEstimationAlgorithm.cpp index a54b10d2e7d..c8a30c7147d 100644 --- a/Examples/Algorithms/TrackFinding/src/TrackParamsEstimationAlgorithm.cpp +++ b/Examples/Algorithms/TrackFinding/src/TrackParamsEstimationAlgorithm.cpp @@ -32,48 +32,6 @@ namespace ActsExamples { -namespace { - -Acts::BoundSquareMatrix makeInitialCovariance( - const TrackParamsEstimationAlgorithm::Config& config, - const Acts::BoundVector& params, const SimSpacePoint& sp) { - Acts::BoundSquareMatrix result = Acts::BoundSquareMatrix::Zero(); - - for (std::size_t i = Acts::eBoundLoc0; i < Acts::eBoundSize; ++i) { - double sigma = config.initialSigmas[i]; - double variance = sigma * sigma; - - if (i == Acts::eBoundQOverP) { - // note that we rely on the fact that sigma theta is already computed - double varianceTheta = result(Acts::eBoundTheta, Acts::eBoundTheta); - - // transverse momentum contribution - variance += - std::pow(config.initialSigmaPtRel * params[Acts::eBoundQOverP], 2); - - // theta contribution - variance += - varianceTheta * std::pow(params[Acts::eBoundQOverP] / - std::tan(params[Acts::eBoundTheta]), - 2); - } - - // Inflate the time uncertainty if no time measurement is available - if (i == Acts::eBoundTime && !sp.t().has_value()) { - variance *= config.noTimeVarInflation; - } - - // Inflate the initial covariance - variance *= config.initialVarInflation[i]; - - result(i, i) = variance; - } - - return result; -} - -} // namespace - TrackParamsEstimationAlgorithm::TrackParamsEstimationAlgorithm( TrackParamsEstimationAlgorithm::Config cfg, Acts::Logging::Level lvl) : IAlgorithm("TrackParamsEstimationAlgorithm", lvl), m_cfg(std::move(cfg)) { @@ -166,8 +124,15 @@ ProcessCode TrackParamsEstimationAlgorithm::execute( const auto& params = optParams.value(); - Acts::BoundSquareMatrix cov = - makeInitialCovariance(m_cfg, params, *bottomSP); + Acts::EstimateTrackParamCovarianceConfig config{ + .initialSigmas = + Eigen::Map{m_cfg.initialSigmas.data()}, + .initialSigmaPtRel = m_cfg.initialSigmaPtRel, + .initialVarInflation = Eigen::Map{ + m_cfg.initialVarInflation.data()}}; + + Acts::BoundSquareMatrix cov = Acts::estimateTrackParamCovariance( + config, params, bottomSP->t().has_value()); trackParameters.emplace_back(surface->getSharedPtr(), params, cov, m_cfg.particleHypothesis); diff --git a/Examples/Algorithms/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/ParticleSelector.cpp b/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSelector.cpp index d9248358160..5fa3ee0e4b2 100644 --- a/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSelector.cpp +++ b/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSelector.cpp @@ -29,9 +29,16 @@ ActsExamples::ParticleSelector::ParticleSelector(const Config& config, if (m_cfg.outputParticles.empty()) { throw std::invalid_argument("Missing output particles collection"); } + if (!m_cfg.outputParticlesFinal.empty() && + m_cfg.inputParticlesFinal.empty()) { + throw std::invalid_argument( + "Output final particles collection requires input final particles"); + } m_inputParticles.initialize(m_cfg.inputParticles); + m_inputParticlesFinal.maybeInitialize(m_cfg.inputParticlesFinal); m_outputParticles.initialize(m_cfg.outputParticles); + m_outputParticlesFinal.maybeInitialize(m_cfg.outputParticlesFinal); ACTS_DEBUG("selection particle rho [" << m_cfg.rhoMin << "," << m_cfg.rhoMax << ")"); @@ -52,29 +59,15 @@ ActsExamples::ParticleSelector::ParticleSelector(const Config& config, ACTS_DEBUG("remove charged particles " << m_cfg.removeCharged); ACTS_DEBUG("remove neutral particles " << m_cfg.removeNeutral); ACTS_DEBUG("remove secondary particles " << m_cfg.removeSecondaries); - - // We only initialize this if we actually select on this - if (m_cfg.measurementsMin > 0 || - m_cfg.measurementsMax < std::numeric_limits::max()) { - m_inputMap.initialize(m_cfg.inputMeasurementParticlesMap); - ACTS_DEBUG("selection particle number of measurements [" - << m_cfg.measurementsMin << "," << m_cfg.measurementsMax << ")"); - } } ActsExamples::ProcessCode ActsExamples::ParticleSelector::execute( const AlgorithmContext& ctx) const { - using ParticlesMeasurmentMap = - boost::container::flat_multimap; - // prepare input/ output types - const auto& inputParticles = m_inputParticles(ctx); - - // Make global particles measurement map if necessary - std::optional particlesMeasMap; - if (m_inputMap.isInitialized()) { - particlesMeasMap = invertIndexMultimap(m_inputMap(ctx)); - } + const SimParticleContainer& inputParticles = m_inputParticles(ctx); + const SimParticleContainer& inputParticlesFinal = + (m_inputParticlesFinal.isInitialized()) ? m_inputParticlesFinal(ctx) + : inputParticles; std::size_t nInvalidCharge = 0; std::size_t nInvalidMeasurementCount = 0; @@ -96,17 +89,14 @@ ActsExamples::ProcessCode ActsExamples::ParticleSelector::execute( nInvalidCharge += static_cast(!validCharge); - // default valid measurement count to true and only change if we have loaded - // the measurement particles map bool validMeasurementCount = true; - if (particlesMeasMap) { - auto [b, e] = particlesMeasMap->equal_range(p.particleId()); + if (auto finalParticleIt = inputParticlesFinal.find(p.particleId()); + finalParticleIt != inputParticlesFinal.end()) { validMeasurementCount = - within(static_cast(std::distance(b, e)), - m_cfg.measurementsMin, m_cfg.measurementsMax); - - ACTS_VERBOSE("Found " << std::distance(b, e) << " measurements for " - << p.particleId()); + within(finalParticleIt->numberOfHits(), m_cfg.measurementsMin, + m_cfg.measurementsMax); + } else { + ACTS_WARNING("No final particle found for " << p.particleId()); } nInvalidMeasurementCount += @@ -136,14 +126,30 @@ ActsExamples::ProcessCode ActsExamples::ParticleSelector::execute( SimParticleContainer outputParticles; outputParticles.reserve(inputParticles.size()); + SimParticleContainer outputParticlesFinal; + if (m_outputParticlesFinal.isInitialized()) { + outputParticlesFinal.reserve(inputParticles.size()); + } + // copy selected particles for (const auto& inputParticle : inputParticles) { - if (isValidParticle(inputParticle)) { - // the input parameters should already be - outputParticles.insert(outputParticles.end(), inputParticle); + if (!isValidParticle(inputParticle)) { + continue; + } + + outputParticles.insert(outputParticles.end(), inputParticle); + + if (m_outputParticlesFinal.isInitialized()) { + if (auto particleFinalIt = + inputParticlesFinal.find(inputParticle.particleId()); + particleFinalIt != inputParticlesFinal.end()) { + outputParticlesFinal.insert(outputParticlesFinal.end(), + *particleFinalIt); + } } } outputParticles.shrink_to_fit(); + outputParticlesFinal.shrink_to_fit(); ACTS_DEBUG("event " << ctx.eventNumber << " selected " << outputParticles.size() << " from " @@ -153,5 +159,9 @@ ActsExamples::ProcessCode ActsExamples::ParticleSelector::execute( << nInvalidMeasurementCount); m_outputParticles(ctx, std::move(outputParticles)); + if (m_outputParticlesFinal.isInitialized()) { + m_outputParticlesFinal(ctx, std::move(outputParticlesFinal)); + } + return ProcessCode::SUCCESS; } diff --git a/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSelector.hpp b/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSelector.hpp index d6c8440fdc7..de05bf621ca 100644 --- a/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSelector.hpp +++ b/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSelector.hpp @@ -29,10 +29,14 @@ class ParticleSelector final : public IAlgorithm { struct Config { /// The input particles collection. std::string inputParticles; - /// Input measurement particles map (Optional) - std::string inputMeasurementParticlesMap; + /// Optional. The input final state particles collection. + /// If provided, this will be used to access the number of measurements. + std::string inputParticlesFinal; /// The output particles collection. std::string outputParticles; + /// Optional. The output final state particles collection. + std::string outputParticlesFinal; + // Minimum/maximum distance from the origin in the transverse plane. double rhoMin = 0; double rhoMax = std::numeric_limits::infinity(); @@ -79,11 +83,13 @@ class ParticleSelector final : public IAlgorithm { Config m_cfg; ReadDataHandle m_inputParticles{this, "InputParticles"}; - ReadDataHandle> m_inputMap{ - this, "InputMeasurementParticlesMap"}; + ReadDataHandle m_inputParticlesFinal{ + this, "InputParticlesFinal"}; WriteDataHandle m_outputParticles{this, "OutputParticles"}; + WriteDataHandle m_outputParticlesFinal{ + this, "OutputParticlesFinal"}; }; } // namespace ActsExamples diff --git a/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSmearing.cpp b/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSmearing.cpp index 937a5bc1863..cfc62ab9da9 100644 --- a/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSmearing.cpp +++ b/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSmearing.cpp @@ -11,6 +11,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/TrackParametrization.hpp" #include "Acts/EventData/ParticleHypothesis.hpp" +#include "Acts/Seeding/EstimateTrackParamsFromSeed.hpp" #include "Acts/Surfaces/PerigeeSurface.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Utilities/Helpers.hpp" @@ -128,31 +129,16 @@ ActsExamples::ProcessCode ActsExamples::ParticleSmearing::execute( Acts::BoundSquareMatrix cov = Acts::BoundSquareMatrix::Zero(); if (m_cfg.initialSigmas) { // use the initial sigmas if set - for (std::size_t i = Acts::eBoundLoc0; i < Acts::eBoundSize; ++i) { - double sigma = (*m_cfg.initialSigmas)[i]; - double variance = sigma * sigma; - - if (i == Acts::eBoundQOverP) { - // note that we rely on the fact that sigma theta is already - // computed - double varianceTheta = cov(Acts::eBoundTheta, Acts::eBoundTheta); - // transverse momentum contribution - variance += std::pow( - m_cfg.initialSigmaPtRel * params[Acts::eBoundQOverP], 2); + Acts::EstimateTrackParamCovarianceConfig config{ + .initialSigmas = + Eigen::Map{ + m_cfg.initialSigmas->data()}, + .initialSigmaPtRel = m_cfg.initialSigmaPtRel, + .initialVarInflation = Eigen::Map{ + m_cfg.initialVarInflation.data()}}; - // theta contribution - variance += varianceTheta * - std::pow(params[Acts::eBoundQOverP] / - std::tan(params[Acts::eBoundTheta]), - 2); - } - - // Inflate the initial covariance - variance *= m_cfg.initialVarInflation[i]; - - cov(i, i) = variance; - } + cov = Acts::estimateTrackParamCovariance(config, params, false); } else { // otherwise use the smearing sigmas diff --git a/Examples/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 100f55cf93c..5c1a76b5bd4 100644 --- a/Examples/Framework/src/Framework/Sequencer.cpp +++ b/Examples/Framework/src/Framework/Sequencer.cpp @@ -126,6 +126,13 @@ Sequencer::Sequencer(const Sequencer::Config& cfg) "ACTS_SEQUENCER_DISABLE_FPEMON"); m_cfg.trackFpes = false; } + + if (m_cfg.trackFpes && !m_cfg.fpeMasks.empty() && + !Acts::FpeMonitor::canSymbolize()) { + ACTS_ERROR("FPE monitoring is enabled but symbolization is not available"); + throw std::runtime_error( + "FPE monitoring is enabled but symbolization is not available"); + } } void Sequencer::addContextDecorator( @@ -360,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; } }; @@ -604,7 +611,7 @@ void Sequencer::fpeReport() const { auto merged = std::accumulate( fpe.begin(), fpe.end(), Acts::FpeMonitor::Result{}, [](const auto& lhs, const auto& rhs) { return lhs.merged(rhs); }); - if (!merged) { + if (!merged.hasStackTraces()) { // no FPEs to report continue; } diff --git a/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/CMakeLists.txt b/Examples/Io/CMakeLists.txt index dcf7c16a0a1..8b7f2861a6e 100644 --- a/Examples/Io/CMakeLists.txt +++ b/Examples/Io/CMakeLists.txt @@ -2,8 +2,6 @@ add_subdirectory(Csv) add_subdirectory_if(EDM4hep ACTS_BUILD_EXAMPLES_EDM4HEP) add_subdirectory_if(HepMC3 ACTS_BUILD_EXAMPLES_HEPMC3) add_subdirectory(Json) -add_subdirectory(NuclearInteractions) add_subdirectory(Obj) -add_subdirectory(Performance) add_subdirectory(Root) add_subdirectory_if(Svg ACTS_BUILD_PLUGIN_ACTSVG) diff --git a/Examples/Io/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/NuclearInteractions/CMakeLists.txt b/Examples/Io/NuclearInteractions/CMakeLists.txt deleted file mode 100644 index 3f7ad2b9b9b..00000000000 --- a/Examples/Io/NuclearInteractions/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -add_library( - ActsExamplesIoNuclearInteractions - SHARED - src/RootNuclearInteractionParametersWriter.cpp - src/detail/NuclearInteractionParametrisation.cpp -) -target_include_directories( - ActsExamplesIoNuclearInteractions - PUBLIC $ -) -target_link_libraries( - ActsExamplesIoNuclearInteractions - PUBLIC ActsCore ActsExamplesFramework Threads::Threads - PRIVATE ROOT::Core ROOT::Hist ROOT::Tree -) - -install( - TARGETS ActsExamplesIoNuclearInteractions - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} -) diff --git a/Examples/Io/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 3ac12286395..353d68debab 100644 --- a/Examples/Io/Root/CMakeLists.txt +++ b/Examples/Io/Root/CMakeLists.txt @@ -23,6 +23,13 @@ add_library( src/RootVertexReader.cpp src/RootVertexWriter.cpp src/RootAthenaDumpReader.cpp + src/RootNuclearInteractionParametersWriter.cpp + src/detail/NuclearInteractionParametrisation.cpp + src/TrackFinderPerformanceWriter.cpp + src/SeedingPerformanceWriter.cpp + src/TrackFinderNTupleWriter.cpp + src/TrackFitterPerformanceWriter.cpp + src/VertexNTupleWriter.cpp ) target_include_directories( ActsExamplesIoRoot diff --git a/Examples/Io/Root/include/ActsExamples/Io/Root/RootAthenaDumpReader.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/RootAthenaDumpReader.hpp index e917e07038d..2a09d8492b2 100644 --- a/Examples/Io/Root/include/ActsExamples/Io/Root/RootAthenaDumpReader.hpp +++ b/Examples/Io/Root/include/ActsExamples/Io/Root/RootAthenaDumpReader.hpp @@ -173,6 +173,7 @@ class RootAthenaDumpReader : public IReader { std::vector> m_eventMap; std::shared_ptr m_inputchain; long unsigned int m_events; + bool m_haveStripFeatures = true; static constexpr unsigned int maxCL = 1500000; static constexpr unsigned int maxSP = 1500000; @@ -189,7 +190,7 @@ class RootAthenaDumpReader : public IReader { int CLindex[maxCL] = {}; //[nCL] // Clusters - std::vector *CLhardware; + std::vector *CLhardware{}; Double_t CLx[maxCL] = {}; //[nCL] Double_t CLy[maxCL] = {}; //[nCL] Double_t CLz[maxCL] = {}; //[nCL] @@ -199,13 +200,13 @@ class RootAthenaDumpReader : public IReader { Int_t CLphi_module[maxCL] = {}; //[nCL] Int_t CLside[maxCL] = {}; //[nCL] ULong64_t CLmoduleID[maxCL] = {}; //[nCL] - std::vector> *CLparticleLink_eventIndex; - std::vector> *CLparticleLink_barcode; - std::vector> *CLbarcodesLinked; - std::vector> *CLparticle_charge; - std::vector> *CLphis; - std::vector> *CLetas; - std::vector> *CLtots; + std::vector> *CLparticleLink_eventIndex{}; + std::vector> *CLparticleLink_barcode{}; + std::vector> *CLbarcodesLinked{}; + std::vector> *CLparticle_charge{}; + std::vector> *CLphis{}; + std::vector> *CLetas{}; + std::vector> *CLtots{}; Double_t CLloc_direction1[maxCL] = {}; //[nCL] Double_t CLloc_direction2[maxCL] = {}; //[nCL] Double_t CLloc_direction3[maxCL] = {}; //[nCL] @@ -223,7 +224,7 @@ class RootAthenaDumpReader : public IReader { Float_t CLnorm_x[maxCL] = {}; //[nCL] Float_t CLnorm_y[maxCL] = {}; //[nCL] Float_t CLnorm_z[maxCL] = {}; //[nCL] - std::vector> *CLlocal_cov; + std::vector> *CLlocal_cov{}; // Particles Int_t nPartEVT = 0; @@ -246,8 +247,8 @@ class RootAthenaDumpReader : public IReader { Int_t Part_vProdNout[maxPart] = {}; //[nPartEVT] Int_t Part_vProdStatus[maxPart] = {}; //[nPartEVT] Int_t Part_vProdBarcode[maxPart] = {}; //[nPartEVT] - std::vector> *Part_vParentID; - std::vector> *Part_vParentBarcode; + std::vector> *Part_vParentID{}; + std::vector> *Part_vParentBarcode{}; // Spacepoints Int_t nSP = 0; @@ -263,27 +264,27 @@ class RootAthenaDumpReader : public IReader { double SPcovz[maxSP] = {}; //[nSP] float SPhl_topstrip[maxSP] = {}; //[nSP] float SPhl_botstrip[maxSP] = {}; //[nSP] - std::vector> *SPtopStripDirection; - std::vector> *SPbottomStripDirection; - std::vector> *SPstripCenterDistance; - std::vector> *SPtopStripCenterPosition; + std::vector> *SPtopStripDirection{}; + std::vector> *SPbottomStripDirection{}; + std::vector> *SPstripCenterDistance{}; + std::vector> *SPtopStripCenterPosition{}; // Tracks Int_t nTRK = 0; Int_t TRKindex[maxTRK] = {}; //[nTRK] Int_t TRKtrack_fitter[maxTRK] = {}; //[nTRK] Int_t TRKparticle_hypothesis[maxTRK] = {}; //[nTRK] - std::vector> *TRKproperties; - std::vector> *TRKpattern; + std::vector> *TRKproperties{}; + std::vector> *TRKpattern{}; Int_t TRKndof[maxTRK] = {}; //[nTRK] Int_t TRKmot[maxTRK] = {}; //[nTRK] Int_t TRKoot[maxTRK] = {}; //[nTRK] Float_t TRKchiSq[maxTRK] = {}; //[nTRK] - std::vector> *TRKmeasurementsOnTrack_pixcl_sctcl_index; - std::vector> *TRKoutliersOnTrack_pixcl_sctcl_index; + std::vector> *TRKmeasurementsOnTrack_pixcl_sctcl_index{}; + std::vector> *TRKoutliersOnTrack_pixcl_sctcl_index{}; Int_t TRKcharge[maxTRK] = {}; //[nTRK] - std::vector> *TRKperigee_position; - std::vector> *TRKperigee_momentum; + std::vector> *TRKperigee_position{}; + std::vector> *TRKperigee_momentum{}; Int_t TTCindex[maxTRK] = {}; //[nTRK] Int_t TTCevent_index[maxTRK] = {}; //[nTRK] Int_t TTCparticle_link[maxTRK] = {}; //[nTRK] @@ -293,10 +294,10 @@ class RootAthenaDumpReader : public IReader { Int_t nDTT = 0; Int_t DTTindex[maxDTT] = {}; //[nDTT] Int_t DTTsize[maxDTT] = {}; //[nDTT] - std::vector> *DTTtrajectory_eventindex; - std::vector> *DTTtrajectory_barcode; - std::vector> *DTTstTruth_subDetType; - std::vector> *DTTstTrack_subDetType; - std::vector> *DTTstCommon_subDetType; + std::vector> *DTTtrajectory_eventindex{}; + std::vector> *DTTtrajectory_barcode{}; + std::vector> *DTTstTruth_subDetType{}; + std::vector> *DTTstTrack_subDetType{}; + std::vector> *DTTstCommon_subDetType{}; }; } // namespace ActsExamples diff --git a/Examples/Io/NuclearInteractions/include/ActsExamples/Io/NuclearInteractions/RootNuclearInteractionParametersWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/RootNuclearInteractionParametersWriter.hpp similarity index 97% rename from Examples/Io/NuclearInteractions/include/ActsExamples/Io/NuclearInteractions/RootNuclearInteractionParametersWriter.hpp rename to Examples/Io/Root/include/ActsExamples/Io/Root/RootNuclearInteractionParametersWriter.hpp index 8edad2c2a7d..d688920fc76 100644 --- a/Examples/Io/NuclearInteractions/include/ActsExamples/Io/NuclearInteractions/RootNuclearInteractionParametersWriter.hpp +++ b/Examples/Io/Root/include/ActsExamples/Io/Root/RootNuclearInteractionParametersWriter.hpp @@ -12,7 +12,7 @@ #include "ActsExamples/EventData/ExtractedSimulationProcess.hpp" #include "ActsExamples/Framework/ProcessCode.hpp" #include "ActsExamples/Framework/WriterT.hpp" -#include "ActsExamples/Io/NuclearInteractions/detail/NuclearInteractionParametrisation.hpp" +#include "ActsExamples/Io/Root/detail/NuclearInteractionParametrisation.hpp" #include #include diff --git a/Examples/Io/Root/include/ActsExamples/Io/Root/RootParticleWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/RootParticleWriter.hpp index 99cf6b5cd61..8be9f05b735 100644 --- a/Examples/Io/Root/include/ActsExamples/Io/Root/RootParticleWriter.hpp +++ b/Examples/Io/Root/include/ActsExamples/Io/Root/RootParticleWriter.hpp @@ -39,7 +39,7 @@ class RootParticleWriter final : public WriterT { std::string inputParticles; /// Optional. If given, the the energy loss and traversed material is /// computed and written. - std::string inputFinalParticles; + std::string inputParticlesFinal; /// Path to the output file. std::string filePath; /// Output file access mode. @@ -74,8 +74,8 @@ class RootParticleWriter final : public WriterT { private: Config m_cfg; - ReadDataHandle m_inputFinalParticles{ - this, "InputFinalParticles"}; + ReadDataHandle m_inputParticlesFinal{ + this, "InputParticlesFinal"}; std::mutex m_writeMutex; diff --git a/Examples/Io/Performance/ActsExamples/Io/Performance/SeedingPerformanceWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/SeedingPerformanceWriter.hpp similarity index 100% rename from Examples/Io/Performance/ActsExamples/Io/Performance/SeedingPerformanceWriter.hpp rename to Examples/Io/Root/include/ActsExamples/Io/Root/SeedingPerformanceWriter.hpp diff --git a/Examples/Io/Performance/ActsExamples/Io/Performance/TrackFinderPerformanceWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/TrackFinderNTupleWriter.hpp similarity index 88% rename from Examples/Io/Performance/ActsExamples/Io/Performance/TrackFinderPerformanceWriter.hpp rename to Examples/Io/Root/include/ActsExamples/Io/Root/TrackFinderNTupleWriter.hpp index 287cf361999..799471be784 100644 --- a/Examples/Io/Performance/ActsExamples/Io/Performance/TrackFinderPerformanceWriter.hpp +++ b/Examples/Io/Root/include/ActsExamples/Io/Root/TrackFinderNTupleWriter.hpp @@ -24,7 +24,7 @@ struct AlgorithmContext; /// /// 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 { +class TrackFinderNTupleWriter final : public WriterT { public: struct Config { /// Input reconstructed track collection. @@ -48,9 +48,9 @@ class TrackFinderPerformanceWriter final : public WriterT { /// Constructor /// @param config the configuration /// @param level The log level - TrackFinderPerformanceWriter(Config config, Acts::Logging::Level level); + TrackFinderNTupleWriter(Config config, Acts::Logging::Level level); - ~TrackFinderPerformanceWriter() override; + ~TrackFinderNTupleWriter() override; ProcessCode finalize() override; @@ -59,7 +59,7 @@ class TrackFinderPerformanceWriter final : public WriterT { private: ProcessCode writeT(const AlgorithmContext& ctx, - const TrackContainer& tracks) override; + const ConstTrackContainer& tracks) override; struct Impl; diff --git a/Examples/Io/Performance/ActsExamples/Io/Performance/CKFPerformanceWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/TrackFinderPerformanceWriter.hpp similarity index 95% rename from Examples/Io/Performance/ActsExamples/Io/Performance/CKFPerformanceWriter.hpp rename to Examples/Io/Root/include/ActsExamples/Io/Root/TrackFinderPerformanceWriter.hpp index 0d9e4c96feb..b3b6c36436c 100644 --- a/Examples/Io/Performance/ActsExamples/Io/Performance/CKFPerformanceWriter.hpp +++ b/Examples/Io/Root/include/ActsExamples/Io/Root/TrackFinderPerformanceWriter.hpp @@ -41,7 +41,7 @@ struct AlgorithmContext; /// 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 { +class TrackFinderPerformanceWriter final : public WriterT { public: struct Config { /// Input (found) tracks collection. @@ -68,8 +68,8 @@ class CKFPerformanceWriter final : public WriterT { }; /// Construct from configuration and log level. - CKFPerformanceWriter(Config cfg, Acts::Logging::Level lvl); - ~CKFPerformanceWriter() override; + TrackFinderPerformanceWriter(Config cfg, Acts::Logging::Level lvl); + ~TrackFinderPerformanceWriter() override; /// Finalize plots. ProcessCode finalize() override; diff --git a/Examples/Io/Performance/ActsExamples/Io/Performance/TrackFitterPerformanceWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/TrackFitterPerformanceWriter.hpp similarity index 100% rename from Examples/Io/Performance/ActsExamples/Io/Performance/TrackFitterPerformanceWriter.hpp rename to Examples/Io/Root/include/ActsExamples/Io/Root/TrackFitterPerformanceWriter.hpp diff --git a/Examples/Io/Performance/ActsExamples/Io/Performance/VertexPerformanceWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/VertexNTupleWriter.hpp similarity index 97% rename from Examples/Io/Performance/ActsExamples/Io/Performance/VertexPerformanceWriter.hpp rename to Examples/Io/Root/include/ActsExamples/Io/Root/VertexNTupleWriter.hpp index 8043dd1cac0..514dbfc8850 100644 --- a/Examples/Io/Performance/ActsExamples/Io/Performance/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/NuclearInteractions/include/ActsExamples/Io/NuclearInteractions/detail/NuclearInteractionParametrisation.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/detail/NuclearInteractionParametrisation.hpp similarity index 98% rename from Examples/Io/NuclearInteractions/include/ActsExamples/Io/NuclearInteractions/detail/NuclearInteractionParametrisation.hpp rename to Examples/Io/Root/include/ActsExamples/Io/Root/detail/NuclearInteractionParametrisation.hpp index b0a6174a0d6..e00fb79c63a 100644 --- a/Examples/Io/NuclearInteractions/include/ActsExamples/Io/NuclearInteractions/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/RootAthenaDumpReader.cpp b/Examples/Io/Root/src/RootAthenaDumpReader.cpp index eea524fe544..a732bb3b49e 100644 --- a/Examples/Io/Root/src/RootAthenaDumpReader.cpp +++ b/Examples/Io/Root/src/RootAthenaDumpReader.cpp @@ -84,6 +84,11 @@ RootAthenaDumpReader::RootAthenaDumpReader( m_outputMeasurements.initialize(m_cfg.outputMeasurements); } + if (m_inputchain->GetBranch("SPtopStripDirection") == nullptr) { + ACTS_WARNING("Additional SP strip features not available"); + m_haveStripFeatures = false; + } + // Set the branches // Set object pointer @@ -192,13 +197,13 @@ RootAthenaDumpReader::RootAthenaDumpReader( m_inputchain->SetBranchAddress("SPcovz", SPcovz); m_inputchain->SetBranchAddress("SPhl_topstrip", SPhl_topstrip); m_inputchain->SetBranchAddress("SPhl_botstrip", SPhl_botstrip); - m_inputchain->SetBranchAddress("SPtopStripDirection", SPtopStripDirection); + m_inputchain->SetBranchAddress("SPtopStripDirection", &SPtopStripDirection); m_inputchain->SetBranchAddress("SPbottomStripDirection", - SPbottomStripDirection); + &SPbottomStripDirection); m_inputchain->SetBranchAddress("SPstripCenterDistance", - SPstripCenterDistance); + &SPstripCenterDistance); m_inputchain->SetBranchAddress("SPtopStripCenterPosition", - SPtopStripCenterPosition); + &SPtopStripCenterPosition); m_inputchain->SetBranchAddress("nTRK", &nTRK); m_inputchain->SetBranchAddress("TRKindex", TRKindex); @@ -578,21 +583,25 @@ RootAthenaDumpReader::readSpacepoints( sLinks.emplace_back(second); using Vector3f = Eigen::Matrix; - const Vector3f topStripDirection{SPtopStripDirection->at(isp).at(0), - SPtopStripDirection->at(isp).at(1), - SPtopStripDirection->at(isp).at(2)}; - const Vector3f bottomStripDirection{ - SPbottomStripDirection->at(isp).at(0), - SPbottomStripDirection->at(isp).at(1), - SPbottomStripDirection->at(isp).at(2)}; - const Vector3f stripCenterDistance{SPstripCenterDistance->at(isp).at(0), - SPstripCenterDistance->at(isp).at(1), - SPstripCenterDistance->at(isp).at(2)}; - const Vector3f topStripCenterPosition{ - SPtopStripCenterPosition->at(isp).at(0), - SPtopStripCenterPosition->at(isp).at(1), - SPtopStripCenterPosition->at(isp).at(2)}; - + Vector3f topStripDirection = Vector3f::Zero(); + Vector3f bottomStripDirection = Vector3f::Zero(); + Vector3f stripCenterDistance = Vector3f::Zero(); + Vector3f topStripCenterPosition = Vector3f::Zero(); + + if (m_haveStripFeatures) { + topStripDirection = {SPtopStripDirection->at(isp).at(0), + SPtopStripDirection->at(isp).at(1), + SPtopStripDirection->at(isp).at(2)}; + bottomStripDirection = {SPbottomStripDirection->at(isp).at(0), + SPbottomStripDirection->at(isp).at(1), + SPbottomStripDirection->at(isp).at(2)}; + stripCenterDistance = {SPstripCenterDistance->at(isp).at(0), + SPstripCenterDistance->at(isp).at(1), + SPstripCenterDistance->at(isp).at(2)}; + topStripCenterPosition = {SPtopStripCenterPosition->at(isp).at(0), + SPtopStripCenterPosition->at(isp).at(1), + SPtopStripCenterPosition->at(isp).at(2)}; + } sp = SimSpacePoint(globalPos, std::nullopt, spCovr, spCovz, std::nullopt, sLinks, SPhl_topstrip[isp], SPhl_botstrip[isp], topStripDirection.cast(), diff --git a/Examples/Io/NuclearInteractions/src/RootNuclearInteractionParametersWriter.cpp b/Examples/Io/Root/src/RootNuclearInteractionParametersWriter.cpp similarity index 96% rename from Examples/Io/NuclearInteractions/src/RootNuclearInteractionParametersWriter.cpp rename to Examples/Io/Root/src/RootNuclearInteractionParametersWriter.cpp index 64a324242c8..995f7bdf57d 100644 --- a/Examples/Io/NuclearInteractions/src/RootNuclearInteractionParametersWriter.cpp +++ b/Examples/Io/Root/src/RootNuclearInteractionParametersWriter.cpp @@ -6,7 +6,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -#include "ActsExamples/Io/NuclearInteractions/RootNuclearInteractionParametersWriter.hpp" +#include "ActsExamples/Io/Root/RootNuclearInteractionParametersWriter.hpp" #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/Common.hpp" @@ -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/RootParticleWriter.cpp b/Examples/Io/Root/src/RootParticleWriter.cpp index fbd1333c38c..436601eb97d 100644 --- a/Examples/Io/Root/src/RootParticleWriter.cpp +++ b/Examples/Io/Root/src/RootParticleWriter.cpp @@ -36,7 +36,7 @@ ActsExamples::RootParticleWriter::RootParticleWriter( throw std::invalid_argument("Missing tree name"); } - m_inputFinalParticles.maybeInitialize(m_cfg.inputFinalParticles); + m_inputParticlesFinal.maybeInitialize(m_cfg.inputParticlesFinal); // open root file and create the tree m_outputFile = TFile::Open(m_cfg.filePath.c_str(), m_cfg.fileMode.c_str()); @@ -73,7 +73,7 @@ ActsExamples::RootParticleWriter::RootParticleWriter( m_outputTree->Branch("generation", &m_generation); m_outputTree->Branch("sub_particle", &m_subParticle); - if (m_inputFinalParticles.isInitialized()) { + if (m_inputParticlesFinal.isInitialized()) { m_outputTree->Branch("e_loss", &m_eLoss); m_outputTree->Branch("total_x0", &m_pathInX0); m_outputTree->Branch("total_l0", &m_pathInL0); @@ -102,8 +102,8 @@ ActsExamples::ProcessCode ActsExamples::RootParticleWriter::finalize() { ActsExamples::ProcessCode ActsExamples::RootParticleWriter::writeT( const AlgorithmContext& ctx, const SimParticleContainer& particles) { const SimParticleContainer* finalParticles = nullptr; - if (m_inputFinalParticles.isInitialized()) { - finalParticles = &m_inputFinalParticles(ctx); + if (m_inputParticlesFinal.isInitialized()) { + finalParticles = &m_inputParticlesFinal(ctx); } // ensure exclusive access to tree/file while writing diff --git a/Examples/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/Performance/ActsExamples/Io/Performance/SeedingPerformanceWriter.cpp b/Examples/Io/Root/src/SeedingPerformanceWriter.cpp similarity index 99% rename from Examples/Io/Performance/ActsExamples/Io/Performance/SeedingPerformanceWriter.cpp rename to Examples/Io/Root/src/SeedingPerformanceWriter.cpp index b2d87be68f9..4ac7ea269ef 100644 --- a/Examples/Io/Performance/ActsExamples/Io/Performance/SeedingPerformanceWriter.cpp +++ b/Examples/Io/Root/src/SeedingPerformanceWriter.cpp @@ -6,7 +6,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -#include "SeedingPerformanceWriter.hpp" +#include "ActsExamples/Io/Root/SeedingPerformanceWriter.hpp" #include "Acts/Utilities/MultiIndex.hpp" #include "Acts/Utilities/VectorHelpers.hpp" diff --git a/Examples/Io/Performance/ActsExamples/Io/Performance/TrackFinderPerformanceWriter.cpp b/Examples/Io/Root/src/TrackFinderNTupleWriter.cpp similarity index 91% rename from Examples/Io/Performance/ActsExamples/Io/Performance/TrackFinderPerformanceWriter.cpp rename to Examples/Io/Root/src/TrackFinderNTupleWriter.cpp index abef2ef0664..3ddfc2b6f84 100644 --- a/Examples/Io/Performance/ActsExamples/Io/Performance/TrackFinderPerformanceWriter.cpp +++ b/Examples/Io/Root/src/TrackFinderNTupleWriter.cpp @@ -6,7 +6,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -#include "ActsExamples/Io/Performance/TrackFinderPerformanceWriter.hpp" +#include "ActsExamples/Io/Root/TrackFinderNTupleWriter.hpp" #include "Acts/Definitions/Units.hpp" #include "ActsExamples/EventData/Index.hpp" @@ -32,7 +32,7 @@ #include #include -struct ActsExamples::TrackFinderPerformanceWriter::Impl { +struct ActsExamples::TrackFinderNTupleWriter::Impl { Config cfg; ReadDataHandle inputParticles; @@ -86,7 +86,7 @@ struct ActsExamples::TrackFinderPerformanceWriter::Impl { // extra logger reference for the logging macros const Acts::Logger& _logger; - Impl(TrackFinderPerformanceWriter* parent, Config&& c, const Acts::Logger& l) + Impl(TrackFinderNTupleWriter* parent, Config&& c, const Acts::Logger& l) : cfg(std::move(c)), inputParticles{parent, "InputParticles"}, inputMeasurementParticlesMap{parent, "InputMeasurementParticlesMap"}, @@ -153,7 +153,7 @@ struct ActsExamples::TrackFinderPerformanceWriter::Impl { const Acts::Logger& logger() const { return _logger; } - void write(std::uint64_t eventId, const TrackContainer& tracks, + void write(std::uint64_t eventId, const ConstTrackContainer& tracks, const SimParticleContainer& particles, const HitParticlesMap& hitParticlesMap, const TrackParticleMatching& trackParticleMatching) { @@ -265,18 +265,17 @@ struct ActsExamples::TrackFinderPerformanceWriter::Impl { } }; -ActsExamples::TrackFinderPerformanceWriter::TrackFinderPerformanceWriter( - ActsExamples::TrackFinderPerformanceWriter::Config config, +ActsExamples::TrackFinderNTupleWriter::TrackFinderNTupleWriter( + ActsExamples::TrackFinderNTupleWriter::Config config, Acts::Logging::Level level) - : WriterT(config.inputTracks, "TrackFinderPerformanceWriter", level), + : WriterT(config.inputTracks, "TrackFinderNTupleWriter", level), m_impl(std::make_unique(this, std::move(config), logger())) {} -ActsExamples::TrackFinderPerformanceWriter::~TrackFinderPerformanceWriter() = - default; +ActsExamples::TrackFinderNTupleWriter::~TrackFinderNTupleWriter() = default; -ActsExamples::ProcessCode ActsExamples::TrackFinderPerformanceWriter::writeT( +ActsExamples::ProcessCode ActsExamples::TrackFinderNTupleWriter::writeT( const ActsExamples::AlgorithmContext& ctx, - const ActsExamples::TrackContainer& tracks) { + 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); @@ -285,13 +284,12 @@ ActsExamples::ProcessCode ActsExamples::TrackFinderPerformanceWriter::writeT( return ProcessCode::SUCCESS; } -ActsExamples::ProcessCode -ActsExamples::TrackFinderPerformanceWriter::finalize() { +ActsExamples::ProcessCode ActsExamples::TrackFinderNTupleWriter::finalize() { m_impl->close(); return ProcessCode::SUCCESS; } -const ActsExamples::TrackFinderPerformanceWriter::Config& -ActsExamples::TrackFinderPerformanceWriter::config() const { +const ActsExamples::TrackFinderNTupleWriter::Config& +ActsExamples::TrackFinderNTupleWriter::config() const { return m_impl->cfg; } diff --git a/Examples/Io/Performance/ActsExamples/Io/Performance/CKFPerformanceWriter.cpp b/Examples/Io/Root/src/TrackFinderPerformanceWriter.cpp similarity index 95% rename from Examples/Io/Performance/ActsExamples/Io/Performance/CKFPerformanceWriter.cpp rename to Examples/Io/Root/src/TrackFinderPerformanceWriter.cpp index e7fa1525615..ecec2fd59ce 100644 --- a/Examples/Io/Performance/ActsExamples/Io/Performance/CKFPerformanceWriter.cpp +++ b/Examples/Io/Root/src/TrackFinderPerformanceWriter.cpp @@ -6,7 +6,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -#include "ActsExamples/Io/Performance/CKFPerformanceWriter.hpp" +#include "ActsExamples/Io/Root/TrackFinderPerformanceWriter.hpp" #include "Acts/EventData/TrackParameters.hpp" #include "Acts/Utilities/VectorHelpers.hpp" @@ -27,9 +27,9 @@ using Acts::VectorHelpers::phi; namespace ActsExamples { -CKFPerformanceWriter::CKFPerformanceWriter(CKFPerformanceWriter::Config cfg, - Acts::Logging::Level lvl) - : WriterT(cfg.inputTracks, "CKFPerformanceWriter", lvl), +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), @@ -76,7 +76,7 @@ CKFPerformanceWriter::CKFPerformanceWriter(CKFPerformanceWriter::Config cfg, m_trackSummaryPlotTool.book(m_trackSummaryPlotCache); } -CKFPerformanceWriter::~CKFPerformanceWriter() { +TrackFinderPerformanceWriter::~TrackFinderPerformanceWriter() { m_effPlotTool.clear(m_effPlotCache); m_fakeRatePlotTool.clear(m_fakeRatePlotCache); m_duplicationPlotTool.clear(m_duplicationPlotCache); @@ -86,7 +86,7 @@ CKFPerformanceWriter::~CKFPerformanceWriter() { } } -ProcessCode CKFPerformanceWriter::finalize() { +ProcessCode TrackFinderPerformanceWriter::finalize() { float eff_tracks = static_cast(m_nTotalMatchedTracks) / m_nTotalTracks; float fakeRate_tracks = static_cast(m_nTotalFakeTracks) / m_nTotalTracks; @@ -147,8 +147,8 @@ ProcessCode CKFPerformanceWriter::finalize() { return ProcessCode::SUCCESS; } -ProcessCode CKFPerformanceWriter::writeT(const AlgorithmContext& ctx, - const ConstTrackContainer& tracks) { +ProcessCode TrackFinderPerformanceWriter::writeT( + const AlgorithmContext& ctx, const ConstTrackContainer& tracks) { // The number of majority particle hits and fitted track parameters using Acts::VectorHelpers::perp; diff --git a/Examples/Io/Performance/ActsExamples/Io/Performance/TrackFitterPerformanceWriter.cpp b/Examples/Io/Root/src/TrackFitterPerformanceWriter.cpp similarity index 98% rename from Examples/Io/Performance/ActsExamples/Io/Performance/TrackFitterPerformanceWriter.cpp rename to Examples/Io/Root/src/TrackFitterPerformanceWriter.cpp index 54441ad7aa8..2063f03b53b 100644 --- a/Examples/Io/Performance/ActsExamples/Io/Performance/TrackFitterPerformanceWriter.cpp +++ b/Examples/Io/Root/src/TrackFitterPerformanceWriter.cpp @@ -6,7 +6,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -#include "ActsExamples/Io/Performance/TrackFitterPerformanceWriter.hpp" +#include "ActsExamples/Io/Root/TrackFitterPerformanceWriter.hpp" #include "Acts/EventData/MultiTrajectoryHelpers.hpp" #include "Acts/EventData/TrackParameters.hpp" diff --git a/Examples/Io/Performance/ActsExamples/Io/Performance/VertexPerformanceWriter.cpp b/Examples/Io/Root/src/VertexNTupleWriter.cpp similarity index 98% rename from Examples/Io/Performance/ActsExamples/Io/Performance/VertexPerformanceWriter.cpp rename to Examples/Io/Root/src/VertexNTupleWriter.cpp index dfc790433f9..c5a800741d3 100644 --- a/Examples/Io/Performance/ActsExamples/Io/Performance/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/Performance/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/Io/NuclearInteractions/src/detail/NuclearInteractionParametrisation.cpp b/Examples/Io/Root/src/detail/NuclearInteractionParametrisation.cpp similarity index 99% rename from Examples/Io/NuclearInteractions/src/detail/NuclearInteractionParametrisation.cpp rename to Examples/Io/Root/src/detail/NuclearInteractionParametrisation.cpp index f9df3d38f85..91f59c56648 100644 --- a/Examples/Io/NuclearInteractions/src/detail/NuclearInteractionParametrisation.cpp +++ b/Examples/Io/Root/src/detail/NuclearInteractionParametrisation.cpp @@ -6,7 +6,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -#include "ActsExamples/Io/NuclearInteractions/detail/NuclearInteractionParametrisation.hpp" +#include "ActsExamples/Io/Root/detail/NuclearInteractionParametrisation.hpp" #include "Acts/Definitions/Common.hpp" #include "ActsFatras/EventData/Particle.hpp" diff --git a/Examples/Python/CMakeLists.txt b/Examples/Python/CMakeLists.txt index ff1e5901f43..0a834ae546f 100644 --- a/Examples/Python/CMakeLists.txt +++ b/Examples/Python/CMakeLists.txt @@ -54,11 +54,9 @@ target_link_libraries( ActsExamplesDetectorTGeo ActsExamplesMagneticField ActsExamplesIoRoot - ActsExamplesIoNuclearInteractions ActsExamplesIoCsv ActsExamplesIoObj ActsExamplesIoJson - ActsExamplesIoPerformance ActsExamplesGenerators ActsExamplesPrinters ActsExamplesTrackFinding @@ -68,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 3bb898ca998..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 @@ -14,12 +13,6 @@ "Default TruthSmeared TruthEstimated Orthogonal HoughTransform Gbts Hashing", ) -TruthSeedRanges = namedtuple( - "TruthSeedRanges", - ["rho", "z", "phi", "eta", "absEta", "pt", "nHits"], - defaults=[(None, None)] * 7, -) - ParticleSmearingSigmas = namedtuple( "ParticleSmearingSigmas", ["d0", "d0PtA", "d0PtB", "z0", "z0PtA", "z0PtB", "t0", "phi", "theta", "ptRel"], @@ -231,7 +224,6 @@ class VertexFinder(Enum): @acts.examples.NamedTypeArgs( seedingAlgorithm=SeedingAlgorithm, - truthSeedRanges=TruthSeedRanges, particleSmearingSigmas=ParticleSmearingSigmas, seedFinderConfigArg=SeedFinderConfigArg, seedFinderOptionsArg=SeedFinderOptionsArg, @@ -251,7 +243,6 @@ def addSeeding( layerMappingConfigFile: Optional[Union[Path, str]] = None, connector_inputConfigFile: Optional[Union[Path, str]] = None, seedingAlgorithm: SeedingAlgorithm = SeedingAlgorithm.Default, - truthSeedRanges: Optional[TruthSeedRanges] = TruthSeedRanges(), particleSmearingSigmas: ParticleSmearingSigmas = ParticleSmearingSigmas(), initialSigmas: Optional[list] = None, initialSigmaPtRel: Optional[float] = None, @@ -273,6 +264,7 @@ def addSeeding( acts.ParticleHypothesis ] = acts.ParticleHypothesis.pion, inputParticles: str = "particles", + selectedParticles: str = "particles_selected", outputDirRoot: Optional[Union[Path, str]] = None, outputDirCsv: Optional[Union[Path, str]] = None, logLevel: Optional[acts.logging.Level] = None, @@ -289,10 +281,6 @@ def addSeeding( Json file for space point geometry selection. Not required for SeedingAlgorithm.TruthSmeared. seedingAlgorithm : SeedingAlgorithm, Default seeding algorithm to use: one of Default (no truth information used), TruthSmeared, TruthEstimated - truthSeedRanges : TruthSeedRanges(rho, z, phi, eta, absEta, pt, nHits) - TruthSeedSelector configuration. Each range is specified as a tuple of (min,max). - Defaults of no cuts specified in Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/TruthSeedSelector.hpp - If specified as None, don't run ParticleSmearing at all (and use addCKFTracks(selectedParticles="particles")) particleSmearingSigmas : ParticleSmearingSigmas(d0, d0PtA, d0PtB, z0, z0PtA, z0PtB, t0, phi, theta, ptRel) ParticleSmearing configuration. Defaults specified in Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSmearing.hpp @@ -324,6 +312,8 @@ def addSeeding( The hypothesis used for track finding. Defaults to pion. inputParticles : str, "particles" input particles name in the WhiteBoard + selectedParticles : str, "particles_selected" + selected particles name in the WhiteBoard outputDirRoot : Path|str, path, None the output folder for the Root output, None triggers no output logLevel : acts.logging.Level, None @@ -336,18 +326,6 @@ def addSeeding( logger = acts.logging.getLogger("addSeeding") logger.setLevel(logLevel) - if truthSeedRanges is not None: - selectedParticles = "truth_seeds_selected" - addSeedingTruthSelection( - s, - inputParticles, - selectedParticles, - truthSeedRanges, - logLevel, - ) - else: - selectedParticles = inputParticles - # Create starting parameters from either particle smearing or combined seed # finding and track parameters estimation if seedingAlgorithm == SeedingAlgorithm.TruthSmeared: @@ -506,41 +484,6 @@ def addSeeding( return s -def addSeedingTruthSelection( - s: acts.examples.Sequencer, - inputParticles: str, - outputParticles: str, - truthSeedRanges: TruthSeedRanges, - logLevel: acts.logging.Level = None, -): - """adds truth particles filtering before filtering - For parameters description see addSeeding - """ - selAlg = acts.examples.TruthSeedSelector( - **acts.examples.defaultKWArgs( - ptMin=truthSeedRanges.pt[0], - ptMax=truthSeedRanges.pt[1], - etaMin=truthSeedRanges.eta[0], - etaMax=truthSeedRanges.eta[1], - nHitsMin=truthSeedRanges.nHits[0], - nHitsMax=truthSeedRanges.nHits[1], - rhoMin=truthSeedRanges.rho[0], - rhoMax=truthSeedRanges.rho[1], - zMin=truthSeedRanges.z[0], - zMax=truthSeedRanges.z[1], - phiMin=truthSeedRanges.phi[0], - phiMax=truthSeedRanges.phi[1], - absEtaMin=truthSeedRanges.absEta[0], - absEtaMax=truthSeedRanges.absEta[1], - ), - level=logLevel, - inputParticles=inputParticles, - inputMeasurementParticlesMap="measurement_particles_map", - outputParticles=outputParticles, - ) - s.addAlgorithm(selAlg) - - def addTruthSmearedSeeding( s: acts.examples.Sequencer, rnd: Optional[acts.examples.RandomNumbers], @@ -1233,7 +1176,7 @@ def addSeedFilterML( from acts.examples.onnx import SeedFilterMLAlgorithm inputParticles = "particles" - selectedParticles = "truth_seeds_selected" + selectedParticles = "particles_selected" seeds = "seeds" estParams = "estimatedparameters" @@ -1375,8 +1318,13 @@ def addTruthTrackingGsf( ) -> None: customLogLevel = acts.examples.defaultLogging(s, logLevel) + # NOTE we specify clampToRange as True to silence warnings in the test about + # queries to the loss distribution outside the specified range, since no dedicated + # approximation for the ODD is done yet. + bha = acts.examples.AtlasBetheHeitlerApprox.makeDefault(clampToRange=True) + gsfOptions = { - "betheHeitlerApprox": acts.examples.AtlasBetheHeitlerApprox.makeDefault(), + "betheHeitlerApprox": bha, "maxComponents": 12, "componentMergeMethod": acts.examples.ComponentMergeMethod.maxWeight, "mixtureReductionAlgorithm": acts.examples.MixtureReductionAlgorithm.KLDistance, @@ -1433,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 @@ -1579,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 @@ -1655,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, ): @@ -1668,15 +1620,22 @@ 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, - # @note The full particles collection is used here to avoid lots of warnings - # since the unselected CKF track might have a majority particle not in the - # filtered particle collection. This could be avoided when a separate track - # selection algorithm is used. inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", inputSimHits="simhits", @@ -1686,34 +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, - # @note The full particles collection is used here to avoid lots of warnings - # since the unselected CKF track might have a majority particle not in the - # filtered particle collection. This could be avoided when a separate track - # selection algorithm is used. inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", - filePath=str(outputDirRoot / f"tracksummary_{name}.root"), - 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="truth_seeds_selected", + 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) @@ -1897,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 @@ -1920,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 @@ -1964,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 @@ -1984,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 @@ -2018,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 @@ -2037,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 @@ -2075,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, ) @@ -2093,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 @@ -2119,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, ) @@ -2180,7 +2147,7 @@ def addVertexFitting( VertexFitterAlgorithm, IterativeVertexFinderAlgorithm, AdaptiveMultiVertexFinderAlgorithm, - VertexPerformanceWriter, + VertexNTupleWriter, ) customLogLevel = acts.examples.defaultLogging(s, logLevel) @@ -2263,7 +2230,7 @@ def addVertexFitting( if not outputDirRoot.exists(): outputDirRoot.mkdir() s.addWriter( - VertexPerformanceWriter( + VertexNTupleWriter( level=customLogLevel(), inputVertices=outputVertices, inputTracks=tracks, @@ -2289,7 +2256,7 @@ def addSingleSeedVertexFinding( ) -> None: from acts.examples import ( SingleSeedVertexFinderAlgorithm, - VertexPerformanceWriter, + VertexNTupleWriter, ) customLogLevel = acts.examples.defaultLogging(s, logLevel) @@ -2310,7 +2277,7 @@ def addSingleSeedVertexFinding( outputDirRoot.mkdir() s.addWriter( - VertexPerformanceWriter( + VertexNTupleWriter( level=customLogLevel(), inputAllTruthParticles=inputParticles, inputSelectedTruthParticles=selectedParticles, diff --git a/Examples/Python/python/acts/examples/simulation.py b/Examples/Python/python/acts/examples/simulation.py index b3b1046dc70..8f6b6d0e603 100644 --- a/Examples/Python/python/acts/examples/simulation.py +++ b/Examples/Python/python/acts/examples/simulation.py @@ -355,7 +355,8 @@ def addParticleSelection( config: ParticleSelectorConfig, inputParticles: str, outputParticles: str, - inputMeasurementParticlesMap: str = "", + inputParticlesFinal: Optional[str] = None, + outputParticlesFinal: Optional[str] = None, logLevel: Optional[acts.logging.Level] = None, ) -> None: """ @@ -371,12 +372,18 @@ def addParticleSelection( the identifier for the input particles to be selected outputParticles: str the identifier for the final selected particle collection + inputParticlesFinal: str, None + the identifier for the input final particles to be selected + outputParticlesFinal: str, None + the identifier for the final selected final particle collection """ customLogLevel = acts.examples.defaultLogging(s, logLevel) s.addAlgorithm( acts.examples.ParticleSelector( **acts.examples.defaultKWArgs( + inputParticlesFinal=inputParticlesFinal, + outputParticlesFinal=outputParticlesFinal, rhoMin=config.rho[0], rhoMax=config.rho[1], absZMin=config.absZ[0], @@ -402,7 +409,6 @@ def addParticleSelection( level=customLogLevel(), inputParticles=inputParticles, outputParticles=outputParticles, - inputMeasurementParticlesMap=inputMeasurementParticlesMap, ) ) @@ -489,27 +495,22 @@ def addFatras( # Selector if postSelectParticles is not None: particlesInitial = "fatras_particles_initial_selected" - addParticleSelection( - s, - postSelectParticles, - inputParticles=alg.config.outputParticlesInitial, - outputParticles=particlesInitial, - ) - particlesFinal = "fatras_particles_final_selected" addParticleSelection( s, postSelectParticles, - inputParticles=alg.config.outputParticlesFinal, - outputParticles=particlesFinal, + inputParticles=outputParticlesInitial, + inputParticlesFinal=outputParticlesFinal, + outputParticles=particlesInitial, + outputParticlesFinal=particlesFinal, ) - s.addWhiteboardAlias("particles_selected", particlesFinal) + s.addWhiteboardAlias("particles_selected", particlesInitial) else: - particlesInitial = alg.config.outputParticlesInitial - particlesFinal = alg.config.outputParticlesFinal + particlesInitial = outputParticlesInitial + particlesFinal = outputParticlesFinal # Only add alias for 'particles_initial' as this is the one we use most - s.addWhiteboardAlias("particles", particlesInitial) + s.addWhiteboardAlias("particles", outputParticlesInitial) # Output addSimWriters( @@ -573,7 +574,7 @@ def addSimWriters( acts.examples.RootParticleWriter( level=customLogLevel(), inputParticles=particlesInitial, - inputFinalParticles=particlesFinal, + inputParticlesFinal=particlesFinal, filePath=str(outputDirRoot / "particles_simulation.root"), ) ) @@ -739,27 +740,22 @@ def addGeant4( # Selector if postSelectParticles is not None: particlesInitial = "geant4_particles_initial_postselected" - addParticleSelection( - s, - postSelectParticles, - inputParticles=alg.config.outputParticlesInitial, - outputParticles=particlesInitial, - ) - particlesFinal = "geant4_particles_final_postselected" addParticleSelection( s, postSelectParticles, - inputParticles=alg.config.outputParticlesFinal, - outputParticles=particlesFinal, + inputParticles=outputParticlesInitial, + inputParticlesFinal=outputParticlesFinal, + outputParticles=particlesInitial, + outputParticlesFinal=particlesFinal, ) - s.addWhiteboardAlias("particles_selected", particlesFinal) + s.addWhiteboardAlias("particles_selected", particlesInitial) else: - particlesInitial = alg.config.outputParticlesInitial - particlesFinal = alg.config.outputParticlesFinal + particlesInitial = outputParticlesInitial + particlesFinal = outputParticlesFinal # Only add alias for 'particles_initial' as this is the one we use most - s.addWhiteboardAlias("particles", particlesInitial) + s.addWhiteboardAlias("particles", outputParticlesInitial) # Output addSimWriters( diff --git a/Examples/Python/src/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 11472d8e203..dce56dc681e 100644 --- a/Examples/Python/src/Output.cpp +++ b/Examples/Python/src/Output.cpp @@ -26,16 +26,11 @@ #include "ActsExamples/Io/Csv/CsvTrackParameterWriter.hpp" #include "ActsExamples/Io/Csv/CsvTrackWriter.hpp" #include "ActsExamples/Io/Csv/CsvTrackingGeometryWriter.hpp" -#include "ActsExamples/Io/NuclearInteractions/RootNuclearInteractionParametersWriter.hpp" -#include "ActsExamples/Io/Performance/CKFPerformanceWriter.hpp" -#include "ActsExamples/Io/Performance/SeedingPerformanceWriter.hpp" -#include "ActsExamples/Io/Performance/TrackFinderPerformanceWriter.hpp" -#include "ActsExamples/Io/Performance/TrackFitterPerformanceWriter.hpp" -#include "ActsExamples/Io/Performance/VertexPerformanceWriter.hpp" #include "ActsExamples/Io/Root/RootBFieldWriter.hpp" #include "ActsExamples/Io/Root/RootMaterialTrackWriter.hpp" #include "ActsExamples/Io/Root/RootMaterialWriter.hpp" #include "ActsExamples/Io/Root/RootMeasurementWriter.hpp" +#include "ActsExamples/Io/Root/RootNuclearInteractionParametersWriter.hpp" #include "ActsExamples/Io/Root/RootParticleWriter.hpp" #include "ActsExamples/Io/Root/RootPropagationStepsWriter.hpp" #include "ActsExamples/Io/Root/RootPropagationSummaryWriter.hpp" @@ -46,6 +41,11 @@ #include "ActsExamples/Io/Root/RootTrackStatesWriter.hpp" #include "ActsExamples/Io/Root/RootTrackSummaryWriter.hpp" #include "ActsExamples/Io/Root/RootVertexWriter.hpp" +#include "ActsExamples/Io/Root/SeedingPerformanceWriter.hpp" +#include "ActsExamples/Io/Root/TrackFinderNTupleWriter.hpp" +#include "ActsExamples/Io/Root/TrackFinderPerformanceWriter.hpp" +#include "ActsExamples/Io/Root/TrackFitterPerformanceWriter.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, @@ -194,14 +194,14 @@ void addOutput(Context& ctx) { ACTS_PYTHON_DECLARE_WRITER(ActsExamples::RootParticleWriter, mex, "RootParticleWriter", inputParticles, - inputFinalParticles, filePath, fileMode, treeName); + inputParticlesFinal, filePath, fileMode, treeName); ACTS_PYTHON_DECLARE_WRITER(ActsExamples::RootVertexWriter, mex, "RootVertexWriter", inputVertices, filePath, 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/src/TrackFitting.cpp b/Examples/Python/src/TrackFitting.cpp index 20c6010c8ee..c8dc72f9eef 100644 --- a/Examples/Python/src/TrackFitting.cpp +++ b/Examples/Python/src/TrackFitting.cpp @@ -39,6 +39,7 @@ namespace py = pybind11; using namespace ActsExamples; using namespace Acts; +using namespace py::literals; namespace Acts::Python { @@ -106,12 +107,17 @@ void addTrackFitting(Context& ctx) { .value("KLDistance", MixtureReductionAlgorithm::KLDistance); py::class_(mex, "AtlasBetheHeitlerApprox") - .def_static("loadFromFiles", - &ActsExamples::BetheHeitlerApprox::loadFromFiles, - py::arg("lowParametersPath"), py::arg("highParametersPath"), - py::arg("lowLimit") = 0.1, py::arg("highLimit") = 0.2) - .def_static("makeDefault", - []() { return Acts::makeDefaultBetheHeitlerApprox(); }); + .def_static( + "loadFromFiles", &ActsExamples::BetheHeitlerApprox::loadFromFiles, + "lowParametersPath"_a, "highParametersPath"_a, "lowLimit"_a = 0.1, + "highLimit"_a = 0.2, "clampToRange"_a = false) + .def_static( + "makeDefault", + [](bool clampToRange) { + return Acts::makeDefaultBetheHeitlerApprox(clampToRange); + }, + "clampToRange"_a = false); + mex.def( "makeGsfFitterFunction", [](std::shared_ptr trackingGeometry, diff --git a/Examples/Python/src/TruthTracking.cpp b/Examples/Python/src/TruthTracking.cpp index 85d34698b7b..2c43b3cfc4d 100644 --- a/Examples/Python/src/TruthTracking.cpp +++ b/Examples/Python/src/TruthTracking.cpp @@ -108,8 +108,9 @@ void addTruthTracking(Context& ctx) { ACTS_PYTHON_STRUCT_BEGIN(c, Config); ACTS_PYTHON_MEMBER(inputParticles); - ACTS_PYTHON_MEMBER(inputMeasurementParticlesMap); + ACTS_PYTHON_MEMBER(inputParticlesFinal); ACTS_PYTHON_MEMBER(outputParticles); + ACTS_PYTHON_MEMBER(outputParticlesFinal); ACTS_PYTHON_MEMBER(rhoMin); ACTS_PYTHON_MEMBER(rhoMax); ACTS_PYTHON_MEMBER(absZMin); diff --git a/Examples/Python/tests/root_file_hashes.txt b/Examples/Python/tests/root_file_hashes.txt index 5eb50dee1b7..3ade64a68ed 100644 --- a/Examples/Python/tests/root_file_hashes.txt +++ b/Examples/Python/tests/root_file_hashes.txt @@ -1,17 +1,17 @@ -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: 87d9c6c82422ca381a17735096b36c547eacb5dda2f26d7377614bd97a70ab1a -test_hashing_seeding__estimatedparams.root: 1f43b760e80089b5674e106d00d962d74be564cbf33ae38222052ebb6f9cbf3a +test_seeding__particles_simulation.root: f937a4cc474e80cfbb6eac4384e42e9c5c7ac981fcd6870d624cc898d1a0c006 +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 -test_seeding_orthogonal__particles_simulation.root: 87d9c6c82422ca381a17735096b36c547eacb5dda2f26d7377614bd97a70ab1a +test_seeding_orthogonal__particles_simulation.root: f937a4cc474e80cfbb6eac4384e42e9c5c7ac981fcd6870d624cc898d1a0c006 test_itk_seeding__estimatedparams.root: 1cc05f9f2aefb5f71a85b31e97bc4e5845fedfcef6c53199495a6340c6b6210b test_itk_seeding__performance_seeding.root: 78ebda54cd0f026ba4b7f316724ffd946de56a932735914baf1b7bba9505c29d test_itk_seeding__particles.root: 0b6f4ad438010ac48803d48ed98e80b5e87d310bae6c2c02b16cd94d7a4d7d07 @@ -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,22 +33,22 @@ 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: de11c0868a70ade0dcc80465d4e6dcf1dd7fcf8149603b47ee7d87d862a6534a -test_ckf_tracks_example[generic-truth_smeared]__tracksummary_ckf.root: f18e9ecce6d9585fd150c5aafc9ac225a5bab342aaab50a28283ba879691af1f -test_ckf_tracks_example[odd-full_seeding]__trackstates_ckf.root: 463d6aaed4d869652b5b184940e789cde0fb441bdd135813b85462a515e6480a -test_ckf_tracks_example[odd-full_seeding]__tracksummary_ckf.root: a8ad83a07b48d4cfcf70d0e6fdc3c8997eb03c1f8c2a7be27ea888b099000d79 +test_ckf_tracks_example[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: 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: 247dd581cc177625c0286718261c004e2149536d70c8281dfaf697879a84d76d -test_ckf_tracks_example[odd-truth_estimated]__tracksummary_ckf.root: 1b08a80e73aedf5cf38a3a407794b82297bec37f556ad4efcda3489a1b17d4d2 +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: 7adfc2bf5ee35a126b713187dd8b11f4497cf864a4a83e57a40885688974413e -test_ckf_tracks_example[odd-truth_smeared]__tracksummary_ckf.root: 7a9de8a8bd1c09f7b4d1c547f824af6c8123afb044dd429180b0d13e47d6f975 +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 test_vertex_fitting_reading[Iterative-True-100]__performance_vertexing.root: e34f217d524a5051dbb04a811d3407df3ebe2cc4bb7f54f6bda0847dbd7b52c3 @@ -73,9 +73,9 @@ 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_refitting[odd]__trackstates_gsf_refit.root: 75cac3d6c0d9ce02169637cff739ab1e72b00c8fd3db9e99945d40b34c35b70b -test_refitting[odd]__tracksummary_gsf_refit.root: 90b9c9b3e24441066376f8cf529df10119b31f83563f001ac438fa70874dcb16 +test_ML_Ambiguity_Solver__performance_finding_ambiML.root: 166dd8bb189097c4957b7b02c04c41267868d72d9a08c4bb892985b06849cb76 +test_refitting[odd]__trackstates_gsf_refit.root: e297749dc1e7eda3b8dea13defa0499986c584740d93e723a901b498b8e90c71 +test_refitting[odd]__tracksummary_gsf_refit.root: d5085882e45a0b699194dff9f40a36e9291227bf65f9aaaf9087f9242ef5ae22 test_refitting[generic]__trackstates_gsf_refit.root: 4424fdf2f27575db825c1a59f8e53a1595946211cbd5b2c8d3a2f71cdcc77ae9 test_refitting[generic]__tracksummary_gsf_refit.root: 562deecee4cfb97ceee72eff53d63da079e3249fb62d6bcd556e6f27d495dfd9 test_truth_tracking_kalman[generic-False-0.0]__trackstates_kf.root: 9f77962b92037cb760b1629a602b1dae61f45e659c45d9a87baa784f6190960e diff --git a/Examples/Python/tests/test_examples.py b/Examples/Python/tests/test_examples.py index 46044a9513c..26f69f4aa82 100644 --- a/Examples/Python/tests/test_examples.py +++ b/Examples/Python/tests/test_examples.py @@ -407,6 +407,7 @@ def test_itk_seeding(tmp_path, trk_geo, field, assert_root_hash): EtaConfig, MomentumConfig, ParticleConfig, + ParticleSelectorConfig, addFatras, addDigitization, ) @@ -428,6 +429,12 @@ def test_itk_seeding(tmp_path, trk_geo, field, assert_root_hash): outputDirCsv=tmp_path / "csv", outputDirRoot=str(tmp_path), rnd=rnd, + postSelectParticles=ParticleSelectorConfig( + pt=(0.9 * u.GeV, None), + eta=(-4, 4), + measurements=(9, None), + removeNeutral=True, + ), ) srcdir = Path(__file__).resolve().parent.parent.parent.parent @@ -442,7 +449,6 @@ def test_itk_seeding(tmp_path, trk_geo, field, assert_root_hash): from acts.examples.reconstruction import ( addSeeding, - TruthSeedRanges, ) from acts.examples.itk import itkSeedingAlgConfig, InputSpacePointsType @@ -450,7 +456,6 @@ def test_itk_seeding(tmp_path, trk_geo, field, assert_root_hash): seq, trk_geo, field, - TruthSeedRanges(pt=(1.0 * u.GeV, None), eta=(-4, 4), nHits=(9, None)), *itkSeedingAlgConfig(InputSpacePointsType.PixelSpacePoints), acts.logging.VERBOSE, geoSelectionConfigFile=srcdir @@ -699,6 +704,7 @@ def test_refitting(tmp_path, detector_config, assert_root_hash): runRefittingGsf( trackingGeometry=trackingGeometry, field=field, + digiConfigFile=detector_config.digiConfigFile, outputDir=tmp_path, s=seq, ).run() @@ -1140,7 +1146,7 @@ def test_ckf_tracks_example( root_files = [ ( - "performance_ckf.root", + "performance_finding_ckf.root", None, ), ( @@ -1284,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_reader.py b/Examples/Python/tests/test_reader.py index 3d458cb8009..b83b1317cc8 100644 --- a/Examples/Python/tests/test_reader.py +++ b/Examples/Python/tests/test_reader.py @@ -290,8 +290,11 @@ def test_edm4hep_simhit_particle_reader(tmp_path): tmp_file = str(tmp_path / "output_edm4hep.root") odd_xml_file = str(getOpenDataDetectorDirectory() / "xml" / "OpenDataDetector.xml") - with multiprocessing.get_context("spawn").Pool() as pool: - pool.apply(generate_input_test_edm4hep_simhit_reader, (odd_xml_file, tmp_file)) + p = multiprocessing.Process( + target=generate_input_test_edm4hep_simhit_reader, args=(odd_xml_file, tmp_file) + ) + p.start() + p.join() assert os.path.exists(tmp_file) 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/Optimization/ckf.py b/Examples/Scripts/Optimization/ckf.py index bf927850ecc..c1761141262 100755 --- a/Examples/Scripts/Optimization/ckf.py +++ b/Examples/Scripts/Optimization/ckf.py @@ -116,13 +116,13 @@ def runCKFTracks( EtaConfig, PhiConfig, ParticleConfig, + ParticleSelectorConfig, addFatras, addDigitization, ) from acts.examples.reconstruction import ( addSeeding, - TruthSeedRanges, ParticleSmearingSigmas, SeedFinderConfigArg, SeedFinderOptionsArg, @@ -169,6 +169,11 @@ def runCKFTracks( trackingGeometry, field, rnd=rnd, + postSelectParticles=ParticleSelectorConfig( + pt=(0.5 * u.GeV, None), + measurements=(9, None), + removeNeutral=True, + ), ) addDigitization( @@ -183,7 +188,6 @@ def runCKFTracks( s, trackingGeometry, field, - TruthSeedRanges(pt=(500.0 * u.MeV, None), nHits=(9, None)), ParticleSmearingSigmas( # only used by SeedingAlgorithm.TruthSmeared # zero eveything so the CKF has a chance to find the measurements d0=0, diff --git a/Examples/Scripts/Python/ckf_tracks.py b/Examples/Scripts/Python/ckf_tracks.py index 9dc665eb835..97f56d17ff0 100755 --- a/Examples/Scripts/Python/ckf_tracks.py +++ b/Examples/Scripts/Python/ckf_tracks.py @@ -27,13 +27,13 @@ def runCKFTracks( EtaConfig, PhiConfig, ParticleConfig, + ParticleSelectorConfig, addFatras, addDigitization, ) from acts.examples.reconstruction import ( addSeeding, - TruthSeedRanges, ParticleSmearingSigmas, SeedFinderConfigArg, SeedFinderOptionsArg, @@ -80,6 +80,11 @@ def runCKFTracks( trackingGeometry, field, rnd=rnd, + postSelectParticles=ParticleSelectorConfig( + pt=(0.5 * u.GeV, None), + measurements=(9, None), + removeNeutral=True, + ), ) addDigitization( @@ -94,7 +99,6 @@ def runCKFTracks( s, trackingGeometry, field, - TruthSeedRanges(pt=(500.0 * u.MeV, None), nHits=(9, None)), ParticleSmearingSigmas( # only used by SeedingAlgorithm.TruthSmeared # zero eveything so the CKF has a chance to find the measurements d0=0, @@ -166,6 +170,7 @@ def runCKFTracks( ), outputDirRoot=outputDir, outputDirCsv=outputDir / "csv" if outputCsv else None, + writeTrackStates=True, ) return s diff --git a/Examples/Scripts/Python/full_chain_itk.py b/Examples/Scripts/Python/full_chain_itk.py index 5e268f87fcb..51746c127a1 100755 --- a/Examples/Scripts/Python/full_chain_itk.py +++ b/Examples/Scripts/Python/full_chain_itk.py @@ -5,6 +5,7 @@ MomentumConfig, EtaConfig, ParticleConfig, + ParticleSelectorConfig, addPythia8, addFatras, ParticleSelectorConfig, @@ -13,7 +14,6 @@ from acts.examples.reconstruction import ( addSeeding, SeedingAlgorithm, - TruthSeedRanges, addCKFTracks, CkfConfig, TrackSelectorConfig, @@ -72,6 +72,12 @@ if ttbar_pu200 else ParticleSelectorConfig() ), + postSelectParticles=ParticleSelectorConfig( + pt=(1.0 * u.GeV, None), + eta=(-4.0, 4.0), + measurements=(9, None), + removeNeutral=True, + ), outputDirRoot=outputDir, ) @@ -88,11 +94,6 @@ s, trackingGeometry, field, - ( - TruthSeedRanges(pt=(1.0 * u.GeV, None), eta=(-4.0, 4.0), nHits=(9, None)) - if ttbar_pu200 - else TruthSeedRanges() - ), seedingAlgorithm=SeedingAlgorithm.Default, *acts.examples.itk.itkSeedingAlgConfig( acts.examples.itk.InputSpacePointsType.PixelSpacePoints diff --git a/Examples/Scripts/Python/full_chain_itk_Gbts.py b/Examples/Scripts/Python/full_chain_itk_Gbts.py index 7a45b7e5a71..a87f5ca6656 100755 --- a/Examples/Scripts/Python/full_chain_itk_Gbts.py +++ b/Examples/Scripts/Python/full_chain_itk_Gbts.py @@ -5,6 +5,7 @@ MomentumConfig, EtaConfig, ParticleConfig, + ParticleSelectorConfig, addPythia8, addFatras, ParticleSelectorConfig, @@ -13,7 +14,6 @@ from acts.examples.reconstruction import ( addSeeding, SeedingAlgorithm, - TruthSeedRanges, addCKFTracks, TrackSelectorConfig, ) @@ -67,6 +67,12 @@ if ttbar_pu200 else ParticleSelectorConfig() ), + postSelectParticles=ParticleSelectorConfig( + pt=(1.0 * u.GeV, None), + eta=(-4.0, 4.0), + measurements=(9, None), + removeNeutral=True, + ), outputDirRoot=outputDir, ) @@ -84,11 +90,6 @@ s, trackingGeometry, field, - ( - TruthSeedRanges(pt=(1.0 * u.GeV, None), eta=(-4.0, 4.0), nHits=(9, None)) - if ttbar_pu200 - else TruthSeedRanges() - ), seedingAlgorithm=SeedingAlgorithm.Gbts, *acts.examples.itk.itkSeedingAlgConfig( acts.examples.itk.InputSpacePointsType.PixelSpacePoints diff --git a/Examples/Scripts/Python/full_chain_odd.py b/Examples/Scripts/Python/full_chain_odd.py index 22f20d3b257..fd98f759577 100755 --- a/Examples/Scripts/Python/full_chain_odd.py +++ b/Examples/Scripts/Python/full_chain_odd.py @@ -13,6 +13,7 @@ EtaConfig, PhiConfig, ParticleConfig, + ParticleSelectorConfig, addPythia8, addFatras, addGeant4, @@ -22,7 +23,6 @@ ) from acts.examples.reconstruction import ( addSeeding, - TruthSeedRanges, CkfConfig, addCKFTracks, TrackSelectorConfig, @@ -271,6 +271,12 @@ pt=(150 * u.MeV, None), removeNeutral=True, ), + postSelectParticles=ParticleSelectorConfig( + pt=(1.0 * u.GeV, None), + eta=(-3.0, 3.0), + measurements=(9, None), + removeNeutral=True, + ), outputDirRoot=outputDir if args.output_root else None, outputDirCsv=outputDir if args.output_csv else None, rnd=rnd, @@ -293,6 +299,12 @@ if args.ttbar else ParticleSelectorConfig() ), + postSelectParticles=ParticleSelectorConfig( + pt=(1.0 * u.GeV, None), + eta=(-3.0, 3.0), + measurements=(9, None), + removeNeutral=True, + ), enableInteractions=True, outputDirRoot=outputDir if args.output_root else None, outputDirCsv=outputDir if args.output_csv else None, @@ -314,11 +326,6 @@ s, trackingGeometry, field, - ( - TruthSeedRanges(pt=(1.0 * u.GeV, None), eta=(-3.0, 3.0), nHits=(9, None)) - if args.ttbar - else TruthSeedRanges() - ), initialSigmas=[ 1 * u.mm, 1 * u.mm, diff --git a/Examples/Scripts/Python/full_chain_odd_LRT.py b/Examples/Scripts/Python/full_chain_odd_LRT.py index a5fd294ceda..2188bb98d6b 100644 --- a/Examples/Scripts/Python/full_chain_odd_LRT.py +++ b/Examples/Scripts/Python/full_chain_odd_LRT.py @@ -21,7 +21,6 @@ ) from acts.examples.reconstruction import ( addSeeding, - TruthSeedRanges, CkfConfig, addCKFTracks, TrackSelectorConfig, @@ -273,6 +272,12 @@ pt=(150 * u.MeV, None), removeNeutral=True, ), + postSelectParticles=ParticleSelectorConfig( + pt=(1.0 * u.GeV, None), + eta=(-3.0, 3.0), + measurements=(9, None), + removeNeutral=True, + ), outputDirRoot=outputDir if args.output_root else None, outputDirCsv=outputDir if args.output_csv else None, rnd=rnd, @@ -295,6 +300,12 @@ if args.ttbar else ParticleSelectorConfig() ), + postSelectParticles=ParticleSelectorConfig( + pt=(1.0 * u.GeV, None), + eta=(-3.0, 3.0), + measurements=(9, None), + removeNeutral=True, + ), enableInteractions=True, outputDirRoot=outputDir if args.output_root else None, outputDirCsv=outputDir if args.output_csv else None, @@ -316,11 +327,6 @@ s, trackingGeometry, field, - ( - TruthSeedRanges(pt=(1.0 * u.GeV, None), eta=(-3.0, 3.0), nHits=(9, None)) - if args.ttbar - else TruthSeedRanges() - ), geoSelectionConfigFile=oddSeedingSel, outputDirRoot=outputDir if args.output_root else None, outputDirCsv=outputDir if args.output_csv else None, diff --git a/Examples/Scripts/Python/hashing_seeding.py b/Examples/Scripts/Python/hashing_seeding.py index a5608a0f329..3148a03837d 100755 --- a/Examples/Scripts/Python/hashing_seeding.py +++ b/Examples/Scripts/Python/hashing_seeding.py @@ -14,7 +14,6 @@ from acts.examples.reconstruction import ( addSeeding, - TruthSeedRanges, addCKFTracks, TrackSelectorConfig, SeedingAlgorithm, @@ -210,7 +209,15 @@ def runHashingSeeding( trackingGeometry, field, preSelectParticles=ParticleSelectorConfig( - eta=(-eta, eta), pt=(150 * u.MeV, None), removeNeutral=True + eta=(-eta, eta), + pt=(150 * u.MeV, None), + removeNeutral=True, + ), + postSelectParticles=ParticleSelectorConfig( + pt=(1.0 * u.GeV, None), + eta=(-eta, eta), + measurements=(9, None), + removeNeutral=True, ), enableInteractions=True, # outputDirRoot=outputDir, # RootParticle ERROR when setting the outputDirRoot @@ -272,7 +279,6 @@ def runHashingSeeding( seedFinderOptionsArg, hashingTrainingConfigArg, hashingAlgorithmConfigArg, - TruthSeedRanges(pt=(1.0 * u.GeV, None), eta=(-eta, eta), nHits=(9, None)), seedingAlgorithm=seedingAlgorithm, geoSelectionConfigFile=geoSelectionConfigFile, initialSigmas=initialSigmas, @@ -338,10 +344,6 @@ def runHashingSeeding( phiBins=phiBins, ) - truthSeedRanges = TruthSeedRanges( - pt=(1.0 * u.GeV, None), eta=(-eta, eta), nHits=(9, None) - ) - doHashing = config.doHashing bucketSize = config.bucketSize npileup = config.mu diff --git a/Examples/Scripts/Python/seeding.py b/Examples/Scripts/Python/seeding.py index 4c87ba9b82b..afe8983eec7 100755 --- a/Examples/Scripts/Python/seeding.py +++ b/Examples/Scripts/Python/seeding.py @@ -57,6 +57,7 @@ def runSeeding( EtaConfig, PhiConfig, ParticleConfig, + ParticleSelectorConfig, addFatras, addDigitization, ) @@ -86,6 +87,12 @@ def runSeeding( outputDirRoot=outputDir, rnd=rnd, preSelectParticles=None, + postSelectParticles=ParticleSelectorConfig( + pt=(1.0 * u.GeV, None), + eta=(-2.5, 2.5), + measurements=(9, None), + removeNeutral=True, + ), ) srcdir = Path(__file__).resolve().parent.parent.parent.parent @@ -97,9 +104,9 @@ def runSeeding( / "Examples/Algorithms/Digitization/share/default-smearing-config-generic.json", rnd=rnd, ) + from acts.examples.reconstruction import ( addSeeding, - TruthSeedRanges, SeedFinderConfigArg, SeedFinderOptionsArg, ) @@ -108,7 +115,6 @@ def runSeeding( s, trackingGeometry, field, - TruthSeedRanges(pt=(1.0 * u.GeV, None), eta=(-2.5, 2.5), nHits=(9, None)), SeedFinderConfigArg( r=(None, 200 * u.mm), # rMin=default, 33mm deltaR=(1 * u.mm, 60 * u.mm), diff --git a/Examples/Scripts/Python/truth_tracking_gsf.py b/Examples/Scripts/Python/truth_tracking_gsf.py index 82c99bb38aa..ae8aca06d6c 100755 --- a/Examples/Scripts/Python/truth_tracking_gsf.py +++ b/Examples/Scripts/Python/truth_tracking_gsf.py @@ -24,13 +24,13 @@ def runTruthTrackingGsf( EtaConfig, PhiConfig, MomentumConfig, + ParticleSelectorConfig, addFatras, addDigitization, ) from acts.examples.reconstruction import ( addSeeding, SeedingAlgorithm, - TruthSeedRanges, addTruthTrackingGsf, ) @@ -77,6 +77,12 @@ def runTruthTrackingGsf( field, rnd=rnd, enableInteractions=True, + postSelectParticles=ParticleSelectorConfig( + pt=(0.9 * u.GeV, None), + measurements=(7, None), + removeNeutral=True, + removeSecondaries=True, + ), ) addDigitization( @@ -95,9 +101,6 @@ def runTruthTrackingGsf( inputParticles="particles_input", seedingAlgorithm=SeedingAlgorithm.TruthSmeared, particleHypothesis=acts.ParticleHypothesis.electron, - truthSeedRanges=TruthSeedRanges( - nHits=(7, None), - ), ) addTruthTrackingGsf( @@ -122,7 +125,7 @@ def runTruthTrackingGsf( acts.examples.RootTrackStatesWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", inputSimHits="simhits", inputMeasurementSimHitsMap="measurement_simhits_map", @@ -134,7 +137,7 @@ def runTruthTrackingGsf( acts.examples.RootTrackSummaryWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", filePath=str(outputDir / "tracksummary_gsf.root"), writeGsfSpecific=True, @@ -145,7 +148,7 @@ def runTruthTrackingGsf( acts.examples.TrackFitterPerformanceWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", filePath=str(outputDir / "performance_gsf.root"), ) diff --git a/Examples/Scripts/Python/truth_tracking_gsf_refitting.py b/Examples/Scripts/Python/truth_tracking_gsf_refitting.py index 138540db2af..686f4af06c2 100755 --- a/Examples/Scripts/Python/truth_tracking_gsf_refitting.py +++ b/Examples/Scripts/Python/truth_tracking_gsf_refitting.py @@ -11,25 +11,27 @@ def runRefittingGsf( - trackingGeometry, - field, - outputDir, + trackingGeometry: acts.TrackingGeometry, + field: acts.MagneticFieldProvider, + digiConfigFile: Path, + outputDir: Path, s: acts.examples.Sequencer = None, ): - srcdir = Path(__file__).resolve().parent.parent.parent.parent - s = runTruthTrackingKalman( trackingGeometry, field, - digiConfigFile=srcdir - / "Examples/Algorithms/Digitization/share/default-smearing-config-generic.json", - # "thirdparty/OpenDataDetector/config/odd-digi-smearing-config.json", + digiConfigFile=digiConfigFile, outputDir=outputDir, s=s, ) + # NOTE we specify clampToRange as True to silence warnings in the test about + # queries to the loss distribution outside the specified range, since no dedicated + # approximation for the ODD is done yet. + bha = acts.examples.AtlasBetheHeitlerApprox.makeDefault(clampToRange=True) + gsfOptions = { - "betheHeitlerApprox": acts.examples.AtlasBetheHeitlerApprox.makeDefault(), + "betheHeitlerApprox": bha, "maxComponents": 12, "componentMergeMethod": acts.examples.ComponentMergeMethod.maxWeight, "mixtureReductionAlgorithm": acts.examples.MixtureReductionAlgorithm.KLDistance, @@ -41,7 +43,7 @@ def runRefittingGsf( acts.examples.RefittingAlgorithm( acts.logging.INFO, inputTracks="kf_tracks", - outputTracks="gsf_tracks", + outputTracks="gsf_refit_tracks", fit=acts.examples.makeGsfFitterFunction( trackingGeometry, field, **gsfOptions ), @@ -51,8 +53,8 @@ def runRefittingGsf( s.addAlgorithm( acts.examples.TrackTruthMatcher( level=acts.logging.INFO, - inputTracks="gsf_tracks", - inputParticles="truth_seeds_selected", + inputTracks="gsf_refit_tracks", + inputParticles="particles_selected", inputMeasurementParticlesMap="measurement_particles_map", outputTrackParticleMatching="refit_track_particle_matching", outputParticleTrackMatching="refit_particle_track_matching", @@ -62,8 +64,8 @@ def runRefittingGsf( s.addWriter( acts.examples.RootTrackStatesWriter( level=acts.logging.INFO, - inputTracks="gsf_tracks", - inputParticles="truth_seeds_selected", + inputTracks="gsf_refit_tracks", + inputParticles="particles_selected", inputTrackParticleMatching="refit_track_particle_matching", inputSimHits="simhits", inputMeasurementSimHitsMap="measurement_simhits_map", @@ -75,7 +77,7 @@ def runRefittingGsf( acts.examples.RootTrackSummaryWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="refit_track_particle_matching", filePath=str(outputDir / "tracksummary_gsf_refit.root"), ) @@ -85,9 +87,9 @@ def runRefittingGsf( acts.examples.TrackFitterPerformanceWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", - filePath=str(outputDir / "performance_refitter.root"), + filePath=str(outputDir / "performance_gsf_refit.root"), ) ) @@ -95,10 +97,28 @@ def runRefittingGsf( if __name__ == "__main__": - outputDir = Path.cwd() + srcdir = Path(__file__).resolve().parent.parent.parent.parent + + # ODD + from acts.examples.odd import getOpenDataDetector + + detector, trackingGeometry, decorators = getOpenDataDetector() + digiConfigFile = ( + srcdir / "thirdparty/OpenDataDetector/config/odd-digi-smearing-config.json" + ) + + ## GenericDetector + # detector, trackingGeometry, _ = acts.examples.GenericDetector.create() + # digiConfigFile = ( + # srcdir + # / "Examples/Algorithms/Digitization/share/default-smearing-config-generic.json" + # ) - # detector, trackingGeometry, decorators = getOpenDataDetector() - detector, trackingGeometry, decorators = acts.examples.GenericDetector.create() field = acts.ConstantBField(acts.Vector3(0, 0, 2 * u.T)) - runRefittingGsf(trackingGeometry, field, outputDir).run() + runRefittingGsf( + trackingGeometry=trackingGeometry, + field=field, + digiConfigFile=digiConfigFile, + outputDir=Path.cwd(), + ).run() diff --git a/Examples/Scripts/Python/truth_tracking_gx2f.py b/Examples/Scripts/Python/truth_tracking_gx2f.py index 46352ac8d21..8503dc982f4 100644 --- a/Examples/Scripts/Python/truth_tracking_gx2f.py +++ b/Examples/Scripts/Python/truth_tracking_gx2f.py @@ -23,13 +23,13 @@ def runTruthTrackingGx2f( EtaConfig, PhiConfig, MomentumConfig, + ParticleSelectorConfig, addFatras, addDigitization, ) from acts.examples.reconstruction import ( addSeeding, SeedingAlgorithm, - TruthSeedRanges, addGx2fTracks, ) @@ -74,6 +74,12 @@ def runTruthTrackingGx2f( field, rnd=rnd, enableInteractions=True, + postSelectParticles=ParticleSelectorConfig( + pt=(0.9 * u.GeV, None), + measurements=(7, None), + removeNeutral=True, + removeSecondaries=True, + ), ) addDigitization( @@ -92,9 +98,6 @@ def runTruthTrackingGx2f( inputParticles="particles_input", seedingAlgorithm=SeedingAlgorithm.TruthSmeared, particleHypothesis=acts.ParticleHypothesis.muon, - truthSeedRanges=TruthSeedRanges( - nHits=(7, None), - ), ) addGx2fTracks( @@ -122,7 +125,7 @@ def runTruthTrackingGx2f( acts.examples.RootTrackStatesWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", inputSimHits="simhits", inputMeasurementSimHitsMap="measurement_simhits_map", @@ -134,7 +137,7 @@ def runTruthTrackingGx2f( acts.examples.RootTrackSummaryWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", filePath=str(outputDir / "tracksummary_gx2f.root"), writeGx2fSpecific=True, @@ -145,7 +148,7 @@ def runTruthTrackingGx2f( acts.examples.TrackFitterPerformanceWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", filePath=str(outputDir / "performance_gx2f.root"), ) diff --git a/Examples/Scripts/Python/truth_tracking_kalman.py b/Examples/Scripts/Python/truth_tracking_kalman.py index 276cb962c8f..91c18f1dd28 100755 --- a/Examples/Scripts/Python/truth_tracking_kalman.py +++ b/Examples/Scripts/Python/truth_tracking_kalman.py @@ -27,13 +27,13 @@ def runTruthTrackingKalman( EtaConfig, PhiConfig, MomentumConfig, + ParticleSelectorConfig, addFatras, addDigitization, ) from acts.examples.reconstruction import ( addSeeding, SeedingAlgorithm, - TruthSeedRanges, addKalmanTracks, ) @@ -82,6 +82,12 @@ def runTruthTrackingKalman( field, rnd=rnd, enableInteractions=True, + postSelectParticles=ParticleSelectorConfig( + pt=(0.9 * u.GeV, None), + measurements=(7, None), + removeNeutral=True, + removeSecondaries=True, + ), ) else: logger.info("Reading hits from %s", inputHitsPath.resolve()) @@ -110,9 +116,6 @@ def runTruthTrackingKalman( inputParticles="particles_input", seedingAlgorithm=SeedingAlgorithm.TruthSmeared, particleHypothesis=acts.ParticleHypothesis.muon, - truthSeedRanges=TruthSeedRanges( - nHits=(7, None), - ), ) addKalmanTracks( @@ -139,7 +142,7 @@ def runTruthTrackingKalman( acts.examples.RootTrackStatesWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", inputSimHits="simhits", inputMeasurementSimHitsMap="measurement_simhits_map", @@ -151,7 +154,7 @@ def runTruthTrackingKalman( acts.examples.RootTrackSummaryWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", filePath=str(outputDir / "tracksummary_kf.root"), ) @@ -161,7 +164,7 @@ def runTruthTrackingKalman( acts.examples.TrackFitterPerformanceWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", filePath=str(outputDir / "performance_kf.root"), ) diff --git a/Examples/Scripts/Python/truth_tracking_kalman_refitting.py b/Examples/Scripts/Python/truth_tracking_kalman_refitting.py new file mode 100755 index 00000000000..46578423f33 --- /dev/null +++ b/Examples/Scripts/Python/truth_tracking_kalman_refitting.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python3 + +from pathlib import Path + +import acts +import acts.examples + +from truth_tracking_kalman import runTruthTrackingKalman + +u = acts.UnitConstants + + +def runRefittingKf( + trackingGeometry: acts.TrackingGeometry, + field: acts.MagneticFieldProvider, + digiConfigFile: Path, + outputDir: Path, + multipleScattering: bool = True, + energyLoss: bool = True, + reverseFilteringMomThreshold=0 * u.GeV, + s: acts.examples.Sequencer = None, +): + s = runTruthTrackingKalman( + trackingGeometry, + field, + digiConfigFile=digiConfigFile, + outputDir=outputDir, + s=s, + ) + + kalmanOptions = { + "multipleScattering": multipleScattering, + "energyLoss": energyLoss, + "reverseFilteringMomThreshold": reverseFilteringMomThreshold, + "freeToBoundCorrection": acts.examples.FreeToBoundCorrection(False), + "level": acts.logging.INFO, + } + + s.addAlgorithm( + acts.examples.RefittingAlgorithm( + level=acts.logging.INFO, + inputTracks="kf_tracks", + outputTracks="kf_refit_tracks", + fit=acts.examples.makeKalmanFitterFunction( + trackingGeometry, field, **kalmanOptions + ), + ) + ) + + s.addAlgorithm( + acts.examples.TrackTruthMatcher( + level=acts.logging.INFO, + inputTracks="kf_refit_tracks", + inputParticles="particles_selected", + inputMeasurementParticlesMap="measurement_particles_map", + outputTrackParticleMatching="refit_track_particle_matching", + outputParticleTrackMatching="refit_particle_track_matching", + ) + ) + + s.addWriter( + acts.examples.RootTrackStatesWriter( + level=acts.logging.INFO, + inputTracks="kf_refit_tracks", + inputParticles="particles_selected", + inputTrackParticleMatching="refit_track_particle_matching", + inputSimHits="simhits", + inputMeasurementSimHitsMap="measurement_simhits_map", + filePath=str(outputDir / "trackstates_kf_refit.root"), + ) + ) + + s.addWriter( + acts.examples.RootTrackSummaryWriter( + level=acts.logging.INFO, + inputTracks="tracks", + inputParticles="particles_selected", + inputTrackParticleMatching="refit_track_particle_matching", + filePath=str(outputDir / "tracksummary_kf_refit.root"), + ) + ) + + s.addWriter( + acts.examples.TrackFitterPerformanceWriter( + level=acts.logging.INFO, + inputTracks="tracks", + inputParticles="particles_selected", + inputTrackParticleMatching="track_particle_matching", + filePath=str(outputDir / "performance_kf_refit.root"), + ) + ) + + return s + + +if __name__ == "__main__": + srcdir = Path(__file__).resolve().parent.parent.parent.parent + outputDir = Path.cwd() + + # ODD + from acts.examples.odd import getOpenDataDetector + + detector, trackingGeometry, decorators = getOpenDataDetector() + digiConfigFile = ( + srcdir / "thirdparty/OpenDataDetector/config/odd-digi-smearing-config.json" + ) + + ## GenericDetector + # detector, trackingGeometry, _ = acts.examples.GenericDetector.create() + # digiConfigFile = ( + # srcdir + # / "Examples/Algorithms/Digitization/share/default-smearing-config-generic.json" + # ) + + field = acts.ConstantBField(acts.Vector3(0, 0, 2 * u.T)) + + runRefittingKf( + trackingGeometry=trackingGeometry, + field=field, + digiConfigFile=digiConfigFile, + outputDir=Path.cwd(), + ).run() 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/Kernel/Simulation.hpp b/Fatras/include/ActsFatras/Kernel/Simulation.hpp index cbc1115225a..2d8280737f0 100644 --- a/Fatras/include/ActsFatras/Kernel/Simulation.hpp +++ b/Fatras/include/ActsFatras/Kernel/Simulation.hpp @@ -245,6 +245,9 @@ struct Simulation { continue; } + assert(result->particle.particleId() == initialParticle.particleId() && + "Particle id must not change during simulation"); + copyOutputs(result.value(), simulatedParticlesInitial, simulatedParticlesFinal, hits); // since physics processes are independent, there can be particle id @@ -256,6 +259,10 @@ struct Simulation { } } + assert( + (simulatedParticlesInitial.size() == simulatedParticlesFinal.size()) && + "Inconsistent final sizes of the simulated particle containers"); + // the overall function call succeeded, i.e. no fatal errors occurred. // yet, there might have been some particle for which the propagation // failed. thus, the successful result contains a list of failed particles. @@ -284,12 +291,13 @@ struct Simulation { // initial particle state was already pushed to the container before // store final particle state at the end of the simulation particlesFinal.push_back(result.particle); + std::copy(result.hits.begin(), result.hits.end(), std::back_inserter(hits)); + // move generated secondaries that should be simulated to the output std::copy_if( result.generatedParticles.begin(), result.generatedParticles.end(), std::back_inserter(particlesInitial), [this](const Particle &particle) { return selectParticle(particle); }); - std::copy(result.hits.begin(), result.hits.end(), std::back_inserter(hits)); } /// Renumber particle ids in the tail of the container. diff --git a/Fatras/include/ActsFatras/Kernel/detail/SimulationActor.hpp b/Fatras/include/ActsFatras/Kernel/detail/SimulationActor.hpp index cc6d7200868..acbaaaa713d 100644 --- a/Fatras/include/ActsFatras/Kernel/detail/SimulationActor.hpp +++ b/Fatras/include/ActsFatras/Kernel/detail/SimulationActor.hpp @@ -69,7 +69,17 @@ struct SimulationActor { void act(propagator_state_t &state, stepper_t &stepper, navigator_t &navigator, result_type &result, const Acts::Logger &logger) const { - assert(generator && "The generator pointer must be valid"); + assert(generator != nullptr && "The generator pointer must be valid"); + + if (state.stage == Acts::PropagatorStage::prePropagation) { + // first step is special: there is no previous state and we need to arm + // the decay simulation for all future steps. + result.particle = + makeParticle(initialParticle, state, stepper, navigator); + result.properTimeLimit = + decay.generateProperTimeLimit(*generator, initialParticle); + return; + } // actors are called once more after the propagation terminated if (!result.isAlive) { @@ -82,28 +92,11 @@ struct SimulationActor { return; } - // check if we are still on the start surface and skip if so - if ((navigator.startSurface(state.navigation) != nullptr) && - (navigator.startSurface(state.navigation) == - navigator.currentSurface(state.navigation))) { - return; - } - // update the particle state first. this also computes the proper time which // needs the particle state from the previous step for reference. that means // this must happen for every step (not just on surface) and before // everything, e.g. any interactions that could modify the state. - if (std::isnan(result.properTimeLimit)) { - // first step is special: there is no previous state and we need to arm - // the decay simulation for all future steps. - result.particle = - makeParticle(initialParticle, state, stepper, navigator); - result.properTimeLimit = - decay.generateProperTimeLimit(*generator, initialParticle); - } else { - result.particle = - makeParticle(result.particle, state, stepper, navigator); - } + result.particle = makeParticle(result.particle, state, stepper, navigator); // decay check. needs to happen at every step, not just on surfaces. if (std::isfinite(result.properTimeLimit) && diff --git a/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/DetrayConversionUtils.hpp b/Plugins/Detray/include/Acts/Plugins/Detray/DetrayConversionUtils.hpp index 201aeb2807d..2f827a08bea 100644 --- a/Plugins/Detray/include/Acts/Plugins/Detray/DetrayConversionUtils.hpp +++ b/Plugins/Detray/include/Acts/Plugins/Detray/DetrayConversionUtils.hpp @@ -20,6 +20,10 @@ namespace Acts { +namespace Experimental { +class DetectorVolume; +} + using DetrayHostDetector = detray::detector; namespace DetrayConversionUtils { @@ -28,12 +32,37 @@ namespace DetrayConversionUtils { /// /// This object is used to synchronize link information between the /// different converters (geometry, material, surface grids) -struct GeometryIdCache { - /// This is a multimap to pass volume local surface link information - /// The portal splitting requires a multimap implementation here - std::multimap localSurfaceLinks; +struct Cache { + /// Explicit constructor with detector volumes + /// + /// @param detectorVolumes the number of detector volumes + Cache(const std::vector& dVolumes) + : detectorVolumes(dVolumes) {} + + /// The volumes of the detector for index lookup + std::vector detectorVolumes; /// This is a map to pass on volume link information std::map volumeLinks; + /// This is a multimap to pass volume local surface link information + /// The portal splitting requires a multimap implementation here + /// + /// These are volume local, hence indexed per volumes + std::map> + localSurfaceLinks; + + /// Find the position of the volume to point to + /// + /// @param volume the volume to find + /// + /// @note throws exception if volume is not found + std::size_t volumeIndex( + const Acts::Experimental::DetectorVolume* volume) const { + auto candidate = std::ranges::find(detectorVolumes, volume); + if (candidate != detectorVolumes.end()) { + return std::distance(detectorVolumes.begin(), candidate); + } + throw std::invalid_argument("Volume not found in the cache"); + } }; /// Convert the binning option diff --git a/Plugins/Detray/include/Acts/Plugins/Detray/DetrayConverter.hpp b/Plugins/Detray/include/Acts/Plugins/Detray/DetrayConverter.hpp index 2c8ca2c7fac..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 /// @@ -54,7 +55,7 @@ class DetrayConverter { const Experimental::Detector& detector, vecmem::memory_resource& mr, const Options& options) { // The building cache object - DetrayConversionUtils::GeometryIdCache geoIdCache; + DetrayConversionUtils::Cache cCache(detector.volumes()); typename detector_t::name_map names = {{0u, detector.name()}}; @@ -62,7 +63,7 @@ class DetrayConverter { detray::detector_builder detectorBuilder{}; // (1) geometry detray::io::detector_payload detectorPayload = - DetrayGeometryConverter::convertDetector(geoIdCache, gctx, detector, + DetrayGeometryConverter::convertDetector(cCache, gctx, detector, logger()); detray::io::geometry_reader::convert(detectorBuilder, names, detectorPayload); @@ -72,7 +73,7 @@ class DetrayConverter { if (options.convertMaterial) { detray::io::detector_homogeneous_material_payload materialSlabsPayload = DetrayMaterialConverter::convertHomogeneousSurfaceMaterial( - geoIdCache, detector, logger()); + cCache, detector, logger()); detray::io::homogeneous_material_reader::convert( detectorBuilder, names, std::move(materialSlabsPayload)); } @@ -85,7 +86,7 @@ class DetrayConverter { detray::io::material_id> materialGridsPayload = DetrayMaterialConverter::convertGridSurfaceMaterial( - geoIdCache, detector, logger()); + cCache, detector, logger()); detray::io::material_map_reader>::convert(detectorBuilder, names, std::move( diff --git a/Plugins/Detray/include/Acts/Plugins/Detray/DetrayGeometryConverter.hpp b/Plugins/Detray/include/Acts/Plugins/Detray/DetrayGeometryConverter.hpp index 2df31096746..b6ea1373125 100644 --- a/Plugins/Detray/include/Acts/Plugins/Detray/DetrayGeometryConverter.hpp +++ b/Plugins/Detray/include/Acts/Plugins/Detray/DetrayGeometryConverter.hpp @@ -64,25 +64,25 @@ detray::io::surface_payload convertSurface(const GeometryContext& gctx, /// Conversion method for Portal object to detray::portal payloads /// +/// @param cCache [in, out] object /// @param gctx the geometry context /// @param portal the portal to be converted /// @param ip the portal index /// @param volume the volume to which the portal belongs /// @param orientedSurfaces the oriented surfaces of the portal -/// @param detectorVolumes the detector volumes for the link lookup /// /// @note due to portal splitting this can add up in N portals for one initial one /// /// @brief convert the acts portal to detray surface payload and populate the payload std::vector convertPortal( - const GeometryContext& gctx, const Experimental::Portal& portal, - std::size_t ip, const Experimental::DetectorVolume& volume, - const std::vector& orientedSurfaces, - const std::vector& detectorVolumes); + DetrayConversionUtils::Cache& cCache, const GeometryContext& gctx, + const Experimental::Portal& portal, std::size_t ip, + const Experimental::DetectorVolume& volume, + const std::vector& orientedSurfaces); /// Conversion method for volume objects to detray::volume payloads /// -/// @param geoIdCache [in, out] object +/// @param cCache [in, out] object /// @param gctx the geometry context /// @param volume the volume to be converted /// @param detectorVolumes the detector volumes for the link lookup @@ -90,23 +90,20 @@ std::vector convertPortal( /// /// @return the volume_payload for portals and volumes by @param volume acts object detray::io::volume_payload convertVolume( - DetrayConversionUtils::GeometryIdCache& geoIdCache, - const GeometryContext& gctx, const Experimental::DetectorVolume& volume, - const std::vector& detectorVolumes, - const Acts::Logger& logger); + DetrayConversionUtils::Cache& cCache, const GeometryContext& gctx, + const Experimental::DetectorVolume& volume, const Acts::Logger& logger); /// Conversion method for detector objects to detray::detector payload /// -/// @param geoIdCache [in, out] object +/// @param cCache [in, out] object /// @param gctx the geometry context /// @param detector the detector to be converted /// @param logger the logger object for screen output /// /// @return the detector_payload for portals and volumes by @param detector acts object detray::io::detector_payload convertDetector( - DetrayConversionUtils::GeometryIdCache& geoIdCache, - const GeometryContext& gctx, const Experimental::Detector& detector, - const Acts::Logger& logger); + DetrayConversionUtils::Cache& cCache, const GeometryContext& gctx, + const Experimental::Detector& detector, const Acts::Logger& logger); } // namespace DetrayGeometryConverter } // namespace Acts diff --git a/Plugins/Detray/include/Acts/Plugins/Detray/DetrayMaterialConverter.hpp b/Plugins/Detray/include/Acts/Plugins/Detray/DetrayMaterialConverter.hpp index d3be849e362..70a2c8cec73 100644 --- a/Plugins/Detray/include/Acts/Plugins/Detray/DetrayMaterialConverter.hpp +++ b/Plugins/Detray/include/Acts/Plugins/Detray/DetrayMaterialConverter.hpp @@ -35,15 +35,15 @@ detray::io::material_slab_payload convertMaterialSlab( /// Conversion method for homogeneous material /// -/// @param geoIdCache object to have the link association from the geometry building +/// @param cCache object to have the link association from the geometry building /// @param detector the detector object /// @param logger the logger object for screen output /// /// @return the volume_payload for portals and volumes by @param volume acts object detray::io::detector_homogeneous_material_payload -convertHomogeneousSurfaceMaterial( - const DetrayConversionUtils::GeometryIdCache& geoIdCache, - const Experimental::Detector& detector, const Logger& logger); +convertHomogeneousSurfaceMaterial(const DetrayConversionUtils::Cache& cCache, + const Experimental::Detector& detector, + const Logger& logger); /// Conversion method for grid based surface material /// @@ -58,16 +58,16 @@ convertGridSurfaceMaterial(const ISurfaceMaterial& material, /// Conversion method for material grids /// -/// @param geoIdCache object to have the link association from the geometry building +/// @param cCache object to have the link association from the geometry building /// @param detector the detector object /// @param logger the logger object for screen output /// /// @return the volume_payload for portals and volumes by @param volume acts object detray::io::detector_grids_payload -convertGridSurfaceMaterial( - const DetrayConversionUtils::GeometryIdCache& geoIdCache, - const Experimental::Detector& detector, const Logger& logger); +convertGridSurfaceMaterial(const DetrayConversionUtils::Cache& cCache, + const Experimental::Detector& detector, + const Logger& logger); } // namespace DetrayMaterialConverter diff --git a/Plugins/Detray/src/DetrayGeometryConverter.cpp b/Plugins/Detray/src/DetrayGeometryConverter.cpp index 664900841f0..23eb56a0f8c 100644 --- a/Plugins/Detray/src/DetrayGeometryConverter.cpp +++ b/Plugins/Detray/src/DetrayGeometryConverter.cpp @@ -27,25 +27,6 @@ using namespace detray; -namespace { - -/// Find the position of the volume to point to -/// -/// @param volume the volume to find -/// @param the collection of volumes -/// -/// @note return -1 if not found, to be interpreted by the caller -int findVolume( - const Acts::Experimental::DetectorVolume* volume, - const std::vector& volumes) { - auto candidate = std::ranges::find(volumes, volume); - if (candidate != volumes.end()) { - return std::distance(volumes.begin(), candidate); - } - return -1; -} -} // namespace - detray::io::transform_payload Acts::DetrayGeometryConverter::convertTransform( const Transform3& t) { detray::io::transform_payload tfPayload; @@ -87,10 +68,10 @@ detray::io::surface_payload Acts::DetrayGeometryConverter::convertSurface( std::vector Acts::DetrayGeometryConverter::convertPortal( - const GeometryContext& gctx, const Experimental::Portal& portal, - std::size_t ip, const Experimental::DetectorVolume& volume, - const std::vector& orientedSurfaces, - const std::vector& detectorVolumes) { + DetrayConversionUtils::Cache& cCache, const GeometryContext& gctx, + const Experimental::Portal& portal, std::size_t ip, + const Experimental::DetectorVolume& volume, + const std::vector& orientedSurfaces) { std::vector portals{}; const RegularSurface& surface = portal.surface(); @@ -135,7 +116,7 @@ Acts::DetrayGeometryConverter::convertPortal( // in order to make sure the size is adjusted if (singleLink != nullptr) { // Single link can be written out - std::size_t vLink = findVolume(singleLink->object(), detectorVolumes); + std::size_t vLink = cCache.volumeIndex(singleLink->object()); auto portalPayload = convertSurface(gctx, *surfaceAdjusted, true); portalPayload.mask.volume_link.link = vLink; portals.push_back(portalPayload); @@ -161,10 +142,10 @@ Acts::DetrayGeometryConverter::convertPortal( auto surfaceType = surfaceAdjusted->type(); std::vector vIndices = {}; for (const auto& v : volumes) { - vIndices.push_back(findVolume(v, detectorVolumes)); + vIndices.push_back(cCache.volumeIndex(v)); } - // Pick the surface dimension - via poly + // Pick the surface dimension std::array clipRange = {0., 0.}; std::vector boundValues = surfaceAdjusted->bounds().values(); if (surfaceType == Surface::SurfaceType::Cylinder && @@ -227,6 +208,7 @@ Acts::DetrayGeometryConverter::convertPortal( 0., 0., clippedBoundaries[ib - 1u] + subBoundValues[CylinderBounds::BoundValues::eHalfLengthZ])); + auto subSurface = Surface::makeShared(subTransform, subBounds); subSurface->assignGeometryId(surface.geometryId()); @@ -251,6 +233,7 @@ Acts::DetrayGeometryConverter::convertPortal( auto subBounds = std::make_shared(subBoundValues); auto subSurface = Surface::makeShared( portal.surface().transform(gctx), subBounds); + subSurface->assignGeometryId(surface.geometryId()); auto portalPayload = convertSurface(gctx, *subSurface, true); portalPayload.mask.volume_link.link = clippedIndices[ib - 1u]; @@ -260,7 +243,6 @@ Acts::DetrayGeometryConverter::convertPortal( } } else { - // End of world portal // Write surface with invalid link auto portalPayload = convertSurface(gctx, *surfaceAdjusted, true); using NavigationLink = @@ -271,27 +253,27 @@ Acts::DetrayGeometryConverter::convertPortal( portals.push_back(portalPayload); } } - return portals; } detray::io::volume_payload Acts::DetrayGeometryConverter::convertVolume( - DetrayConversionUtils::GeometryIdCache& geoIdCache, - const GeometryContext& gctx, + DetrayConversionUtils::Cache& cCache, const GeometryContext& gctx, const Acts::Experimental::DetectorVolume& volume, - const std::vector& detectorVolumes, const Acts::Logger& logger) { ACTS_DEBUG("DetrayGeometryConverter: converting volume " << volume.name() << " with " << volume.surfaces().size() << " surfaces and " << volume.portals().size() << " portals"); detray::io::volume_payload volumePayload; + std::size_t volumeIndex = cCache.volumeIndex(&volume); volumePayload.name = volume.name(); - volumePayload.index.link = findVolume(&volume, detectorVolumes); + volumePayload.index.link = volumeIndex; volumePayload.transform = convertTransform(volume.transform(gctx)); // Remember the link - geoIdCache.volumeLinks[volume.geometryId()] = volumePayload.index.link; + cCache.volumeLinks[volume.geometryId()] = volumePayload.index.link; + + std::multimap localSurfaceLinks; // iterate over surfaces and portals keeping the same surf_pd.index_in_coll std::size_t sIndex = 0; @@ -299,7 +281,7 @@ detray::io::volume_payload Acts::DetrayGeometryConverter::convertVolume( io::surface_payload surfacePayload = convertSurface(gctx, *surface, false); // Set the index in the collection & remember it in the cache surfacePayload.index_in_coll = sIndex++; - geoIdCache.localSurfaceLinks.insert( + localSurfaceLinks.insert( {surface->geometryId(), surfacePayload.index_in_coll.value()}); // Set mask to volume link surfacePayload.mask.volume_link.link = @@ -314,30 +296,32 @@ detray::io::volume_payload Acts::DetrayGeometryConverter::convertVolume( int portalCounter = 0; for (const auto& [ip, p] : enumerate(volume.portals())) { auto portals = - convertPortal(gctx, *p, ip, volume, orientedSurfaces, detectorVolumes); - + convertPortal(cCache, gctx, *p, ip, volume, orientedSurfaces); + ACTS_VERBOSE(" > portal " << ip << " split into " << portals.size() + << " surfaces"); GeometryIdentifier geoID = p->surface().geometryId(); std::for_each(portals.begin(), portals.end(), [&](auto& portalPayload) { // Set the index in the collection & remember it in the cache portalPayload.index_in_coll = sIndex++; - geoIdCache.localSurfaceLinks.insert( - {geoID, portalPayload.index_in_coll.value()}); + localSurfaceLinks.insert({geoID, portalPayload.index_in_coll.value()}); // Add it to the surfaces volumePayload.surfaces.push_back(portalPayload); portalCounter++; }); } - ACTS_VERBOSE(" > " << volume.portals().size() - << " initial ACTS portals split into final " - << portalCounter << " detray portals"); + cCache.localSurfaceLinks[volumeIndex] = localSurfaceLinks; + ACTS_DEBUG(" > " << volume.portals().size() + << " initial ACTS portals split into final " << portalCounter + << " detray portals"); + ACTS_VERBOSE(" > Local surface link cache has " << localSurfaceLinks.size() + << " entries"); return volumePayload; } detray::io::detector_payload Acts::DetrayGeometryConverter::convertDetector( - DetrayConversionUtils::GeometryIdCache& geoIdCache, - const GeometryContext& gctx, const Acts::Experimental::Detector& detector, - const Acts::Logger& logger) { + DetrayConversionUtils::Cache& cCache, const GeometryContext& gctx, + const Acts::Experimental::Detector& detector, const Acts::Logger& logger) { ACTS_DEBUG("DetrayGeometryConverter: converting detector" << detector.name() << " with " << detector.volumes().size() << " volumes."); @@ -347,7 +331,7 @@ detray::io::detector_payload Acts::DetrayGeometryConverter::convertDetector( for (const auto volume : detector.volumes()) { detectorPayload.volumes.push_back( - convertVolume(geoIdCache, gctx, *volume, detector.volumes(), logger)); + convertVolume(cCache, gctx, *volume, logger)); } return detectorPayload; diff --git a/Plugins/Detray/src/DetrayMaterialConverter.cpp b/Plugins/Detray/src/DetrayMaterialConverter.cpp index dd82b0d1b93..c08bdc447bf 100644 --- a/Plugins/Detray/src/DetrayMaterialConverter.cpp +++ b/Plugins/Detray/src/DetrayMaterialConverter.cpp @@ -52,13 +52,13 @@ Acts::DetrayMaterialConverter::convertMaterialSlab( detray::io::detector_homogeneous_material_payload Acts::DetrayMaterialConverter::convertHomogeneousSurfaceMaterial( - const DetrayConversionUtils::GeometryIdCache& geoIdCache, + const DetrayConversionUtils::Cache& cCache, const Experimental::Detector& detector, const Logger& logger) { detray::io::detector_homogeneous_material_payload materialPayload; for (const auto volume : detector.volumes()) { - auto volumeIndex = geoIdCache.volumeLinks.find(volume->geometryId()); - if (volumeIndex != geoIdCache.volumeLinks.end()) { + auto volumeIndex = cCache.volumeLinks.find(volume->geometryId()); + if (volumeIndex != cCache.volumeLinks.end()) { // The volume material payload & its link detray::io::material_volume_payload volumePayload; detray::io::single_link_payload volumeLink; @@ -80,18 +80,24 @@ Acts::DetrayMaterialConverter::convertHomogeneousSurfaceMaterial( auto materialSlab = homogeneousMaterial->materialSlab(); detray::io::material_slab_payload slabPayload = convertMaterialSlab(materialSlab); - // Find the surfaces and assign - auto surfaceIndices = - geoIdCache.localSurfaceLinks.equal_range(surface->geometryId()); - // Loop over the equal range and fill one grid each, this is needed - // as the initial portal could be split into multiple surfaces - for (auto itr = surfaceIndices.first; itr != surfaceIndices.second; - ++itr) { - // Make an identified link copy for every matching surface - detray::io::single_link_payload surfaceLink; - surfaceLink.link = itr->second; - slabPayload.surface = surfaceLink; - volumePayload.mat_slabs.push_back(slabPayload); + // Find the surfaces to assign + auto vIndex = cCache.volumeIndex(volume); + auto localSurfaceLinks = cCache.localSurfaceLinks.find(vIndex); + if (localSurfaceLinks != cCache.localSurfaceLinks.end()) { + // Find the surface link + auto surfaceIndices = + localSurfaceLinks->second.equal_range(surface->geometryId()); + // Loop over the equal range and fill one grid each, this is needed + // as the initial portal could be split into multiple surfaces + for (auto itr = surfaceIndices.first; itr != surfaceIndices.second; + ++itr) { + // Make an identified link copy for every matching surface + slabPayload.surface.link = itr->second; + volumePayload.mat_slabs.push_back(slabPayload); + } + } else { + ACTS_WARNING( + "DetrayMaterialConverter: no local surface links found"); } } } @@ -232,7 +238,7 @@ Acts::DetrayMaterialConverter::convertGridSurfaceMaterial( detray::io::detector_grids_payload Acts::DetrayMaterialConverter::convertGridSurfaceMaterial( - const DetrayConversionUtils::GeometryIdCache& geoIdCache, + const DetrayConversionUtils::Cache& cCache, const Experimental::Detector& detector, const Logger& logger) { // The material grid payload detray::io::detector_grids_payloadvisitSurfaces(selector); - ACTS_DEBUG("DetrayMaterialConverter: found " - << selector.surfaces.size() - << " surfaces/portals with material in volume " - << volume->name()); + ACTS_VERBOSE("DetrayMaterialConverter: found " + << selector.surfaces.size() + << " surfaces/portals with material in volume " + << volume->name()); // Find the voluem index first - auto volumeIndex = geoIdCache.volumeLinks.find(volume->geometryId()); - if (volumeIndex != geoIdCache.volumeLinks.end()) { + auto volumeIndex = cCache.volumeLinks.find(volume->geometryId()); + if (volumeIndex != cCache.volumeLinks.end()) { std::vector volumeMaterialGrids = {}; // Now convert the surfaces for (const auto& surface : selector.surfaces) { - // Find the surface index - auto surfaceIndices = - geoIdCache.localSurfaceLinks.equal_range(surface->geometryId()); - DetrayMaterialGrid materialGrid = - convertGridSurfaceMaterial(*surface->surfaceMaterial(), logger); - // Ignore if an empty payload is returned - if (materialGrid.axes.empty() && materialGrid.bins.empty()) { - continue; - } - // Loop over the equal range and fill one grid each, this is needed - // as the initial portal could be split into multiple surfaces - for (auto itr = surfaceIndices.first; itr != surfaceIndices.second; - ++itr) { - // Fill the surface index - materialGrid.owner_link = - detray::io::single_link_payload{itr->second}; - // Fill the grid - volumeMaterialGrids.push_back(materialGrid); + // Find the surfaces to assign + auto vIndex = cCache.volumeIndex(volume); + auto localSurfaceLinks = cCache.localSurfaceLinks.find(vIndex); + if (localSurfaceLinks != cCache.localSurfaceLinks.end()) { + // Find the surface link + auto surfaceIndices = + localSurfaceLinks->second.equal_range(surface->geometryId()); + + ACTS_VERBOSE( + "DetrayMaterialConverter: assigning to " + << std::distance(surfaceIndices.first, surfaceIndices.second) + << " surfaces with material in volume " << volume->name()); + DetrayMaterialGrid materialGrid = + convertGridSurfaceMaterial(*surface->surfaceMaterial(), logger); + // Ignore if an empty payload is returned + if (materialGrid.axes.empty() || materialGrid.bins.empty()) { + continue; + } + + // Loop over the equal range and fill one grid each, this is needed + // as the initial portal could be split into multiple surfaces + for (auto itr = surfaceIndices.first; itr != surfaceIndices.second; + ++itr) { + // Fill the surface index + materialGrid.owner_link = + detray::io::single_link_payload{itr->second}; + // Fill the grid + volumeMaterialGrids.push_back(materialGrid); + } } } // Register the grids of this volume materialGrids.grids.insert({volumeIndex->second, volumeMaterialGrids}); - } else { ACTS_WARNING( "DetrayMaterialConverter: volume not found in cache, should not " diff --git a/Plugins/FpeMonitoring/CMakeLists.txt b/Plugins/FpeMonitoring/CMakeLists.txt index 05a6126e2f3..ccd7c7f4ceb 100644 --- a/Plugins/FpeMonitoring/CMakeLists.txt +++ b/Plugins/FpeMonitoring/CMakeLists.txt @@ -24,6 +24,11 @@ else() set(_backtrace_setup_complete FALSE) + find_path( + boost_stacktrace_include + NAMES "boost/stacktrace.hpp" + REQUIRED + ) if(Backtrace_FOUND) # check if we need to link against bracktrace or not set(backtrace_include "") @@ -44,6 +49,7 @@ else() "${CMAKE_BINARY_DIR}" "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/backtrace.cpp" LINK_LIBRARIES ${dl_LIBRARY} + CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${boost_stacktrace_include}" COMPILE_DEFINITIONS -DBOOST_STACKTRACE_USE_BACKTRACE OUTPUT_VARIABLE __OUTPUT ) @@ -54,9 +60,9 @@ else() message(CHECK_FAIL "no") file(GLOB hints "/usr/lib/gcc/*/*/include") - find_file(backtrace_header "backtrace.h" HINTS ${hints}) + find_file(backtrace_header NAMES "backtrace.h" HINTS ${hints}) - if(${backtrace_header} STREQUAL "backtrcae_header-NOTFOUND") + if(${backtrace_header} STREQUAL "backtrace_header-NOTFOUND") message(STATUS "Could not find backtrace header file") else() set(backtrace_include @@ -82,6 +88,8 @@ else() "${CMAKE_BINARY_DIR}" "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/backtrace.cpp" LINK_LIBRARIES ${dl_LIBRARY} + CMAKE_FLAGS + "-DINCLUDE_DIRECTORIES=${boost_stacktrace_include}" COMPILE_DEFINITIONS -DBOOST_STACKTRACE_USE_BACKTRACE ${backtrace_include} @@ -111,6 +119,7 @@ else() "${CMAKE_BINARY_DIR}" "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/backtrace.cpp" LINK_LIBRARIES ${dl_LIBRARY} + CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${boost_stacktrace_include}" COMPILE_DEFINITIONS -DBOOST_STACKTRACE_USE_BACKTRACE ${backtrace_include} @@ -137,6 +146,8 @@ else() "${CMAKE_BINARY_DIR}" "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/backtrace.cpp" LINK_LIBRARIES backtrace ${dl_LIBRARY} + CMAKE_FLAGS + "-DINCLUDE_DIRECTORIES=${boost_stacktrace_include}" COMPILE_DEFINITIONS -DBOOST_STACKTRACE_USE_BACKTRACE ${backtrace_include} @@ -158,23 +169,6 @@ else() endif() endif() - if(NOT _backtrace_setup_complete) - message(CHECK_START "Is addr2line available") - if(addr2line_EXECUTABLE) - list(APPEND _fpe_options -DBOOST_STACKTRACE_USE_ADDR2LINE) - list( - APPEND - _fpe_options - -DBOOST_STACKTRACE_ADDR2LINE_LOCATION=${addr2line_EXECUTABLE} - ) - message(CHECK_PASS "yes") - - set(_backtrace_setup_complete TRUE) - else() - message(CHECK_FAIL "no") - endif() - endif() - if(NOT _backtrace_setup_complete) message(STATUS "Unable to set up stacktrace setup: use noop") list(APPEND _fpe_options -BOOST_STACKTRACE_USE_NOOP) diff --git a/Plugins/FpeMonitoring/include/Acts/Plugins/FpeMonitoring/FpeMonitor.hpp b/Plugins/FpeMonitoring/include/Acts/Plugins/FpeMonitoring/FpeMonitor.hpp index 99e39da96d0..022a07a3426 100644 --- a/Plugins/FpeMonitoring/include/Acts/Plugins/FpeMonitoring/FpeMonitor.hpp +++ b/Plugins/FpeMonitoring/include/Acts/Plugins/FpeMonitoring/FpeMonitor.hpp @@ -40,7 +40,7 @@ std::ostream &operator<<(std::ostream &os, FpeType type); class FpeMonitor { public: struct Buffer { - Buffer(std::size_t bufferSize) + explicit Buffer(std::size_t bufferSize) : m_data{std::make_unique(bufferSize)}, m_size{bufferSize} {} @@ -105,12 +105,12 @@ class FpeMonitor { Result() = default; - operator bool() const { return !m_stracktraces.empty(); } + bool hasStackTraces() const { return !m_stackTraces.empty(); } void add(Acts::FpeType type, void *stackPtr, std::size_t bufferSize); private: - std::vector m_stracktraces; + std::vector m_stackTraces; std::array m_counts{}; friend FpeMonitor; @@ -131,6 +131,8 @@ class FpeMonitor { std::size_t depth); static std::string getSourceLocation(const boost::stacktrace::frame &frame); + static bool canSymbolize(); + private: void enable(); void disable(); diff --git a/Plugins/FpeMonitoring/src/FpeMonitor.cpp b/Plugins/FpeMonitoring/src/FpeMonitor.cpp index 8b4feb5f1d2..09dce1f4b0a 100644 --- a/Plugins/FpeMonitoring/src/FpeMonitor.cpp +++ b/Plugins/FpeMonitoring/src/FpeMonitor.cpp @@ -61,10 +61,10 @@ FpeMonitor::Result FpeMonitor::Result::merged(const Result &with) const { result.m_counts[i] = m_counts[i] + with.m_counts[i]; } - std::copy(with.m_stracktraces.begin(), with.m_stracktraces.end(), - std::back_inserter(result.m_stracktraces)); - std::copy(m_stracktraces.begin(), m_stracktraces.end(), - std::back_inserter(result.m_stracktraces)); + std::copy(with.m_stackTraces.begin(), with.m_stackTraces.end(), + std::back_inserter(result.m_stackTraces)); + std::copy(m_stackTraces.begin(), m_stackTraces.end(), + std::back_inserter(result.m_stackTraces)); result.deduplicate(); @@ -76,8 +76,8 @@ void FpeMonitor::Result::merge(const Result &with) { m_counts[i] = m_counts[i] + with.m_counts[i]; } - std::copy(with.m_stracktraces.begin(), with.m_stracktraces.end(), - std::back_inserter(m_stracktraces)); + std::copy(with.m_stackTraces.begin(), with.m_stackTraces.end(), + std::back_inserter(m_stackTraces)); deduplicate(); } @@ -87,20 +87,20 @@ void FpeMonitor::Result::add(FpeType type, void *stackPtr, auto st = std::make_unique( boost::stacktrace::stacktrace::from_dump(stackPtr, bufferSize)); - auto it = std::ranges::find_if(m_stracktraces, [&](const FpeInfo &el) { + auto it = std::ranges::find_if(m_stackTraces, [&](const FpeInfo &el) { return areFpesEquivalent({el.type, *el.st}, {type, *st}); }); - if (it != m_stracktraces.end()) { + if (it != m_stackTraces.end()) { it->count += 1; } else { - m_stracktraces.push_back({1, type, std::move(st)}); + m_stackTraces.push_back({1, type, std::move(st)}); } } bool FpeMonitor::Result::contains( FpeType type, const boost::stacktrace::stacktrace &st) const { - return std::ranges::any_of(m_stracktraces, [&](const FpeInfo &el) { + return std::ranges::any_of(m_stackTraces, [&](const FpeInfo &el) { return areFpesEquivalent({el.type, *el.st}, {type, st}); }); } @@ -128,12 +128,12 @@ unsigned int FpeMonitor::Result::count(FpeType type) const { } unsigned int FpeMonitor::Result::numStackTraces() const { - return m_stracktraces.size(); + return m_stackTraces.size(); } const std::vector & FpeMonitor::Result::stackTraces() const { - return m_stracktraces; + return m_stackTraces; } bool FpeMonitor::Result::encountered(FpeType type) const { @@ -161,18 +161,18 @@ void FpeMonitor::Result::summary(std::ostream &os, std::size_t depth) const { void FpeMonitor::Result::deduplicate() { std::vector copy{}; - copy = std::move(m_stracktraces); - m_stracktraces.clear(); + copy = std::move(m_stackTraces); + m_stackTraces.clear(); for (auto &info : copy) { - auto it = std::ranges::find_if(m_stracktraces, [&info](const FpeInfo &el) { + auto it = std::ranges::find_if(m_stackTraces, [&info](const FpeInfo &el) { return areFpesEquivalent({el.type, *el.st}, {info.type, *info.st}); }); - if (it != m_stracktraces.end()) { + if (it != m_stackTraces.end()) { it->count += info.count; continue; } - m_stracktraces.push_back({info.count, info.type, std::move(info.st)}); + m_stackTraces.push_back({info.count, info.type, std::move(info.st)}); } } @@ -332,4 +332,12 @@ std::string FpeMonitor::getSourceLocation( return frame.source_file() + ":" + std::to_string(frame.source_line()); } +bool FpeMonitor::canSymbolize() { +#if defined(BOOST_STACKTRACE_USE_NOOP) + return false; +#else + return true; +#endif +} + } // namespace Acts 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/GridJsonConverter.hpp b/Plugins/Json/include/Acts/Plugins/Json/GridJsonConverter.hpp index 20065d488bb..3215bd66eae 100644 --- a/Plugins/Json/include/Acts/Plugins/Json/GridJsonConverter.hpp +++ b/Plugins/Json/include/Acts/Plugins/Json/GridJsonConverter.hpp @@ -9,6 +9,7 @@ #pragma once #include "Acts/Plugins/Json/ActsJson.hpp" +#include "Acts/Plugins/Json/TrackParametersJsonConverter.hpp" #include "Acts/Utilities/AxisFwd.hpp" #include "Acts/Utilities/GridAccessHelpers.hpp" #include "Acts/Utilities/IAxis.hpp" @@ -266,15 +267,17 @@ auto fromJson(const nlohmann::json& jGrid, if constexpr (GridType::DIM == 1u) { for (const auto& jd : jData) { std::array lbin = jd[0u]; - value_type values = jd[1u]; - grid.atLocalBins(lbin) = values; + if (!jd[1u].is_null()) { + grid.atLocalBins(lbin) = jd[1u].get(); + } } } if constexpr (GridType::DIM == 2u) { for (const auto& jd : jData) { std::array lbin = jd[0u]; - value_type values = jd[1u]; - grid.atLocalBins(lbin) = values; + if (!jd[1u].is_null()) { + grid.atLocalBins(lbin) = jd[1u].get(); + } } } return grid; diff --git a/Plugins/Json/include/Acts/Plugins/Json/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/include/Acts/Plugins/Json/TrackParametersJsonConverter.hpp b/Plugins/Json/include/Acts/Plugins/Json/TrackParametersJsonConverter.hpp new file mode 100644 index 00000000000..ebf7d5c6054 --- /dev/null +++ b/Plugins/Json/include/Acts/Plugins/Json/TrackParametersJsonConverter.hpp @@ -0,0 +1,221 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 CERN for the benefit of the ACTS project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +#pragma once + +#include "Acts/EventData/TrackParameters.hpp" +#include "Acts/Plugins/Json/ActsJson.hpp" +#include "Acts/Plugins/Json/SurfaceJsonConverter.hpp" + +#include + +namespace { + +// Alias to bound adl_serializer specialization +// only to track parameters +template +concept TrackParameters = Acts::FreeTrackParametersConcept || + Acts::BoundTrackParametersConcept; + +// Shorthand for bound track parameters +template +concept IsGenericBound = + std::same_as>; + +} // namespace + +namespace Acts { +NLOHMANN_JSON_SERIALIZE_ENUM(Acts::PdgParticle, + + {{Acts::PdgParticle::eInvalid, "Invalid"}, + {Acts::PdgParticle::eElectron, "Electron"}, + {Acts::PdgParticle::eAntiElectron, + "AntiElectron"}, + {Acts::PdgParticle::ePositron, "Positron"}, + {Acts::PdgParticle::eMuon, "Muon"}, + {Acts::PdgParticle::eAntiMuon, "AntiMuon"}, + {Acts::PdgParticle::eTau, "Tau"}, + {Acts::PdgParticle::eAntiTau, "AntiTau"}, + {Acts::PdgParticle::eGamma, "Gamma"}, + {Acts::PdgParticle::ePionZero, "PionZero"}, + {Acts::PdgParticle::ePionPlus, "PionPlus"}, + {Acts::PdgParticle::ePionMinus, "PionMinus"}, + {Acts::PdgParticle::eKaonPlus, "KaonPlus"}, + {Acts::PdgParticle::eKaonMinus, "KaonMinus"}, + {Acts::PdgParticle::eNeutron, "Neutron"}, + {Acts::PdgParticle::eAntiNeutron, "AntiNeutron"}, + {Acts::PdgParticle::eProton, "Proton"}, + {Acts::PdgParticle::eAntiProton, "AntiProton"}, + {Acts::PdgParticle::eLead, "Lead"}} + +) +} + +namespace nlohmann { + +/// @brief Serialize a track parameters object to json +/// +/// nlohmann::json serializer specialized for track parameters +/// as they are not default constructible. Is able to serialize +/// either bound or free track parameters given that the constructor +/// convention is followed. +/// +/// @tparam parameters_t The track parameters type +template +struct adl_serializer { + /// Covariance matrix type attached to the parameters + using CovarianceMatrix = typename parameters_t::CovarianceMatrix; + + /// @brief Serialize track parameters object to json + /// + /// @param j Json object to write to + /// @param t Track parameters object to serialize + static void to_json(nlohmann::json& j, const parameters_t& t) { + // Serialize parameters + // common to all track parameters + j["direction"] = t.direction(); + j["qOverP"] = t.qOverP(); + j["particleHypothesis"] = t.particleHypothesis().absolutePdg(); + + // Covariance is optional + j["covariance"]; + if (t.covariance().has_value()) { + // Extract covariance matrix + // parameters and serialize + auto cov = t.covariance().value(); + constexpr unsigned int size = cov.rows(); + std::array covData{}; + for (std::size_t n = 0; n < size; ++n) { + for (std::size_t m = 0; m < size; ++m) { + covData[n * size + m] = cov(n, m); + } + } + j["covariance"] = covData; + } + // Bound track parameters have + // reference surface attached + // and position takes a geometry context + if constexpr (IsGenericBound) { + Acts::GeometryContext gctx; + j["position"] = t.fourPosition(gctx); + + j["referenceSurface"] = + Acts::SurfaceJsonConverter::toJson(gctx, t.referenceSurface()); + } else { + j["position"] = t.fourPosition(); + } + } + + /// @brief Deserialize track parameters object from json + /// + /// @param j Json object to read from + /// @return Track parameters object + static parameters_t from_json(const nlohmann::json& j) { + // Extract common parameters + std::array posData = j.at("position"); + Acts::Vector4 position(posData[0], posData[1], posData[2], posData[3]); + + std::array dirData = j.at("direction"); + Acts::Vector3 direction(dirData[0], dirData[1], dirData[2]); + + Acts::ActsScalar qOverP = j.at("qOverP"); + Acts::PdgParticle absPdg = j.at("particleHypothesis"); + + // Covariance is optional + std::optional cov; + if (j.at("covariance").is_null()) { + cov = std::nullopt; + } else { + // Extract covariance matrix + // parameters and deserialize + CovarianceMatrix mat; + constexpr unsigned int size = mat.rows(); + std::array covData = j.at("covariance"); + for (std::size_t n = 0; n < size; ++n) { + for (std::size_t m = 0; m < size; ++m) { + mat(n, m) = covData[n * size + m]; + } + } + cov.emplace(std::move(mat)); + } + + // Create particle hypothesis + typename parameters_t::ParticleHypothesis particle(absPdg); + + // Bound track parameters have + // reference surface attached + // and constructor is hidden + // behind a factory method + if constexpr (IsGenericBound) { + Acts::GeometryContext gctx; + auto referenceSurface = + Acts::SurfaceJsonConverter::fromJson(j.at("referenceSurface")); + + auto res = parameters_t::create(referenceSurface, gctx, position, + direction, qOverP, cov, particle); + + if (!res.ok()) { + throw std::invalid_argument("Invalid bound track parameters"); + } + return res.value(); + } else { + return parameters_t(position, direction, qOverP, cov, particle); + } + } +}; + +/// @brief Serialize a shared pointer to track parameters object to json +/// +/// nlohmann::json serializer specialized for shared pointers to track +/// parameters as they are not default constructible. Is able to serialize +/// either bound or free track parameters given that the constructor +/// convention is followed. +/// +/// @tparam parameters_t The track parameters type +template +struct adl_serializer> { + using CovarianceMatrix = typename parameters_t::CovarianceMatrix; + static void to_json(nlohmann::json& j, + const std::shared_ptr& t) { + if (t == nullptr) { + return; + } + j = *t; + } + + static std::shared_ptr from_json(const nlohmann::json& j) { + return std::make_shared(j.get()); + } +}; + +/// @brief Serialize a unique pointer to track parameters object to json +/// +/// nlohmann::json serializer specialized for unique pointers to track +/// parameters as they are not default constructible. Is able to serialize +/// either bound or free track parameters given that the constructor +/// convention is followed. +/// +/// @tparam parameters_t The track parameters type +template +struct adl_serializer> { + using CovarianceMatrix = typename parameters_t::CovarianceMatrix; + static void to_json(nlohmann::json& j, + const std::unique_ptr& t) { + if (t == nullptr) { + return; + } + j = *t; + } + + static std::unique_ptr from_json(const nlohmann::json& j) { + return std::make_unique(j.get()); + } +}; + +} // namespace nlohmann diff --git a/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/EventData/BoundTrackParametersTests.cpp b/Tests/UnitTests/Core/EventData/BoundTrackParametersTests.cpp index a05d273f7a1..9daf24c8a79 100644 --- a/Tests/UnitTests/Core/EventData/BoundTrackParametersTests.cpp +++ b/Tests/UnitTests/Core/EventData/BoundTrackParametersTests.cpp @@ -76,6 +76,14 @@ void checkParameters(const BoundTrackParameters& params, double l0, double l1, eps); CHECK_CLOSE_OR_SMALL(params.momentum(), p * unitDir, eps, eps); BOOST_CHECK_EQUAL(params.charge(), q); + + // reflection + BoundTrackParameters reflectedParams = params; + reflectedParams.reflectInPlace(); + CHECK_CLOSE_OR_SMALL(params.reflect().parameters(), + reflectedParams.parameters(), eps, eps); + CHECK_CLOSE_OR_SMALL(reflectedParams.reflect().parameters(), + params.parameters(), eps, eps); } void runTest(const std::shared_ptr& surface, double l0, diff --git a/Tests/UnitTests/Core/EventData/CurvilinearTrackParametersTests.cpp b/Tests/UnitTests/Core/EventData/CurvilinearTrackParametersTests.cpp index 122d4b075d0..143515148d4 100644 --- a/Tests/UnitTests/Core/EventData/CurvilinearTrackParametersTests.cpp +++ b/Tests/UnitTests/Core/EventData/CurvilinearTrackParametersTests.cpp @@ -72,6 +72,15 @@ void checkParameters(const CurvilinearTrackParameters& params, double phi, // curvilinear reference surface CHECK_CLOSE_OR_SMALL(referenceSurface->center(geoCtx), pos, eps, eps); CHECK_CLOSE_OR_SMALL(referenceSurface->normal(geoCtx), unitDir, eps, eps); + + // reflection + CurvilinearTrackParameters reflectedParams = params; + reflectedParams.reflectInPlace(); + CHECK_CLOSE_OR_SMALL(params.reflect().parameters(), + reflectedParams.parameters(), eps, eps); + CHECK_CLOSE_OR_SMALL(reflectedParams.reflect().parameters(), + params.parameters(), eps, eps); + // TODO verify reference frame } diff --git a/Tests/UnitTests/Core/EventData/FreeTrackParametersTests.cpp b/Tests/UnitTests/Core/EventData/FreeTrackParametersTests.cpp index 71b0dc0a20e..fb7a11f3f68 100644 --- a/Tests/UnitTests/Core/EventData/FreeTrackParametersTests.cpp +++ b/Tests/UnitTests/Core/EventData/FreeTrackParametersTests.cpp @@ -67,6 +67,14 @@ void checkParameters(const FreeTrackParameters& params, const Vector4& pos4, eps); CHECK_CLOSE_OR_SMALL(params.time(), params.template get(), eps, eps); + + // reflection + FreeTrackParameters reflectedParams = params; + reflectedParams.reflectInPlace(); + CHECK_CLOSE_OR_SMALL(params.reflect().parameters(), + reflectedParams.parameters(), eps, eps); + CHECK_CLOSE_OR_SMALL(reflectedParams.reflect().parameters(), + params.parameters(), eps, eps); } } // namespace 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() diff --git a/Tests/UnitTests/Fatras/Kernel/SimulationActorTests.cpp b/Tests/UnitTests/Fatras/Kernel/SimulationActorTests.cpp index e52d586c30b..3306c5702d6 100644 --- a/Tests/UnitTests/Fatras/Kernel/SimulationActorTests.cpp +++ b/Tests/UnitTests/Fatras/Kernel/SimulationActorTests.cpp @@ -244,7 +244,13 @@ BOOST_AUTO_TEST_CASE(HitsOnEmptySurface) { BOOST_CHECK_EQUAL(f.actor.initialParticle.absoluteMomentum(), f.p); BOOST_CHECK_EQUAL(f.actor.initialParticle.energy(), f.e); + // call.actor: pre propagation + f.state.stage = Acts::PropagatorStage::prePropagation; + f.actor.act(f.state, f.stepper, f.navigator, f.result, + Acts::getDummyLogger()); + // call.actor: surface selection -> one hit, no material -> no secondary + f.state.stage = Acts::PropagatorStage::postStep; f.actor.act(f.state, f.stepper, f.navigator, f.result, Acts::getDummyLogger()); BOOST_CHECK(f.result.isAlive); @@ -271,6 +277,7 @@ BOOST_AUTO_TEST_CASE(HitsOnEmptySurface) { BOOST_CHECK_EQUAL(f.state.stepping.p, f.result.particle.absoluteMomentum()); // call.actor again: one more hit, still no secondary + f.state.stage = Acts::PropagatorStage::postStep; f.actor.act(f.state, f.stepper, f.navigator, f.result, Acts::getDummyLogger()); BOOST_CHECK(f.result.isAlive); @@ -317,7 +324,13 @@ BOOST_AUTO_TEST_CASE(HitsOnMaterialSurface) { BOOST_CHECK_EQUAL(f.actor.initialParticle.absoluteMomentum(), f.p); BOOST_CHECK_EQUAL(f.actor.initialParticle.energy(), f.e); + // call.actor: pre propagation + f.state.stage = Acts::PropagatorStage::prePropagation; + f.actor.act(f.state, f.stepper, f.navigator, f.result, + Acts::getDummyLogger()); + // call.actor: surface selection -> one hit, material -> one secondary + f.state.stage = Acts::PropagatorStage::postStep; f.actor.act(f.state, f.stepper, f.navigator, f.result, Acts::getDummyLogger()); BOOST_CHECK(f.result.isAlive); @@ -346,6 +359,7 @@ BOOST_AUTO_TEST_CASE(HitsOnMaterialSurface) { tol); // call.actor again: one more hit, one more secondary + f.state.stage = Acts::PropagatorStage::postStep; f.actor.act(f.state, f.stepper, f.navigator, f.result, Acts::getDummyLogger()); BOOST_CHECK(f.result.isAlive); @@ -392,7 +406,13 @@ BOOST_AUTO_TEST_CASE(NoHitsEmptySurface) { BOOST_CHECK_EQUAL(f.actor.initialParticle.absoluteMomentum(), f.p); BOOST_CHECK_EQUAL(f.actor.initialParticle.energy(), f.e); + // call.actor: pre propagation + f.state.stage = Acts::PropagatorStage::prePropagation; + f.actor.act(f.state, f.stepper, f.navigator, f.result, + Acts::getDummyLogger()); + // call.actor: no surface sel. -> no hit, no material -> no secondary + f.state.stage = Acts::PropagatorStage::postStep; f.actor.act(f.state, f.stepper, f.navigator, f.result, Acts::getDummyLogger()); BOOST_CHECK(f.result.isAlive); @@ -419,6 +439,7 @@ BOOST_AUTO_TEST_CASE(NoHitsEmptySurface) { BOOST_CHECK_EQUAL(f.state.stepping.p, f.result.particle.absoluteMomentum()); // call.actor again: no hit, still no secondary + f.state.stage = Acts::PropagatorStage::postStep; f.actor.act(f.state, f.stepper, f.navigator, f.result, Acts::getDummyLogger()); BOOST_CHECK(f.result.isAlive); @@ -455,7 +476,13 @@ BOOST_AUTO_TEST_CASE(NoHitsEmptySurface) { BOOST_AUTO_TEST_CASE(NoHitsMaterialSurface) { Fixture f(125_MeV, makeMaterialSurface()); + // call.actor: pre propagation + f.state.stage = Acts::PropagatorStage::prePropagation; + f.actor.act(f.state, f.stepper, f.navigator, f.result, + Acts::getDummyLogger()); + // call.actor: no surface sel. -> no hit, material -> one secondary + f.state.stage = Acts::PropagatorStage::postStep; f.actor.act(f.state, f.stepper, f.navigator, f.result, Acts::getDummyLogger()); BOOST_CHECK(f.result.isAlive); @@ -483,6 +510,7 @@ BOOST_AUTO_TEST_CASE(NoHitsMaterialSurface) { tol); // call.actor again: still no hit, one more secondary + f.state.stage = Acts::PropagatorStage::postStep; f.actor.act(f.state, f.stepper, f.navigator, f.result, Acts::getDummyLogger()); BOOST_CHECK(f.result.isAlive); @@ -523,7 +551,13 @@ BOOST_AUTO_TEST_CASE(Decay) { // inverse Lorentz factor for proper time dilation: 1/gamma = m/E const auto gammaInv = f.m / f.e; + // call.actor: pre propagation + f.state.stage = Acts::PropagatorStage::prePropagation; + f.actor.act(f.state, f.stepper, f.navigator, f.result, + Acts::getDummyLogger()); + // first step w/ defaults leaves particle alive + f.state.stage = Acts::PropagatorStage::postStep; f.actor.act(f.state, f.stepper, f.navigator, f.result, Acts::getDummyLogger()); BOOST_CHECK(f.result.isAlive); @@ -536,6 +570,7 @@ BOOST_AUTO_TEST_CASE(Decay) { BOOST_CHECK_EQUAL(f.result.particle.properTime(), 0_ns); // second step w/ defaults increases proper time + f.state.stage = Acts::PropagatorStage::postStep; f.state.stepping.time += 1_ns; f.actor.act(f.state, f.stepper, f.navigator, f.result, Acts::getDummyLogger()); @@ -549,6 +584,7 @@ BOOST_AUTO_TEST_CASE(Decay) { CHECK_CLOSE_REL(f.result.particle.properTime(), gammaInv * 1_ns, tol); // third step w/ proper time limit decays the particle + f.state.stage = Acts::PropagatorStage::postStep; f.state.stepping.time += 1_ns; f.result.properTimeLimit = f.result.particle.properTime() + gammaInv * 0.5_ns; f.actor.act(f.state, f.stepper, f.navigator, f.result, diff --git a/Tests/UnitTests/Plugins/Detray/DetrayGeometryConverterTests.cpp b/Tests/UnitTests/Plugins/Detray/DetrayGeometryConverterTests.cpp index 97c1c7dff13..2ed99f4a68b 100644 --- a/Tests/UnitTests/Plugins/Detray/DetrayGeometryConverterTests.cpp +++ b/Tests/UnitTests/Plugins/Detray/DetrayGeometryConverterTests.cpp @@ -107,10 +107,11 @@ BOOST_AUTO_TEST_CASE(DetrayVolumeConversion) { auto [volumes, portals, rootVolumes] = beampipe->construct(tContext); auto volume = volumes.front(); - DetrayConversionUtils::GeometryIdCache geoIdCache; + std::vector dVolumes = {volume.get()}; + DetrayConversionUtils::Cache cCache(dVolumes); detray::io::volume_payload payload = DetrayGeometryConverter::convertVolume( - geoIdCache, tContext, *volume, {volume.get()}, *logger); + cCache, tContext, *volume, *logger); // Check the volume payload BOOST_CHECK(payload.name == "BeamPipe"); @@ -134,10 +135,10 @@ BOOST_AUTO_TEST_CASE(CylindricalDetector) { auto detector = buildCylindricalDetector(tContext); // Convert the detector - DetrayConversionUtils::GeometryIdCache geoIdCache; + DetrayConversionUtils::Cache cCache(detector->volumes()); detray::io::detector_payload payload = - DetrayGeometryConverter::convertDetector(geoIdCache, tContext, *detector, + DetrayGeometryConverter::convertDetector(cCache, tContext, *detector, *logger); // Test the payload - we have six volumes diff --git a/Tests/UnitTests/Plugins/Json/CMakeLists.txt b/Tests/UnitTests/Plugins/Json/CMakeLists.txt index 1f8573fdf50..141f86fb3fe 100644 --- a/Tests/UnitTests/Plugins/Json/CMakeLists.txt +++ b/Tests/UnitTests/Plugins/Json/CMakeLists.txt @@ -15,3 +15,4 @@ add_unittest(UtilitiesJsonConverter UtilitiesJsonConverterTests.cpp) add_unittest(SurfaceBoundsJsonConverter SurfaceBoundsJsonConverterTests.cpp) add_unittest(SurfaceJsonConverter SurfaceJsonConverterTests.cpp) add_unittest(VolumeBoundsJsonConverter VolumeBoundsJsonConverterTests.cpp) +add_unittest(TrackParametersJsonConverter TrackParametersJsonConverterTests.cpp) diff --git a/Tests/UnitTests/Plugins/Json/TrackParametersJsonConverterTests.cpp b/Tests/UnitTests/Plugins/Json/TrackParametersJsonConverterTests.cpp new file mode 100644 index 00000000000..566464a1889 --- /dev/null +++ b/Tests/UnitTests/Plugins/Json/TrackParametersJsonConverterTests.cpp @@ -0,0 +1,97 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 CERN for the benefit of the ACTS project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +#include + +#include "Acts/Plugins/Json/TrackParametersJsonConverter.hpp" +#include "Acts/Surfaces/PlaneSurface.hpp" +#include "Acts/Surfaces/RectangleBounds.hpp" +#include "Acts/Tests/CommonHelpers/FloatComparisons.hpp" + +#include +#include + +#include + +BOOST_AUTO_TEST_SUITE(TrackParametersJsonIO) + +BOOST_AUTO_TEST_CASE(TrackParametersJsonIO) { + Acts::GeometryContext gctx; + + // Track parameters + Acts::Vector4 position(1., 2., 3., 4.); + Acts::ActsScalar phi = 0.1; + Acts::ActsScalar theta = 0.2; + Acts::ActsScalar qOverP = 3.0; + Acts::ParticleHypothesis particle = Acts::ParticleHypothesis::electron(); + Acts::FreeMatrix freeCov = Acts::FreeMatrix::Identity(); + Acts::BoundMatrix boundCov = Acts::BoundMatrix::Identity(); + + auto surface = Acts::Surface::makeShared( + Acts::Transform3::Identity(), + std::make_shared(10., 10.)); + surface->assignGeometryId(Acts::GeometryIdentifier(1u)); + + // Free track parameters conversion + Acts::FreeTrackParameters ftp(position, phi, theta, qOverP, freeCov, + particle); + + nlohmann::json ftpJson = ftp; + + Acts::FreeTrackParameters ftpRead = ftpJson; + + BOOST_CHECK_EQUAL(ftp.position(), ftpRead.position()); + BOOST_CHECK_EQUAL(ftp.direction(), ftpRead.direction()); + BOOST_CHECK_EQUAL(ftp.qOverP(), ftpRead.qOverP()); + BOOST_CHECK_EQUAL(ftp.covariance().value(), ftpRead.covariance().value()); + BOOST_CHECK_EQUAL(ftp.particleHypothesis(), ftpRead.particleHypothesis()); + + // Curvilinear track parameters conversion + Acts::CurvilinearTrackParameters ctp(position, phi, theta, qOverP, boundCov, + particle); + + nlohmann::json ctpJson = ctp; + + Acts::CurvilinearTrackParameters ctpRead = ctpJson; + + BOOST_CHECK_EQUAL(ctp.position(), ctpRead.position()); + BOOST_CHECK_EQUAL(ctp.direction(), ctpRead.direction()); + BOOST_CHECK_EQUAL(ctp.qOverP(), ctpRead.qOverP()); + BOOST_CHECK_EQUAL(ctp.covariance().value(), ctpRead.covariance().value()); + BOOST_CHECK_EQUAL(ctp.particleHypothesis(), ctpRead.particleHypothesis()); + + BOOST_CHECK(ctp.referenceSurface().transform(gctx).isApprox( + ctpRead.referenceSurface().transform(gctx))); + BOOST_CHECK_EQUAL(ctp.referenceSurface().geometryId(), + ctpRead.referenceSurface().geometryId()); + BOOST_CHECK_EQUAL(ctp.referenceSurface().bounds(), + ctpRead.referenceSurface().bounds()); + + // Bound track parameters conversion + Acts::BoundVector boundPosition{1., 2., 3., 4., 5., 6.}; + Acts::BoundTrackParameters btp(surface, boundPosition, boundCov, particle); + + nlohmann::json btpJson = btp; + + Acts::BoundTrackParameters btpRead = btpJson; + + BOOST_CHECK_EQUAL(btp.position(gctx), btpRead.position(gctx)); + BOOST_CHECK_EQUAL(btp.direction(), btpRead.direction()); + BOOST_CHECK_EQUAL(btp.qOverP(), btpRead.qOverP()); + BOOST_CHECK_EQUAL(btp.covariance().value(), btpRead.covariance().value()); + BOOST_CHECK_EQUAL(btp.particleHypothesis(), btpRead.particleHypothesis()); + + BOOST_CHECK(btp.referenceSurface().transform(gctx).isApprox( + btpRead.referenceSurface().transform(gctx))); + BOOST_CHECK_EQUAL(btp.referenceSurface().geometryId(), + btpRead.referenceSurface().geometryId()); + BOOST_CHECK_EQUAL(btp.referenceSurface().bounds(), + btpRead.referenceSurface().bounds()); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/docs/getting_started.md b/docs/getting_started.md index fbc247a3e05..f17ec5abcf1 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -9,9 +9,9 @@ following commands will clone the repository, configure, and build the core library: ```console -$ git clone https://github.com/acts-project/acts -$ cmake -B -S -$ cmake --build +git clone https://github.com/acts-project/acts +cmake -B -S +cmake --build ``` For a full list of dependencies, including specific versions, see the @@ -23,27 +23,27 @@ section. The following dependencies are required to build the ACTS core library: -- A C++17 compatible compiler (recent versions of either gcc and clang should work) -- [CMake](https://cmake.org) >= 3.14 -- [Boost](https://www.boost.org) >= 1.71 with `filesystem`, `program_options`, and `unit_test_framework` -- [Eigen](https://eigen.tuxfamily.org) >= 3.3.7 +- A C++17 compatible compiler (recent versions of either gcc and clang should work) +- [CMake](https://cmake.org) >= 3.14 +- [Boost](https://www.boost.org) >= 1.71 with `filesystem`, `program_options`, and `unit_test_framework` +- [Eigen](https://eigen.tuxfamily.org) >= 3.3.7 The following dependencies are optional and are needed to build additional components: -- [CUDA](https://developer.nvidia.com/cuda-zone) for the CUDA plugin and the Exa.TrkX plugin and its examples -- [DD4hep](http://dd4hep.cern.ch) >= 1.11 for the DD4hep plugin and some examples -- [Doxygen](http://doxygen.org) >= 1.8.15 for the documentation -- [Geant4](https://geant4.org/) for some examples -- [HepMC](https://gitlab.cern.ch/hepmc/HepMC3) >= 3.2.1 for some examples -- [Intel Threading Building Blocks](https://github.com/oneapi-src/oneTBB) >= 2020.1 for the examples -- [ONNX Runtime](https://onnxruntime.ai/) >= 1.12.0 for the ONNX plugin, the Exa.TrkX plugin and some examples -- [Pythia8](https://pythia.org) for some examples -- [ROOT](https://root.cern.ch) >= 6.20 for the TGeo plugin and the examples -- [Sphinx](https://www.sphinx-doc.org) >= 2.0 with [Breathe](https://breathe.readthedocs.io/en/latest/), [Exhale](https://exhale.readthedocs.io/en/latest/), and [recommonmark](https://recommonmark.readthedocs.io/en/latest/index.html) extensions for the documentation -- [cugraph](https://github.com/rapidsai/cugraph) for the Exa.TrkX plugin -- [libtorch](https://pytorch.org/cppdocs/installing.html) for the Exa.TrkX plugin -- [Pybind11](https://github.com/pybind/pybind11) for the Python bindings of the examples +- [CUDA](https://developer.nvidia.com/cuda-zone) for the CUDA plugin and the Exa.TrkX plugin and its examples +- [DD4hep](http://dd4hep.cern.ch) >= 1.11 for the DD4hep plugin and some examples +- [Doxygen](http://doxygen.org) >= 1.8.15 for the documentation +- [Geant4](https://geant4.org/) for some examples +- [HepMC](https://gitlab.cern.ch/hepmc/HepMC3) >= 3.2.1 for some examples +- [Intel Threading Building Blocks](https://github.com/oneapi-src/oneTBB) >= 2020.1 for the examples +- [ONNX Runtime](https://onnxruntime.ai/) >= 1.12.0 for the ONNX plugin, the Exa.TrkX plugin and some examples +- [Pythia8](https://pythia.org) for some examples +- [ROOT](https://root.cern.ch) >= 6.20 for the TGeo plugin and the examples +- [Sphinx](https://www.sphinx-doc.org) >= 2.0 with [Breathe](https://breathe.readthedocs.io/en/latest/), [Exhale](https://exhale.readthedocs.io/en/latest/), and [recommonmark](https://recommonmark.readthedocs.io/en/latest/index.html) extensions for the documentation +- [cugraph](https://github.com/rapidsai/cugraph) for the Exa.TrkX plugin +- [libtorch](https://pytorch.org/cppdocs/installing.html) for the Exa.TrkX plugin +- [Pybind11](https://github.com/pybind/pybind11) for the Python bindings of the examples There are some additional dependencies that are automatically provided as part of the build system. @@ -69,7 +69,7 @@ runs the configuration and searches for the dependencies. The `` directory is automatically created. ```console -$ cmake -B -S +cmake -B -S ``` The build can be configured via various options that are listed in detail in the @@ -77,19 +77,19 @@ The build can be configured via various options that are listed in detail in the The previous command could be e.g. modified to ```console -$ cmake -B -S -DACTS_BUILD_UNITTESTS=on -DACTS_BUILD_FATRAS=on +cmake -B -S -DACTS_BUILD_UNITTESTS=on -DACTS_BUILD_FATRAS=on ``` After the configuration succeeded, the software is build. This is also done with cmake via the following command ```console -$ cmake --build +cmake --build ``` This automatically calls the configure build tool, e.g. Make or Ninja. To build only a specific target, the target names has to be separated from the CMake options by `--`, i.e. ```console -$ cmake --build -- ActsFatras # to build the Fatras library +cmake --build -- ActsFatras # to build the Fatras library ``` The build commands are the same regardless of where you are building the @@ -103,8 +103,8 @@ e.g. CERNs lxplus login machines, the dependencies can be easily satisfied via a LCG releases available through CVMFS. A setup script is provided to activate a compatible releases that can be used as follows: ```console -$ cd -$ source CI/setup_cvmfs_lcg.sh +cd +source CI/setup_cvmfs_lcg.sh ``` After sourcing the setup script, you can build ACTS as described above. The @@ -112,10 +112,10 @@ following commands will build ACTS in the `/build` directory with the Fatras component. ```console -$ cd -$ source CI/setup_cvmfs_lcg.sh -$ cmake -B build -S . -DACTS_BUILD_FATRAS=on -$ cmake --build build +cd +source CI/setup_cvmfs_lcg.sh +cmake -B build -S . -DACTS_BUILD_FATRAS=on +cmake --build build ``` ### In a container @@ -144,13 +144,13 @@ available tags, e.g. for the `ubuntu2004` image, you can use the following command: ```console -$ docker search --list-tags ghcr.io/acts-project/ubuntu2404 +docker search --list-tags ghcr.io/acts-project/ubuntu2404 ``` The following command then downloads a stable tag of the `ubuntu2404` image: ```console -$ docker pull ghcr.io/acts-project/ubuntu2404:51 +docker pull ghcr.io/acts-project/ubuntu2404:51 ``` This should print the image id as part of the output. You can also find out the @@ -163,7 +163,7 @@ following command will make the source directory available as `/acts` in the container and start an interactive `bash` shell ```console -$ docker run --volume=:/acts:ro --interactive --tty /bin/bash +docker run --volume=:/acts:ro --interactive --tty /bin/bash ``` where `` is the image id that was previously mentioned. If you are using the Ubuntu-based image you are already good to go. For the images based on LCG releases, you can now activate the LCG release in the container shell by sourcing a setup script: @@ -191,6 +191,7 @@ install ACTS' dependencies; see the [building with Spack](misc/spack) page for more information. (build_docs)= + ## Building the documentation The documentation uses [Doxygen][doxygen] to extract the source code @@ -201,8 +202,8 @@ need to have [Doxygen][doxygen] version `1.9.5` or newer installed. package manager `pip`: ```console -$ cd -$ pip install -r docs/requirements.txt +cd +pip install -r docs/requirements.txt ``` :::{tip} @@ -211,8 +212,8 @@ environment](https://realpython.com/python-virtual-environments-a-primer/) for this purpose! For example, run ```console -$ python -m venv docvenv -$ source docvenv/bin/activate +python -m venv docvenv +source docvenv/bin/activate ``` to create a local virtual environment, and then run the `pip` command above. @@ -221,13 +222,13 @@ to create a local virtual environment, and then run the `pip` command above. To activate the documentation build targets, the `ACTS_BUILD_DOCS` option has to be set ```console -$ cmake -B -S -DACTS_BUILD_DOCS=on +cmake -B -S -DACTS_BUILD_DOCS=on ``` Then the documentation can be build with this target ```console -$ cmake --build --target docs +cmake --build --target docs ``` The default option includes the Doxygen, Sphinx, and the Breathe extension, @@ -239,8 +240,6 @@ of errors you will need to manually pull in symbols to be documented. [doxygen]: https://doxygen.nl/ [sphinx]: https://www.sphinx-doc.org [breathe]: https://breathe.readthedocs.io -[exhale]: https://exhale.readthedocs.io -[rtd_acts]: https://acts.readthedocs.io ## Build options @@ -248,7 +247,7 @@ CMake options can be set by adding `-D