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. .. contents:: :local: :depth: 2 Unfolding Methods ----------------- All 88 methods are accessible as instance methods on the :class:`bssunfold.Detector` class. They are organised into the following categories: .. mermaid:: 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 ~~~~~~~~~~~~~~~~ .. list-table:: Complete method reference :header-rows: 1 :widths: 5 4 4 15 8 12 * - # - Method - Category - Unique Parameters - Dependencies - Description * - 1 - ``unfold_cvxpy`` - Tikhonov - `regularization`, `norm` (1/2), `solver`, `regularization_method` - cvxpy - Convex optimization with Tikhonov regularization. See :ref:`math-tikhonov`. * - 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 :ref:`math-tikhonov`. * - 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 :ref:`math-tikhonov`. * - 6 - ``unfold_landweber`` - Iterative - `max_iterations`, `tolerance` - — - Landweber fixed-point iteration. See :ref:`math-iterative`. * - 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 :ref:`math-em`. * - 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 :ref:`math-maxent`. * - 16 - ``unfold_statreg`` - Statistical Reg. - `unfoldermethod` (EmpiricalBayes/...), `regularization`, `basis_name`, `boundary`, `derivative_degree` - — - Turchin's statistical regularization. See :ref:`math-tikhonov`. * - 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 :ref:`math-parametric`. * - 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 :ref:`math-tikhonov`. * - 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 :ref:`math-krylov`. * - 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 :ref:`math-tikhonov`. * - 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 :ref:`math-iterative`. * - 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 :ref:`math-bayesian`. * - 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 :ref:`math-bayesian`. * - 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 :ref:`math-parametric`. * - 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 :doc:`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, https://github.com/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, https://github.com/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 :ref:`math-tikhonov`. * - 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, https://github.com/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 :ref:`math-tikhonov`. * - 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 :ref:`genindex` or :doc:`detector` for complete API signatures. Regularization Parameter Selection ----------------------------------- Nine automatic regularization parameter selection methods are available via :func:`bssunfold.core.regularization.select_regularization_parameter`: .. list-table:: :header-rows: 1 :widths: 20 15 65 * - 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: .. list-table:: Built-in RF datasets :header-rows: 1 :widths: 12 20 12 15 30 * - 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. .. code-block:: python 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. .. list-table:: Dose conversion coefficient datasets :header-rows: 1 :widths: 20 15 25 20 20 * - 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. .. code-block:: python 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). .. mermaid:: 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 ~~~~~~~~~~~~~~~~~ .. list-table:: Complete metrics reference :header-rows: 1 :widths: 5 6 12 5 * - 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. .. list-table:: Benchmark results (60-bin grid, 500 iterations, macOS arm64) :header-rows: 1 :widths: 20 15 15 15 * - 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: .. code-block:: bash pip install bssunfold[numba] The JIT functions are defined in :mod:`bssunfold.core._numba_jit` and use ``@njit(cache=True)`` for automatic disk caching of compiled code.