For particle physicists, ROOT is one of the most important toolkits around. It
is a huge suite of tools that predates the C++ standard library, and has almost
anything a particle physicist could want. It has driven developments in other
areas too. ROOT’s current C++ interpreter, CLING, is the most powerful C++
interpreter available and is used by the Xeus project for Jupyter. The Python
work has helped PyPy, with CPPYY also coming from ROOT. However, due to the
size, complexity, and age of some parts of ROOT, it can be a bit challenging to
install; and it is even more challenging when you want it to talk to Python. I
would like to point to the brand-new Conda-Forge ROOT package for Linux and
macOS, and point out a few other options for macOS installs. Note for Windows
users: Due to the fact that ROOT expects the type long to match the system
pointer size, 64-bit Windows cannot be supported for quite some time. While you
can use it in 32 bit form, this is generally impossible to connect to Python,
which usually will be a 64-bit build.
My favorite posts and series
C++11 C++14 C++17 C++20 C++23 2→3 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 macOS setup AS setup Windows setup SSH
My classes and books
Modern CMake CompClass se-for-sci
My workshops
CMake Workshop CPU GPU Compiled Level Up Your Python Packaging
My Python libraries
packaging cibuildwheel build pipx dependency-groups pyproject-metadata scikit-build (classic, core, cmake, ninja, moderncmakedomain, sample-projects) pybind11 (python_example scikit_build_example) meson-python boost-histogram Hist UHI Vector GooFit Particle DecayLanguage Conda-Forge ROOT uproot-browser nox Scientific-Python/cookie repo-review validate-pyproject(-schema-store) flake8-errmsg flake8-lazy check-sdist pytest GHA annotate-failures Plumbum
My other projects
CLI11 beautifulhugo Jekyll-Indico POVM hypernewsviewer AoC 2023 AoC 2024 AoC 2025
My sites
Scientific-Python Development Guide IRIS-HEP Scikit-HEP Scikit-Build CLARIPHY
Histogram Speeds in Python
Let’s compare several ways of making Histograms. I’m going to assume you would like to end up with a nice OO histogram interface, so all the 2D methods will fill a Physt histogram. We will be using a 2 x 1,000,000 element array and filling a 2D histogram, or 10,000,000 elements in a 1D histogram. Binnings are regular.
1D 10,000,000 item histogram
| Example | KNL | MBP | X24 |
|---|---|---|---|
| NumPy: histogram | 704 ms | 147 ms | 114 ms |
| NumPy: bincount | 432 ms | 110 ms | 117 ms |
| fast-histogram | 337 ms | 45.9 ms | 45.7 ms |
| Numba | 312 ms | 58.8 ms | 60.7 ms |
2D 1,000,000 item histogram
| Example | KNL | MBP | X24 |
|---|---|---|---|
| Physt | 1.21 s | 293 ms | 246 ms |
| NumPy: histogram2d | 456 ms | 114 ms | 88.3 ms |
| NumPy: add.at | 247 ms | 62.7 ms | 49.7 ms |
| NumPy: bincount | 81.7 ms | 23.3 ms | 20.3 ms |
| fast-histogram | 53.7 ms | 10.4 ms | 7.31 ms |
| fast-hist threaded 0.5 | (6) 62.5 ms | 9.78 ms | (6) 15.4 ms |
| fast-hist threaded (m) | 62.3 ms | 4.89 ms | 3.71 ms |
| Numba | 41.8 ms | 10.2 ms | 9.73 ms |
| Numba threaded | (6) 49.2 ms | 4.23 ms | (6) 4.12 ms |
| Cython | 112 ms | 12.2 ms | 11.2 ms |
| Cython threaded | (6) 128 ms | 5.68 ms | (8) 4.89 ms |
| pybind11 sequential | 93.9 ms | 9.20 ms | 17.8 ms |
| pybind11 OpenMP atomic | 4.06 ms | 6.87 ms | 1.91 ms |
| pybind11 C++11 atomic | (32) 10.7 ms | 7.08 ms | (48) 2.65 ms |
| pybind11 C++11 merge | (32) 23.0 ms | 6.03 ms | (48) 4.79 ms |
| pybind11 OpenMP merge | 8.74 ms | 5.04 ms | 1.79 ms |
Binding Minuit2
Let’s try a non-trivial example of a binding: Minuit2 (6.14.0 standalone edition).
[Read More]Tools to Bind to Python
This was originally given as a PyHEP 2018 talk. It is designed to be interactive, and can be run in SWAN if you have a CERN account. If you want to run it manually, just download the repository: github.com/henryiii/pybindings_cc. It is easy to run in Anaconda.
[Read More]Announcing CLI11 1.6
CLI11, a powerful library for writing beautiful command line interfaces in C++11, has been updated to 1.6, the largest update ever. CLI11 output is more customizable than ever, and has a better functionality separation under the hood.
CLI11 has had the formatting system completely redesigned, with minor or complete customization of the output possible. Configuration file reading and writing also can be configured; a new example with json instead of ini formatting is included. Validators (finally) have custom help output, as well. Many odd corner cases have been made possible, such as interleaving options.
[Read More]CMake 3.11
CMake 3.11 was just released; this is a particularly exciting release for CMake. I’d like to give a quick and friendly introduction to the new features that might make the largest difference for CMake users.
[Read More]Announcing GooFit 2.1

GooFit 2.1 introduces the full-featured Python bindings to GooFit. These bindings mimic the C++ usage of GooFit, including bindings for all PDFs, and also provide NumPy-centric conversions, live Jupyter notebook printing, pip install, and more. Most of the examples in C++ are provided in Python form, as well.
Several other API changes were made. Observables are now distinguished from Variables and provided as a separate class. Both these classes are now passed around by copy everywhere.1 The three and four body amplitude classes have been refactored and simplified. OpenMP is now supported via homebrew on macOS; GooFit is one of the only packages that currently can build with OpenMP on the default macOS compiler. Eigen is now available, and CLI11 has been updated to version 1.3.
GooFit 2.1 will receive continuing support while development on GooFit 2.2 presses on with a new indexing scheme for PDFs.
[Read More]Include What You Use
Include-what-you-use is a promising little tool for cleaning up a codebase. It didn’t end up working for the use I had for it, but it still could be useful. Here is a quick guideline on installing it on macOS.
[Read More]