Package Overview#
BSSunfold is a Python package for neutron spectrum unfolding from Bonner Sphere Spectrometers (BSS). It provides 88 unfolding algorithms, 41 spectrum comparison metrics, ICRP-116 dose calculations, and Monte Carlo uncertainty quantification. Iterative solvers are accelerated with Numba JIT compilation.
Unfolding Methods#
All 88 methods are accessible as instance methods on the
bssunfold.Detector class. They are organised into the following
categories:
graph TD
A["Unfolding Methods"] --> B["Tikhonov-type"]
A --> C["Iterative"]
A --> D["Bayesian"]
A --> E["Maximum Entropy"]
A --> F["Statistical Regularization"]
A --> G["Optimization-based"]
A --> P["Dictionary / Sparse"]
A --> H["Pipeline"]
A --> I["Parametric"]
A --> J["Krylov/hybrid"]
A --> K["EM family"]
A --> L["Multi-sphere ratio"]
A --> M["Advanced proximal"]
A --> N["Evolutionary"]
A --> O["Classic RSICC codes"]
B --> B1["unfold_cvxpy"]
B --> B2["unfold_qpsolvers"]
B --> B3["unfold_tsvd"]
B --> B4["unfold_tikhonov_legendre"]
J --> J1["unfold_lanczos"]
J --> J2["unfold_gks"]
J --> J3["unfold_cgls"]
J --> J4["unfold_hybrid_gmres"]
J --> J5["unfold_fista"]
C --> C1["unfold_landweber"]
C --> C2["unfold_mlem"]
C --> C3["unfold_mlem_stop"]
C --> C4["unfold_mlem_odl"]
C --> C5["unfold_gravel"]
C --> C6["unfold_doroshenko"]
C --> C7["unfold_kaczmarz"]
C --> C8["unfold_sart"]
C --> C9["unfold_randomized_kaczmarz"]
K --> K1["unfold_osem"]
K --> K4["unfold_osem_anlm"]
K --> K2["unfold_mapem"]
K --> K3["unfold_bsrem"]
L --> L1["unfold_sandii"]
L --> L2["unfold_bunki"]
L --> L3["unfold_bunkiut"]
L --> L4["unfold_rebunki"]
L --> L5["unfold_nsduaz"]
L --> L6["unfold_ferdor"]
L --> L7["unfold_directed_divergence"]
D --> D1["unfold_bayes"]
D --> D2["unfold_bayes_spline_regularization"]
D --> D3["unfold_mcmc"]
D --> D4["unfold_zfit"]
D --> D5["unfold_eki"]
E --> E1["unfold_maxed"]
E --> E2["unfold_imaxed"]
E --> E3["unfold_amaxed"]
E --> E4["unfold_amaxed_regularization"]
F --> F1["unfold_statreg"]
F --> F2["unfold_reconst"]
G --> G1["unfold_lmfit"]
G --> G2["unfold_scipy_direct_method"]
G --> G3["unfold_mystic"]
G --> GH["unfold_mystic_hybrid"]
G --> G4["unfold_smt"]
G --> G5["unfold_genetic"]
G --> G7["unfold_scip"]
G --> G8["unfold_docplex"]
G --> G9["unfold_epic"]
G --> G10["unfold_qubo"]
P --> P1["unfold_cs"]
P --> P2["unfold_nnksvd"]
H --> H1["unfold_combined"]
H --> H2["unfold_cascade"]
H --> H3["unfold_composite"]
H --> H4["unfold_ensemble"]
H --> H5["unfold_iterative_refinement"]
H --> H6["unfold_binned"]
I --> I1["unfold_parametric"]
I --> I2["unfold_parametric_cvxpy"]
I --> I3["unfold_parametric_qpsolvers"]
I --> I4["unfold_parametric_combined"]
I --> I5["unfold_parametric2"]
I --> I6["unfold_fruit_like"]
I --> I7["unfold_hybrid_parametric"]
I --> I8["unfold_bayesian_parametric"]
I --> I9["unfold_express"]
M --> M1["unfold_odl_pdhg"]
M --> M2["unfold_odl_douglas_rachford"]
N --> N1["unfold_maeo"]
O --> O1["unfold_crystal_ball"]
O --> O2["unfold_rfsp_jul"]
O --> O3["unfold_staysl"]
style A fill:#4a90d9,color:#fff
style B fill:#e8f0fe
style C fill:#e8f0fe
style D fill:#e8f0fe
style E fill:#e8f0fe
style F fill:#e8f0fe
style G fill:#e8f0fe
style H fill:#e8f0fe
style I fill:#e8f0fe
style J fill:#e8f0fe
style M fill:#e8f0fe
style N fill:#e8f0fe
style O fill:#e8f0fe
style P fill:#e8f0fe
Method Reference#
# |
Method |
Category |
Unique Parameters |
Dependencies |
Description |
|---|---|---|---|---|---|
1 |
|
Tikhonov |
regularization, norm (1/2), solver, regularization_method |
cvxpy |
Convex optimization with Tikhonov regularization. See Variational (Tikhonov-Type) Methods. |
2 |
|
Tikhonov |
regularization, norm (1/2), solver, smoothness_order, smoothness_weight, regularization_method |
qpsolvers |
QP-based unfolding with L1/L2/smoothness norms. See Variational (Tikhonov-Type) Methods. |
3 |
|
Tikhonov |
method (l_curve/gcv/discrepancy/energy/median/donoho), k, threshold, noise_level |
— |
Truncated SVD with automatic k-selection |
4 |
|
Krylov/hybrid |
regularization_method (gcv), max_iterations, regularization, noise_level |
— |
Lanczos-hybrid (Golub-Kahan bidiagonalization) with automatic per-iteration GCV regularization; no a-priori spectrum required |
5 |
|
Tikhonov |
delta, n_polynomials |
— |
Tikhonov regularization in Legendre polynomial basis. See Variational (Tikhonov-Type) Methods. |
6 |
|
Iterative |
max_iterations, tolerance |
— |
Landweber fixed-point iteration. See Algebraic Iterative Methods. |
7 |
|
Iterative |
max_iterations, tolerance |
— |
Pure-NumPy MLEM (expectation maximization) |
8 |
|
Iterative |
max_iterations, cps_crossover, j_threshold |
— |
MLEM with J-factor early stopping criterion (Montgomery et al. 2020). See Poisson-Likelihood (EM) Family. |
9 |
|
Iterative |
max_iterations, tolerance |
odl |
MLEM via ODL operator framework |
10 |
|
Iterative |
max_iterations, tolerance, regularization |
— |
GRAVEL algorithm with relative entropy weighting |
11 |
|
Iterative |
max_iterations, tolerance, regularization |
— |
Coordinate-update iterative method |
12 |
|
Iterative |
max_iterations, omega, tolerance |
— |
ART (Algebraic Reconstruction Technique) |
13 |
|
Bayesian |
max_iterations, tolerance |
— |
D’Agostini Bayesian iterative unfolding |
14 |
|
Bayesian |
max_iterations, tolerance, spline_degree, spline_smooth |
— |
Bayes iteration with spline smoothing |
15 |
|
MaxEnt |
sigma_factor, max_iterations, tolerance |
— |
Maximum entropy deconvolution (Reginatto & Goldhagen). See Maximum Entropy and Information Divergence. |
16 |
|
Statistical Reg. |
unfoldermethod (EmpiricalBayes/…), regularization, basis_name, boundary, derivative_degree |
— |
Turchin’s statistical regularization. See Variational (Tikhonov-Type) Methods. |
17 |
|
Statistical Reg. |
alpha, beta, max_iter_alpha, max_iter_beta, tol_alpha, tol_beta |
— |
Fortran STREG1 port: auto α/β with discrepancy principle & ω-criterion |
18 |
|
Optimization |
method (lbfgsb/leastsq/…), model_name (elastic/lasso/ridge), regularization, regularization2, l1_weight, regularization_method (manual/aic/aicc/bic), lambda_range, n_lambda |
lmfit |
L1/L2/Elastic Net via lmfit, with optional AIC/AICc/BIC-based regularization selection |
19 |
|
Optimization |
method (cg/gmres/lsqr/lsmr/minres), tolerance, max_iterations |
— |
Direct SciPy linear solvers |
20 |
|
Pipeline |
pipeline (list of {method, params} dicts) |
— |
Sequential multi-method pipeline |
21 |
|
Parametric |
parametric_method, optimizer, solver_backend, initial_params |
lmfit, cvxpy, qpsolvers |
FRUIT-style thermal/epithermal/fast model. See Parametric Models. |
22 |
|
Parametric |
parametric_method, initial_params, solver_backend |
cvxpy |
SQP solver using cvxpy for parametric fitting |
23 |
|
Parametric |
parametric_method, initial_params, solver_backend |
qpsolvers |
SQP solver using qpsolvers backends |
24 |
|
Parametric |
parametric_method, initial_params, solver_backend |
lmfit, cvxpy, qpsolvers |
lmfit first-pass + QP refinement |
25 |
|
Parametric |
b_range, Tf_range, c_range, noise_level, max_iter, tol_chi2, optimizer, solver_backend |
grid, cvxpy, qpsolvers, combined |
BON95 4-component model + directed-divergence iterations |
26 |
|
Parametric |
initial_params, max_iterations, tolerance |
— |
FRUIT-like model: Maxwellian thermal + 1/E epithermal + evaporation fast |
27 |
|
Parametric |
refinement_method (landweber/mlem), max_iterations, tolerance |
— |
Parametric initial guess refined by Landweber or MLEM |
28 |
|
Parametric |
n_samples, burn_in, proposal_scale, prior_mean, prior_std |
— |
Metropolis-Hastings MCMC for spectral parameter estimation |
29 |
|
Optimization |
regularization, norm (1/2), solver (fmin/fmin_powell/diffev/diffev2), maxiter, maxfun, smoothness_order, smoothness_weight, regularization_method |
mystic |
Direct-search minimization of the penalized least-squares objective. See Variational (Tikhonov-Type) Methods. |
30 |
|
Optimization |
nonneg, timeout_ms |
z3-solver |
Exact SMT solving of A·x = b (integer/rational) with fluence minimization |
31 |
|
Optimization |
solver (pso/ga/de/es/ep/abc/gwo/cmaes/nsga2), epoch, pop_size, regularization, norm (1/2), smoothness_order, smoothness_weight, entropy_weight, n_runs, early_stop, half_range, two_step, n_coarse, smoother, sigma_smooth, crossover (single/arithmetic), mutation (random/iterative), pareto_select (knee/min_residual/max_entropy) |
mealpy |
Population-based meta-heuristic unfolding (PSO/GA/DE/ES/EP/ABC/GWO/CMA-ES/NSGA-II), with an optional TGASU-style two-step coarse-to-fine scheme, NSGA-II Pareto selection, arithmetic crossover/iterative mutation and post-processing smoothers |
32 |
|
Optimization |
n_atoms, sparsity, dictionary, n_dictionary_iterations, sigma_min, sigma_decrease_factor, mu_0, L, max_iterations, tolerance |
— |
Compressive sensing: K-SVD dictionary + OMP sparse coding + SL0 reconstruction |
33 |
|
Optimization |
regularization, norm (1/2), timeout, smoothness_order, smoothness_weight, nonneg, regularization_method |
pyscipopt |
Tikhonov QP solved by the SCIP Optimization Suite (global NLP/QP optimizer) |
34 |
|
Optimization |
regularization, norm (1/2), timeout, smoothness_order, smoothness_weight, nonneg, regularization_method |
docplex, cplex |
Tikhonov QP solved by IBM CPLEX via docplex.mp (CPLEX Community Edition) |
35 |
|
Regularization |
target_sigmas, sigma_frac, regularization_order (0/1/2), non_neg, noise_var, homogeneous_step, regularize, beta_shift_k, beta_distance, EPIC_bool, V, LSQpar |
— |
EPIC Tikhonov regularization (Ortega-Culaciati et al. 2021): prior variances chosen so a posteriori variances match target sigmas |
36 |
|
Interpretation |
regularization, norm (1/2), smoothness_order, smoothness_weight, enforce_norm, norm_value, regularization_method, interpret_options |
pyoptexplain (optional) |
Unfolding QP solved via pyoptexplain plus an interpretation report (robustness, shadow prices, detector sensitivity, regularization sweep, scenarios). Also Detector.interpret_result for interpretation-only runs |
37 |
|
Krylov/iterative |
max_iterations, tolerance, regularization, smoothness_order, noise_level |
— |
CGLS (conjugate gradient for least squares) with optional |
38 |
|
Krylov/hybrid |
regularization_method (gcv/dp/lcurve/manual), max_iterations, smoothness_order, regularization, noise_level |
— |
Generalized Krylov Subspace (Golub-Kahan bidiagonalization + projected regularization selection); no a-priori spectrum required |
39 |
|
Regularization |
epsilon, mu, max_iterations, type_ (TT/TV/T), beta (float or |
— |
Noise-constrained Tikhonov+TV via ADMM (Gazzola & Gholami); adaptive balancing of the TV and Tikhonov terms. See Variational (Tikhonov-Type) Methods. |
40 |
|
Multi-sphere ratio |
max_iterations, tolerance, chi_fac (0/1), relative_uncertainty, noise_level |
— |
SAND-II geometric-mean ratio method (McElroy et al. 1967): chi-square or max-relative-deviation stopping |
41 |
|
Multi-sphere ratio |
smoothing, max_iterations, tolerance, noise_level |
— |
BUNKI (SPUNIT) iterative unfolding with three-point smoothing (RSICC PSR-266) |
42 |
|
Multi-sphere ratio |
smoothing, max_iterations, tolerance, noise_level |
— |
BUNKI-UT (BON31G) modernised unfolding (University of Texas) |
43 |
|
EM family |
max_iterations, n_subsets, tolerance, noise_level |
— |
Ordered-subset expectation maximisation (Hudson & Larkin 1994); |
44 |
|
EM family |
prior (none/quadratic/logcosh/relative_difference), beta, prior_delta, gamma, max_iterations, tolerance, noise_level |
— |
MAP-EM (OSMAPOSL one-step-late penalised EM) with nearest-neighbour priors over the energy axis |
45 |
|
EM family |
prior (none/quadratic/logcosh/relative_difference), beta, prior_delta, gamma, max_iterations, n_subsets, tolerance, relaxation, addition_after_iteration, noise_level |
— |
Block-sequential regularised EM with relaxation sequence and floor clamping (guaranteed convergence for non-convex priors) |
46 |
|
Iterative |
max_iterations, tolerance, relaxation, noise_level |
— |
Simultaneous algebraic reconstruction technique: relaxed, residual-normalised additive correction |
47 |
|
Multi-sphere deconvolution |
max_iterations, tolerance, smoothing, chi_squared_target, relative_uncertainty |
— |
FERDOR few-channel unfolding: constrained least squares with an automatically adjusted smoothing weight chosen by the discrepancy principle |
47a |
|
Multi-sphere ratio |
max_iterations, tol_chi2, tol_rel, smoothness_order, smoothness_weight |
— |
Directed-divergence I-divergence unfolding on Bonner-sphere response matrices with optional smoothness regularisation |
48 |
|
Multi-sphere ratio |
smoothing, max_iterations, tolerance |
— |
ReBUNKI (SPUNIT) few-iteration spectral stripping with three-point smoothing and ~1% convergence tolerance |
49 |
|
Multi-sphere ratio |
initial_spectrum, catalogue, use_catalogue, reference_name, smoothing, max_iterations, tolerance |
— |
NSDUAZ unfolding: catalogue-selected initial spectrum (nuclear-data reference fluxes) refined by the SPUNIT iteration, with a flat-spectrum mode |
50a |
|
Parametric |
n_groups, interval_boundaries, max_iterations, tol_iteration, relative_uncertainty |
scipy |
Piecewise-exponential Express fit adapted to Bonner-sphere response functions using direct least-squares on the measured readings |
50 |
|
Krylov/hybrid |
max_iterations, tolerance, regularization, l1_penalty, tv_penalty, nonnegativity, x_min, x_max, noise_level, eta |
— |
FISTA (Fast Iterative Shrinkage-Thresholding Algorithm): accelerated proximal gradient method for L1/L2/TV regularized problems with box constraints; O(1/k²) convergence. See Algebraic Iterative Methods. |
51 |
|
Krylov/hybrid |
max_iterations, regularization_method, regularization, noise_level, eta, reorthogonalization |
— |
Hybrid GMRES: combines GMRES iteration with Tikhonov regularization on projected problem; automatic regularization selection via GCV/discrepancy principle |
52 |
|
MaxEnt |
sigma_factor, max_iterations, tolerance |
— |
Improved MAXED with gradient-based log-space optimization and cross-entropy regularization (Wong 2024) |
53 |
|
MaxEnt |
sigma_factor, target_chi2, max_iterations, tolerance |
— |
Alternative MAXED with reversed cross-entropy definition using Lagrangian multipliers (Wong 2024) |
54 |
|
MaxEnt |
sigma_factor, tau, max_iterations, tolerance |
— |
AMAXED with Tikhonov-style simultaneous minimization of chi-squared and cross-entropy (Wong 2024) |
55 |
|
Evolutionary |
n_cycles, n_gen_per_cycle, pop_size, algorithms (nsga3/ctaea/agemoea2/spea2), lambda_smooth, prior_spectrum, convergence_assist_ratio |
pymoo |
MAEO multi-island ensemble of NSGA-III/C-TAEA/AGE-MOEA-II/SPEA2 with hypervolume-based migration, convergence-assist phase and knee-point selection from the combined Pareto front |
56 |
|
Bayesian |
sigma_prior, lambda_prior, n_samples, tune, chains, target_accept, use_hierarchical, progressbar |
pymc, arviz |
Full Bayesian unfolding with the NUTS (Hamiltonian Monte Carlo) sampler: mean posterior spectrum, 95% HPD credible intervals, per-bin posterior std and R-hat / ESS convergence diagnostics under mcmc_stats. See Bayesian and Stochastic Methods. |
57 |
|
Bayesian |
use_mcmc, n_samples, regularization, smoothness_weight |
zfit, tensorflow |
Poisson-likelihood spectrum inference with smoothness/L2 priors via zfit (Minuit) and a SciPy fallback |
58 |
|
Optimization |
n_bits, max_value, regularization, annealing_time, num_reads |
pyqubo, dwave-neal |
Quantum-inspired QUBO formulation: binary-encoded spectrum amplitudes minimized by classical simulated annealing |
59 |
|
Advanced proximal |
tau, sigma, use_tv, tv_weight, nonnegativity, tolerance |
— |
Primal-Dual Hybrid Gradient (Chambolle-Pock) for L2+TV / L2+L2 problems; TV preserves sharp spectral features (pure-NumPy, ODL-independent) |
60 |
|
Advanced proximal |
use_tv, tv_weight, nonnegativity, tolerance |
— |
Douglas-Rachford splitting for composite objectives (data fidelity + TV/L2 + non-negativity indicator); pure-NumPy, ODL-independent |
61 |
|
Pipeline/Ensemble |
cascade_stages, multi_resolution, coarse_bins |
— |
Sequential multi-method cascade; each stage may use the previous result as an initial guess/prior; with multi_resolution=True the first stage runs on a coarse energy grid and its prolongated solution seeds the fine-grid stages |
62 |
|
Ensemble |
n_methods, timeout_per_method, method_names, ensemble_weights, spectrum, energy |
— |
Adaptive ensemble (stacked generalization): classifies the spectrum by hardness, runs a pool of individual methods and combines their results with confidence-weighted averaging |
63 |
|
Classic RSICC codes |
regularization, noise_level |
— |
CRYSTAL BALL direct (non-iterative) method: approximates the spectrum as a linear combination of the detector response functions; independent reimplementation from the published delta-operator description (the original code is proprietary/RSICC) |
64 |
|
Classic RSICC codes |
max_iterations, tolerance, weights, noise_level |
— |
RFSP-JUL iterative damped least squares: minimises a weighted residual functional with a Marquardt-style damping term tying each iterate to the previous one; independent reimplementation (original code proprietary/RSICC) |
65 |
|
Classic RSICC codes |
relative_uncertainty, prior_uncertainty, noise_level |
— |
STAY’SL single-step linear Bayesian least-squares update refining a prior spectrum with full measurement/prior covariance information; independent reimplementation from the published mathematical formalism (original code proprietary/RSICC) |
66 |
|
Optimization |
global_solver (diffev2), local_solver (fmin_powell), global_maxiter, global_maxfun, local_maxiter, local_maxfun, npop, regularization, norm (1/2), smoothness_order, smoothness_weight, regularization_method |
mystic |
Two-stage hybrid solver: diffev2 performs global exploration of the penalized least-squares objective, then fmin_powell refines the result for precise local convergence; registered in unfold_combined / unfold_composite pipelines as ‘mystic_hybrid’ |
67 |
|
Ensemble |
methods, weights, combination (weighted_average/median/trimmed_mean/best_residual), trim_fraction |
— |
Robust ensemble combining several base solvers (default MLEM/Bayes/Landweber/CGLS/GRAVEL) via inverse-residual weighting or robust statistics to reduce method-specific bias |
68 |
|
Ensemble/Refinement |
first_pass_kwargs, second_pass_kwargs, alpha, max_alpha_search |
— |
Two-pass refinement: an initial unfold is refined by a second pass with an automatically selected blending factor α between the two spectra |
69 |
|
Iterative |
max_iterations, omega, tolerance, random_state |
— |
Randomized Kaczmarz (Strohmer & Vershynin 2009): probabilistic row selection with probability ∝ ‖A_i‖², achieving faster convergence than the cyclic variant for ill-conditioned systems |
70 |
|
Bayesian |
n_ensemble, n_iterations, regularization, inflation, noise_std, random_state |
— |
Ensemble Kalman Inversion (Iglesias et al. 2013): Bayesian posterior approximation without MCMC by propagating an ensemble through the forward model and updating via the Kalman gain equation with regularized covariance. See Bayesian and Stochastic Methods. |
71 |
|
Ensemble/Adaptive |
bin_lookup, lookup_path, timeout_per_method |
— |
Bin-wise adaptive unfolding: for each energy bin, selects the best method from a pre-computed benchmark lookup (67 methods x 271 spectra) and assembles the final spectrum by direct bin-picking; the lookup ships as |
72 |
|
Dictionary / Sparse |
n_atoms, sparsity, E_MeV, dictionary, training_signals, n_dictionary_iterations, lambda_tik, prior_wt, sparse_coder (nnls_topk/omp/nn_omp), tolerance, n_nnls_iter |
— |
Non-negative K-SVD unfolding (Xu et al. NIMA 2026, https://doi.org/10.1016/j.nima.2026.172070): non-negative dictionary learning + Tikhonov-regularized NNLS via augmented form (Eq. 2.5/2.6) with three sparse coders — |
73 |
|
Maximum entropy / parametric |
knots (preset name / explicit / None), continuity (C0C1/C0/none), relative_uncertainty, max_iterations, tol, step_theta, smoothing, n_segments |
— |
N-spline unfolding (Islamgulov & Lartsev, Atomic Energy 104(5), 2008): spectrum parameterised by exp(a + q lnE + rE) splines with C0/C1 knot continuity; directed-divergence (MIRD) minimisation loop with per-iteration N-spline smoothing; paper’s stopping criteria and |
74 |
|
Iterative / Spline |
n_basis, spline_order, beta, beta_relative, knot_spacing (auto/uniform/log), auto_params, bootstrap_ci, n_bootstrap, ci_alpha, max_iterations, tolerance |
— |
B-spline MLEM (MLEM-BS, Mazankova et al., CNDGS’2026, https://doi.org/10.47459/cndcgs.2026.61): the spectrum is represented in a B-spline basis (effective matrix RB = R B) and the coefficients are found with the regularized MLEM iteration (Eq. 4) with the second-derivative penalty |
75 |
|
Optimization |
population, max_gens, max_fevals, stall_limit, conv_tol, opt_conv_tol, frac_elite, frac_levy, frac_mutation, alpha_levy, gamma_levy, n_levy, scaling_factor, init_sampling (lhc/random), regularization, norm (1/2), smoothness_order, smoothness_weight, entropy_weight, half_range |
— |
Gnowee hybrid metaheuristic optimizer (Bevins & Parsons, UC Berkeley / Slaybaugh Lab, SlaybaughLab/Gnowee). Combines Lévy flights (Cuckoo Search via the Mantegna algorithm), golden-ratio crossover (Modified Cuckoo Search / Differential Evolution), scatter search (Egea 2009) and DE-style mutation in an elitist population with Metropolis-Hastings acceptance and stall-driven restarts. Searches in log space, seeded with a Landweber warm-start solution, with a scale-consistent objective combining the relative L2 residual, Tikhonov regularisation, second-difference smoothness and (optionally) negative Shannon entropy. Pure-Python 3 port (no external optimisation library required). |
76 |
|
Optimization / QP |
regularization, smoothness_order (0/1/2), smoothness_weight, tol, max_iterations, floor |
— |
Non-Negative Quadratic Programming solver (Giovannucci & Pehlevan, simonsfoundation/NNQP). Coordinate-descent algorithm for |
77 |
|
Optimization / QP |
regularization, smoothness_order (0/1/2), smoothness_weight, floor, lb, ub, backend (python/qpmad), tol, max_iterations |
qpmad (optional, for the C++ backend) |
qpmad-style strictly-convex QP solver (Sherikov, asherikov/qpmad). Solves |
78 |
|
Optimization course |
max_iterations, tolerance, regularization, constraint (nonnegative/box/simplex), total_fluence, x_max, backtracking, variance_reduction |
— |
Projected gradient descent (MIPT optimization course, lecture 9 / homework 14): gradient step followed by the Euclidean projection onto the nonnegative orthant, a box or the fluence simplex; optional Armijo backtracking; reports a Lagrange-duality-gap optimality certificate ( |
79 |
|
Optimization course |
total_fluence, max_iterations, tolerance, away_steps, line_search (exact/backtracking), variance_reduction |
— |
Frank-Wolfe conditional gradient (lecture 9): linear minimization oracle over the fluence simplex with Wolfe away-steps and Frank-Wolfe-gap stopping; total fluence preserved exactly at every iterate. |
80 |
|
Optimization course |
mirror_map (entropy/log/l2/pnorm), step_size, total_fluence, regularization, p, max_iterations, tolerance, variance_reduction |
— |
Mirror descent in Bregman geometries (lecture 10 / homework 16): the entropy map yields multiplicative updates generalizing MLEM/GRAVEL/SAND-II while preserving total fluence; log-barrier, L2 and p-norm maps; per-iteration golden-section line search. |
81 |
|
Optimization course |
l1_penalty, tv_penalty, rho, adaptive_rho, max_iterations, tolerance, variance_reduction |
— |
Consensus ADMM (lecture 11 / homework 18; Boyd et al. 2011): exact NNLS x-update on the augmented system enforces non-negativity at every iteration; soft-thresholding z-updates handle L1/TV penalties; Boyd primal/dual-residual stopping with adaptive rho. |
82 |
|
Optimization course |
regularization, smoothness, x_min, x_max, lbfgs_history, max_iterations, tolerance, variance_reduction |
— |
L-BFGS-B quasi-Newton with box bounds (lecture 7 / homework 10): smooth Tikhonov objective with analytic gradients and a second-difference curvature penalty; O(n·history) memory. |
83 |
|
Optimization course |
l1_penalty, l2_penalty, selection (cyclic/random), max_iterations, tolerance, variance_reduction |
— |
Coordinate descent for NNLS with L1/L2 penalties (lecture 15): exact closed-form coordinate minimization with O(m) per-coordinate residual updates; cyclic or seeded random order. |
84 |
|
Optimization course |
l1_penalty, tv_penalty, step_policy (polyak/diminishing/fixed), step_size, decay, polyak_margin, max_iterations, tolerance, variance_reduction |
— |
Projected subgradient descent for nonsmooth L1/TV objectives (lecture 8 / homework 12): Polyak, diminishing or fixed steps; best iterate by objective value is returned. |
85 |
|
Optimization course |
noise_level, step_size, max_iterations, tolerance, variance_reduction |
— |
Korpelevich extragradient (lecture 13 / homework 20) on the robust saddle formulation |
86 |
|
EM family |
max_iterations, n_subsets, tolerance, h (noise level; None = automatic MAD estimate), search_window (N), similarity_window (nu), alpha, anlm_mode (subset/post), log_space, noise_level |
— |
OSEM-ANLM (Jamaati et al. 2026, Sci. Rep.): ordered-subset EM with the two-stage asymptotic non-local means filter (stage 1 |
87 |
|
Quadratic programming |
smoothness, smooth_order (0/1/2), auto_smooth, chi2_target, max_iterations, tolerance, relative_uncertainty, variance_reduction |
— |
LOUHI78 (Routti & Sandberg 1980, Comput. Phys. Commun. 21): constrained weighted least squares |
Note
Common parameters shared by most methods:
readings, initial_spectrum, calculate_errors, noise_level,
n_montecarlo, variance_reduction (none/antithetic/control/both
— variance-reduced Monte-Carlo uncertainty), save_result,
random_state.
See the Index or Detector Class for complete API signatures.
Regularization Parameter Selection#
Nine automatic regularization parameter selection methods are available via
bssunfold.core.regularization.select_regularization_parameter():
Method key |
Reference |
Description |
|---|---|---|
|
Hansen 1992 |
L-curve corner heuristic (max distance from chord in log-log) |
|
Golub et al. 1979 |
Generalized Cross Validation (minimises GCV function) |
|
Morozov 1966 |
Discrepancy principle (residual ≈ noise level) |
|
— |
Maximises cosine similarity to a reference spectrum |
|
Hochstenbach & Reichel 2015 |
Minimises the noise component in the SVD basis |
|
— |
Normalized Cumulative Periodogram: KS-test on residual whiteness |
|
— |
Maximises signal-to-noise ratio in the Tikhonov solution |
|
— |
GCV with Poisson variance weights for heteroscedastic noise |
|
— |
K-fold cross-validation; noise-independent alternative to GCV |
Built-in Response Functions#
7 response function datasets are included as Python dicts, importable from the package root:
Dataset |
Source |
Detectors |
Energy Range |
Notes |
|---|---|---|---|---|
|
GSF (Germany) |
10 (0in–18in) |
1e-9 – 631 MeV |
Standard range |
|
PTB (Germany) |
15 (0in–18in) |
1e-9 – 631 MeV |
Standard range |
|
LANL (USA) |
11 (3in–18in) |
1e-9 – 631 MeV |
Includes Pb-shielded (9inPb, 12inPb, 18inPb) |
|
JINR (Dubna) |
9 (0in–12in) |
1e-9 – 631 MeV |
Includes Cd-covered (Cd0in) and Pb-shielded (10inPb) |
|
Fermilab (USA) |
8 (0in–18in) |
1e-9 – 631 MeV |
Standard range |
|
EURADOS round-robin |
13 (0in–12in) |
1e-9 – 20 MeV |
Narrower range; includes Cd2in, 3.5in, 4.5in |
|
IHEP (Protvino) |
12 (0in–18in) |
1e-9 – 2000 MeV |
Wider range; includes 15in |
Warning
RF_EURADOS max energy is 20 MeV and RF_IHEP max energy is 2000 MeV,
compared to 631 MeV for the other datasets. Use caution when comparing
results across datasets with different energy ranges.
from bssunfold import Detector, RF_JINR
detector = Detector(RF_JINR)
result = detector.unfold_cvxpy(readings, regularization=1e-4)
Dose Conversion Coefficients#
4 dose conversion coefficient datasets are included for flexible dose rate calculations. The default is ICRP-116 effective dose.
Dataset |
Standard |
Quantities |
Energy Range |
Notes |
|---|---|---|---|---|
|
ICRP-116 |
AP, PA, LLAT, RLAT, ISO, ROT |
1e-9 – 631 MeV |
Standard range |
|
ICRP-74 |
AP, PA, RLAT, ROT, ISO |
1e-9 – 398 MeV |
Effective dose |
|
NRB99-2009 |
AP, ISO |
25 eV – 20 MeV |
Limited range |
|
ICRP-74 |
ADE, PDE0, PDE45, PDE60, PDE75 |
1e-9 – 398 MeV |
Operational quantities |
Warning
NRB99_2009_effective covers a limited energy range (25 eV – 20 MeV).
Values outside this range are set to zero during interpolation.
from bssunfold import Detector, get_coefficients, interpolate_coefficients
# Set on Detector (affects all subsequent unfolds)
detector = Detector(cc_type="ICRP74_effective")
# Change after creation
detector.set_dose_coefficients("ICRP74_operational")
# Get coefficients directly for custom use
cc = get_coefficients("NRB99_2009_effective")
cc_interp = interpolate_coefficients(cc, detector.E_MeV)
Spectrum Comparison Metrics#
41 metrics organised into 9 categories: 27 simple pairwise metrics (entropy, distribution, correlation, error, similarity, chi-squared, statistical) implemented with pure NumPy/SciPy, plus EURADOS-style integral quantities and spectral diagnostics that are computed automatically when an energy grid is available (Gomez-Ros et al. 2022).
graph TD
A["Comparison Metrics"] --> B["Entropy"]
A --> C["Distribution"]
A --> D["Correlation"]
A --> E["Error"]
A --> F["Similarity"]
A --> G["Chi-squared"]
A --> H["Statistical"]
A --> I["Integral"]
A --> J["Spectral Diagnostics"]
B --> B1["kl_divergence"]
B --> B2["cross_entropy"]
B --> B3["entropy_difference_percent"]
C --> C1["wasserstein_dist"]
C --> C2["energy_dist"]
C --> C3["kolmogorov_smirnov_stat"]
D --> D1["pearson_r"]
D --> D2["spearman_r"]
E --> E1["mean_squared_error"]
E --> E2["root_mean_squared_error"]
E --> E3["mean_absolute_error"]
E --> E4["mape"]
E --> E5["r2_score"]
E --> E6["max_error"]
E --> E7["median_absolute_error"]
F --> F1["cosine_similarity"]
F --> F2["mmd_rbf"]
F --> F3["total_flux_ratio"]
F --> F4["spectral_shape_similarity"]
G --> G1["chi_squared"]
G --> G2["g_test"]
G --> G3["freeman_tukey"]
G --> G4["cressie_read"]
H --> H1["anderson_darling"]
H --> H2["wilcoxon_test"]
H --> H3["mannwhitneyu_test"]
H --> H4["standardized_mean_difference"]
I --> I1["fluence_averaged_energy"]
I --> I2["energy_group_fluence"]
I --> I3["dose_averaged_energy"]
I --> I4["ambient_dose_equivalent_rate"]
J --> J1["fluence_difference_percent"]
J --> J2["energy_group_fluence_diff"]
J --> J3["dose_difference_percent"]
J --> J4["fluence_averaged_energy_diff"]
J --> J5["dose_averaged_energy_diff"]
J --> J6["log_lethargy_correlation"]
J --> J7["peak_location_error"]
J --> J8["peak_width_error"]
J --> J9["dose_weighted_error"]
J --> J10["response_matrix_consistency"]
style A fill:#4a90d9,color:#fff
Metrics Reference#
Category |
Metric Key |
Description |
Range |
|---|---|---|---|
Entropy |
|
Kullback-Leibler divergence D_KL(p‖q) |
[0, ∞) |
|
Cross-entropy H(p,q) = -∑p·log(q) |
[0, ∞) |
|
|
Relative cross-entropy excess (%) |
[0, ∞) |
|
Distribution |
|
Earth mover’s / Wasserstein distance |
[0, ∞) |
|
Energy distance between distributions |
[0, ∞) |
|
|
Kolmogorov-Smirnov D-statistic |
[0, 1] |
|
Correlation |
|
Pearson correlation coefficient |
[-1, 1] |
|
Spearman rank correlation |
[-1, 1] |
|
Error |
|
Mean squared error |
[0, ∞) |
|
Root mean squared error |
[0, ∞) |
|
|
Mean absolute error |
[0, ∞) |
|
|
Mean absolute percentage error (%) |
[0, 100] |
|
|
R² (coefficient of determination) |
(-∞, 1] |
|
|
Maximum residual error |
[0, ∞) |
|
|
Median absolute error |
[0, ∞) |
|
Similarity |
|
Cosine similarity cos(θ) |
[0, 1] |
|
Maximum Mean Discrepancy (RBF kernel) |
[0, ∞) |
|
|
Ratio of total fluxes sum(p)/sum(q) |
(0, ∞) |
|
|
Similarity of normalized spectral shapes |
[0, 1] |
|
Chi-squared |
|
Pearson’s chi-squared statistic |
[0, ∞) |
|
G-test (log-likelihood ratio) |
[0, ∞) |
|
|
Freeman-Tukey statistic |
[0, ∞) |
|
|
Cressie-Read power divergence |
[0, ∞) |
|
Statistical |
|
Anderson-Darling k-sample statistic |
[0, ∞) |
|
Wilcoxon signed-rank test statistic |
[0, ∞) |
|
|
Mann-Whitney U test statistic |
[0, ∞) |
|
|
Cohen’s d (standardized mean difference) |
(-∞, ∞) |
|
EURADOS Integral |
|
Fluence-averaged energy ⟨E⟩, single spectrum (MeV) |
[0, ∞) |
|
Fluence rate per energy group (thermal/epithermal/fast), single spectrum |
[0, ∞) |
|
|
H*(10)-averaged energy ⟨E⟩_H, single spectrum (MeV) |
[0, ∞) |
|
|
Ambient dose equivalent rate H*(10), single spectrum |
[0, ∞) |
|
Spectral Diagnostics |
|
Relative difference in total fluence (%) |
[0, ∞) |
|
Fluence rate difference per energy group (%) |
[0, ∞) |
|
|
Relative difference in ambient dose equivalent H*(10) (%) |
[0, ∞) |
|
|
Difference in fluence-averaged energy (%) |
[0, ∞) |
|
|
Difference in H*(10)-averaged energy (%) |
[0, ∞) |
|
|
Pearson correlation in log(E)·Φ(E) coordinates |
[-1, 1] |
|
|
Relative error in peak location (%) |
[0, ∞) |
|
|
Relative error in FWHM (%) |
[0, ∞) |
|
|
Dose-weighted mean squared error |
[0, ∞) |
|
|
Consistency of unfolded spectrum with measured readings (χ²) |
[0, ∞) |
The 27 simple metrics are always available. The EURADOS integral quantities and spectral diagnostics additionally require an energy grid and, for the dose-related entries, the packaged ICRP-116 conversion coefficients.
Performance#
All iterative solvers use Numba JIT-compiled inner loops when numba is installed (including Landweber and D’Agostini Bayes), with automatic fallback to pure Python.
Solver |
Before |
After |
Speedup |
|---|---|---|---|
Doroshenko |
40.6 ms |
0.8 ms |
50x |
Kaczmarz |
1.4 ms |
0.1 ms |
14x |
MLEM |
2.7 ms |
0.4 ms |
7x |
GRAVEL |
~2 ms |
0.6 ms |
3x |
Landweber |
2.8 ms |
0.23 ms |
12x |
Bayes (D’Agostini) |
7.9 ms |
0.36 ms |
22x |
cvxpy |
84 ms |
78 ms |
~1x (external solver) |
qpsolvers |
1.7 ms |
1.6 ms |
~1x (external solver) |
Install numba for the best performance:
pip install bssunfold[numba]
The JIT functions are defined in bssunfold.core._numba_jit and use
@njit(cache=True) for automatic disk caching of compiled code.