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#

Complete method reference#

#

Method

Category

Unique Parameters

Dependencies

Description

1

unfold_cvxpy

Tikhonov

regularization, norm (1/2), solver, regularization_method

cvxpy

Convex optimization with Tikhonov regularization. See Variational (Tikhonov-Type) Methods.

2

unfold_qpsolvers

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

unfold_tsvd

Tikhonov

method (l_curve/gcv/discrepancy/energy/median/donoho), k, threshold, noise_level

Truncated SVD with automatic k-selection

4

unfold_lanczos

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

unfold_tikhonov_legendre

Tikhonov

delta, n_polynomials

Tikhonov regularization in Legendre polynomial basis. See Variational (Tikhonov-Type) Methods.

6

unfold_landweber

Iterative

max_iterations, tolerance

Landweber fixed-point iteration. See Algebraic Iterative Methods.

7

unfold_mlem

Iterative

max_iterations, tolerance

Pure-NumPy MLEM (expectation maximization)

8

unfold_mlem_stop

Iterative

max_iterations, cps_crossover, j_threshold

MLEM with J-factor early stopping criterion (Montgomery et al. 2020). See Poisson-Likelihood (EM) Family.

9

unfold_mlem_odl

Iterative

max_iterations, tolerance

odl

MLEM via ODL operator framework

10

unfold_gravel

Iterative

max_iterations, tolerance, regularization

GRAVEL algorithm with relative entropy weighting

11

unfold_doroshenko

Iterative

max_iterations, tolerance, regularization

Coordinate-update iterative method

12

unfold_kaczmarz

Iterative

max_iterations, omega, tolerance

ART (Algebraic Reconstruction Technique)

13

unfold_bayes

Bayesian

max_iterations, tolerance

D’Agostini Bayesian iterative unfolding

14

unfold_bayes_spline_regularization

Bayesian

max_iterations, tolerance, spline_degree, spline_smooth

Bayes iteration with spline smoothing

15

unfold_maxed

MaxEnt

sigma_factor, max_iterations, tolerance

Maximum entropy deconvolution (Reginatto & Goldhagen). See Maximum Entropy and Information Divergence.

16

unfold_statreg

Statistical Reg.

unfoldermethod (EmpiricalBayes/…), regularization, basis_name, boundary, derivative_degree

Turchin’s statistical regularization. See Variational (Tikhonov-Type) Methods.

17

unfold_reconst

Statistical Reg.

alpha, beta, max_iter_alpha, max_iter_beta, tol_alpha, tol_beta

Fortran STREG1 port: auto α/β with discrepancy principle & ω-criterion

18

unfold_lmfit

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

unfold_scipy_direct_method

Optimization

method (cg/gmres/lsqr/lsmr/minres), tolerance, max_iterations

Direct SciPy linear solvers

20

unfold_combined

Pipeline

pipeline (list of {method, params} dicts)

Sequential multi-method pipeline

21

unfold_parametric

Parametric

parametric_method, optimizer, solver_backend, initial_params

lmfit, cvxpy, qpsolvers

FRUIT-style thermal/epithermal/fast model. See Parametric Models.

22

unfold_parametric_cvxpy

Parametric

parametric_method, initial_params, solver_backend

cvxpy

SQP solver using cvxpy for parametric fitting

23

unfold_parametric_qpsolvers

Parametric

parametric_method, initial_params, solver_backend

qpsolvers

SQP solver using qpsolvers backends

24

unfold_parametric_combined

Parametric

parametric_method, initial_params, solver_backend

lmfit, cvxpy, qpsolvers

lmfit first-pass + QP refinement

25

unfold_parametric2

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

unfold_fruit_like

Parametric

initial_params, max_iterations, tolerance

FRUIT-like model: Maxwellian thermal + 1/E epithermal + evaporation fast

27

unfold_hybrid_parametric

Parametric

refinement_method (landweber/mlem), max_iterations, tolerance

Parametric initial guess refined by Landweber or MLEM

28

unfold_bayesian_parametric

Parametric

n_samples, burn_in, proposal_scale, prior_mean, prior_std

Metropolis-Hastings MCMC for spectral parameter estimation

