Warning, /acts/docs/groups/python_bindings.md is written in an unsupported language. File is not indexed.
0001 @defgroup python_bindings Python Bindings
0002 @brief Python bindings for the ACTS tracking toolkit, available via PyPI or built from source.
0003
0004 # Installation from PyPI
0005
0006 The easiest way to get the ACTS Python bindings is via [PyPI](https://pypi.org/project/pyacts/):
0007
0008 ```console
0009 pip install pyacts
0010 ```
0011
0012 A nightly development build is also available from [TestPyPI](https://test.pypi.org/project/pyacts/):
0013
0014 ```console
0015 pip install -i https://test.pypi.org/simple pyacts
0016 ```
0017
0018 The `pyacts` distribution includes bindings for the core library, Fatras, and
0019 the Examples framework.
0020
0021 > [!warning]
0022 > The PyPI package does not include all optional plugins (e.g. DD4hep/ODD, Geant4, ROOT).
0023 > To use those, build from source with the relevant CMake options enabled.
0024
0025 > [!note]
0026 > Even though the name of the PyPI package is `pyacts`, the python module must be imported
0027 > as `import acts`.
0028
0029 # Building from source
0030
0031 To use the full Python bindings including optional components such as DD4hep/ODD, Geant4, ROOT, build ACTS from
0032 source with `ACTS_BUILD_PYTHON_BINDINGS=ON`.
0033
0034 ```console
0035 cmake -B <build> -S <source> -DACTS_BUILD_PYTHON_BINDINGS=ON
0036 ```
0037
0038 Bindings for additional components (plugins, Examples framework) are built automatically if
0039 they are enabled.
0040
0041 ```console
0042 cmake -B <build> -S <source> -DACTS_BUILD_PYTHON_BINDINGS=ON -DACTS_BUILD_EXAMPLES=ON
0043 ```
0044
0045 Building requires a Python installation including the development headers.
0046 You can then build the special target `ActsPythonBindings` to build everything
0047 that can be accessed from Python:
0048
0049 ```console
0050 cmake --build <build> -- ActsPythonBindings
0051 ```
0052
0053 The build creates a setup script `$BUILD/this_acts_withdeps.sh` which modifies
0054 `$PYTHONPATH` so that you can import the `acts` module in Python.
0055
0056 > [!warning]
0057 > The old flag `ACTS_BUILD_EXAMPLES_PYTHON_BINDINGS` is **deprecated**.
0058 > Use `ACTS_BUILD_PYTHON_BINDINGS` (together with `ACTS_BUILD_EXAMPLES` if
0059 > needed) instead.
0060
0061 # Minimal example
0062
0063 Here is a minimal example of a Python script using the bindings, which sets up
0064 particle propagation and runs a few events.
0065
0066 @snippet{trimleft} examples/test_generic.py Basic propagation example with GenericDetector
0067
0068 ## Python based example scripts
0069
0070 The repository contains a set of example scripts that can be used to execute various workflows.
0071 They can be found in `$REPO_ROOT/Examples/Scripts/Python`. Make sure you have run
0072
0073 ```console
0074 source $BUILD/this_acts_withdeps.sh
0075 ```
0076
0077 to make sure Python can find the `acts` module.
0078
0079 ## Python based unit tests
0080
0081 A number of unit tests based on the `pytest` library are shipped with the
0082 repository. They are located under `$REPO_ROOT/Examples/Python/tests`, and
0083 intend to cover the public API of the Python bindings. A set of tests also
0084 execute the standalone example scripts.
0085
0086 To run these Python based tests, `pytest` and a few other dependencies need
0087 to be installed. They can be installed via `pip install -r
0088 Examples/Python/tests/requirements.txt` from the repository root. You can
0089 then simply run `pytest` from the repository root.
0090
0091 > [!tip]
0092 > It is **strongly recommended** to use a [virtual
0093 > environment](https://realpython.com/python-virtual-environments-a-primer/)
0094 > for this purpose! For example, run
0095 > ```console
0096 > python -m venv venv
0097 > source venv/bin/activate
0098 > ```
0099 > to create a local virtual environment, and then run the `pip` command above.
0100
0101 ## ROOT file hash regression checks {#root_file_hashes}
0102
0103 In a number of cases, the python based test suite will run hash based regression tests against ROOT files that are
0104 written by the test workloads. These tests use a custom hash algorithm written in python, which hashes each individual
0105 entry of each `TTree` found in a file. These entry hashes are then sorted, concatenated and hashed again for the final output.
0106 This procedure ensures that if the ROOT file content changes, the hash changes, while also giving the same hash when the events
0107 stored in the file are reordered.
0108
0109 The tests are implemented by looking up a reference hash from a central data file `$REPO_ROOT/Examples/Python/tests/root_file_hashes.txt`
0110 that looks like
0111
0112 ```none
0113 test_ckf_tracks_example_full_seeding__performance_seeding_trees.root: 938bcc9b9425b12c620f5d0efa2c592817dfe92a18c309e97aa9d87412918620
0114 test_ckf_tracks_example_full_seeding__trackstates_ckf.root: 2faceafd4a521ff4030557301723e29c3d870edad052965eb644b824b57e2146
0115 test_ckf_tracks_example_truth_estimate__performance_seeding_trees.root: 5c0cf9e84af64e6814ab1ddf4cbaf4be6008ad8b2371b5b0241085b19d0fc52c
0116 test_ckf_tracks_example_truth_estimate__performance_seeding_trees.root: 5c0cf9e84af64e6814ab1ddf4cbaf4be6008ad8b2371b5b0241085b19d0fc52c
0117 test_ckf_tracks_example_truth_estimate__trackstates_ckf.root: ac4485c09a68fca3d056cb8d9adb81695e68d822629e48c71fd2b6d2bbd31f88
0118 ```
0119
0120 where the left side before the `:` indicates the test in which the check is
0121 performed and the name of the ROOT file that is checked. The right side is the
0122 reference hash.
0123
0124 > [!note]
0125 > The file from which reference hashes are loaded can be changed by setting the
0126 > environment variable `ROOT_HASH_FILE` to the desired file.
0127
0128 These checks have two purposes:
0129
0130 1. Detect regressions in the algorithms: if an algorithm produces different
0131 output, the test will catch it. This also means that if algorithmic changes
0132 are made that intentionally change the output, the reference hashes also have
0133 to be updated.
0134
0135 > [!warning]
0136 > Please make sure to check the contents of a changed file are
0137 > correct/reasonable before updating the reference hash!
0138
0139 2. Detect potential reproducibility issues. Tests that run with multiple
0140 threads should produce the same output every run, event ordering aside. If a
0141 test workload has a thread-reproducibility issue, the output hash should also
0142 change.
0143
0144 ### Running the hash checks locally and how to update the reference hashes
0145
0146 By default, the hash checks are not executed when the `pytest` command is run. To enable them, you need to set the environment
0147 variable `ROOT_HASH_CHECKS` needs to be set to `ON`, for example like:
0148
0149 ```console
0150 ROOT_HASH_CHECKS=ON pytest
0151 ```
0152
0153 If any hash mismatches are observed, the corresponding tests will fail, and `pytest` will print a summary at the end that looks like
0154
0155 ```console
0156 ------------------------------------------- RootHashAssertionErrors -----------------------------------------------------
0157 The ROOT files produced by tests have changed since the last recorded reference.
0158 This can be be expected if e.g. the underlying algorithm changed, or it can be a test failure symptom.
0159 Please manually check the output files listed below and make sure that their content is correct.
0160 If it is, you can update the test reference file Examples/Python/tests/root_file_hashes.txt with the new hashes below.
0161
0162 test_seeding__estimatedparams.root: 8bbc97cb3d4777c61dd0b483a1c8268fc8411ad182c35bc731e5ed222450deca
0163 test_material_recording__geant4_material_tracks.root: 019ce62ce378efa5c02a94768039686ed3cdfbd60c115c1f0cab2cbc53def57b
0164 test_material_mapping__material-maps_tracks.root: c03215e8b53733a3a7d7a0a5f9aec5bf2df20e8e40cc0492a8fa22400491d216
0165 test_material_mapping__propagation-material.root: a15a5c1e92fc3b848efb232eea1d40c422ee3a1d9ef1f7140294415621a04ce5
0166 test_ckf_tracks_example_full_seeding__tracksummary_ckf.root: 9e4d14169f20961be38d0305853a7cf7eeea4a647f0c94a48aada22c3c2c7a51
0167 test_ckf_tracks_example_truth_estimate__tracksummary_ckf.root: 3d56b26788163852e2c1f7288920f60a505bd14deeabb6f9189b680fcd90bfc5
0168 test_ckf_tracks_example_truth_smeared__tracksummary_ckf.root: ca2ce4069d2a2388c3d3c826dec8bea9f9d1e622239a20f8b985784d6c546c6e
0169 =========================================== short test summary info =====================================================
0170 FAILED Examples/Python/tests/test_examples.py::test_seeding
0171 FAILED Examples/Python/tests/test_examples.py::test_material_recording
0172 FAILED Examples/Python/tests/test_examples.py::test_material_mapping
0173 FAILED Examples/Python/tests/test_examples.py::test_ckf_tracks_example_full_seeding
0174 FAILED Examples/Python/tests/test_examples.py::test_ckf_tracks_example_truth_estimate
0175 FAILED Examples/Python/tests/test_examples.py::test_ckf_tracks_example_truth_smeared
0176 ================================== 6 failed, 183 passed in 199.82s (0:03:19) ============================================
0177 ```
0178
0179 Here, we see that 7 hash checks have failed. The error output conveniently has the same format as the reference hashes found in `root_file_hashes.txt`.
0180 To update the reference hashes, simply replace the corresponding entries in `root_file_hashes.txt` with the output from the `pytest` run.
0181
0182 > [!note]
0183 > CI runs the ROOT hash checks. However, we have observed the hashes to change
0184 > between different machines. This is believed to be due to differences in math
0185 > libraries producing slightly different outputs. As a consequence, locally
0186 > obtained file hashes might cause CI failures, as the CI hashes are different.
0187 >
0188 > For local testing, it is therefore advisable to use `ROOT_HASH_FILE` to use a
0189 > different file for the reference hashes and populated it with known-good
0190 > reference hashes from the `main` branch, before testing your developments.
0191 >
0192 > To make the CI succeed if it obtains different hashes than you get locally:
0193 > make sure that the output is correct, and then update the central
0194 > `root_file_hashes.txt` with the hashes reported in the failed CI job.