A C++ port (from the Rust farm analysis) of a CLAS12 v_z / PID diagnostic:
read HIPO files with the vendored hipo4 library, match reconstructed tracks
to MC truth via MC::RecMatch for charged pions/muons, swim them back through
the CLAS12 magnetic field to the beamline, and write ~1722 v_z / PID diagnostic
histograms to a ROOT file.
- Histograms: CERN ROOT (
TFile/TH1D/TH2D), zstd-compressed. - Swimmer: Boost.odeint (
runge_kutta_dopri5dense output + closest-approach root-find), replacing the Rustdiffsolsolver. - HIPO reading + record-level parallelism: vendored
external/hipo4(hipo::chain).
- Meson + Ninja, a C++23 compiler
- CERN ROOT 6 (discovered via
root-config) - Boost (header-only
boost/numeric/odeint.hpp) - liblz4 and {fmt} (used by hipo4)
meson setup build
ninja -C build
meson test -C build # swimmer + field-map unit testsThe build defines -D__LZ4__ project-wide — hipo4 gates its LZ4 record
decompression behind that macro, and HIPO files are LZ4-compressed, so without
it no events are read.
git clone git@gitlab.com:MathieuOuillon/swim-cpp.git
cd swim-cpp
# Make the toolchain + libraries discoverable, e.g.:
# module load root # puts root-config in PATH
# module load boost lz4 # or source your CLAS12 software environment
# pip install --user meson ninja # if not already available
meson setup build # downloads/builds fmt via the wrap if not installed
ninja -C buildRequirements on the farm: root-config in PATH (ROOT 6), Boost headers, lz4,
and Meson/Ninja. fmt is used if installed, otherwise built from the
subprojects/fmt.wrap (the first meson setup then needs network — run it on a
login node). The macOS-only Homebrew paths in meson.build are guarded behind a
darwin check, so they are ignored on Linux.
./build/swim-analysis <input>... [--output FILE] [--threads N] [--quiet] \
--torus /path/to/Full_torus_r501_phi361_z501_31Mar2021.dat \
--solenoid /path/to/Symm_solenoid_r601_phi1_z1201_21May2019.dat| flag | default | meaning |
|---|---|---|
<input>... |
(required) | .hipo files, quoted globs, dirs, @list |
--output, -o |
vz.root |
output ROOT file |
--threads, -t |
0 (auto) |
worker threads (-j also accepted) |
--quiet, -q |
off | hide the progress bar |
--torus |
Full_torus_…dat |
torus field map (clas12-cmag binary) |
--solenoid |
Symm_solenoid_…dat |
solenoid field map |
--torus-scale |
-1 |
torus field scale (inbending) |
--solenoid-scale |
-1 |
solenoid field scale |
--solenoid-z-shift |
-3 |
solenoid map z translation (cm) |
@listfile.txt holds one path per line (# comments and blank lines ignored).
The ~1 GB torus map is loaded once and shared read-only across worker threads.
plot_vz.py renders the diagnostic figures from vz.root (its histogram-key
conventions match this analysis's output exactly). It writes a set of PDFs:
confusion matrix, v_z truth×reco grids (integrated + per momentum bin), Δv_z vs
p, v_z–θ 2D, track-variable grid, the per-momentum resolution matrices
(σtx/σty/σθ), the true vertex→DC-R1 momentum-loss set, and the swim comparisons
(swum_minus_rec, rec_vs_swum, swim_resolution, recoswum_minus_rec, …).
pip install -r requirements.txt # uproot, numpy, matplotlib, mplhep (+ optional scienceplots, tqdm)
python plot_vz.py vz.root
python plot_vz.py vz.root --suffix _rgd # -> vz_confusion_matrix_rgd.pdf, etc.--suffix/-s is inserted before the .pdf of every figure, so outputs from
different runs (datasets, field settings) don't overwrite each other.
It degrades gracefully without scienceplots/LaTeX (uses matplotlib mathtext).
The generator-thrown spectrum in gen_vs_reco_p reads single-pion .lund files
from LUND_DIR (hardcoded near the top of the script); if that directory is
absent the thrown curve is simply skipped.
src/constants.hpp— binning, species, region, correlation-variable tablessrc/field.{hpp,cpp}— clas12-cmag binary field-map reader + composite fieldsrc/swim.{hpp,cpp}— Boost.odeint swimmer (dopri5 dense output + root-find)src/bank_access.hpp— per-detector bank readers overconst hipo::bank*src/analysis.{hpp,cpp}—Analysisaccumulator (build / fill / merge / write)src/accumulator_registry.hpp— thread-local Analysis registry + mergesrc/main.cpp— CLI, input expansion, field load,chain::process, summarytest/— swimmer straight-line test + field-map load testplot_vz.py— matplotlib/uproot plotter for the output histograms