Disclaimer

This project is no longer actively maintained!

rustitude is intended to be a one-stop-shop for amplitude analysis. At GlueX, we typically rely on AmpTools or PyPWA for performing partial-wave analyses (PWAs), moment analyses, and the like. These each come with pros and cons. For AmpTools, the major pros are that its fast (C++), can use MPI and run on GPUs, and has an assortment of pre-written amplitudes that allow users to just start writing analysis code. The major con, in my opinion, is that you typically don’t write C++ to use AmpTools, you instead write a config file with a completely new syntax. In practice, since these config files aren’t code, you end up writing quite a few of them for very similar purposes. Since it isn’t code, it’s very prone to typos which won’t be detected till runtime and you can accidentally overwrite things by including other configs within configs. Furthermore, the output file must then be read by some custom C++ code that will typically vary for each kind of fit you might do. I usually see people write C++ code to put the fit results in a format that is easier to read in Python or messy ROOT code to directly make histograms. On the other hand PyPWA, as the name suggests, is written in Python, so it’s already leagues slower than AmpTools, despite optimizations that can be made with JIT compilers like numba. The pros here are that Python is a very simple language which can be used to quickly prototype and test new code and easily visualize the results. You can even run it interactively! However, the documentation is a bit lacking, the implementation of amplitudes is not straightforward, and it hasn’t been updated in over a year.

These are mostly minor annoyances. AmpTools works great, and I’ve used it for my own thesis work, but I’ve always wanted to try my hand at writing something to do the task in a different way. rustitude is the first iteration of this, and was my first project using Rust with PyO3 bindings to Python. I knew at the outset I wanted the primary interface for users to be Python, but for speed purposes there needed to be a compiled backend. I began the project with a few other goals, the first of which was to make it extremely simple to write new amplitudes without knowing much Rust. Next, I wanted the framework to precalculate and cache as much as possible ahead of time. For example, there are a couple of AmpTools amplitudes which are based on spherical harmonics. For every spherical harmonic, the spherical angles are generally going to depend on data from the events and not from any free parameters in a model, so it really isn’t necessary to calculate them every time the main function is evaluated. AmpTools does some caching, but because it can only do it on a per-amplitude basis (you can’t cache different values for a $Y_{00}$ and a $Y_{10}$ amplitude without writing separate amplitude files for each, for instance), there is still a lot of room for optimization.

This project is currently operational and accomplishes most of these goals to my satisfaction. However, it is still a bit slower than I’d like and very memory-hungry. AmpTools uses a lot of nice pointer manipulation, and MPI allows the calculation to be divided across multiple nodes of an HPC cluster, which also spreads out the memory usage. In rustitude, ROOT files are primarily read into memory in their entirety, and calculations are limited to one node (although multiprocessing is set up to efficiently use as many cores as desired). There are also some ergonomics that I’m not happy about, and if you look in the git history, you can see that it went through several rewrites before getting to this form. I used this project to learn Rust, and now that I understand it a bit more, there are a lot of things that will be difficult to improve without major refactors. I’ve since started working on a successor project (see laddu above) that will hopefully address these issues.