29

unfold_mystic

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

unfold_smt

Optimization

nonneg, timeout_ms

z3-solver

Exact SMT solving of A·x = b (integer/rational) with fluence minimization

31

unfold_genetic

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

unfold_cs

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

unfold_scip

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

unfold_docplex

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

unfold_epic

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

unfold_interpret

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

unfold_cgls

Krylov/iterative

max_iterations, tolerance, regularization, smoothness_order, noise_level

CGLS (conjugate gradient for least squares) with optional ||L x||^2 Tikhonov term and discrepancy-principle stopping; nonnegative spectrum via clamping. See Spectral Filtering and Krylov Methods.

38

unfold_gks

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

unfold_tikhonov_tv

Regularization

epsilon, mu, max_iterations, type_ (TT/TV/T), beta (float or 'adapt'), zthr, tolerance, noise_level

Noise-constrained Tikhonov+TV via ADMM (Gazzola & Gholami); adaptive balancing of the TV and Tikhonov terms. See Variational (Tikhonov-Type) Methods.

40

unfold_sandii

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

unfold_bunki

Multi-sphere ratio

smoothing, max_iterations, tolerance, noise_level

BUNKI (SPUNIT) iterative unfolding with three-point smoothing (RSICC PSR-266)

42

unfold_bunkiut

Multi-sphere ratio

smoothing, max_iterations, tolerance, noise_level

BUNKI-UT (BON31G) modernised unfolding (University of Texas)

43

unfold_osem

EM family

max_iterations, n_subsets, tolerance, noise_level

Ordered-subset expectation maximisation (Hudson & Larkin 1994); n_subsets=1 reduces to standard MLEM

44

unfold_mapem

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

unfold_bsrem

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

unfold_sart

Iterative

max_iterations, tolerance, relaxation, noise_level

Simultaneous algebraic reconstruction technique: relaxed, residual-normalised additive correction

47

unfold_ferdor

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

unfold_directed_divergence

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

unfold_rebunki

Multi-sphere ratio

smoothing, max_iterations, tolerance

ReBUNKI (SPUNIT) few-iteration spectral stripping with three-point smoothing and ~1% convergence tolerance

49

unfold_nsduaz

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

unfold_express

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

unfold_fista

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

unfold_hybrid_gmres

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

unfold_imaxed

MaxEnt

sigma_factor, max_iterations, tolerance

Improved MAXED with gradient-based log-space optimization and cross-entropy regularization (Wong 2024)

53

unfold_amaxed

MaxEnt

sigma_factor, target_chi2, max_iterations, tolerance

Alternative MAXED with reversed cross-entropy definition using Lagrangian multipliers (Wong 2024)

54

unfold_amaxed_regularization

MaxEnt

sigma_factor, tau, max_iterations, tolerance

AMAXED with Tikhonov-style simultaneous minimization of chi-squared and cross-entropy (Wong 2024)

55

unfold_maeo

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

unfold_mcmc

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

unfold_zfit

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

unfold_qubo

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

unfold_odl_pdhg

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

unfold_odl_douglas_rachford

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

unfold_cascade

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

unfold_composite

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

unfold_crystal_ball

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

unfold_rfsp_jul

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

unfold_staysl

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

unfold_mystic_hybrid

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

unfold_ensemble

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

unfold_iterative_refinement

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

unfold_randomized_kaczmarz

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

unfold_eki

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

unfold_binned

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 data/bin_lookup.json

72

unfold_nnksvd

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 — nnls_topk (proposed), omp, nn_omp; default training signals are log-spaced Gaussian bumps on the energy grid; training-sample prior via prior_wt

73

unfold_nspline

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 nev <= 1 + 2/sqrt(N) acceptability; BARS-5/IGRIK/YAGUAR knot presets from the paper. See Parametric Models.

74

unfold_mlem_bs

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 P(b) = ||D^(2) b||^2 (Eq. 5) and the Szkutnik (2005) sieve restriction to non-negative coefficients; iterations, N_s and beta are selected by minimizing the K_S statistic (Eq. 6) with auto_params=True; optional Poisson-bootstrap confidence intervals (Eqs. 7-9). See B-spline MLEM unfolding (MLEM-BS).

