|
mist-hep 0.1.0
ROOT-backed analysis helpers built on mist
|
Clean-room sibling library to mist, layering ROOT and RooFit on top of mist's primitives. Pronounced "mist-hep", not "mishep".
mist is deliberately ROOT-free pure C++17. Anything in mist builds without ROOT in scope and links nothing from cern/root. Once you add ROOT, the dependency surface explodes — Cling, RooFit, ROOT::Core, the whole imaging stack — and every consumer of the logger or the RNG would pay that cost just to get a progress bar.
mist-hep is the place for everything that needs ROOT but still benefits from mist's primitives:
std::unique_ptr<TF1> instead of leaking global pointers.TRandom3, TBenchmark, TLatex) as Meyers-singleton accessors rather than ODR-unsafe header globals.quadrature_sum, barlow_parameter, clip_outliers_nsigma) — these don't need ROOT, but they belong here because their natural callers already have ROOT in scope.A downstream app picks either or both:
mist-hep does not wrap mist (no API re-export, no shadow headers). #include <mist/logger/logger.h> and #include <mist/hep/stats.h> are both first-class entry points.
Headers go under include/mist/hep/ (not include/mist-hep/) so consumers see one mist/ include root regardless of which sibling library a header came from.
Core, Hist, Graf, Gpad, RIO, Tree, MathCore, Matrix, Minuit, RooFit, RooFitCoremist_DIR must point at an installed mist (or its build tree once mist's T-01 lands). Until then, install mist to a prefix first:
Lays down:
libmist-hep.a under lib/include/mist/hep/lib/cmake/mist-hep/Either via find_package:
Or via FetchContent (two-step, in dependency order):
mist-hep's CMakeLists.txt short-circuits its own find_package(mist) when the mist::mist target already exists, so the two-step FetchContent works without duplicate lookups.
Header-only. Drops in anywhere that already includes the standard library.
Meyers singletons (static T obj; return obj; inside an inline accessor). Lazy, thread-safe init since C++11, no ODR risk. Replaces AAU's pattern of defining TRandom* uRandomGen = new TRandom(); at TU scope in a header.
mist::hep::rng() returns a TRandom3 (Mersenne Twister), one transparent upgrade from AAU's plain TRandom (LCG).
Each factory returns an owned root_ptr<TF1>. Callers decide lifetime; nothing leaks at TU scope. Parameter names and sensible defaults are wired up at construction. Available: make_levy_tsallis, make_gauss, make_qgauss (plus the public q_exp Tsallis primitive), make_exgauss (EMG), make_erf_step, make_expo, make_arrhenius.
root_ptr<T> (a unique_ptr with an ownership-aware deleter) plus make / clone / adopt and a scoped_directory_off guard. Objects are detached from gDirectory on creation, so they are never double-owned when a TFile is open. All the factories below return owned::root_ptr<T>.
Header-only, const-ref in / owning root_ptr out, non-mutating. Point-wise transforms (relative_diff, shift_x_to_origin, negate_x/y/xy, scale, swap_xy, to_graph_errors, from_profile), block/window reductions (block_average, block_rms, moving_average over mist::algo), and an error-propagating algebra on TGraphErrors (eval, add, power, scale_values, log, log10, ratio, product, difference, trim, mean_of, derivative).
Introspection (dimension, pair_dimension, is_consistent), construction and binning (make_th1_from_vector, uniform_binning, log_binning), manipulation (offset, absolute, scale), and fill bridges (project_y, fill_profile, fill_persistence, fill_from_interval).
amplitude, extremum, threshold_crossings, first_above / last_above, maximum_filter, gaussian_filter, integrate, find_peaks.
main): https://nikolajal.github.io/mist-hep/MIST_* → MIST_HEP_*).The Doxygen site is built and published by .github/workflows/docs.yml on every push to main; manual rebuilds are possible from the Actions tab.
Off by default so downstream consumers aren't affected. Enable with -DMIST_HEP_BUILD_TESTS=ON:
| Binary | Source | Coverage |
|---|---|---|
test_stats | test/tester_stats.cxx | quadrature_sum on initializer-list + ranges; barlow_parameter NaN handling; clip_outliers_nsigma happy / no-outlier / zero-variance / empty / single-element |
test_fit | test/tester_fit.cxx | make_levy_tsallis parameter names + defaults, finiteness + positivity over [0, 10] GeV, integral sanity (~0.9997 for default dNdy=1), rng() singleton smoke-test |
test_graph | test/tester_graph.cxx | transforms (shift / negate / scale / swap_xy / relative_diff policies / to_graph_errors / from_profile), binning + smoothing, derivative, and the TGraphErrors algebra (eval, add, power, scale_values, log10 error, ratio, product, difference, trim, mean_of) |
test_histo | test/tester_histo.cxx | introspection (dimension / pair_dimension / is_consistent), uniform_binning / log_binning, make_th1_from_vector, offset / absolute / scale, and the fill bridges (project_y, fill_profile, fill_persistence, fill_from_interval) |
test_owned | test/tester_owned.cxx | make / clone / adopt detachment, scoped_directory_off restore, and the decisive open-TFile no-double-free case |
test_signal | test/tester_signal.cxx | amplitude / extremum, threshold crossings + first/last_above, maximum_filter / gaussian_filter, integrate, find_peaks |
mist-hep is a clean-room rewrite of the salvageable parts of AAU (2021–2022), not a vendor drop. Each port:
fIsWorthFitting, ODR-unsafe header globals, dead-branch stubs like fRatioPlot).snake_case + namespaces (mist::hep::*).using namespace std/RooFit from headers.TF1* globals with std::unique_ptr<TF1> factories.Day-1 surface is intentionally small (stats + globals + Levy–Tsallis). Subsequent ports happen on demand; see D-01 for the proposed order.
The full set lives in `DISCUSSION.md`. Currently open:
MIST_HEP_WITH_ROOFIT) so the smaller cousins can build without it?In-flight TODOs (T-01 … T-03): CI build+ctest workflow, README docs badge once Pages publishes, AAU function-port queue.
MIT License. See [LICENSE](LICENSE) for details.