Analysis code for data from the Multi-Sampling Ionization Chamber at the ATLAS accelerator facility, Argonne National Laboratory. MUSIC is an active target: the gas it is filled with is both the target and the detector, so a single run records the full excitation function of a reaction rather than one point of it.
I use it to measure the 37Cl(α, n)40K cross section.
A monorepo, not a fork per experiment
Every experiment that runs on MUSIC wants the same event building and a different set of constants. Forking the analysis per experiment is how that usually goes, and it is how the two copies then drift apart.
Instead there is one shared tooling tree, compiled separately against each
experiment’s configuration. Each dataset — 37Cl, 87Rb — lives under
analysis/<dataset>/ and supplies only its own Constants.cpp and control
TOMLs. A fix to event building is a fix everywhere, immediately.
$ nix build
# builds music-tooling-37Cl, the default package
$ nix build .#87Rb
$ nix develop .#37Cl
$ ./result/bin/pipeline
four digitizers merged · 1.2e9 hits sorted on GPU
What the analysis does
Offline time synchronisation. The four digitizers were free-running, so there is no hardware trigger tying them together. The beam is: its time structure is a known periodic signature present in all four streams, and fitting that structure recovers the offsets after the fact.
GPU timestamp sorting. Merging four unsynchronised streams means sorting on
the order of a billion timestamps per run. That sort is a CUDA kernel, dlopend
at runtime so the same binary still runs on a machine without a GPU, falling
back to the CPU path.
Event building and calibration. Anode-by-anode energy calibration, beam identification, and the tagging that separates reaction events from the beam that produced them.
Cross-section extraction. Excitation functions from the tagged events, with the per-anode energy loss handled where it belongs rather than in a spreadsheet.
Unsupervised classification. The older dataset has a quality problem that cuts alone do not solve, so clustering is used to separate populations that the hand-written tags merge.
Built on
The flake pins ROOT with CUDA, a C++ toolchain, tomlplusplus, and
Analysis-Utilities as a library input, so
the two projects are always compiled against each other at a known revision.
The documentation build fails on any Doxygen warning, which is what keeps the
published reference honest.