75

unfold_gnowee

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

unfold_nnqp

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 min 0.5 x^T Q x + f^T x  s.t.  x >= 0, applied to the regularised BSS least-squares problem Q = A^T A + α L^T L + α0 I, f = -A^T b. Pure-NumPy port of the original nnqp.py (which used numba); drops the numba hard-dependency in favour of a vectorised inner loop. See Variational (Tikhonov-Type) Methods.

77

unfold_qpmad

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 min 0.5 ||A x - b||^2 + α/2 ||L x||^2 + α0/2 ||x||^2  s.t.  lb <= x <= ub (default: x >= 0) by recasting it as min 0.5 x^T H x + g^T x with H = A^T A + α L^T L + α0 I (symmetric PD). The default backend='python' uses a self-contained NumPy port of an active-set QP solver (Nocedal & Wright, Numerical Optimization ch. 16.4). When the upstream qpmad C++ library with Python bindings is installed, backend='qpmad' calls it directly. See Variational (Tikhonov-Type) Methods.

78

unfold_pgd

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 (duality_gap).

79

unfold_frank_wolfe

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

unfold_mirror_descent

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

unfold_admm

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

unfold_lbfgsb

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

unfold_coordinate_descent

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

unfold_subgradient

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

unfold_extragradient

Optimization course

noise_level, step_size, max_iterations, tolerance, variance_reduction

Korpelevich extragradient (lecture 13 / homework 20) on the robust saddle formulation min_{x>=0} max_{||y||<=1} 1/2||Ax-b||^2 + delta y^T(Ax-b) — least squares made robust against measurement noise of L2 norm up to delta.

86

unfold_osem_anlm

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 h1 = 0.5 sigma; stage 2 point-wise h2(i) = sqrt(sum_j w(i,j)^2 sigma^2), article eq. 6) applied after every subset update or once post-reconstruction; log-space filtering by default.

87

unfold_louhi

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 min ||(b-Aphi)/sigma||^2 + lambda^2 ||L(phi-phi0)||^2 s.t. phi >= 0 via Hildreth’s iterative coordinate QP; identity/first/second-difference smoothing operators anchored to the a-priori spectrum; auto_smooth=True adjusts lambda by golden-section regression so the data chi-square reaches its expected value; louhi_covariance propagates uncertainties on the active set.

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

'lcurve'

Hansen 1992

L-curve corner heuristic (max distance from chord in log-log)

'gcv'

Golub et al. 1979

Generalized Cross Validation (minimises GCV function)

'dp'

Morozov 1966

Discrepancy principle (residual ≈ noise level)

'cosine'

Maximises cosine similarity to a reference spectrum

'quasi_optimality'

Hochstenbach & Reichel 2015

Minimises the noise component in the SVD basis

'ncp'

Normalized Cumulative Periodogram: KS-test on residual whiteness

'snr'

Maximises signal-to-noise ratio in the Tikhonov solution

'weighted_gcv_poisson'

GCV with Poisson variance weights for heteroscedastic noise

'kfold_cv'

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:

Built-in RF datasets#

Dataset

Source

Detectors

Energy Range

Notes

RF_GSF

GSF (Germany)

10 (0in–18in)

1e-9 – 631 MeV

Standard range

RF_PTB

PTB (Germany)

15 (0in–18in)

1e-9 – 631 MeV

Standard range

RF_LANL

LANL (USA)

11 (3in–18in)

1e-9 – 631 MeV

Includes Pb-shielded (9inPb, 12inPb, 18inPb)

RF_JINR

JINR (Dubna)

9 (0in–12in)

1e-9 – 631 MeV

Includes Cd-covered (Cd0in) and Pb-shielded (10inPb)

RF_FERMILAB

Fermilab (USA)

8 (0in–18in)

1e-9 – 631 MeV

Standard range

RF_EURADOS

EURADOS round-robin

13 (0in–12in)

1e-9 – 20 MeV

Narrower range; includes Cd2in, 3.5in, 4.5in

RF_IHEP

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.

Dose conversion coefficient datasets#

