Changelog¶
All notable changes to primat are documented here. The format follows
Keep a Changelog; this project has
not yet reached a stable public API (0.x), so backwards-incompatible
changes may still land in minor bumps.
Entries here are coarse-grained by design — one line per user-visible change
or theme, not a mirror of git log. For full detail on any entry, git log
in this repository is the authoritative source.
Unreleased¶
Changed¶
Python backend: the ten weak-rate Fermi-Dirac integrand kernels (
weak_rates/integrands.py) and the four e± electron-thermo integrands (plasma.py) are now numba-compiled withcache=True, so a fresh process (joblib MC worker, Streamlit server, re-run CLI) loads the compiled machine code from numba’s on-disk cache instead of recompiling — ~2.3 s of cold-start JIT saved per process (measured). The plasma integrands were moved to module level and now take the electron massmeas an explicit argument (rather than closing overcfg.me), which is what makes the on-disk cache safe. No effect on any observable.C backend (
primat-c) now routes its ~250 unrecoverable heap allocations (ODE work vectors, spline tables, loaded network, result arrays, …) through new checked helperscpr_xmalloc/cpr_xcalloc/cpr_xrealloc(include/xalloc.h): a failed allocation now printsprimat: out of memory (<bytes>) at <file>:<line>and exits, instead of dereferencing NULL and crashing anonymously. Sites that intentionally degrade gracefully (cache writers with their own NULL checks,errmsg-return paths) are unchanged. No effect on any observable — purely OOM-diagnostic robustness.
Removed¶
rate_interp_orderDEFAULT_PARAMS/C config parameter: never consumed by any solver, resampler, or rate-lookup path on either backend (rate-table resampling always hardcoded log-log cubic, and the per-step master-grid lookup always used linearsearchsortedregardless of its value), so setting it toquadratic/cubicchanged neither observables nor runtime. Removed together with its C field/default/validation, both param templates’ entries, both backends’ enum tests, and the now-empty_PARAM_CHOICESmachinery it was the last user of.
0.3.2 - 2026-07-11¶
Added¶
output_rates_time_evolutionnow writes per-reaction forward-rate columns (<reaction>_frwrd, small/small_parthenope networks), on both backends — previously a no-op. Populated inEvolutionResult.ratesand round-tripped byprimat.evolution.load_evolution.primat.sensitivity.sensitivity_table— a one-call API returning the logarithmic-sensitivity matrix ∂ln(observable)/∂ln(parameter) as aSensitivityTabledataclass (.to_markdown()/.to_dataframe()views), withnotebooks/Sensitivity.ipynbreduced to a thin demo and a new How-to → Sensitivity tables docs page.primat --list-paramsand--version(with backend build status) for CLI discoverability.Type hints across the public API,
py.typedmarker, and a lenient mypy CI job.primat.__citation__(ready-made BibTeX string) and top-levelrun_bbn/run_mc/HAS_C_BACKENDaliases, so common entry points no longer require reaching intoprimat.backend.CITATION.cffand Zenodo archival instructions inPyPiGuide.md.This changelog.
Config validation with clearer error messages, shared between both backends.
MC covariance/correlation output (
MCResult.cov()/.corr()) and arunfiles/primat_mc.pydemo script.Sphinx documentation site (
docs/, published to Read the Docs), migrating and superseding the oldREADME.md/EXTENDING.mdprose content.primat-gui’s Final abundances tab gained a single reproduction-bundle download (.py/.ini+ README,primat/gui/export_params.py): prints the full standard-ratiorun_bbncentrals plus arun_mc(seed=0)std-only block, pinsforce_backendto whichever backend actually ran, and for a custom network embeds the exactcustom_networkdict (Python) or anuclear/overlay directory (.ini, viauser_nuclear_dir) — including any uploaded/edited rate tables — so a downloaded bundle reproduces the GUI run bit-exactly.notebooks/ReactionRates.ipynb(⟨σv⟩(T9) of any reaction vs. the Hubble rate, with the master-grid reinterpolation overlaid) andnotebooks/AnimatedAbundances.ipynb(animated GIFs of the small-network abundance evolution vs. ΔNeff/Ω_b h²), both wired into the docs tutorial gallery with a guard test against future gallery drift.
Changed¶
The C backend now supports
extra_rhoanddecay_era, closing two of the three former Python-only feature gaps.extra_rhocallables are sampled onto a dense temperature grid and splined into the C Friedmann equation;decay_era’s long-lived-isotope Decay-Time propagation is ported via a scaling-and-squaring Padé matrix exponential, writing an identicaloutput_decay_evolutionTSV. Onlybackground=(a customBackgroundobject) remains Python-only.Default
Omegabh2changed to the Planck 2018 + BAO value (0.02242), from the previous default.plotlyandjoblibmoved from hard dependencies to themc/plots/guiextras — a plainpip install primatinstall is now lighter.Nuclear rate tables (
largenetwork) regenerated at 1000 points instead of being reinterpolated onto the master T9 grid from a coarser source grid, for both backends.Cache trees consolidated under
cache_plasma_weak/{weak,plasma}/with an additivecache_diroverlay redirect for read-only installs, and non-fatal (warn, not crash) cache-write failures on both backends (80 → 81DEFAULT_PARAMSkeys).Per-flavour neutrino degeneracies
munuOverTnu_e/mu/tau.
Fixed¶
Assorted release-blocker fixes ahead of the first PyPI publish: packaging metadata, wheel build matrix, and related polish.
The Python backend’s
run_bbnnow also exposes aY_finalsub-dict, matching the C backend and restoring result-dict parity (CLAUDE.md).Windows editable-install C-extension shadowing, and assorted Windows-portability failures in the CI Tests matrix.
MSVC POSIX-header/pthreads build failures on the Windows leg of
wheels.yml, so Windows users now get binary wheels (with the fast C backend) from PyPI instead of falling back to a source build (64-bit only).GN(Newton’s constant) default corrected to the exact CODATA literal6.6743e-11; the previous default (6.674299257609439e-11) was off at the ~1.1e-7 relative level.
Documented¶
Electron-thermo / QED-pressure table extrapolation behaviour beyond the tabulated range, with a runtime warning when a run goes past it.
0.3.1 - 2026-07-02¶
Added¶
show_progressconfig flag to control[primat]/[MC]stderr progress messages, wired through both the Python and C backends’ CLIs (including--flag/--no-flagboolean parsing).mc_rate_rescale_capparameter to cap Monte Carlo rate-rescaling factors (default lowered from1e3to30after further validation).Flat
sigma_<name>fields in MC results on both backends.Ctrl-C abort support for a running
primat-cMonte Carlo (run_mc) sample.Memory-leak checking (
make leak-test) and an ASan/UBSan CI job for the C backend.A pre-computed
PRIMAT_Yp_DH_ErrorMC_1000_2026.dattable for CLASS/CAMB consumption.
Changed¶
Renamed
rates_dir/user_rates_dirconfig fields todata_dir/user_nuclear_dir(clearer overlay semantics — seeCLAUDE.md’s “Rates directory resolution” section).Split the three separate QED plasma-pressure correction table files into one consolidated
QED_tables.txt.Integrated three background-ODE performance branches: dense-output RK45, a combined 2D background ODE, and monotone spline lookups for rate interpolation.
Smoothed MC progress reporting (was jumping straight from 0% to 100%).
Moved C backend headers from
include/cprimat/toinclude/.
Fixed¶
--no-show_progressbeing silently ignored by theprimat-cCLI’s--mcpath.delta_<rxn>rate perturbations not applying whenrescale_nuclear_rateswas left at its default.A NaN issue in the C backend’s
electron_thermoplasma cache.Several gcc-14 warnings (
-Wformat-truncation,-Wmaybe-uninitialized, unused-parameter) in the C backend.
0.3.0 - 2026-06-25¶
Initial PyPI-track release. By this point the project already had its current two-backend architecture in place:
Added¶
Dual backend: a pure-Python implementation (
primat/) and a fast C99 port (primat-c/), exposed to Python via a compiled extension and dispatched throughprimat.backend.run_bbn(force_backend={"auto","c","python"}).primat-gui, a Streamlit application (four usage modes: Python API, CLI, GUI, notebooks), including a “Customise Reactions” flow to build and import/export custom nuclear networks.Monte Carlo uncertainty propagation (
run_mc) with rate-key resolution and incremental sample reuse (prev) on the Python backend.Non-instantaneous neutrino decoupling via the NEVO tables, with overridable
nevo_file/nevo_spectral_file/nevo_grid_file/nevo_file_prefixparameters.Analytic QED plasma-pressure corrections and per-reaction weak-rate correction terms (Born, CCR, finite-mass, thermal, spectral-distortion).
Grid-agnostic nuclear rate loading (tables resampled onto a configurable master T9 grid at load time) and the
large/amaxnetwork-filtering mechanism.Unified log-log cubic not-a-knot interpolation for n↔p weak rates on both backends, collapsing the former C-vs-Python D/H gap to ≲1e-5.
Unified time-evolution TSV schema (
primat/evolution.py,EvolutionResult/load_evolution), implemented identically by both backends.