Warning, /acts/docs/pages/examples/python_bindings.md is written in an unsupported language. File is not indexed.
0001 # Python bindings for the Examples
0002
0003 The examples part of ACTS ships with python bindings using the `pybind11`
0004 library. Building these bindings can be enabled via
0005 `-DACTS_BUILD_EXAMPLES_PYTHON_BINDINGS=ON`, and requires a python installation
0006 including the development files to be installed. You can then build the special
0007 target `ActsPythonBindings` to build everything that can be accessed in python.
0008
0009 The build will create a setup script in `$BUILD/this_acts_withdeps.sh` which
0010 modifies `$PYTHONPATH` so that you can import the `acts` module in python.
0011
0012 Here is a minimal example of a python script using the example bindings, which
0013 sets up the particle propagation and runs a few events.
0014
0015 ```python
0016 import os
0017
0018 import acts
0019 import acts.examples
0020
0021 detector = acts.examples.GenericDetector()
0022 trackingGeometry = detector.trackingGeometry()
0023 s = acts.examples.Sequencer(events=10)
0024
0025 rnd = acts.examples.RandomNumbers(seed=42)
0026
0027 nav = acts.Navigator(trackingGeometry=trackingGeometry)
0028
0029 field = acts.ConstantBField(acts.Vector3(0, 0, 2 * acts.UnitConstants.T))
0030 stepper = acts.EigenStepper(field)
0031
0032 prop = acts.examples.ConcretePropagator(acts.Propagator(stepper, nav))
0033
0034 alg = acts.examples.PropagationAlgorithm(
0035 propagatorImpl=prop,
0036 level=acts.logging.INFO,
0037 randomNumberSvc=rnd,
0038 ntests=1000,
0039 sterileLogger=False,
0040 outputSummaryCollection="propagation_summary",
0041 )
0042
0043 s.addAlgorithm(alg)
0044
0045 outputDir = "."
0046 objDir = outputDir + "/obj"
0047 if not os.path.exists(objDir):
0048 os.mkdir(objDir)
0049
0050 s.addWriter(
0051 acts.examples.ObjPropagationStepsWriter(
0052 level=acts.logging.INFO,
0053 collection="propagation_summary",
0054 outputDir=objDir,
0055 )
0056 )
0057
0058 s.addWriter(
0059 acts.examples.RootPropagationStepsWriter(
0060 level=acts.logging.INFO,
0061 collection="propagation_summary",
0062 filePath=outputDir + "/propagation_steps.root",
0063 )
0064 )
0065
0066 s.run()
0067 ```
0068
0069 ## Python based example scripts
0070
0071 The repository contains a set of example scripts that can be used to execute various workflows.
0072 They can be found in `$REPO_ROOT/Examples/Scripts/Python`. Make sure you have run
0073
0074 ```console
0075 source $BUILD/this_acts_withdeps.sh
0076 ```
0077
0078 to make sure python can find the `acts` module.
0079
0080 ## Python based unit tests
0081
0082 A number of unit tests based on the `pytest` library are shipped with the
0083 repository. They are located under `$REPO_ROOT/Examples/Python/tests`, and
0084 intend to cover the public API of the python bindings. A set of tests also
0085 executed the standalone example scripts.
0086
0087 To run these python based tests, `pytest` and a few other dependencies need
0088 to be installed. They can be installed via `pip install -r
0089 Examples/Python/tests/requirements.txt` from the repository root. You can
0090 then simply run `pytest` from the repository root.
0091
0092 > **Tip: python-virtualenv**
0093 >
0094 > It is **strongly recommended** to use a [virtual environment](https://realpython.com/python-virtual-environments-a-primer/) for
0095 > this purpose! For example, run
0096 >
0097 > ```console
0098 > python -m venv venv
0099 > source venv/bin/activate
0100 > ```
0101 >
0102 > to create a local virtual environment, and then run the `pip` command above.
0103
0104 ## ROOT file hash regression checks
0105
0106 In a number of cases, the python based test suite will run hash based regression tests against ROOT files that are
0107 written by the test workloads. These tests use a custom hash algorithm written in python, which hashes each individual
0108 entry of each `TTree` found in a file. These entry hashes are then sorted, concatenated and hashed again for the final output.
0109 This procedure ensures that if the ROOT file content changes, the hash changes, while also giving the same hash when the events
0110 stored in the file are reordered.
0111
0112 The tests are implemented by looking up a reference hash from a central data file `$REPO_ROOT/Examples/Python/tests/root_file_hashes.txt`
0113 that looks like
0114
0115 ```none
0116 test_ckf_tracks_example_full_seeding__performance_seeding_trees.root: 938bcc9b9425b12c620f5d0efa2c592817dfe92a18c309e97aa9d87412918620
0117 test_ckf_tracks_example_full_seeding__trackstates_ckf.root: 2faceafd4a521ff4030557301723e29c3d870edad052965eb644b824b57e2146
0118 test_ckf_tracks_example_truth_estimate__performance_seeding_trees.root: 5c0cf9e84af64e6814ab1ddf4cbaf4be6008ad8b2371b5b0241085b19d0fc52c
0119 test_ckf_tracks_example_truth_estimate__performance_seeding_trees.root: 5c0cf9e84af64e6814ab1ddf4cbaf4be6008ad8b2371b5b0241085b19d0fc52c
0120 test_ckf_tracks_example_truth_estimate__trackstates_ckf.root: ac4485c09a68fca3d056cb8d9adb81695e68d822629e48c71fd2b6d2bbd31f88
0121 ```
0122
0123 where the left side before the `:` indicates the test in which the check is performed and the name of the ROOT file
0124 that is checked. The right side is the reference hash.
0125
0126 > **Note:** The file from which reference hashes are loaded can be changed by setting the environment variable `ROOT_HASH_FILE`
0127 > to the desired file.
0128
0129 These checks have two purposes:
0130
0131 1. Detect regressions in the algorithms: if an algorithm produces different output, the test will catch it. This also means that
0132 if algorithmic changes are made that intentionally change the output, the reference hashes also have to be updated.
0133
0134 > **Warning:** Please make sure to check the contents of a changed file are correct/reasonable before updating the reference hash!
0135
0136 2. Detect potential reproducibility issues. Tests that run with multiple threads should produce the same output every run,
0137 event ordering aside. If a test workload has a thread-reproducibility issue, the output hash should also change.
0138
0139 ### Running the hash checks locally and how to update the reference hashes
0140
0141 By default, the hash checks are not executed when the `pytest` command is run. To enable them, you need to set the environment
0142 variable `ROOT_HASH_CHECKS` needs to be set to `ON`, for example like:
0143
0144 ```console
0145 ROOT_HASH_CHECKS=ON pytest
0146 ```
0147
0148 If any hash mismatches are observed, the corresponding tests will fail, and `pytest` will print a summary at the end that looks like
0149
0150 ```console
0151 ------------------------------------------- RootHashAssertionErrors -----------------------------------------------------
0152 The ROOT files produced by tests have changed since the last recorded reference.
0153 This can be be expected if e.g. the underlying algorithm changed, or it can be a test failure symptom.
0154 Please manually check the output files listed below and make sure that their content is correct.
0155 If it is, you can update the test reference file Examples/Python/tests/root_file_hashes.txt with the new hashes below.
0156
0157 test_seeding__estimatedparams.root: 8bbc97cb3d4777c61dd0b483a1c8268fc8411ad182c35bc731e5ed222450deca
0158 test_material_recording__geant4_material_tracks.root: 019ce62ce378efa5c02a94768039686ed3cdfbd60c115c1f0cab2cbc53def57b
0159 test_material_mapping__material-maps_tracks.root: c03215e8b53733a3a7d7a0a5f9aec5bf2df20e8e40cc0492a8fa22400491d216
0160 test_material_mapping__propagation-material.root: a15a5c1e92fc3b848efb232eea1d40c422ee3a1d9ef1f7140294415621a04ce5
0161 test_ckf_tracks_example_full_seeding__tracksummary_ckf.root: 9e4d14169f20961be38d0305853a7cf7eeea4a647f0c94a48aada22c3c2c7a51
0162 test_ckf_tracks_example_truth_estimate__tracksummary_ckf.root: 3d56b26788163852e2c1f7288920f60a505bd14deeabb6f9189b680fcd90bfc5
0163 test_ckf_tracks_example_truth_smeared__tracksummary_ckf.root: ca2ce4069d2a2388c3d3c826dec8bea9f9d1e622239a20f8b985784d6c546c6e
0164 =========================================== short test summary info =====================================================
0165 FAILED Examples/Python/tests/test_examples.py::test_seeding
0166 FAILED Examples/Python/tests/test_examples.py::test_material_recording
0167 FAILED Examples/Python/tests/test_examples.py::test_material_mapping
0168 FAILED Examples/Python/tests/test_examples.py::test_ckf_tracks_example_full_seeding
0169 FAILED Examples/Python/tests/test_examples.py::test_ckf_tracks_example_truth_estimate
0170 FAILED Examples/Python/tests/test_examples.py::test_ckf_tracks_example_truth_smeared
0171 ================================== 6 failed, 183 passed in 199.82s (0:03:19) ============================================
0172 ```
0173
0174 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`.
0175 To update the reference hashes, simply replace the corresponding entries in `root_file_hashes.txt` with the output from the `pytest` run.
0176
0177 > **Note:** The CI runs the ROOT hash checks. However, we have observed the hashes to change between different machines.
0178 > This is believed to be due to differences in math libraries producing slightly different outputs. As a consequence,
0179 > locally obtained file hashes might cause CI failures, as the CI hashes are different.
0180 >
0181 > For local testing, it is therefore advisable to use `ROOT_HASH_FILE` to use a different file for the reference hashes
0182 > and populated it with known-good reference hashes from the `main` branch, before testing your developments.
0183 >
0184 > To make the CI succeed if it obtains different hashes than you get locally: make sure that the output is correct, and then
0185 > update the central `root_file_hashes.txt` with the hashes reported in the failed CI job.