Dataset

Standard

Quantities

Energy Range

Notes

ICRP116 (default)

ICRP-116

AP, PA, LLAT, RLAT, ISO, ROT

1e-9 – 631 MeV

Standard range

ICRP74_effective

ICRP-74

AP, PA, RLAT, ROT, ISO

1e-9 – 398 MeV

Effective dose

NRB99_2009_effective

NRB99-2009

AP, ISO

25 eV – 20 MeV

Limited range

ICRP74_operational

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#

Complete metrics reference#

Category

Metric Key

Description

Range

Entropy

kl_divergence

Kullback-Leibler divergence D_KL(p‖q)

[0, ∞)

cross_entropy

Cross-entropy H(p,q) = -∑p·log(q)

[0, ∞)

entropy_difference_percent

Relative cross-entropy excess (%)

[0, ∞)

Distribution

wasserstein_dist

Earth mover’s / Wasserstein distance

[0, ∞)

energy_dist

Energy distance between distributions

[0, ∞)

kolmogorov_smirnov_stat

Kolmogorov-Smirnov D-statistic

[0, 1]

Correlation

pearson_r

Pearson correlation coefficient

[-1, 1]

spearman_r

Spearman rank correlation

[-1, 1]

Error

mean_squared_error

Mean squared error

[0, ∞)

root_mean_squared_error

Root mean squared error

[0, ∞)

mean_absolute_error

Mean absolute error

[0, ∞)

mape

Mean absolute percentage error (%)

[0, 100]

r2_score

R² (coefficient of determination)

(-∞, 1]

max_error

Maximum residual error

[0, ∞)

median_absolute_error

Median absolute error

[0, ∞)

Similarity

cosine_similarity

Cosine similarity cos(θ)

[0, 1]

mmd_rbf

Maximum Mean Discrepancy (RBF kernel)

[0, ∞)

total_flux_ratio

Ratio of total fluxes sum(p)/sum(q)

(0, ∞)

spectral_shape_similarity

Similarity of normalized spectral shapes

[0, 1]

Chi-squared

chi_squared

Pearson’s chi-squared statistic

[0, ∞)

g_test

G-test (log-likelihood ratio)

[0, ∞)

freeman_tukey

Freeman-Tukey statistic

[0, ∞)

cressie_read

Cressie-Read power divergence

[0, ∞)

Statistical

anderson_darling

Anderson-Darling k-sample statistic

[0, ∞)

wilcoxon_test

Wilcoxon signed-rank test statistic

[0, ∞)

mannwhitneyu_test

Mann-Whitney U test statistic

[0, ∞)

standardized_mean_difference

Cohen’s d (standardized mean difference)

(-∞, ∞)

EURADOS Integral

fluence_averaged_energy

Fluence-averaged energy ⟨E⟩, single spectrum (MeV)

[0, ∞)

energy_group_fluence

Fluence rate per energy group (thermal/epithermal/fast), single spectrum

[0, ∞)

dose_averaged_energy

H*(10)-averaged energy ⟨E⟩_H, single spectrum (MeV)

[0, ∞)

ambient_dose_equivalent_rate

Ambient dose equivalent rate H*(10), single spectrum

[0, ∞)

Spectral Diagnostics

fluence_difference_percent

Relative difference in total fluence (%)

[0, ∞)

energy_group_fluence_diff

Fluence rate difference per energy group (%)

[0, ∞)

dose_difference_percent

Relative difference in ambient dose equivalent H*(10) (%)

[0, ∞)

fluence_averaged_energy_diff

Difference in fluence-averaged energy (%)

[0, ∞)

dose_averaged_energy_diff

Difference in H*(10)-averaged energy (%)

[0, ∞)

log_lethargy_correlation

Pearson correlation in log(E)·Φ(E) coordinates

[-1, 1]

peak_location_error

Relative error in peak location (%)

[0, ∞)

peak_width_error

Relative error in FWHM (%)

[0, ∞)

dose_weighted_error

Dose-weighted mean squared error

[0, ∞)

response_matrix_consistency

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.

Benchmark results (60-bin grid, 500 iterations, macOS arm64)#

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.