Detector Class#
- class bssunfold.Detector(response_functions: DataFrame | dict | None = None, E_MeV: ndarray | None = None, sensitivities: dict | ndarray | None = None, cc_type: str = 'ICRP116')[source]#
Bases:
objectClass for neutron detector operations and spectrum unfolding.
This class provides methods for neutron spectrum unfolding using various algorithms and includes tools for dose rate calculations based on ICRP-116 conversion coefficients.
- Parameters:
response_functions (pd.DataFrame, dict, optional) – Response functions data. Can be: - pandas DataFrame with ‘E_MeV’ column and detector columns. - dict with ‘E_MeV’ key (array) and detector names as keys (arrays). If None, default GSF response functions are used.
E_MeV (np.ndarray, optional) – Energy grid in MeV. Required if response_functions is not provided and sensitivities is provided.
sensitivities (dict or np.ndarray, optional) – Detector sensitivities. If dict, keys are detector names and values are arrays of same length as E_MeV. If 2D array, shape (n_energy, n_detectors). Required if response_functions is not provided and E_MeV is provided.
- Variables:
Amat (np.ndarray) – Response matrix with logarithmic energy step corrections
E_MeV (np.ndarray) – Energy grid in MeV
detector_names (List[str]) – Names of available detectors/spheres
log_steps (np.ndarray) – Logarithmic steps for each energy point
sensitivities (Dict[str, np.ndarray]) – Dictionary mapping detector names to their sensitivity arrays
cc_icrp116 (Dict[str, np.ndarray]) – Raw (non-interpolated) conversion coefficients for dose calculation
cc_type (str) – Name of the dose conversion coefficient dataset (default: “ICRP116”)
n_detectors (int) – Number of available detectors (property)
n_energy_bins (int) – Number of energy bins (property)
Examples
>>> from bssunfold import Detector >>> # Create detector with default GSF response functions >>> detector = Detector() >>> # Perform unfolding >>> readings = {'sphere_1': 100.5, 'sphere_2': 85.3} >>> result = detector.unfold_cvxpy(readings)
- __init__(response_functions: DataFrame | dict | None = None, E_MeV: ndarray | None = None, sensitivities: dict | ndarray | None = None, cc_type: str = 'ICRP116')[source]#
Initialize Detector with response functions.
- Parameters:
response_functions (pd.DataFrame, dict, optional) – Response functions data.
E_MeV (np.ndarray, optional) – Energy grid in MeV.
sensitivities (dict or np.ndarray, optional) – Detector sensitivities.
cc_type (str, optional) – Name of the dose conversion coefficient dataset to use. Options: “ICRP116”, “ICRP74_effective”, “NRB99_2009_effective”, “ICRP74_operational”. Default: “ICRP116”.
- Raises:
ValueError – If E_MeV is not a 1D array or has less than 2 energy points, or if input data is inconsistent.
TypeError – If response_functions has an unsupported type.
- _process_input(response_functions: DataFrame | dict | None, E_MeV: ndarray | None, sensitivities: dict | ndarray | None) DataFrame[source]#
Convert various input formats to a unified DataFrame.
- property n_detectors: int#
Number of available detectors.
- property n_energy_bins: int#
Number of energy bins.
- set_dose_coefficients(name: str) None[source]#
Change the dose conversion coefficient dataset.
- Parameters:
name (str) –
Name of the coefficient dataset. Options:
"ICRP116": ICRP-116 effective dose (default)"ICRP74_effective": ICRP-74 effective dose"NRB99_2009_effective": NRB99-2009 effective dose"ICRP74_operational": ICRP-74 operational quantities
- Raises:
ValueError – If the coefficient name is not found.
Examples
>>> detector = Detector() >>> detector.set_dose_coefficients("ICRP74_effective") >>> detector.cc_type 'ICRP74_effective'
- _get_interpolated_cc() dict[str, ndarray][source]#
Get conversion coefficients interpolated to this detector’s energy grid.
- Returns:
Interpolated conversion coefficients on self.E_MeV.
- Return type:
Dict[str, np.ndarray]
- _validate_readings(readings: dict[str, float]) dict[str, float][source]#
Validate detector readings.
- _build_system(readings: dict[str, float]) tuple[ndarray, ndarray, list[str]][source]#
Build response matrix A and measurement vector b.
- _standardize_output(spectrum: ndarray, A: ndarray, b: ndarray, selected: list[str], method: str, **kwargs) dict[str, Any][source]#
Create standardized output dictionary.
- _convert_rf_to_matrix_variable_step(rf_df: DataFrame, Emin: float = 1e-09) tuple[ndarray, ndarray, list[str], ndarray][source]#
Convert response functions to matrix with variable step correction.
- get_result(key: str | None = None) dict[str, Any] | None[source]#
Get unfolding result from history.
- _normalize_initial_spectrum(initial_spectrum: ndarray | dict | DataFrame | None) ndarray | None[source]#
Normalize initial spectrum to detector’s energy grid.
- _cosine_similarity(spectrum1: ndarray, spectrum2: ndarray) float[source]#
Compute cosine similarity between two spectra.
- _add_noise(readings: dict[str, float], noise_level: float = 0.01, random_state: int | None = None) dict[str, float][source]#
Add Gaussian noise to readings.
- Parameters:
readings (Dict[str, float]) – Original readings.
noise_level (float, optional) – Relative noise level (default: 0.01).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Noisy readings.
- Return type:
Dict[str, float]
- _max_energy_mask(max_neutron_energy: float | None) ndarray[source]#
Boolean mask of energy bins with
E_MeV <= max_neutron_energy.Returns an all-True mask when
max_neutron_energyisNone(i.e. no upper cutoff is applied and the full grid is used).
- _subdetector(mask: ndarray) Detector[source]#
Return a new Detector restricted to the bins selected by
mask.
- _expand_result(result: dict[str, Any], mask: ndarray, readings: dict[str, float]) dict[str, Any][source]#
Expand a reduced-grid unfolding result back to the full energy grid.
Bins excluded by
mask(i.e.E_MeV > max_neutron_energy) are set to zero. Dose rates, effective readings and the residual are recomputed on the full grid so that all downstream quantities stay consistent. Whenmaskis allTrue(no cutoff) the result is left unchanged apart from a consistent recomputation of the derived quantities.
- unfold_cvxpy(readings: dict[str, float], initial_spectrum: ndarray | None = None, regularization: float = 0.0001, norm: int = 2, solver: str = 'default', calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, regularization_method: str = 'manual', noise_var: float | None = None, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using convex optimization (cvxpy).
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
regularization (float, optional) – Regularization parameter (default: 1e-4).
norm (int, optional) – Norm type (1 for L1, 2 for L2), default: 2.
solver (str, optional) – Solver to use (‘ECOS’ or ‘default’).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
regularization_method (str, optional) – Method for selecting regularization parameter.
noise_var (float, optional) – Noise variance for discrepancy principle.
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_landweber(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 1000, tolerance: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using Landweber iteration method.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
max_iterations (int, optional) – Maximum iterations (default: 1000).
tolerance (float, optional) – Convergence tolerance (default: 1e-6).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_mlem(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 1000, tolerance: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using MLEM algorithm.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
max_iterations (int, optional) – Maximum iterations (default: 1000).
tolerance (float, optional) – Convergence tolerance (default: 1e-6).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_amg(readings: dict[str, float], initial_spectrum: ndarray | None = None, method: str = 'cg', preconditioner: str = 'amg', omega: float = 1.0, max_iterations: int = 200, tolerance: float = 1e-10, outer_iterations: int = 3, nonnegativity: bool = True, regularization: float | None = None, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using AMG/stationary-preconditioned Krylov iteration.
Python analogue of the
Rlinsolveiterative-solver family and of algebraic multigrid preconditioning: the normal equations of the least-squares unfolding problem are solved withcg/bicgstab/gmresaccelerated by a preconditioner approximating(A^T A)^-1– algebraic multigrid (optionalpyamgdependency) or one sweep of a classical stationary iteration (Jacobi, Gauss-Seidel, SOR, SSOR). Non-negativity is enforced with projected outer restarts.- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial guess for the Krylov iteration.
method (str, optional) – Krylov solver:
"cg"(default),"bicgstab"or"gmres".preconditioner (str, optional) –
"amg"(default),"jacobi","gs","sor","ssor"or"none"."amg"falls back to Jacobi with a warning whenpyamgis not installed.omega (float, optional) – Relaxation factor for SOR/SSOR (default: 1.0).
max_iterations (int, optional) – Maximum Krylov iterations per restart (default: 200).
tolerance (float, optional) – Relative residual tolerance (default: 1e-10).
outer_iterations (int, optional) – Number of projected non-negativity restarts (default: 3).
nonnegativity (bool, optional) – Clamp between restarts (default: True).
regularization (float or None, optional) – Tikhonov damping for the normal equations;
None(default) selects1e-4 * mean(diag(A^T A))automatically,0.0disables the damping.calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Relative noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_pspline_reml(readings: dict[str, float], initial_spectrum: ndarray | None = None, n_basis: int | None = None, spline_order: int = 4, diff_order: int = 2, knot_spacing: str = 'auto', weights: str | ndarray | None = 'uniform', lam_relative: float | None = None, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using P-spline mixed-model REML smoothing selection.
Python analogue of the R package
LMMsolver(Boer 2023): the spectrum is represented as a P-spline, the spline coefficients are split into an unpenalised fixed part (polynomial trend, the null space of the difference penalty) and a penalised random part (the range space), and the smoothing parameter is the variance ratio estimated by maximising the REML profile likelihood of the resulting linear mixed model. The Henderson mixed model equations are then solved for the final spectrum.- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Unused (kept for API compatibility).
n_basis (Optional[int], optional) – Dimension of the B-spline space (default:
min(n//2, 30)).spline_order (int, optional) – B-spline order (default: 4, cubic).
diff_order (int, optional) – Difference order of the P-spline penalty (default: 2).
knot_spacing (str, optional) – Interior knot placement:
"auto"(default),"uniform"or"log".weights (str or np.ndarray, optional) –
"uniform"(default),"poisson"(w_i = 1 / b_i) or an explicit positive weight array.lam_relative (Optional[float], optional) – Fixed relative smoothing parameter; skips REML selection.
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Relative noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary with additional keys
lam,lam_relative,reml_loglik,sigma2,edanded_norm.- Return type:
Dict[str, Any]
- unfold_gee(readings: dict[str, float], initial_spectrum: ndarray | None = None, family: str = 'gaussian', corstr: str = 'exchangeable', regularization: float = 0.0001, max_iterations: int = 100, tolerance: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold by generalized estimating equations (R
geeport).The detector spheres are treated as a correlated cluster of observations of the measurement vector
b = A x; the GEE score equationsA^T R(alpha)^{-1} (b - A x) - lam G x = 0are solved by iterated reweighted least squares with an exchangeable / AR-1 working correlation, and robust Liang-Zeger sandwich uncertainties are reported for the spectrum.- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess (used as starting point).
family (str, optional) – Quasi-likelihood family:
"gaussian"(default),"poisson"or"gamma".corstr (str, optional) – Working correlation:
"exchangeable"(default),"ar1"or"independence".regularization (float, optional) – Relative ridge on the second-difference roughness penalty (default: 1e-4).
max_iterations (int, optional) – Maximum GEE iterations (default: 100).
tolerance (float, optional) – Relative convergence tolerance (default: 1e-6).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Relative noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary with additional keys
alpha,phi,family,corstr,robust_se,naive_se,spectrum_uncert_robust,pearson_chi2andgee_converged.- Return type:
Dict[str, Any]
- unfold_uno(readings: dict[str, float], initial_spectrum: ndarray | None = None, preset: str = 'filter_sqp', weights: str | ndarray | None = 'uniform', regularization: float = 0.001, hessian: str = 'exact', max_iterations: int = 300, tolerance: float = 1e-10, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold with an Uno-style Lagrange-Newton NLP preset.
Python analogue of the R package
Uno(Vanaret & Leyffer 2024): the unfolding problem is solved as the constrained non-linear programmin 1/2||W(Ax-b)||^2 + lam/2||D2 x||^2 s.t. x >= 0either by thefilterSQPpreset (exact Hessian, filter globalisation; the convex objective is solved exactly in one QP sub-problem) or by the IPOPT-like primal-dual interior-point method (exact or BFGS Hessian).- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess (interior-point start).
preset (str, optional) –
"filter_sqp"(default) or"ipopt_like".weights (str or np.ndarray, optional) –
"uniform"(default),"poisson"or an explicit array.regularization (float, optional) – Relative roughness ridge (default: 1e-3).
hessian (str, optional) –
"exact"(default) or"bfgs"(interior-point preset).max_iterations (int, optional) – Maximum iterations (default: 300).
tolerance (float, optional) – KKT tolerance (default: 1e-10).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Relative noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary with additional keys
uno_preset,objective,constraint_violation,dual_infeasibilityanduno_converged.- Return type:
Dict[str, Any]
- unfold_qpsolvers(readings: dict[str, float], initial_spectrum: ndarray | None = None, regularization: float = 0.0001, norm: int = 2, solver: str = 'osqp', calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, regularization_method: str = 'manual', noise_var: float | None = None, smoothness_order: int = 0, smoothness_weight: float = 1.0, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using qpsolvers with regularization selection.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess.
regularization (float, optional) – Regularization parameter, default: 1e-4.
norm (int, optional) – Norm type (1 for L1, 2 for L2), default: 2.
solver (str, optional) – QP solver name, default: ‘osqp’.
calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty, default: False.
noise_level (float, optional) – Noise level for Monte-Carlo, default: 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples, default: 100.
save_result (bool, optional) – Save result to history, default: False.
regularization_method (str, optional) – Method for selecting regularization parameter. Options: ‘manual’, ‘cosine’, ‘gcv’, ‘lcurve’, ‘dp’.
noise_var (float, optional) – Noise variance for discrepancy principle (‘dp’ method).
smoothness_order (int, optional) – Smoothness constraint order (0, 1, or 2), default: 0.
smoothness_weight (float, optional) – Weight for smoothness term, default: 1.0.
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results including spectrum, residuals, and metadata.
- Return type:
Dict[str, Any]
- unfold_nnqp(readings: dict[str, float], initial_spectrum: ndarray | None = None, regularization: float = 0.0001, smoothness_order: int = 0, smoothness_weight: float = 1.0, tol: float = 1e-06, max_iterations: int = 10000, floor: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using NNQP (non-negative QP by coordinate descent).
Solves
min 0.5 ||A x - b||^2 + alpha/2 ||L x||^2 + alpha0/2 ||x||^2subject tox >= 0using the NNQP coordinate-descent solver of Giovannucci & Pehlevan (simonsfoundation/NNQP).- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Warm-start spectrum. If None, the NNQP solver uses a uniform random initial guess.
regularization (float, optional) – Tikhonov / smoothness regularization weight, default 1e-4.
smoothness_order (int, optional) – Smoothness penalty order (0, 1 or 2), default 0.
smoothness_weight (float, optional) – Weight for the smoothness term, default 1.0.
tol (float, optional) – Convergence tolerance, default 1e-6.
max_iterations (int, optional) – Iteration cap, default 10 000.
floor (float, optional) – Diagonal regularization floor added to Q to guarantee strict positive-definiteness, default 1e-6.
calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty, default False.
noise_level (float, optional) – Noise level for Monte-Carlo, default 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples, default 100.
save_result (bool, optional) – Save result to history, default False.
random_state (int, optional) – Random seed for reproducibility.
max_neutron_energy (float, optional) – Truncate the energy grid above this value (MeV).
- Returns:
Unfolding results including spectrum, residuals, and metadata.
- Return type:
Dict[str, Any]
- unfold_qpmad(readings: dict[str, float], initial_spectrum: ndarray | None = None, regularization: float = 0.0001, smoothness_order: int = 0, smoothness_weight: float = 1.0, floor: float = 1e-06, lb: ndarray | None = None, ub: ndarray | None = None, backend: str = 'python', tol: float = 1e-09, max_iterations: int = 10000, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using qpmad (Goldfarb-Idnani dual active-set QP).
Solves
min 0.5 ||A x - b||^2 + alpha/2 ||L x||^2 + alpha0/2 ||x||^2subject tolb <= x <= ub(default:x >= 0) using the qpmad algorithm of Sherikov (asherikov/qpmad).- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Accepted for API compatibility (Goldfarb-Idnani starts from the unconstrained minimum, not from
x0).regularization (float, optional) – Tikhonov / smoothness regularization weight, default 1e-4.
smoothness_order (int, optional) – Smoothness penalty order (0, 1 or 2), default 0.
smoothness_weight (float, optional) – Weight for the smoothness term, default 1.0.
floor (float, optional) – Diagonal regularization floor added to H to guarantee strict positive-definiteness, default 1e-6.
lb (np.ndarray, optional) – Simple bounds on the spectrum. If both are None (default) the method enforces
x >= 0.ub (np.ndarray, optional) – Simple bounds on the spectrum. If both are None (default) the method enforces
x >= 0.backend (str, optional) – ‘python’ (default) uses a pure-NumPy port of Goldfarb-Idnani; ‘qpmad’ calls the upstream C++ library if available.
tol (float, optional) – Numerical tolerance, default 1e-9.
max_iterations (int, optional) – Iteration cap for the Python backend, default 10 000.
calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty, default False.
noise_level (float, optional) – Noise level for Monte-Carlo, default 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples, default 100.
save_result (bool, optional) – Save result to history, default False.
random_state (int, optional) – Random seed for reproducibility.
max_neutron_energy (float, optional) – Truncate the energy grid above this value (MeV).
- Returns:
Unfolding results including spectrum, residuals, and metadata.
- Return type:
Dict[str, Any]
- unfold_mystic(readings: dict[str, float], initial_spectrum: ndarray | None = None, regularization: float = 0.0001, norm: int = 2, solver: str = 'fmin_powell', maxiter: int | None = 2000, maxfun: int | None = 20000, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, regularization_method: str = 'manual', noise_var: float | None = None, smoothness_order: int = 0, smoothness_weight: float = 1.0, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using mystic with regularization selection.
Solves
min ||A x - b||^2 + alpha * ||x||_normsubject tox >= 0with the constrained-optimization framework mystic.- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess.
regularization (float, optional) – Regularization parameter, default: 1e-4.
norm (int, optional) – Norm type (1 for L1, 2 for L2), default: 2.
solver (str, optional) – Mystic solver name: ‘fmin’, ‘fmin_powell’, ‘diffev’ or ‘diffev2’, default: ‘fmin_powell’.
maxiter (int, optional) – Maximum number of solver iterations, default: 2000.
maxfun (int, optional) – Maximum number of function evaluations, default: 20000.
calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty, default: False.
noise_level (float, optional) – Noise level for Monte-Carlo, default: 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples, default: 100.
save_result (bool, optional) – Save result to history, default: False.
regularization_method (str, optional) – Method for selecting regularization parameter. Options: ‘manual’, ‘cosine’, ‘gcv’, ‘lcurve’, ‘dp’.
noise_var (float, optional) – Noise variance for discrepancy principle (‘dp’ method).
smoothness_order (int, optional) – Smoothness constraint order (0, 1, or 2), default: 0.
smoothness_weight (float, optional) – Weight for smoothness term, default: 1.0.
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results including spectrum, residuals, and metadata.
- Return type:
Dict[str, Any]
- unfold_mystic_hybrid(readings: dict[str, float], initial_spectrum: ndarray | None = None, regularization: float = 0.0001, norm: int = 2, global_solver: str = 'diffev2', local_solver: str = 'fmin_powell', global_maxiter: int | None = None, global_maxfun: int | None = None, local_maxiter: int | None = None, local_maxfun: int | None = None, npop: int | None = None, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, regularization_method: str = 'manual', noise_var: float | None = None, smoothness_order: int = 0, smoothness_weight: float = 1.0, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Two-stage hybrid unfolding: global search + local refinement.
Stage 1 uses a population-based solver (
diffev2by default) with automatically derived bounds to robustly locate the basin of the global minimum. Stage 2 feeds that result asx0into a local direct-search solver (fmin_powellby default) for precise final convergence.- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess for the global stage.
regularization (float, optional) – Regularization parameter, default: 1e-4.
norm (int, optional) – Norm type (1 for L1, 2 for L2), default: 2.
global_solver (str, optional) – Population-based solver for stage 1 (
'diffev'or'diffev2'), default:'diffev2'.local_solver (str, optional) – Local solver for stage 2 (
'fmin'or'fmin_powell'), default:'fmin_powell'.global_maxiter (int, optional) – Maximum iterations for the global stage (default: 200).
global_maxfun (int, optional) – Maximum function evaluations for the global stage.
local_maxiter (int, optional) – Maximum iterations for the local stage (default: 2000).
local_maxfun (int, optional) – Maximum function evaluations for the local stage.
npop (int, optional) – Population size for the global stage.
calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty, default: False.
noise_level (float, optional) – Noise level for Monte-Carlo, default: 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples, default: 100.
save_result (bool, optional) – Save result to history, default: False.
regularization_method (str, optional) – Method for selecting regularization parameter. Options: ‘manual’, ‘cosine’, ‘gcv’, ‘lcurve’, ‘dp’.
noise_var (float, optional) – Noise variance for discrepancy principle (‘dp’ method).
smoothness_order (int, optional) – Smoothness constraint order (0, 1, or 2), default: 0.
smoothness_weight (float, optional) – Weight for smoothness term, default: 1.0.
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results including spectrum, residuals, and metadata.
- Return type:
Dict[str, Any]
- unfold_genetic(readings: dict[str, float], initial_spectrum: ndarray | None = None, solver: str = 'pso', epoch: int = 500, pop_size: int = 50, regularization: float = 0.01, norm: int = 2, smoothness_order: int = 2, smoothness_weight: float = 1.0, entropy_weight: float = 0.0, n_runs: int = 1, early_stop: int | None = None, half_range: float = 2.0, two_step: bool = False, n_coarse: int | None = None, smoother: str = 'none', sigma_smooth: float = 2.0, crossover: str = 'single', mutation: str = 'random', pareto_select: str = 'knee', calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, verbose: bool = False, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using a meta-heuristic (evolutionary) algorithm.
The optimizer searches in log space seeded with a Landweber warm-start solution (or the provided
initial_spectrum), bounded tolog(seed) +/- half_rangedecades, with a scale-consistent objective. Inspired by the genetic / PSO unfolding works of Shahabinejad & Sohrabpour (2017), Suman & Sarkar (2012), Woo et al. (2019) and Mukherjee (2004).- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess. If None, a Landweber warm-start solution is used to seed the population.
solver (str, optional) – Meta-heuristic algorithm: ‘pso’, ‘ga’, ‘de’, ‘es’, ‘ep’, ‘abc’, ‘gwo’, ‘cmaes’ or ‘nsga2’, default: ‘pso’.
epoch (int, optional) – Maximum number of generations, default: 500.
pop_size (int, optional) – Population size, default: 50.
regularization (float, optional) – Tikhonov regularization weight, default: 1e-2.
norm (int, optional) – Norm for the regularization term (1 or 2), default: 2.
smoothness_order (int, optional) – Smoothness constraint order (0, 1, or 2), default: 2.
smoothness_weight (float, optional) – Weight for the smoothness term, default: 1.0.
entropy_weight (float, optional) – Weight of the negative Shannon-entropy objective (0 disables it).
n_runs (int, optional) – Number of independent runs whose results are averaged, default: 1. Not used by the ‘nsga2’ solver.
early_stop (int, optional) – Stop if the global best does not improve for this many consecutive epochs.
half_range (float, optional) – Half-width of the log-space search bounds in decades around the seed, default: 2.0.
two_step (bool, optional) – Run the two-step genetic scheme (TGASU-style): a coarse first step seeds the full-resolution population, default: False.
n_coarse (int, optional) – Number of coarse bins for
two_stepmode (default: None, i.e.max(8, n // 4)).smoother (str, optional) – Post-processing smoother: ‘none’, ‘gaussian’, ‘mbc’, ‘gaussian_mbc’ or ‘second_difference’, default: ‘none’.
sigma_smooth (float, optional) – Gaussian filter sigma for the smoothers, default: 2.0.
crossover (str, optional) – GA crossover operator: ‘single’ or ‘arithmetic’ (TGASU); used by the numpy GA engine, default: ‘single’.
mutation (str, optional) – GA mutation operator: ‘random’ or ‘iterative’ (TGASU, decreasing step); used by the numpy GA engine, default: ‘random’.
pareto_select (str, optional) – Selection from the Pareto front for the ‘nsga2’ solver: ‘knee’, ‘min_residual’ or ‘max_entropy’, default: ‘knee’.
calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty, default: False.
noise_level (float, optional) – Noise level for Monte-Carlo, default: 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples, default: 100.
save_result (bool, optional) – Save result to history, default: False.
random_state (int, optional) – Random seed for reproducibility.
verbose (bool, optional) – If True, print the MEALPY optimization progress.
- Returns:
Unfolding results including spectrum, residuals, and metadata.
- Return type:
Dict[str, Any]
- unfold_gnowee(readings: dict[str, float], initial_spectrum: ndarray | None = None, population: int = 25, max_gens: int = 200, max_fevals: int = 5000, stall_limit: int = 200, conv_tol: float = 1e-06, opt_conv_tol: float = 0.01, frac_elite: float = 0.2, frac_levy: float = 1.0, frac_mutation: float = 0.2, alpha_levy: float = 1.5, gamma_levy: float = 1.0, n_levy: int = 1, scaling_factor: float = 10.0, init_sampling: str = 'lhc', regularization: float = 0.01, norm: int = 2, smoothness_order: int = 2, smoothness_weight: float = 1.0, entropy_weight: float = 0.0, half_range: float = 2.0, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, verbose: bool = False, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using the Gnowee hybrid metaheuristic optimizer.
Gnowee (Bevins & Parsons, SlaybaughLab/Gnowee) combines Lévy flights (Cuckoo Search), golden-ratio crossover (Modified Cuckoo Search), scatter search (Egea 2009) and differential-evolution mutation in an elitist population with Metropolis-Hastings acceptance and stall-driven restarts.
The optimizer searches in log space seeded with a Landweber warm-start solution (or the provided
initial_spectrum), bounded tolog(seed) ± half_rangedecades, with a scale-consistent objective combining the relative L2 residual, Tikhonov regularisation, second-difference smoothness and (optionally) negative Shannon entropy.- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess. If None, a Landweber warm-start solution is used to seed the population.
population (int, optional) – Population size, default 25 (Gnowee’s recommended value).
max_gens (int, optional) – Maximum number of generations, default 200.
max_fevals (int, optional) – Maximum fitness evaluations, default 5_000.
stall_limit (int, optional) – Stall-based termination threshold (evaluations), default 200.
conv_tol (float, optional) – Relative improvement tolerance for timeline extension, default 1e-6.
opt_conv_tol (float, optional) – Tolerance on the optimum value for fitness convergence, default 1e-2.
frac_elite (float, optional) – Elite fraction (crossover / scatter search), default 0.2.
frac_levy (float, optional) – Lévy flight fraction, default 1.0.
frac_mutation (float, optional) – Mutation discovery probability, default 0.2.
alpha_levy (float, optional) – Lévy exponent, default 1.5.
gamma_levy (float, optional) – Lévy scale, default 1.0.
n_levy (int, optional) – Number of independent Lévy samples, default 1.
scaling_factor (float, optional) – Lévy step length scale, default 10.0.
init_sampling (str, optional) – Initial sampler:
'lhc'or'random', default'lhc'.regularization (float, optional) – Tikhonov regularisation weight, default 1e-2.
norm (int, optional) – Norm for the regularisation term (1 or 2), default 2.
smoothness_order (int, optional) – Smoothness penalty order (0, 1 or 2), default 2.
smoothness_weight (float, optional) – Weight for the smoothness term, default 1.0.
entropy_weight (float, optional) – Weight of the negative Shannon-entropy objective (0 disables it).
half_range (float, optional) – Half-width of the log-space search bounds in decades around the seed, default 2.0.
calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty, default False.
noise_level (float, optional) – Noise level for Monte-Carlo, default 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples, default 100.
save_result (bool, optional) – Save result to history, default False.
random_state (int, optional) – Random seed for reproducibility.
verbose (bool, optional) – Print Gnowee progress every 10 generations.
max_neutron_energy (float, optional) – Truncate the energy grid above this value (MeV).
- Returns:
Unfolding results including spectrum, residuals, and metadata.
- Return type:
Dict[str, Any]
- unfold_smt(readings: dict[str, float], initial_spectrum: ndarray | None = None, nonneg: bool = True, timeout_ms: int = 10000, objective: str = 'l2', calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold a neutron spectrum using an SMT solver.
Minimizes
||A x - b||_2and then the total fluencesum(x)over the non-negative orthant using the Z3 optimizer (z3-solver package, optional dependency). Falls back to the L1 residual on non-converging solves.- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess (accepted for API compatibility).
nonneg (bool, optional) – Constrain the spectrum to be non-negative, default: True.
timeout_ms (int, optional) – SMT solver timeout in milliseconds, default: 10000.
objective (str, optional) – Residual objective:
'l2'(default) or'l1'.calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty, default: False.
noise_level (float, optional) – Noise level for Monte-Carlo, default: 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples, default: 100.
save_result (bool, optional) – Save result to history, default: False.
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results including spectrum, residuals, and metadata.
- Return type:
Dict[str, Any]
- unfold_scip(readings: dict[str, float], initial_spectrum: ndarray | None = None, regularization: float = 0.0001, norm: int = 2, timeout: float = 10.0, smoothness_order: int = 0, smoothness_weight: float = 1.0, nonneg: bool = True, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, regularization_method: str = 'manual', noise_var: float | None = None, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold a neutron spectrum using the SCIP optimizer.
Minimizes the Tikhonov-regularized least-squares objective
0.5 * ||A x - b||^2 + penalty(x)with the SCIP Optimization Suite (pyscipopt package, optional dependency).- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess, used as a warm start.
regularization (float, optional) – Regularization parameter, default: 1e-4.
norm (int, optional) – Norm type (1 for L1, 2 for L2), default: 2.
timeout (float, optional) – Time limit in seconds, default: 10.0.
smoothness_order (int, optional) – Smoothness constraint order (0, 1, or 2), default: 0.
smoothness_weight (float, optional) – Weight for the smoothness term, default: 1.0.
nonneg (bool, optional) – Constrain the spectrum to be non-negative, default: True.
calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty, default: False.
noise_level (float, optional) – Noise level for Monte-Carlo, default: 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples, default: 100.
save_result (bool, optional) – Save result to history, default: False.
regularization_method (str, optional) – Method for selecting the regularization parameter (‘manual’, ‘cosine’, ‘lcurve’, ‘gcv’, ‘dp’), default: ‘manual’.
noise_var (float, optional) – Noise variance for discrepancy principle (‘dp’ method).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results including spectrum, residuals, and metadata.
- Return type:
Dict[str, Any]
- unfold_docplex(readings: dict[str, float], initial_spectrum: ndarray | None = None, regularization: float = 0.0001, norm: int = 2, timeout: float = 10.0, smoothness_order: int = 0, smoothness_weight: float = 1.0, nonneg: bool = True, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, regularization_method: str = 'manual', noise_var: float | None = None, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold a neutron spectrum using CPLEX (docplex).
Minimizes the Tikhonov-regularized least-squares objective
0.5 * ||A x - b||^2 + penalty(x)with IBM Decision Optimization CPLEX Modeling for Python (docplex + cplex packages, optional dependencies).- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess (accepted for API compatibility).
regularization (float, optional) – Regularization parameter, default: 1e-4.
norm (int, optional) – Norm type (1 for L1, 2 for L2), default: 2.
timeout (float, optional) – Time limit in seconds, default: 10.0.
smoothness_order (int, optional) – Smoothness constraint order (0, 1, or 2), default: 0.
smoothness_weight (float, optional) – Weight for the smoothness term, default: 1.0.
nonneg (bool, optional) – Constrain the spectrum to be non-negative, default: True.
calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty, default: False.
noise_level (float, optional) – Noise level for Monte-Carlo, default: 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples, default: 100.
save_result (bool, optional) – Save result to history, default: False.
regularization_method (str, optional) – Method for selecting the regularization parameter (‘manual’, ‘cosine’, ‘lcurve’, ‘gcv’, ‘dp’), default: ‘manual’.
noise_var (float, optional) – Noise variance for discrepancy principle (‘dp’ method).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results including spectrum, residuals, and metadata.
- Return type:
Dict[str, Any]
- unfold_cs(readings: dict[str, float], initial_spectrum: ndarray | None = None, n_atoms: int | None = None, sparsity: int | None = None, dictionary: ndarray | None = None, n_dictionary_iterations: int = 20, sigma_min: float = 0.01, sigma_decrease_factor: float = 0.5, mu_0: float = 1.0, L: int = 3, max_iterations: int = 1000, tolerance: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Compressive Sensing (CS).
The spectrum is represented sparsely in a learned dictionary (K-SVD), sparse coding is performed with OMP, and reconstruction is done with the SL0 algorithm. This method is well suited for the highly underdetermined problem where the number of energy groups greatly exceeds the number of detector readings.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
n_atoms (int, optional) – Number of dictionary atoms.
sparsity (int, optional) – Target sparsity for dictionary learning.
dictionary (np.ndarray, optional) – Pre-learned dictionary (n x n_atoms).
n_dictionary_iterations (int, optional) – Number of K-SVD iterations (default: 20).
sigma_min (float, optional) – SL0 minimum sigma (default: 0.01).
sigma_decrease_factor (float, optional) – SL0 sigma decrease factor (default: 0.5).
mu_0 (float, optional) – SL0 step-size factor (default: 1.0).
L (int, optional) – SL0 inner iterations per sigma (default: 3).
max_iterations (int, optional) – SL0 maximum outer iterations (default: 1000).
tolerance (float, optional) – Convergence tolerance (default: 1e-6).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_nnksvd(readings: dict[str, float], initial_spectrum: ndarray | None = None, n_atoms: int = 15, sparsity: int = 2, dictionary: ndarray | None = None, training_signals: ndarray | None = None, n_dictionary_iterations: int = 80, lambda_tik: float = 0.01, prior_wt: float = 0.5, sparse_coder: str = 'nnls_topk', tolerance: float = 1e-06, n_nnls_iter: int | None = None, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Non-negative K-SVD (NN-KSVD).
Implements the BNCT epithermal neutron spectrum unfolding method of Xu et al. (NIMA 2026, https://doi.org/10.1016/j.nima.2026.172070). A non-negative dictionary is learned with non-negative K-SVD (non-negative truncation of dictionary atoms during the rank-1 SVD update), the spectrum is then represented as
phi = D @ alphawherealphais a non-negative K-sparse coefficient vector recovered on the equivalent (column-normalized) detection dictionaryM_norm = normalize(R @ D).Three sparse-coding strategies are supported:
"nnls_topk"(default, the article’s proposed method): global NNLS coarse solution → top-K atom screening → local NNLS fine optimization. Achieves ~0.97 correlation and ~12.5% relative flux error with the article’s optimal configuration (15 atoms, K=2)."omp"— classic Orthogonal Matching Pursuit (greedy)."nn_omp"— OMP with non-negativity constraint on the support LS step (solved as NNLS).
The reconstruction objective is a Tikhonov-regularized non-negative least-squares (Eq. 2.5/2.6 of the article) solved via augmented-matrix NNLS, with an optional training-sample prior constraint (
prior_wt > 0).- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. Used to seed training signals when no
training_signalsis supplied.n_atoms (int, optional) – Number of dictionary atoms (default: 15, the article’s optimum).
sparsity (int, optional) – Target sparsity
K(default: 2, the article’s optimum).dictionary (np.ndarray, optional) – Pre-learned non-negative dictionary (n x n_atoms). Bypasses online K-SVD training.
training_signals (np.ndarray, optional) – Training signals for online K-SVD (n x m). If not provided, log-spaced Gaussian bumps on the energy grid are used.
n_dictionary_iterations (int, optional) – K-SVD iterations (default: 80, as in the article).
lambda_tik (float, optional) – Tikhonov smoothing regularization weight (default: 0.01).
prior_wt (float, optional) – Training-sample-driven prior weight (default: 0.5).
sparse_coder (str, optional) – Sparse-coding strategy:
"nnls_topk","omp"or"nn_omp"(default:"nnls_topk").tolerance (float, optional) – Convergence tolerance (default: 1e-6).
n_nnls_iter (int, optional) – Maximum NNLS iterations.
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
max_neutron_energy (float, optional) – Optional upper energy cutoff (MeV).
- Returns:
Unfolding results dictionary with standard fields plus
n_atoms,sparsity,sparse_coder,lambda_tik,prior_wt.- Return type:
Dict[str, Any]
- unfold_reconst(readings: dict[str, float], initial_spectrum: ndarray | None = None, pp: float = 0.001, alpha: float = -1.0, beta: float = 0.0, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Turchin’s statistical regularization.
Pure numpy port of the RECONST.FOR algorithm (STREG1). Solves (B * beta + Omega * alpha) * f = A_vec * beta with automatic alpha/beta selection.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Ignored (for API compatibility).
pp (float, optional) – PP parameter for the smoothing matrix (default: 1e-3).
alpha (float, optional) – Regularization parameter. >0 fixed, <0 auto-select absolute value (default: -1).
beta (float, optional) – Data fidelity weight. >0 fixed, <=0 auto-select (default: 0).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_lmfit(readings: dict[str, float], initial_spectrum: ndarray | None = None, method: str = 'lbfgsb', model_name: str = 'elastic', regularization: float = 0.0001, regularization2: float = 0.0001, l1_weight: float = 0.5, regularization_method: str = 'manual', lambda_range: tuple[float, float] = (1e-06, 0.1), n_lambda: int = 30, verbose: bool = True, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using lmfit with L1/L2/Elastic regularization.
- Parameters:
readings (Dict[str, float]) – Detector readings (counts or dose rates)
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
method (str, optional) – lmfit solver name (leastsq, lbfgsb, etc.), default: “lbfgsb”.
model_name (str, optional) – Regularization model: elastic, lasso, ridge, default: “elastic”.
regularization (float, optional) – L1 regularization strength, default: 1e-4.
regularization2 (float, optional) – L2 regularization strength for elastic net, default: 1e-4.
l1_weight (float, optional) – L1 weight for elastic net (0=pure L2, 1=pure L1), default: 0.5.
regularization_method (str, optional) – How to choose the regularization parameter. Options: ‘manual’ (use the supplied
regularization/regularization2), or an information criterion ‘aic’, ‘aicc’ or ‘bic’. For non-manual selection the regularization parameter is swept overlambda_rangeand the candidate minimizing the chosen criterion is used. Default: ‘manual’.lambda_range (Tuple[float, float], optional) – Log-spaced range of lambda candidates for information-criterion selection, default: (1e-6, 1e-1).
n_lambda (int, optional) – Number of lambda candidates for information-criterion selection, default: 30.
verbose (bool, optional) – Print the regularization selection summary, default: True.
calculate_errors (bool, optional) – Flag to calculate uncertainty via Monte-Carlo, default: False.
noise_level (float, optional) – Noise level for Monte-Carlo uncertainty calculation, default: 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples for error estimation, default: 100.
save_result (bool, optional) – If True, save result to internal history, default: False.
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Dictionary containing unfolding results.
- Return type:
Dict[str, Any]
- unfold_mlem_bs(readings: dict[str, float], initial_spectrum: ndarray | None = None, n_basis: int | None = None, spline_order: int = 4, beta: float | None = None, beta_relative: float | None = None, knot_spacing: str = 'auto', max_iterations: int = 1000, tolerance: float = 1e-06, auto_params: bool = False, bootstrap_ci: bool = False, n_bootstrap: int = 100, ci_alpha: float = 0.05, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using the B-spline MLEM method with regularization.
Implements the MLEM-BS algorithm of Mazankova et al. (CNDGS’2026, https://doi.org/10.47459/cndcgs.2026.61): the spectrum is represented as a non-negative combination of B-splines (B-spline sieve, Szkutik 2005) and the coefficients are found with the regularized MLEM iteration (Eq. 4 of the paper) using the second-derivative penalty
P(b) = ||D^(2) b||_2^2(Eq. 5). The iteration count, the B-spline space dimensionN_sand the penalty strength can be selected automatically by minimizing theK_Sgoodness-of-fit statistic (Eq. 6). Confidence intervals of the unfolded spectrum can be estimated with the Poisson bootstrap of Eqs. 7-9.- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess; projected onto the non-negative B-spline sieve. A flat spectrum is used when
None.n_basis (Optional[int], optional) – Dimension
N_sof the B-spline space (default:Noneselectsmax(spline_order + 1, min(n_bins // 2, 40))). The paper optimizesN_svia the first local minimum ofK_S; enableauto_paramsto reproduce that.spline_order (int, optional) – B-spline order
p(degreep - 1); the paper usesp = 4(cubic). Default: 4.beta (Optional[float], optional) – Absolute penalty strength of Eq. 4 (problem-scale dependent; the paper uses 1.0e-17 for its counting setup).
beta_relative (Optional[float], optional) – Scale-aware penalty strength: effective
beta = beta_relative * mean column sum of RB. Mutually exclusive withbeta; default (bothNone) disables the penalty.knot_spacing (str, optional) – Interior knot placement:
"auto"(default; log knots for grids spanning more than two decades, uniform knots otherwise),"uniform"or"log".max_iterations (int, optional) – Iteration budget (default: 1000).
tolerance (float, optional) – Relative coefficient-change convergence tolerance (default: 1e-6).
auto_params (bool, optional) – Select the iteration count,
N_sand the penalty strength by minimizingK_S(Eq. 6), following the paper’s parameter-optimization procedure (default: False).bootstrap_ci (bool, optional) – Estimate percentile confidence intervals with the Poisson bootstrap (Eqs. 7-9). Default: False.
n_bootstrap (int, optional) – Number of bootstrap replicates (default: 100).
ci_alpha (float, optional) – Significance level; 0.05 gives a 95% interval (default).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for the bootstrap resampling.
max_neutron_energy (Optional[float], optional) – Truncate the energy grid at this value (default: None).
- Returns:
Unfolding results dictionary enriched with
ks_history,ks_final,chi2_pearson,n_basis,spline_order,knot_spacing,interior_knots,beta_effective,beta_relative,coefficientsand, when requested,auto_selection,ci_lowandci_highkeys.- Return type:
Dict[str, Any]
- unfold_mlem_odl(readings: dict[str, float], initial_spectrum: ndarray | None = None, tolerance: float = 1e-06, max_iterations: int = 1000, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using MLEM with ODL (Operator Discretization Library).
Requires the ‘odl’ package to be installed.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum approximation.
tolerance (float, optional) – Convergence tolerance. Default is 1e-6.
max_iterations (int, optional) – Maximum number of iterations. Default is 1000.
calculate_errors (bool, optional) – Flag for calculating restoration errors. Default is False.
noise_level (float, optional) – Noise level for error calculation. Default is 0.01.
n_montecarlo (int, optional) – Number of Monte Carlo samples for error calculation. Default is 100.
save_result (bool, optional) – If True, save result to internal history. Default is False.
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Dictionary containing the spectrum restoration results.
- Return type:
Dict
- unfold_imaxed(readings: dict[str, float], initial_spectrum: ndarray | None = None, sigma_factor: float = 0.1, max_iterations: int = 5000, tolerance: float = 1e-08, line_search_tol: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using the IMAXED algorithm (Wong 2024).
- unfold_amaxed(readings: dict[str, float], initial_spectrum: ndarray | None = None, sigma_factor: float = 0.1, target_chi2: float | None = None, max_iterations: int = 5000, tolerance: float = 1e-08, line_search_tol: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using the AMAXED algorithm (Wong 2024).
- unfold_amaxed_regularization(readings: dict[str, float], initial_spectrum: ndarray | None = None, sigma_factor: float = 0.1, tau: float = 1.0, max_iterations: int = 5000, tolerance: float = 1e-08, line_search_tol: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using the AMAXED-Regularization algorithm (Wong 2024).
- unfold_odl_pdhg(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 100, tau: float | None = None, sigma: float | None = None, use_tv: bool = True, tv_weight: float = 0.1, nonnegativity: bool = True, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using the Primal-Dual Hybrid Gradient (PDHG) algorithm.
- unfold_odl_douglas_rachford(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 100, use_tv: bool = True, tv_weight: float = 0.1, nonnegativity: bool = True, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using Douglas-Rachford splitting.
- unfold_qubo(readings: dict[str, float], initial_spectrum: ndarray | None = None, n_bits: int = 6, max_value: float | None = None, regularization: float = 0.01, max_iterations: int = 1000, annealing_time: int = 1000, num_reads: int = 10, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 50, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using a QUBO formulation with quantum-inspired annealing.
- unfold_zfit(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 100, use_mcmc: bool = False, n_samples: int = 1000, regularization: float = 0.1, smoothness_weight: float = 0.01, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using zfit Bayesian inference.
- unfold_mlem_stop(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 15000, cps_crossover: float = 30000.0, j_threshold: float | None = None, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using MLEM-STOP with J-factor early stopping criterion.
Uses the modified MLEM-STOP method from Montgomery et al. (2020). The J-factor indicator (Bouallegue et al. 2013) is computed at each iteration: J = sum((meas - est)^2) / sum(est). The algorithm stops when J falls below the threshold (mean(measurements) / cps_crossover).
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
max_iterations (int, optional) – Maximum iterations (default: 15000).
cps_crossover (float, optional) – Crossover CPS value for automatic J threshold (default: 30000).
j_threshold (float, optional) – Explicit J threshold. If None, computed from cps_crossover.
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_epic(readings: dict[str, float], initial_spectrum: ndarray | None = None, target_sigmas: ndarray | None = None, sigma_frac: float = 0.1, regularization_order: int = 1, non_neg: bool = True, noise_var: float | None = None, homogeneous_step: bool = True, regularize: dict[str, Any] | None = None, beta_shift_k: float = 0, beta_distance: float = 2, EPIC_bool: ndarray | None = None, V: ndarray | None = None, LSQpar: dict[str, Any] | None = None, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold a neutron spectrum using EPIC Tikhonov regularization.
Selects the prior variances of the regularization operator such that the a posteriori variances of the model parameters match the target sigmas (Equal Posterior Information Condition), then solves the weighted least squares problem. Port of the EPIC_LS method of Ortega-Culaciati et al. (2021), frortega/EPIC_LS.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess (unused by this method).
target_sigmas (np.ndarray, optional) – Target a posteriori standard deviations of the model parameters. If None, derived as
sigma_fractimes the magnitude of the naive least-squares solution.sigma_frac (float, optional) – Fraction used to derive the default target sigmas, default: 0.1.
regularization_order (int, optional) – Regularization operator order: 0 (identity), 1 (first derivative, default) or 2 (second derivative).
non_neg (bool, optional) – Constrain the spectrum to be non-negative, default: True.
noise_var (float, optional) – Variance of the i.i.d. misfit errors used to build Cx, default: None (identity Cx).
homogeneous_step (bool, optional) – Run a preliminary homogeneous Ch search, default: True.
regularize (dict, optional) – If given (can be empty), damp the EPIC weights towards a minimum-norm solution.
beta_shift_k (float, optional) – Center shift for the beta bounds, default: 0.
beta_distance (float, optional) – Distance kept from the representability limit, default: 2.
EPIC_bool (np.ndarray, optional) – Boolean mask of which parameters are subject to the EPIC.
V (np.ndarray, optional) – Matrix mapping the searched betas to the regularization rows, beta = V @ y (shape (H.shape[0], len(y))).
LSQpar (dict, optional) – Tuning parameters for the nonlinear least-squares solver.
calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty, default: False.
noise_level (float, optional) – Noise level for Monte-Carlo, default: 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples, default: 100.
save_result (bool, optional) – Save result to history, default: False.
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results including spectrum, residuals, and metadata.
- Return type:
Dict[str, Any]
- unfold_combined(readings: dict[str, float], pipeline: list[dict[str, Any]], calculate_errors: bool = False, verbose: bool = True, max_neutron_energy: float | None = None) dict[str, Any] | None[source]#
Combined unfolding method applying multiple methods sequentially.
- Parameters:
readings (Dict[str, float]) – Detector readings
pipeline (List[Dict[str, Any]]) – List of methods for sequential application.
calculate_errors (bool, optional) – Flag to calculate errors for the last method.
verbose (bool, optional) – Flag to print debug information.
- Returns:
Dictionary with unfolding results.
- Return type:
Dict
- unfold_cascade(readings: dict[str, float], cascade_stages: list[CascadeStage] | None = None, calculate_errors: bool = False, verbose: bool = True, save_result: bool = False, multi_resolution: bool = False, coarse_bins: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Cascade unfolding with sequential method refinement.
Applies unfolding methods in sequence; each stage may use the previous result as an initial guess, a prior/reference spectrum, or a regularization target, and the cascade may stop early when a stage reaches its quality threshold. With
multi_resolution=Truethe first stage runs on a coarse energy grid and its prolongated solution seeds the fine-grid stages. Seebssunfold.core.unfold_cascade.unfold_cascade().
- unfold_composite(readings: dict[str, float], n_methods: int = 5, timeout_per_method: float = 30.0, save_result: bool = False, spectrum: ndarray | None = None, energy: ndarray | None = None, method_names: list[str] | None = None, ensemble_weights: dict[str, float] | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Adaptive ensemble of unfolding methods with confidence-weighted combination.
Classifies the unknown spectrum by hardness, runs a pool of suitable individual methods, and combines their results. See
bssunfold.core.unfold_composite.unfold_composite().
- unfold_binned(readings: dict[str, float], bin_lookup: dict[str, Any] | None = None, lookup_path: str | None = None, timeout_per_method: float = 30.0, save_result: bool = False, max_neutron_energy: float | None = None) dict[str, Any][source]#
Bin-wise adaptive unfolding: best method per energy bin.
For each of the 60 energy bins, selects the unfolding method that performed best in that bin during benchmarking, and assembles the final spectrum by picking the winning value at every bin.
- Parameters:
readings (Dict[str, float]) – Detector readings.
bin_lookup (dict, optional) – Pre-computed per-bin method ranking. If None, loaded from lookup_path (or the built-in default shipped with the package).
lookup_path (str, optional) – Path to a JSON lookup file. Ignored when bin_lookup is given.
timeout_per_method (float) – Wall-clock timeout per individual method (seconds).
save_result (bool) – Persist result to detector history.
max_neutron_energy (float, optional) – Upper cut-off for the energy grid.
- Returns:
Standard bssunfold result dict with extra keys
method_map,successful_methods,individual_spectra.- Return type:
dict
See also
unfold_compositeConfidence-weighted ensemble of methods.
- unfold_interpret(readings: dict[str, float], initial_spectrum: ndarray | None = None, regularization: float = 0.0001, norm: int = 2, smoothness_order: int = 0, smoothness_weight: float = 1.0, enforce_norm: bool = False, norm_value: float = 1.0, regularization_method: str = 'manual', noise_var: float | None = None, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, tolerance: float = 1e-08, interpret_options: dict[str, Any] | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold a neutron spectrum and interpret the solution with pyoptexplain.
Solves the same unfolding QP as
unfold_qpsolvers()through pyoptexplain and attaches an interpretation report. The returned dict is the standard bssunfold result with two extra keys:report– Markdown interpretation report.interpretation_metrics– JSON-friendly metrics dictionary.interpretation_spectrum– interpreted (zeroed) spectrum.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess (used by the ‘cosine’ regularization method).
regularization (float, optional) – Regularization parameter (default: 1e-4).
norm (int, optional) – Penalty norm, 1 or 2 (default: 2).
smoothness_order (int, optional) – Smoothness derivative order, 0, 1 or 2 (default: 0).
smoothness_weight (float, optional) – Weight of the smoothness term (default: 1.0).
enforce_norm (bool, optional) – Add
sum(x) == norm_value(default: False).norm_value (float, optional) – Target total fluence (default: 1.0).
regularization_method (str, optional) – Method for selecting the regularization parameter.
noise_var (float, optional) – Noise variance for the discrepancy principle (‘dp’ method).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
tolerance (float, optional) – Solver feasibility/optimality tolerance (default: 1e-8). Relax it (e.g. 1e-5) if pyoptexplain’s backend reports
iteration_limit.interpret_options (dict, optional) – Extra keyword arguments forwarded to
interpret_qp().
- Returns:
Standardized unfolding result plus
reportandinterpretation_metricskeys.- Return type:
Dict[str, Any]
- interpret_result(readings: dict[str, float], alpha: float = 0.0001, norm: int = 2, smoothness_order: int = 0, smoothness_weight: float = 1.0, enforce_norm: bool = False, norm_value: float = 1.0, max_neutron_energy: float | None = None, **kwargs: Any) dict[str, Any][source]#
Interpret a set of detector readings without unfolding.
Builds the response matrix from
readingsand runsinterpret_qp()directly, returning the report, metrics, tables and interpreted spectrum.- Parameters:
readings (Dict[str, float]) – Detector readings.
alpha (float, optional) – Regularization parameter (default: 1e-4).
norm (int, optional) – Penalty norm, 1 or 2 (default: 2).
smoothness_order (int, optional) – Smoothness derivative order, 0, 1 or 2 (default: 0).
smoothness_weight (float, optional) – Weight of the smoothness term (default: 1.0).
enforce_norm (bool, optional) – Add
sum(x) == norm_value(default: False).norm_value (float, optional) – Target total fluence (default: 1.0).
max_neutron_energy (float, optional) – Maximum neutron energy (MeV). Bins with
E_MeV > max_neutron_energyare excluded from the interpretation.**kwargs – Extra keyword arguments forwarded to
interpret_qp().
- Returns:
Dictionary with
report,metrics,tablesandspectrumkeys.- Return type:
Dict[str, Any]
- discretize_spectra(spectra: DataFrame | dict) DataFrame[source]#
Interpolate spectra onto target energy grid.
- get_effective_readings_for_spectra(spectra: DataFrame | dict) dict[str, float][source]#
Calculate effective readings for a given spectrum.
- static _import_optional(module_name: str, purpose: str) Any[source]#
Import optional dependency with informative error message.
- _save_figure(fig: Any, save_to: str | None = None, dpi: int = 300, bbox_inches: str = 'tight', **savefig_kwargs) None[source]#
Save figure to file with support for multiple formats.
- unfold_doroshenko(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 1000, tolerance: float = 1e-06, regularization: float = 0.0, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the Doroshenko coordinate update method.
- Parameters:
readings (Dict[str, float]) – Detector readings (counts or dose rates)
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, uniform spectrum is used
max_iterations (int, optional) – Maximum number of iterations, default: 1000
tolerance (float, optional) – Convergence tolerance for solution change, default: 1e-6
regularization (float, optional) – Regularization strength to prevent division by zero, default: 0.0
calculate_errors (bool, optional) – Flag to calculate uncertainty via Monte-Carlo, default: False
noise_level (float, optional) – Noise level for Monte-Carlo uncertainty calculation, default: 0.01
n_montecarlo (int, optional) – Number of Monte-Carlo samples for error estimation, default: 100
save_result (bool, optional) – If True, save result to internal history, default: False
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Dictionary containing unfolding results.
- Return type:
Dict[str, Any]
- unfold_directed_divergence(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 200, tol_chi2: float = 1.0, tol_rel: float = 1e-06, relative_uncertainty: float = 0.05, smoothness_order: int = 0, smoothness_weight: float = 0.0, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold sphere readings with the directed-divergence iteration.
- unfold_express(readings: dict[str, float], initial_spectrum: ndarray | None = None, n_groups: int = 6, interval_boundaries: ndarray | None = None, max_iterations: int = 3, tol_iteration: float = 0.05, relative_uncertainty: float = 0.05, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold sphere readings with the piecewise-exponential Express model.
- unfold_kaczmarz(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 1000, omega: float = 1.0, tolerance: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the Kaczmarz algorithm (ART).
- Parameters:
readings (Dict[str, float]) – Detector readings (counts or dose rates)
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, zero spectrum is used
max_iterations (int, optional) – Maximum number of iterations, default: 1000
omega (float, optional) – Relaxation parameter (0 < omega <= 2), default: 1.0
tolerance (float, optional) – Convergence tolerance for solution change, default: 1e-6
calculate_errors (bool, optional) – Flag to calculate uncertainty via Monte-Carlo, default: False
noise_level (float, optional) – Noise level for Monte-Carlo uncertainty calculation, default: 0.01
n_montecarlo (int, optional) – Number of Monte-Carlo samples for error estimation, default: 100
save_result (bool, optional) – If True, save result to internal history, default: False
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Dictionary containing unfolding results.
- Return type:
Dict[str, Any]
- unfold_randomized_kaczmarz(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 1000, omega: float = 1.0, tolerance: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the Randomized Kaczmarz algorithm.
Row selection is probabilistic with probability proportional to the squared row norm, achieving faster convergence than the cyclic variant for ill-conditioned systems (Strohmer & Vershynin, 2009).
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
max_iterations (int, optional) – Maximum number of iterations (default: 1000).
omega (float, optional) – Relaxation parameter (default: 1.0).
tolerance (float, optional) – Convergence tolerance (default: 1e-6).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
max_neutron_energy (float, optional) – Maximum neutron energy cutoff.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_gravel(readings: dict[str, float], initial_spectrum: ndarray | None = None, tolerance: float = 1e-08, max_iterations: int = 1000, regularization: float = 0.0, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the GRAVEL algorithm.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, default initial spectrum is used.
tolerance (float, optional) – Convergence tolerance (default: 1e-8).
max_iterations (int, optional) – Maximum iterations (default: 1000).
regularization (float, optional) – Regularization parameter (default: 0.0).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_maxed(readings: dict[str, float], initial_spectrum: ndarray | None = None, sigma_factor: float = 0.01, max_iterations: int = 5000, tolerance: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the MAXED algorithm.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Reference spectrum. If None, a flat reference is used.
sigma_factor (float, optional) – Relative measurement uncertainty (default: 0.01).
max_iterations (int, optional) – Maximum L-BFGS-B iterations (default: 5000).
tolerance (float, optional) – Convergence tolerance (default: 1e-6).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_tikhonov_legendre(readings: dict[str, float], initial_spectrum: ndarray | None = None, delta: float = 0.05, n_polynomials: int = 15, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Tikhonov regularization with Legendre basis.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Not used (provided for API consistency).
delta (float, optional) – Regularization parameter (default: 0.05).
n_polynomials (int, optional) – Number of Legendre polynomials (default: 15).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_bayes(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 4000, tolerance: float = 0.001, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Bayesian iterative unfolding (D’Agostini).
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Prior spectrum. If None, uniform prior is used.
max_iterations (int, optional) – Maximum iterations (default: 4000).
tolerance (float, optional) – Convergence tolerance (default: 1e-3).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_bayes_spline_regularization(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 4000, tolerance: float = 0.001, spline_degree: int = 3, spline_smooth: float = 0.01, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Bayesian iterative unfolding with spline regularization.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Prior spectrum. If None, uniform prior is used.
max_iterations (int, optional) – Maximum iterations (default: 4000).
tolerance (float, optional) – Convergence tolerance (default: 1e-3).
spline_degree (int, optional) – Spline degree (default: 3).
spline_smooth (float, optional) – Spline smoothing parameter (default: 1e-2).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_statreg(readings: dict[str, float], initial_spectrum: ndarray | None = None, unfoldermethod: str = 'EmpiricalBayes', regularization: float | None = None, basis_name: str = 'CubicSplines', boundary: str | None = None, derivative_degree: int = 2, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Turchin’s method of statistical regularization.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
unfoldermethod (str, optional) – Regularization method: ‘EmpiricalBayes’ or ‘User’ (default: ‘EmpiricalBayes’).
regularization (float, optional) – Regularization parameter for ‘User’ method.
basis_name (str, optional) – Basis type (default: ‘CubicSplines’).
boundary (str, optional) – Boundary condition, None or ‘dirichlet’.
derivative_degree (int, optional) – Derivative degree (1, 2, 3), default: 2.
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_scipy_direct_method(readings: dict[str, float], initial_spectrum: ndarray | None = None, tolerance: float = 1e-08, max_iterations: int = 4000, method: str = 'cg', calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using scipy linear solvers.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
tolerance (float, optional) – Solver tolerance (default: 1e-8).
max_iterations (int, optional) – Maximum solver iterations (default: 4000).
method (str, optional) – Solver method: ‘cg’, ‘cgs’, ‘bicgstab’, ‘gmres’, etc. (default: ‘cg’).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_tsvd(readings: dict[str, float], initial_spectrum: ndarray | None = None, method: str = 'discrepancy', k: int | None = None, threshold: float | None = None, noise_level: float | None = None, svd_solver: str = 'full', calculate_errors: bool = False, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Truncated SVD (TSVD).
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
method (str, optional) – K-selection method: ‘discrepancy’, ‘l_curve’, ‘gcv’, ‘energy’, ‘threshold_ratio’, ‘median_threshold’, ‘donoho’ (default: ‘discrepancy’).
k (int, optional) – Fixed number of singular values to keep.
threshold (float, optional) – Threshold ratio for singular value truncation.
noise_level (float, optional) – Noise level for discrepancy principle.
svd_solver (str, optional) – SVD backend:
'full'(dense LAPACK, default),'arpack'(implicit restarted Lanczos, therARPACKanalogue) or'propack'(Lanczos bidiagonalization, the RsvdPROPACK analogue). The iterative backends are used when a fixedkis provided; automatic k-selection always uses the dense solver.calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_lanczos(readings: dict[str, float], initial_spectrum: ndarray | None = None, regularization_method: str = 'gcv', max_iterations: int | None = None, regularization: float = 1e-08, noise_level: float | None = None, calculate_errors: bool = False, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the Lanczos-hybrid (Krylov) method.
Performs Golub-Kahan (Lanczos-type) bidiagonalization of the response matrix, building a sequence of Krylov subspaces. At each iteration a new approximation is obtained by solving the projected Tikhonov problem, with the regularization parameter selected automatically on the projected problem by Generalized Cross Validation (GCV). No a-priori spectrum is required.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess (accepted for API compatibility).
regularization_method (str, optional) – Method for selecting the regularization parameter. Only
'gcv'is supported (default: ‘gcv’).max_iterations (int, optional) – Maximum Krylov dimension. Defaults to
min(n_detectors, n_energy_bins).regularization (float, optional) – Fallback regularization parameter (default: 1e-8).
noise_level (float, optional) – Relative noise level used for discrepancy-principle early stopping.
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_cgls(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 100, tolerance: float = 1e-12, regularization: float = 0.0, smoothness_order: int = 0, noise_level: float | None = None, calculate_errors: bool = False, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the CGLS iterative method.
CGLS (Conjugate Gradient for Least Squares) solves the least squares problem
min ||A x - b||^2with a truncated-CG iteration, optionally regularized by a||L x||^2Tikhonov term and/or stopped early by the discrepancy principle. Nonnegativity is enforced by clamping at each iteration.- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, a zero vector is used (the CGLS iteration does not depend on the initial guess).
max_iterations (int, optional) – Maximum number of CG iterations (default: 100).
tolerance (float, optional) – Relative tolerance on the normal-equation residual (default: 1e-12).
regularization (float, optional) – Tikhonov regularization parameter for the
||L x||^2term (default: 0.0 = no extra regularization).smoothness_order (int, optional) – Order of the derivative matrix used as the regularization operator
L(0 = identity, 1 = first derivative, 2 = second derivative). Ignored whenregularizationis 0.noise_level (float, optional) – Relative noise level used for discrepancy-principle stopping.
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_gks(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int | None = None, smoothness_order: int = 2, regularization_method: str = 'gcv', regularization: float = 1e-08, noise_level: float | None = None, calculate_errors: bool = False, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the GKS Krylov-hybrid method.
GKS (Golub-Kahan hybrid) performs Lanczos-type bidiagonalization of the response matrix, building a Krylov subspace of modest dimension. At each iteration the regularized problem is projected onto the subspace and solved, with the regularization parameter chosen automatically on the projected problem by GCV, the discrepancy principle, or the L-curve.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess (accepted for API compatibility).
max_iterations (int, optional) – Maximum Krylov dimension. Defaults to
min(n_detectors, n_energy_bins).smoothness_order (int, optional) – Order of the derivative matrix used for regularization (default: 2).
regularization_method (str, optional) – Method for selecting the regularization parameter:
'gcv','dp','lcurve'or'manual'(default: ‘gcv’).regularization (float, optional) – Fallback/manual regularization parameter (default: 1e-8).
noise_level (float, optional) – Relative noise level used by the discrepancy principle when
regularization_method='dp'.calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_tikhonov_tv(readings: dict[str, float], initial_spectrum: ndarray | None = None, epsilon: float | None = None, mu: tuple[float, float, float] = (1.0, 1.0, 1.0), max_iterations: int = 100, type_: str = 'TT', beta: float = 1.0, zthr: float = 2.5, tolerance: float = 0.0001, noise_level: float | None = None, calculate_errors: bool = False, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum with noise-constrained Tikhonov-TV.
Solves
min f(x)subject to||A x - b||^2 = epsilonwith the ADMM scheme of Gazzola & Gholami adapted to 1D spectra. The regularizerfis a blend of total variation on the first derivative and Tikhonov smoothing on the second derivative, with the balancing parameterbetaeither fixed or estimated adaptively.- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess (accepted for API compatibility).
epsilon (float, optional) – Estimate of the squared 2-norm of the noise. If None, derived from
noise_level((noise_level * ||b||)^2) or from the residuals of an unregularized least-squares solve.mu (Tuple[float, float, float], optional) – Penalty parameters
(mu1, mu2, mu3)(default: (1, 1, 1)).max_iterations (int, optional) – Maximum number of ADMM iterations (default: 100).
type (str, optional) – Optimization problem:
'TT'(TV + Tikhonov),'TV'(pure total variation) or'T'(pure Tikhonov) (default: ‘TT’).beta (float, optional) – Balancing parameter between TV and Tikhonov terms, or
'adapt'for adaptive estimation (default: 1.0).zthr (float, optional) – Threshold for the adaptive beta estimation (default: 2.5).
tolerance (float, optional) – Stabilization stopping criterion (default: 1e-4).
noise_level (float, optional) – Relative noise level used to derive a default
epsilon.calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_tikhonov_sobolev_dp(readings: dict[str, float], initial_spectrum: ndarray | None = None, noise_level: float = 0.02, delta: float | None = None, penalty: str = 'sobolev', alpha_range: tuple[float, float] = (1e-10, 10000000000.0), max_iter: int = 100, calculate_errors: bool = False, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using Tikhonov + generalized discrepancy (alfaFinder).
Python port of the energy-non-invariant apparatus-function method of Ogorodnikov (2024), sections 3 and 5 (
alfaFinder()): Tikhonov regularization with the discrete SobolevW_2^1penalty (first-difference operator, the discrete analogue of the Euler equationA*A z + alpha (z - z'') = A* u), with the regularization parameteralpha*selected by the generalized discrepancy principle||A z - b||^2 = delta^2(root found by a bracketing + Brent scheme combining the bisection and chord/secant methods used in the article).- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess (accepted for API compatibility).
noise_level (float, optional) – Relative noise level used to derive
delta(default: 0.02, the article’s 0-2 % range).delta (float, optional) – Explicit RMS noise level; overrides
noise_level.penalty (str, optional) – Penalty operator:
"sobolev"(first difference, default),"curvature"(second difference) or"identity"(ridge).alpha_range (tuple, optional) – Search interval for the regularization parameter.
max_iter (int, optional) – Maximum number of root-finder iterations (default: 100).
calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty (default: False).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
max_neutron_energy (float, optional) – Truncate the energy grid above this value (MeV).
- Returns:
Unfolding results dictionary with additional keys
alpha(selected regularization parameter),discrepancy_status(0 = root found, 1 = delta too small, 2 = delta too large),dp_convergedandresidual_sq.- Return type:
Dict[str, Any]
- unfold_sandii(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 50, tolerance: float = 0.001, chi_fac: int = 1, relative_uncertainty: float = 0.1, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the SAND-II algorithm.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, a flat spectrum is used.
max_iterations (int, optional) – Maximum number of iterations (default: 50).
tolerance (float, optional) – Maximum relative spectrum change used when
chi_fac=0(default: 1e-3).chi_fac (int, optional) – Convergence criterion:
1= chi-square based,0= maximum relative deviation based (default: 1).relative_uncertainty (float, optional) – Relative measurement uncertainty for the chi-square criterion (default: 0.1).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_louhi(readings: dict[str, float], initial_spectrum: ndarray | None = None, smoothness: float = 1.0, smooth_order: int = 1, auto_smooth: bool = False, chi2_target: float | None = None, max_iterations: int = 500, tolerance: float = 1e-06, relative_uncertainty: float = 0.1, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, variance_reduction: str = 'none', save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the LOUHI78 algorithm.
Constrained weighted least squares with generalized smoothing (Routti & Sandberg 1980): the quadratic program
- min chi2(phi) = ||(b - A phi) / sigma||^2
smoothness^2 * ||L (phi - phi0)||^2
is solved under non-negativity constraints by Hildreth’s iterative quadratic programming (the LSI step of LOUHI78). With
auto_smooth=Truethe smoothing weight is adjusted by a nonlinear regression so that the data chi-square reaches its expected value (LOUHI’s nonlinear mode).- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Default (a-priori) spectrum. If None, a flat spectrum is used.
smoothness (float, optional) – Smoothing weight
lambda(default: 1.0).smooth_order (int, optional) – Smoothing operator order: 0 (identity), 1 (first differences) or 2 (second differences); default 1.
auto_smooth (bool, optional) – Adjust the smoothing weight automatically (default: False).
chi2_target (Optional[float], optional) – Target data chi-square for
auto_smooth(default: number of detectors).max_iterations (int, optional) – Maximum number of Hildreth sweeps (default: 500).
tolerance (float, optional) – Relative objective change per sweep for convergence (default: 1e-6).
relative_uncertainty (float, optional) – Relative measurement uncertainty (default: 0.1).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
variance_reduction (str, optional) – MC variance reduction: ‘none’, ‘antithetic’, ‘control’, ‘both’ (default: ‘none’).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
max_neutron_energy (Optional[float], optional) – Restrict the energy grid to bins below this energy.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_crystal_ball(readings: dict[str, float], initial_spectrum: ndarray | None = None, regularization: float = 0.0, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the CRYSTAL BALL algorithm.
CRYSTAL BALL is a direct (non-iterative) method that represents the spectrum as a linear combination of the detector response functions. This is an independent open-source reimplementation based on the published algorithmic description; the original code is proprietary.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Unused; accepted for interface uniformity.
regularization (float, optional) – Tikhonov regularization strength for the Gram-matrix inversion (default: 0.0).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_rfsp_jul(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 200, tolerance: float = 0.0001, weights: ndarray | None = None, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the RFSP-JUL algorithm.
RFSP-JUL is an iterative, damped least-squares method minimising a weighted residual functional with a Marquardt-style damping term that ties each iterate to the previous one. This is an independent open-source reimplementation based on the published description; the original code is proprietary.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, a flat spectrum is used.
max_iterations (int, optional) – Maximum number of iterations (default: 200).
tolerance (float, optional) – Convergence tolerance on maximum relative spectrum change (default: 1e-4).
weights (np.ndarray, optional) – Per-detector weights for the residual term. None => equal weights.
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_ssr(readings: dict[str, float], initial_spectrum: ndarray | None = None, fn: str | int = 'auto', max_iterations: int = 500, tolerance: float = 1e-06, smooth_every: int = 1, inner_sweeps: int = 1, fn_ladder_cap: int = 8, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using SSR Sign-Simplicity-Regression (sisireg port).
Python port of the R package
sisireg1.2.1 (Metzner): MLEM data-fidelity steps alternate with non-equidistant SSR QSOR sweeps of the spectrum over the energy grid. Each sweep replaces interior bins by the simplicitic neighbour interpolation and reverts updates that would violate the partial sum criterion (thresholdfn), which suppresses sign-inadequate wiggles. Withfn="auto"the threshold is selected by the minimum statistic ladder: it starts atint(0.66 * partial_sum_quantile(n, k_run))and decreases while the folded residuals stay sign-adequate (partial sum / maximum run test in the data space) and the spectrum does not gain extrema.- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess (flat start when missing).
fn (str or int, optional) –
"auto"(default, minimum statistic ladder) or a fixed partial sum threshold.max_iterations (int, optional) – Maximum number of outer MLEM + sweep iterations (default: 500).
tolerance (float, optional) – Relative L2 stopping tolerance (default: 1e-6).
smooth_every (int, optional) – Apply the SSR sweep every
smooth_every-th iteration (default: 1).inner_sweeps (int, optional) – Number of QSOR passes per SSR step (default: 1).
fn_ladder_cap (int, optional) – Maximum number of ladder candidates for
fn="auto"(default: 8).calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Relative noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary with additional keys
fn,fn_start,k_run,n_extrema,ps_valid_data,run_valid_dataandssr_converged.- Return type:
Dict[str, Any]
- unfold_staysl(readings: dict[str, float], initial_spectrum: ndarray | None = None, relative_uncertainty: float = 0.1, prior_uncertainty: float = 1.0, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the STAY’SL Bayesian algorithm.
STAY’SL is a single-step linear Bayesian least-squares update that refines a prior spectrum using the full measurement and prior covariance information. This is an independent open-source reimplementation based on the published mathematical formulation; the original code is proprietary.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Prior spectrum guess. If None, a flat spectrum is used as the prior mean.
relative_uncertainty (float, optional) – Relative measurement uncertainty for the covariance (default: 0.1).
prior_uncertainty (float, optional) – Relative prior uncertainty for the covariance (default: 1.0).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_bunki(readings: dict[str, float], initial_spectrum: ndarray | None = None, smoothing: float = 0.1, max_iterations: int = 1000, tolerance: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the BUNKI (SPUNIT) algorithm.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, a flat spectrum is used.
smoothing (float, optional) – Three-point smoothing factor (default: 0.1).
max_iterations (int, optional) – Maximum number of iterations (default: 1000).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 1e-6).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_bunkiut(readings: dict[str, float], initial_spectrum: ndarray | None = None, smoothing: float = 0.05, max_iterations: int = 1000, tolerance: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the BUNKI-UT (BON31G) algorithm.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, a flat spectrum is used.
smoothing (float, optional) – Three-point smoothing factor (default: 0.05).
max_iterations (int, optional) – Maximum number of iterations (default: 1000).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 1e-6).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_ferdor(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 100, tolerance: float = 0.001, smoothing: float = 0.001, chi_squared_target: float = 1.0, relative_uncertainty: float = 0.1, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the FERDOR algorithm.
FERDOR (ORNL; Burrus, ORNL-4154) is a constrained least-squares unfolding code with second-difference smoothing. The smoothing weight is adjusted iteratively so the reduced chi-square of the fit reaches
chi_squared_target(discrepancy principle), and the final spectrum is non-negative.- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, a flat spectrum is used.
max_iterations (int, optional) – Maximum number of smoothing-weight iterations (default: 100).
tolerance (float, optional) – Relative tolerance on the reduced chi-square (default: 1e-3).
smoothing (float, optional) – Initial smoothing weight alpha (default: 1e-3).
chi_squared_target (float, optional) – Target reduced chi-square per degree of freedom (default: 1.0).
relative_uncertainty (float, optional) – Relative measurement uncertainty for the chi-square criterion (default: 0.1).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_rebunki(readings: dict[str, float], initial_spectrum: ndarray | None = None, smoothing: float = 0.1, max_iterations: int = 1000, tolerance: float = 0.01, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the ReBUNKI (SPUNIT) algorithm.
ReBUNKI (Lacerda et al., 2018) is a modern open reimplementation of the BUNKI code; its Python version supports the SPUNIT iterative algorithm. The default tolerance matches the ~1% relative-error convergence recommended by ReBUNKI.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, a flat spectrum is used.
smoothing (float, optional) – Three-point smoothing factor (default: 0.1).
max_iterations (int, optional) – Maximum number of iterations (default: 1000).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 0.01).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_nsduaz(readings: dict[str, float], initial_spectrum: ndarray | None = None, catalogue: dict[str, ndarray] | None = None, use_catalogue: bool = True, reference_name: str | None = None, smoothing: float = 0.1, max_iterations: int = 1000, tolerance: float = 0.01, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the NSDUAZ algorithm.
NSDUAZ (Universidad Autonoma de Zacatecas; Ortiz-Rodriguez & Vega-Carrillo, 2012) uses the SPUNIT iterative algorithm with an initial spectrum selected from a catalogue of standard spectra by a statistical test on count-rate ratios relative to the reference (20.32 cm) sphere.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Explicit initial spectrum guess. When given, it overrides the catalogue selection.
catalogue (Optional[Dict[str, np.ndarray]], optional) – User-supplied catalogue of candidate initial spectra (label -> spectrum on the detector energy grid). When None, the built-in mini-catalogue is used.
use_catalogue (bool, optional) – If True (default), select the initial spectrum from the catalogue when
initial_spectrumis not provided; if False, a flat spectrum is used.reference_name (str, optional) – Reference sphere name for the catalogue test (default: auto-detect 20.32 cm sphere).
smoothing (float, optional) – Three-point smoothing factor (default: 0.1).
max_iterations (int, optional) – Maximum number of iterations (default: 1000).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 0.01).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_nspline(readings: dict[str, float], initial_spectrum: ndarray | None = None, knots: Any | None = None, continuity: str = 'C0C1', relative_uncertainty: float = 0.1, max_iterations: int = 200, tol: float = 0.001, step_theta: float = 0.1, smoothing: bool = True, n_segments: int | None = None, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the N-spline method (2008).
Implements Islamgulov & Lartsev (Atomic Energy 104(5), 295-302, 2008): the spectrum is parameterised by a “neutron” spline
N(E) = exp(a + q ln E + r E)with C0/C1 continuity at the knots, and the activation equations are solved by the directed divergence (MIRD) minimisation loop with an N-spline smoothing at every iteration. The result includes the paper’s acceptability statisticnev(acceptable whennev <= 1 + 2/sqrt(N)).- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess; the paper recommends a Monte-Carlo calculated spectrum. A flat spectrum is used when
None.knots (Optional[Any], optional) – N-spline knots:
None(automatic log-uniform grid), a preset name frombssunfold.core.NSPLINE_KNOT_PRESETS(“BARS5_channel”, “IGRIK_channel”, “IGRIK_surface”, “YAGUAR_channel”) or an explicit increasing sequence (MeV).continuity (str, optional) – Spline continuity:
"C0C1"(default),"C0"or"none".relative_uncertainty (float, optional) – Relative measurement uncertainty dQ/Q for the stopping criteria and the
nevstatistic (default: 0.1).max_iterations (int, optional) – Iteration budget (default: 200).
tol (float, optional) – Relative H-decrease stopping tolerance (default: 1e-3).
step_theta (float, optional) – Conservative MIRD step factor (default: 0.1).
smoothing (bool, optional) – Per-iteration N-spline smoothing (default: True, as in the paper;
Falsereduces the loop to the plain MIRD update).n_segments (int, optional) – Number of spline segments when
knots=None.calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
max_neutron_energy (Optional[float], optional) – Truncate the energy grid at this value (default: None).
- Returns:
Unfolding results dictionary enriched with
H,H_history,H_target,nev,nev_limit,acceptable,stop_reason,fluence,mean_energy,knotsandknots_sourcekeys.- Return type:
Dict[str, Any]
- unfold_mcmc(readings: dict[str, float], initial_spectrum: ndarray | None = None, sigma_prior: float = 0.05, lambda_prior: float = 0.5, lengthscale: float = 3.0, n_samples: int = 2000, tune: int = 1000, chains: int = 2, target_accept: float = 0.95, use_hierarchical: bool = False, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, progressbar: bool = False, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Bayesian MCMC with NUTS sampler.
Full Bayesian unfolding with the No-U-Turn Sampler (NUTS). The method returns the mean posterior spectrum together with 95% HPD credible intervals, per-bin posterior standard deviations and convergence diagnostics (R-hat, effective sample size) under
result['mcmc_stats'].The spectrum is modelled on the log scale with a smoothness (Ornstein-Uhlenbeck) prior anchored on a data-driven center (the non-negative least-squares solution, or a user-supplied
initial_spectrum), which keeps the underdetermined unfolding problem well posed for NUTS.Requires optional
pymcandarviz(pip install bssunfold[mcmc]orpip install pymc arviz).- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Prior center guess for the spectrum. When None, the non-negative least-squares solution of
A @ x = bis used as the prior center.sigma_prior (float, optional) – Relative likelihood noise scale (default: 0.05). With
use_hierarchical=Falsethe noise is fixed atsigma_prior * |b|; withuse_hierarchical=Trueit is the prior scale of the estimated relative noise.lambda_prior (float, optional) – Prior scale of the log-spectrum spatial amplitude (default: 0.5).
lengthscale (float, optional) – OU smoothness correlation length in energy bins (default: 3.0).
n_samples (int, optional) – Number of MCMC samples per chain after tuning (default: 2000).
tune (int, optional) – Number of tuning (warmup) samples per chain (default: 1000).
chains (int, optional) – Number of independent MCMC chains (default: 2).
target_accept (float, optional) – Target acceptance rate for NUTS (default: 0.95).
use_hierarchical (bool, optional) – Estimate the likelihood noise from the data (default: False).
calculate_errors (bool, optional) – Calculate additional Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for additional Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of additional Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
progressbar (bool, optional) – Show sampling progress bar (default: False).
- Returns:
Unfolding results dictionary. Includes the standard keys (
energy,spectrum,effective_readings,residual,residual_norm,method,doserates) plus MCMC-specific keysspectrum_uncertainty,spectrum_lower,spectrum_upperandmcmc_stats.- Return type:
Dict[str, Any]
- Raises:
ImportError – If PyMC or ArviZ is not installed.
RuntimeError – If MCMC sampling fails.
- unfold_maeo(readings: dict[str, float], n_cycles: int = 20, n_gen_per_cycle: int = 10, pop_size: int = 100, algorithms: list[str] | None = None, lambda_smooth: float = 0.01, prior_spectrum: ndarray | None = None, initial_spectrum: ndarray | None = None, convergence_assist_ratio: float = 0.2, seed: int | None = None, verbose: bool = False, save_result: bool = False, max_neutron_energy: float | None = None, **kwargs) dict[str, Any][source]#
Unfold neutron spectrum using MAEO ensemble optimization.
This method implements the Multiobjective Animorphic Ensemble Optimization (MAEO) framework from Erdem et al. (2026), which combines multiple multiobjective optimization algorithms (NSGA-III, CTAEA, AGEMOEA2, SPEA2) in an ensemble with adaptive migration based on hypervolume performance.
The MAEO framework is particularly effective for neutron spectrum unfolding because it: - Handles multiple conflicting objectives (data fit vs. smoothness) - Automatically selects the best-performing algorithm for the problem - Provides robust convergence through ensemble diversity - Supports parallel evaluation of individuals
- Parameters:
readings (dict) – Dictionary mapping detector names to measured count rates.
n_cycles (int, optional) – Number of MAEO cycles (default: 20). Each cycle runs n_gen_per_cycle generations for each island algorithm.
n_gen_per_cycle (int, optional) – Generations per cycle for each island (default: 10).
pop_size (int, optional) – Population size per island (default: 100).
algorithms (list of str, optional) – List of algorithm names to use as islands. Default uses the four algorithms from the MAEO paper: [“nsga3”, “ctaea”, “agemoea2”, “spea2”]. Available options: “nsga3”, “ctaea”, “agemoea2”, “spea2”.
lambda_smooth (float, optional) – Smoothness regularization weight (default: 0.01). Controls the trade-off between data fidelity and spectrum smoothness.
prior_spectrum (np.ndarray, optional) – Prior/guess spectrum for additional objective. If provided, adds a third objective to minimize deviation from this prior.
initial_spectrum (np.ndarray, optional) – Initial spectrum for warm-start. Used to seed the population in log space.
convergence_assist_ratio (float, optional) – Fraction of cycles to dedicate to the best-performing island at the end (default: 0.2). Implements the “convergence assist” mechanism from MAEO.
seed (int, optional) – Random seed for reproducibility.
verbose (bool, optional) – Print progress information including hypervolume history (default: False).
save_result (bool, optional) – Save result to history (default: False).
**kwargs – Additional keyword arguments passed to the underlying optimizer.
- Returns:
Standardized result dictionary containing:
’energy’: Energy grid in MeV
’spectrum’: Unfolded spectrum (non-negative)
’spectrum_absolute’: Absolute flux values
’effective_readings’: Computed readings from unfolded spectrum
’residual’: Difference between measured and computed readings
’residual_norm’: L2 norm of residual
’method’: ‘MAEO’
’doserates’: Dose rates calculated from spectrum
’maeo_info’: Dictionary with MAEO-specific information:
’n_cycles’: Number of cycles executed
’best_algorithm’: Name of best-performing algorithm
’hypervolume_history’: HV history for each island
’population_history’: Population sizes per island per cycle
’algorithms_used’: List of algorithms used
’maeo_pareto_front’: Final Pareto front objectives (if available)
’maeo_objectives’: Objectives for selected solution
- Return type:
dict
Notes
The MAEO framework optimizes multiple objectives simultaneously:
Minimize data fidelity error ||b - A*phi||^2 / ||b||^2
Minimize spectrum roughness ||D2 * phi||^2 (second derivative)
(Optional) Minimize deviation from prior spectrum
The final solution is selected from the combined Pareto front using a knee-point detection method to balance accuracy and smoothness.
The algorithm runs in two phases:
Migration phase: All islands run in parallel, with individuals migrating toward better-performing islands based on hypervolume indicators.
Convergence phase: Only the best-performing island continues, focusing computational resources on exploitation.
References
- [1] O.F. Erdem, D. Price, P. Seurin, M.I. Radaideh, “MAEO: Multiobjective
Animorphic Ensemble Optimization for Scalable Large-scale Engineering Applications”, arXiv:2604.26973 (2026).
- [2] D. Price, M.I. Radaideh, “Animorphic Ensemble Optimization: a large-scale
island model”, Neural Computing and Applications 35 (4) (2023) 3221-3243.
Examples
>>> from bssunfold import Detector >>> detector = Detector() >>> readings = { ... 'sphere_1': 100.5, ... 'sphere_2': 85.3, ... 'sphere_3': 72.1, ... 'sphere_4': 58.9, ... 'sphere_5': 45.2, ... 'sphere_6': 32.8, ... } >>> # Run MAEO with default settings >>> result = detector.unfold_maeo(readings, n_cycles=15) >>> print(f"Spectrum integral: {np.sum(result['spectrum']):.2f}") >>> print(f"Best algorithm: {result['maeo_info']['best_algorithm']}") >>> >>> # Run with custom algorithms and verbose output >>> result = detector.unfold_maeo( ... readings, ... algorithms=["nsga3", "spea2"], ... n_cycles=10, ... verbose=True, ... )
- unfold_osem(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 50, n_subsets: int = 1, tolerance: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the OSEM algorithm.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, a flat spectrum is used.
max_iterations (int, optional) – Maximum number of iterations (default: 50).
n_subsets (int, optional) – Number of ordered subsets over the detector readings (default: 1, i.e. standard MLEM).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 1e-6).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_osem_anlm(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 50, n_subsets: int = 1, tolerance: float = 1e-06, h: float | None = None, search_window: int = 11, similarity_window: int = 3, alpha: float = 1.0, anlm_mode: str = 'subset', log_space: bool = True, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the OSEM-ANLM algorithm.
Ordered-subset expectation maximisation with asymptotic non-local means regularization (Jamaati et al. 2026, https://doi.org/10.1038/s41598-026-70607-1): the two-stage ANLM filter is applied to the intermediate spectrum after every OSEM subset update (
anlm_mode='subset') or once to the OSEM result (anlm_mode='post').- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, a flat spectrum is used.
max_iterations (int, optional) – Maximum number of iterations (default: 50).
n_subsets (int, optional) – Number of ordered subsets over the detector readings (default: 1, i.e. standard MLEM with per-iteration ANLM).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 1e-6).
h (float, optional) – Noise level for the ANLM filter (in log units when
log_space=True). If None (default), it is estimated automatically from the intermediate spectra.search_window (int, optional) – ANLM search window
N(default: 11, article optimum).similarity_window (int, optional) – ANLM similarity (patch) window
nu(default: 3, article optimum).alpha (float, optional) – Spread of the Gaussian kernel over the similarity window (default: 1.0).
anlm_mode (str, optional) –
'subset'— ANLM after every subset update (default, article pseudo-code);'post'— single ANLM application to the OSEM result.log_space (bool, optional) – Apply the ANLM filter to the logarithm of the spectrum (default: True, scale-free for spectra spanning orders of magnitude).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_mapem(readings: dict[str, float], initial_spectrum: ndarray | None = None, prior: str = 'quadratic', beta: float = 0.001, prior_delta: float = 1.0, gamma: float = 1.0, max_iterations: int = 50, tolerance: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using penalised EM (MAP-EM).
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, a flat spectrum is used.
prior (str, optional) – Prior type:
'none','quadratic','logcosh'or'relative_difference'(default:'quadratic').beta (float, optional) – Prior weight (default: 1e-3).
prior_delta (float, optional) – Width parameter of the quadratic/logcosh priors and additive floor of the relative-difference prior (default: 1.0).
gamma (float, optional) – Edge-preservation parameter of the relative-difference prior (default: 1.0).
max_iterations (int, optional) – Maximum number of iterations (default: 50).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 1e-6).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_bsrem(readings: dict[str, float], initial_spectrum: ndarray | None = None, prior: str = 'none', beta: float = 0.001, prior_delta: float = 1.0, gamma: float = 1.0, max_iterations: int = 50, n_subsets: int = 1, tolerance: float = 1e-06, relaxation: float | Callable[[int], float] | None = None, addition_after_iteration: float = 0.0001, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the BSREM algorithm.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, a flat spectrum is used.
prior (str, optional) – Prior type:
'none','quadratic','logcosh'or'relative_difference'(default:'none').beta (float, optional) – Prior weight (default: 1e-3).
prior_delta (float, optional) – Width parameter of the quadratic/logcosh priors and additive floor of the relative-difference prior (default: 1.0).
gamma (float, optional) – Edge-preservation parameter of the relative-difference prior (default: 1.0).
max_iterations (int, optional) – Maximum number of iterations (default: 50).
n_subsets (int, optional) – Number of ordered subsets over the detector readings (default: 1).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 1e-6).
relaxation (float or callable, optional) – Relaxation sequence (default: None -> constant 1).
addition_after_iteration (float, optional) – Floor value for spectrum bins (default: 1e-4).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_sart(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 50, tolerance: float = 1e-06, relaxation: float | Callable[[int], float] | None = None, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the SART algorithm.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, a flat spectrum is used.
max_iterations (int, optional) – Maximum number of iterations (default: 50).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 1e-6).
relaxation (float or callable, optional) – Relaxation sequence (default: None -> constant 0.8).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_fista(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 500, tolerance: float = 1e-08, regularization: float = 0.0, l1_penalty: float = 0.0, tv_penalty: float = 0.0, nonnegativity: bool = True, x_min: float = 0.0, x_max: float = inf, noise_level: float | None = None, eta: float = 1.01, calculate_errors: bool = False, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using FISTA algorithm.
The Fast Iterative Shrinkage-Thresholding Algorithm (FISTA) is an accelerated proximal gradient method that achieves O(1/k^2) convergence rate for convex optimization problems. It can handle L1 regularization (sparsity), TV regularization, and box constraints.
Based on IRtools IRfista.m by Silvia Gazzola et al.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial guess for spectrum. If None, a flat spectrum is used.
max_iterations (int, optional) – Maximum number of iterations (default: 500).
tolerance (float, optional) – Convergence tolerance (default: 1e-8).
regularization (float, optional) – Tikhonov regularization parameter (default: 0.0).
l1_penalty (float, optional) – L1 regularization penalty parameter for sparsity (default: 0.0).
tv_penalty (float, optional) – Total variation penalty parameter (default: 0.0).
nonnegativity (bool, optional) – Apply nonnegativity constraints (default: True).
x_min (float, optional) – Lower bound for solution (default: 0.0).
x_max (float, optional) – Upper bound for solution (default: inf).
noise_level (float, optional) – Relative noise level for discrepancy principle stopping.
eta (float, optional) – Safety factor for discrepancy principle (default: 1.01).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_ensemble(readings: dict[str, float], initial_spectrum: ndarray | None = None, methods: list[tuple[Callable, dict[str, Any]]] | None = None, weights: ndarray | None = None, combination: str = 'weighted_average', trim_fraction: float = 0.2, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using ensemble method.
Combines results from multiple base unfolding methods for robust reconstruction. Different methods have different biases; the ensemble reduces variance and is more robust to method-specific failures.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
methods (list of (callable, dict), optional) – Solver functions and their keyword arguments.
weights (np.ndarray, optional) – Per-method weights for weighted average.
combination (str, optional) – Combination strategy: ‘weighted_average’, ‘median’, ‘trimmed_mean’, or ‘best_residual’ (default: ‘weighted_average’).
trim_fraction (float, optional) – Trim fraction for trimmed mean (default: 0.2).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_iterative_refinement(readings: dict[str, float], initial_spectrum: ndarray | None = None, first_pass_kwargs: dict[str, Any] | None = None, second_pass_kwargs: dict[str, Any] | None = None, alpha: float | None = None, max_alpha_search: int = 20, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using iterative refinement.
Two-pass method: first pass (MLEM) captures gross structure, second pass (Landweber) corrects systematic errors via residual.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
first_pass_kwargs (dict, optional) – Keyword arguments for first-pass solver.
second_pass_kwargs (dict, optional) – Keyword arguments for second-pass solver.
alpha (float, optional) – Blending factor (None = auto-select via line search).
max_alpha_search (int, optional) – Number of alpha candidates for line search (default: 20).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_hybrid_gmres(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 100, regularization_method: str = 'gcv', regularization: float = 0.0, noise_level: float | None = None, eta: float = 1.01, reorthogonalization: bool = True, calculate_errors: bool = False, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Hybrid GMRES method.
The hybrid GMRES method combines the GMRES iterative solver with Tikhonov regularization applied to the projected problem at each iteration. The regularization parameter is selected automatically using GCV or discrepancy principle.
Based on IRtools IRhybrid_gmres.m by Silvia Gazzola et al.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial guess for spectrum. If None, zero vector is used.
max_iterations (int, optional) – Maximum Krylov dimension (default: 100).
regularization_method (str, optional) – Method for selecting regularization parameter: ‘gcv’, ‘modgcv’, ‘discrep’ (default: ‘gcv’).
regularization (float, optional) – Fixed regularization parameter (used if not auto-selected).
noise_level (float, optional) – Relative noise level for discrepancy principle.
eta (float, optional) – Safety factor for discrepancy principle (default: 1.01).
reorthogonalization (bool, optional) – Apply full reorthogonalization (default: True).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_fruit_like(readings: dict[str, float], initial_spectrum: ndarray | None = None, initial_params: dict[str, float] | None = None, method: str = 'leastsq', calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using FRUIT-like parametric method.
Uses a parametric model with Maxwellian thermal component, 1/E epithermal component, and evaporation spectrum for fast neutrons.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess (unused in parametric method).
initial_params (Optional[Dict[str, float]], optional) – Initial parameter values for the parametric model. Keys: A_th, T_th, A_epi, A_f, T_ev.
method (str, optional) – lmfit solver method (default: “leastsq”).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_fission_ga(readings: dict[str, float], initial_spectrum: ndarray | None = None, initial_params: dict[str, float] | None = None, fit_scale: bool = True, ga_popsize: int = 15, ga_maxiter: int = 100, ga_tol: float = 1e-10, lm_method: str = 'trf', lm_max_nfev: int = 2000, eps_threshold: float = 0.05, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using the Fission-model GA+LM algorithm (BonnerFinder).
Python port of the multisphere unfolding algorithm of Ogorodnikov (2024), sections 4-5 (
BonnerFinder()), which follows the FRUIT paradigm of parameterized model curves. The spectrum is modelled by the three-fraction Fission model (thermal Maxwellian, epithermal tail with cutoff, Watt-type fast fission peak) with seven free parameters. Stage 1 searches the parameter hypercube globally with a genetic (differential evolution) algorithm minimizing the L1 discrepancy of the folded readings; stage 2 refines the best point with a nonlinear least-squares routine. The article’s validation criteria (per-sphere relative uncertainties, sign alternation, FOM, spectrum norm) are attached to the result.- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess (unused by the parametric method).
initial_params (Optional[Dict[str, float]], optional) – Optional starting parameter values (
a1, a2, a3, b, beta, alpha, TF, optionallyphi_scale); refined as an extra stage-2 start.fit_scale (bool, optional) – Fit a free overall scale factor so the model matches absolutely calibrated readings (default: True). Set False for the exact 7-parameter normalized formulation of the article (adds the norm-in-[0.6, 1.2] validation check).
ga_popsize (int, optional) – Population multiplier of the genetic algorithm (default: 15).
ga_maxiter (int, optional) – Maximum number of GA generations (default: 100).
ga_tol (float, optional) – GA convergence tolerance (default: 1e-10).
lm_method (str, optional) – Stage-2 least-squares method:
"trf"(bounded, default) or"lm"(Levenberg-Marquardt, as in the article).lm_max_nfev (int, optional) – Maximum function evaluations of one stage-2 run (default: 2000).
eps_threshold (float, optional) – Threshold on per-sphere relative uncertainty used by the validation criteria (default: 0.05).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
max_neutron_energy (float, optional) – Truncate the energy grid above this value (MeV).
- Returns:
Unfolding results dictionary with additional keys
model_params(fitted Fission-model parameters includingweight_fractions) andvalidation(article’s validation criteria).- Return type:
Dict[str, Any]
- unfold_hybrid_parametric(readings: dict[str, float], initial_spectrum: ndarray | None = None, refinement_method: str = 'landweber', max_iterations: int = 100, tolerance: float = 1e-06, step_size: float = 0.01, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using hybrid parametric-nonparametric method.
Combines parametric initial guess with iterative refinement using Landweber or MLEM iteration.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
refinement_method (str, optional) – Refinement method: “landweber” or “mlem” (default: “landweber”).
max_iterations (int, optional) – Maximum iterations (default: 100).
tolerance (float, optional) – Convergence tolerance (default: 1e-6).
step_size (float, optional) – Step size for Landweber (default: 0.01).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_bayesian_parametric(readings: dict[str, float], initial_spectrum: ndarray | None = None, sigma: float = 0.02, n_samples: int = 1000, burn_in: int = 200, proposal_scale: float = 0.1, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Bayesian parametric method.
Uses Bayesian inference with MCMC sampling to estimate spectral parameters and quantify uncertainty.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess (unused).
sigma (float, optional) – Measurement uncertainty (default: 0.02).
n_samples (int, optional) – Number of MCMC samples (default: 1000).
burn_in (int, optional) – Burn-in samples (default: 200).
proposal_scale (float, optional) – Proposal scale (default: 0.1).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_parametric(readings: dict[str, float], initial_spectrum: ndarray | None = None, initial_params: dict[str, float] | None = None, method: str = 'leastsq', optimizer: str = 'lmfit', alpha: float = 0.0001, alpha_auto: bool = False, solver_backend: str = 'auto', max_iter: int = 50, tol: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the FRUIT-based parametric method.
Uses the three-component parameterization from Bedogni FRUIT / Pyshkina B3S: thermal (Maxwellian), epithermal (1/E with exponential cutoffs), and fast (power-law x exponential).
The
optimizerparameter selects the backend:"lmfit"– classic lmfit least-squares (default)."cvxpy"– sequential QP via cvxpy (SQP)."qpsolvers"– sequential QP via qpsolvers (SQP)."combined"– lmfit first, then QP refinement.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess (unused in parametric method).
initial_params (Optional[Dict[str, float]], optional) – Initial parameter values for the parametric model. Keys: b, beta_prime, alpha, beta, P_th, P_epi.
method (str, optional) – lmfit solver method (default: “leastsq”).
optimizer (str, optional) – Backend optimizer (default: “lmfit”).
alpha (float, optional) – Regularization weight for QP-based optimizers (default: 1e-4).
alpha_auto (bool, optional) – If True, select alpha automatically via GCV for the lmfit optimizer (default: False).
solver_backend (str, optional) – QP solver backend: “auto”, “cvxpy”, “cvxpy:ECOS”, “qpsolvers”, “qpsolvers:osqp”, etc. (default: “auto”).
max_iter (int, optional) – Max SQP iterations (default: 50).
tol (float, optional) – Convergence tolerance for SQP (default: 1e-6).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_parametric2(readings: dict[str, float], initial_spectrum: ndarray | None = None, optimizer: str = 'grid', b_range: tuple[float, float, int] = (0.5, 2.0, 5), Tf_range: tuple[float, float, int] = (0.5, 10.0, 5), c_range: tuple[float, float, int] = (0.5, 3.0, 4), alpha: float = 0.0001, solver_backend: str = 'auto', max_iter_qp: int = 50, tol_qp: float = 1e-06, noise_level: float = 0.05, max_iter: int = 200, tol_chi2: float = 1.0, calculate_errors: bool = False, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the BON95 parametric method.
Uses the four-component parameterization from Sannikov BON95: thermal (Maxwellian), epithermal (1/E), intermediate, and fast (evaporation/cascade) components. After parametric fitting, the result is refined by directed-divergence iterations.
The
optimizerparameter selects the parametric fit backend:"grid"– grid search + NLS (default, no extra deps)."cvxpy"– SQP via cvxpy."qpsolvers"– SQP via qpsolvers."combined"– grid search + SQP refinement.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess (unused in parametric method).
optimizer (str) – Parametric fit optimizer (default: “grid”).
b_range (tuple) – Grid range for b: (min, max, n_points). Used by “grid”/”combined”.
Tf_range (tuple) – Grid range for Tf (MeV): (min, max, n_points). Used by “grid”/”combined”.
c_range (tuple) – Grid range for c: (min, max, n_points). Used by “grid”/”combined”.
alpha (float) – Tikhonov regularization for SQP (default: 1e-4).
solver_backend (str) – QP backend for SQP (default: “auto”).
max_iter_qp (int) – Max SQP iterations (default: 50).
tol_qp (float) – SQP convergence tolerance (default: 1e-6).
noise_level (float) – Relative uncertainty for measurements (default: 0.05 = 5%).
max_iter (int) – Max directed-divergence iterations (default: 200).
tol_chi2 (float) – Chi-squared convergence threshold (default: 1.0).
calculate_errors (bool) – Calculate Monte-Carlo errors (default: False).
n_montecarlo (int) – Number of Monte-Carlo samples (default: 100).
save_result (bool) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
max_neutron_energy (float, optional) – Upper energy cutoff in MeV. Bins above this energy are excluded from the unfolding and set to zero in the returned spectrum.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_eki(readings: dict[str, float], initial_spectrum: ndarray | None = None, n_ensemble: int = 50, n_iterations: int = 50, regularization: float = 0.0001, inflation: float = 1.02, noise_std: float | None = None, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Ensemble Kalman Inversion (EKI).
Approximates the Bayesian posterior without MCMC by propagating an ensemble of particles through the forward model and updating via the Kalman gain equation (Iglesias et al., 2013).
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess (centre of the ensemble).
n_ensemble (int, optional) – Number of ensemble members (default: 50).
n_iterations (int, optional) – Number of EKI iterations (default: 50).
regularization (float, optional) – Regularization for covariance stability (default: 1e-4).
inflation (float, optional) – Covariance inflation factor (default: 1.02).
noise_std (float, optional) – Measurement noise std (default: None = auto).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
max_neutron_energy (float, optional) – Maximum neutron energy cutoff.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- plot_response_functions(save_to: str | None = None, show: bool = True, dpi: int = 300, bbox_inches: str = 'tight', **savefig_kwargs) None[source]#
Plot all detector response functions.
- plot_with_uncertainty(result: dict[str, Any], reference_spectrum: dict[str, ndarray] | None = None, save_to: str | None = None, show: bool = True, **plot_kwargs) tuple[Any, Any][source]#
Plot unfolded spectrum with uncertainty range.
- Parameters:
result (Dict[str, Any]) – Unfolding result dictionary containing ‘energy’, ‘spectrum’, and optionally ‘spectrum_uncert_min’, ‘spectrum_uncert_max’, ‘spectrum_uncert_std’.
reference_spectrum (Dict[str, np.ndarray], optional) – Reference spectrum with ‘E_MeV’ and ‘Phi’ keys.
save_to (str, optional) – Path to save figure.
show (bool, optional) – Call plt.show() (default: True).
**plot_kwargs (dict) – Additional keyword arguments for plotting.
- Returns:
Figure and axes objects.
- Return type:
Tuple[plt.Figure, plt.Axes]
- compare_regularization_methods(readings: dict[str, float], noise_var: float | None = None, plot: bool = False, plot_path: str | None = None) dict[str, Any][source]#
Compare regularization selection methods for given readings.
- Parameters:
readings (Dict[str, float]) – Detector readings.
noise_var (float, optional) – Noise variance for discrepancy principle.
plot (bool, optional) – If True, generate comparison plot.
plot_path (str, optional) – Path to save the plot.
- Returns:
Comparison results.
- Return type:
Dict[str, Any]
- randomization_experiment(readings: dict[str, float], noise_var: float | None = None, n_samples: int = 10, rseed: int = 0, methods: list[str] | None = None) dict[str, Any][source]#
Run randomization experiments for given readings.
- Parameters:
readings (Dict[str, float]) – Detector readings.
noise_var (float, optional) – Noise variance for generating perturbed measurements.
n_samples (int, optional) – Number of random samples for each method, default 10.
rseed (int, optional) – Random seed for reproducibility, default 0.
methods (list of str, optional) – List of methods to run: ‘lcurve’, ‘dp’, ‘gcv’, ‘lcurve_full’.
- Returns:
Randomization experiment results.
- Return type:
Dict[str, Any]
- compare(*spectra: Any, metrics: str | list[str] | None = None, labels: list[str] | None = None, readings1: ndarray | None = None, readings2: ndarray | None = None, response_matrix: ndarray | None = None, plot: bool = False, save_to: str | None = None, dpi: int = 300, figsize: tuple[int, int] = (14, 5), return_fig: bool = False, **plot_kwargs) dict[str, float] | DataFrame | tuple[dict[str, float] | DataFrame, Any, Any][source]#
Compare two or more spectra using comparison metrics.
Each spectrum can be provided as: - np.ndarray of length matching
self.n_energy_bins- dict with a'spectrum'key (e.g. an unfolding result) - result dictionary returned by anyunfold_*methodWhen the energy grid is available, EURADOS-style metrics (dose differences, peak errors, log-lethargy correlation, etc.) are computed automatically.
- Parameters:
*spectra (np.ndarray or dict) – Two or more spectra to compare.
metrics (str, list of str, or None) – Metric(s) to compute. If None, all metrics are used.
labels (list of str, optional) – Labels for each spectrum. Required for 3+ spectra.
readings1 (np.ndarray, optional) – Measured readings for response-matrix consistency check. If a spectrum is a result dict containing
'readings', those values are used as a fallback.readings2 (np.ndarray, optional) – Measured readings for response-matrix consistency check. If a spectrum is a result dict containing
'readings', those values are used as a fallback.response_matrix (np.ndarray, optional) – Response matrix for the consistency check. If a spectrum is a result dict containing
'response_matrix', that value is used as a fallback.plot (bool, optional) – If True, generate a comparison figure with spectra overlay and metric bar chart.
save_to (str, optional) – Path to save the figure (png/jpg/eps/pdf).
dpi (int, optional) – Figure DPI (default: 300).
figsize (tuple, optional) – Figure size (default: (14, 5)).
return_fig (bool, optional) – If True, return (result, fig, ax) tuple.
**plot_kwargs (dict) – Additional keyword arguments passed to matplotlib/seaborn plots.
- Returns:
If two spectra: dict {metric: value}. If three or more: pd.DataFrame with metrics as rows and comparison pairs as columns. If return_fig=True: (result, fig, ax).
- Return type:
dict or pd.DataFrame or tuple
- unfold_pgd(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 1000, tolerance: float = 1e-06, regularization: float = 0.0, constraint: str = 'nonnegative', total_fluence: float | None = None, x_max: float = inf, backtracking: bool = False, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, variance_reduction: str = 'none', save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using projected gradient descent.
Solves
min 1/2||Ax-b||^2 + reg/2||x||^2with the iterates projected onto the constraint set at every step (‘nonnegative’, ‘box’ or ‘simplex’); the simplex option keeps the total fluence exactly fixed. A duality-gap certificate (Lagrange duality / KKT diagnostics) is appended to the result asduality_gap.- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
max_iterations (int, optional) – Maximum iterations (default: 1000).
tolerance (float, optional) – Relative change tolerance (default: 1e-6).
regularization (float, optional) – Tikhonov regularization strength (default: 0.0).
constraint (str, optional) –
'nonnegative','box'or'simplex'(default: ‘nonnegative’).total_fluence (Optional[float], optional) – Total fluence for the simplex constraint.
x_max (float, optional) – Upper bound for the box constraint (default: inf).
backtracking (bool, optional) – Use Armijo backtracking (default: False).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
variance_reduction (str, optional) – MC variance reduction: ‘none’, ‘antithetic’, ‘control’, ‘both’.
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
max_neutron_energy (Optional[float], optional) – Restrict the energy grid to bins below this energy.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_mirror_descent(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 2000, tolerance: float = 1e-08, mirror_map: str = 'entropy', step_size: float | None = None, total_fluence: float | None = None, regularization: float = 0.0, p: float = 3.0, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, variance_reduction: str = 'none', save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using mirror descent.
Bregman-geometry descent: the ‘entropy’ mirror map yields multiplicative updates generalizing MLEM/GRAVEL/SAND-II and keeps the total fluence constant; ‘log’, ‘l2’ and ‘pnorm’ maps give other non-negative geometries.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess (strictly positive for ‘entropy’/’log’).
max_iterations (int, optional) – Maximum iterations (default: 2000).
tolerance (float, optional) – Relative change tolerance (default: 1e-8).
mirror_map (str, optional) –
'entropy','log','l2'or'pnorm'(default: ‘entropy’).step_size (Optional[float], optional) – Mirror step; golden-section line search when None.
total_fluence (Optional[float], optional) – Simplex level for the entropy map.
regularization (float, optional) – Tikhonov regularization strength (default: 0.0).
p (float, optional) – Order of the p-norm mirror map (default: 3.0).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
variance_reduction (str, optional) – MC variance reduction: ‘none’, ‘antithetic’, ‘control’, ‘both’.
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
max_neutron_energy (Optional[float], optional) – Restrict the energy grid to bins below this energy.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_frank_wolfe(readings: dict[str, float], initial_spectrum: ndarray | None = None, total_fluence: float | None = None, max_iterations: int = 1000, tolerance: float = 1e-08, away_steps: bool = True, line_search: str = 'exact', calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, variance_reduction: str = 'none', save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the Frank-Wolfe algorithm.
Conditional-gradient method on the fluence simplex: each iteration solves a linear minimization oracle (single active bin) and moves a fraction towards it; the total fluence is preserved exactly. Optional Wolfe away-steps reduce zig-zagging near the optimum.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess (projected onto the simplex).
total_fluence (Optional[float], optional) – Simplex level F; estimated from a uniform fit when None.
max_iterations (int, optional) – Maximum iterations (default: 1000).
tolerance (float, optional) – Frank-Wolfe gap tolerance (default: 1e-8).
away_steps (bool, optional) – Use Wolfe away-steps (default: True).
line_search (str, optional) –
'exact'or'backtracking'(default: ‘exact’).calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
variance_reduction (str, optional) – MC variance reduction: ‘none’, ‘antithetic’, ‘control’, ‘both’.
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
max_neutron_energy (Optional[float], optional) – Restrict the energy grid to bins below this energy.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_admm(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 500, tolerance: float = 1e-06, l1_penalty: float = 0.0, tv_penalty: float = 0.0, rho: float | None = None, adaptive_rho: bool = True, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, variance_reduction: str = 'none', save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using consensus ADMM.
Splits the L1/TV-regularized NNLS problem into an exact NNLS x-update (non-negativity enforced at every iteration), soft- thresholding z-updates and dual ascent;
rhois adapted automatically (Boyd et al., sec. 3.4.1).- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
max_iterations (int, optional) – Maximum outer iterations (default: 500).
tolerance (float, optional) – Relative change tolerance (default: 1e-6).
l1_penalty (float, optional) – L1 (sparsity) penalty weight (default: 0.0).
tv_penalty (float, optional) – Total-variation penalty weight (default: 0.0).
rho (Optional[float], optional) – ADMM penalty parameter (auto when None).
adaptive_rho (bool, optional) – Adapt rho every 10 iterations (default: True).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
variance_reduction (str, optional) – MC variance reduction: ‘none’, ‘antithetic’, ‘control’, ‘both’.
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
max_neutron_energy (Optional[float], optional) – Restrict the energy grid to bins below this energy.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_lbfgsb(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 500, tolerance: float = 1e-08, regularization: float = 0.0, smoothness: float = 0.0, x_min: float = 0.0, x_max: float = inf, lbfgs_history: int = 10, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, variance_reduction: str = 'none', save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the L-BFGS-B quasi-Newton method.
Limited-memory BFGS with box bounds minimizes the smooth Tikhonov objective with analytic gradients;
smoothnessadds a second-difference (curvature) penalty against oscillations.- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
max_iterations (int, optional) – Maximum iterations (default: 500).
tolerance (float, optional) – Gradient-norm stopping tolerance (default: 1e-8).
regularization (float, optional) – Tikhonov (L2) regularization strength (default: 0.0).
smoothness (float, optional) – Second-difference penalty weight (default: 0.0).
x_min (float, optional) – Lower bound (default: 0.0).
x_max (float, optional) – Upper bound (default: inf).
lbfgs_history (int, optional) – L-BFGS memory (default: 10).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
variance_reduction (str, optional) – MC variance reduction: ‘none’, ‘antithetic’, ‘control’, ‘both’.
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
max_neutron_energy (Optional[float], optional) – Restrict the energy grid to bins below this energy.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_coordinate_descent(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 2000, tolerance: float = 1e-08, l1_penalty: float = 0.0, l2_penalty: float = 0.0, selection: str = 'cyclic', calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, variance_reduction: str = 'none', save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using coordinate descent.
Exact closed-form coordinate minimization of the NNLS objective with optional L1/L2 penalties; O(m) per coordinate via a running residual, cyclic or random coordinate order.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
max_iterations (int, optional) – Maximum sweeps (default: 2000).
tolerance (float, optional) – Relative change tolerance (default: 1e-8).
l1_penalty (float, optional) – L1 penalty weight (default: 0.0).
l2_penalty (float, optional) – Ridge penalty weight (default: 0.0).
selection (str, optional) –
'cyclic'or'random'(default: ‘cyclic’).calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
variance_reduction (str, optional) – MC variance reduction: ‘none’, ‘antithetic’, ‘control’, ‘both’.
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed (also used by ‘random’ selection).
max_neutron_energy (Optional[float], optional) – Restrict the energy grid to bins below this energy.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_subgradient(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 3000, tolerance: float = 1e-08, l1_penalty: float = 0.0, tv_penalty: float = 0.0, step_policy: str = 'diminishing', step_size: float = 1.0, decay: float = 1.0, polyak_margin: float = 0.05, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, variance_reduction: str = 'none', save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using projected subgradient descent.
Nonsmooth L1/TV penalties handled natively via subgradients with Polyak / diminishing / fixed step-size policies; the best iterate by objective value is returned.
- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
max_iterations (int, optional) – Maximum iterations (default: 3000).
tolerance (float, optional) – Relative change tolerance (default: 1e-8).
l1_penalty (float, optional) – L1 penalty weight (default: 0.0).
tv_penalty (float, optional) – TV penalty weight (default: 0.0).
step_policy (str, optional) –
'polyak','diminishing'or'fixed'(default: ‘diminishing’).step_size (float, optional) – Base step size (default: 1.0).
decay (float, optional) – Diminishing-step decay rate (default: 1.0).
polyak_margin (float, optional) – Relative margin for the Polyak optimal-value estimate (default: 0.05).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
variance_reduction (str, optional) – MC variance reduction: ‘none’, ‘antithetic’, ‘control’, ‘both’.
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
max_neutron_energy (Optional[float], optional) – Restrict the energy grid to bins below this energy.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_extragradient(readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 2000, tolerance: float = 1e-08, noise_level: float = 0.02, step_size: float | None = None, calculate_errors: bool = False, mc_noise_level: float = 0.01, n_montecarlo: int = 100, variance_reduction: str = 'none', save_result: bool = False, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Korpelevich’s extragradient.
Solves the robust saddle formulation
min_{x>=0} 1/2||Ax-b||^2 + delta*||Ax-b||_2(guarding against measurement noise of L2 norm up todelta = noise_level * ||b||_2) via its bilinear saddle form with the two-step extragradient scheme.- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
max_iterations (int, optional) – Maximum iterations (default: 2000).
tolerance (float, optional) – Relative change tolerance (default: 1e-8).
noise_level (float, optional) – Relative noise-ball radius (default: 0.02).
step_size (Optional[float], optional) – Extragradient step; auto from the Lipschitz bound when None.
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
mc_noise_level (float, optional) – Noise level for Monte-Carlo uncertainty (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
variance_reduction (str, optional) – MC variance reduction: ‘none’, ‘antithetic’, ‘control’, ‘both’.
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
max_neutron_energy (Optional[float], optional) – Restrict the energy grid to bins below this energy.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- unfold_cuqi(readings: dict[str, float], initial_spectrum: ndarray | None = None, sampler: str = 'pcn', noise_level: float = 0.05, prior: str = 'gmrf', gmrf_order: int = 1, lengthscale: float = 3.0, prec: float = 1.0, hierarchical: bool | None = None, delta_alpha: float = 1.0, delta_beta: float = 0.0001, n_samples: int = 2000, n_burnin: int = 1000, thin: int = 1, chains: int = 2, scale: float = 0.05, max_depth: int = 8, step_size: float | None = None, credible_level: float = 95.0, calculate_errors: bool = False, mc_noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, progressbar: bool = False, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum with CUQIpy Bayesian samplers.
Full Bayesian unfolding powered by CUQIpy (Computational Uncertainty Quantification for Inverse Problems, DTU). The spectrum is modelled on the log scale with a smoothness prior (GMRF or Ornstein-Uhlenbeck Gaussian) anchored on a data-driven center, and the posterior is explored with one of the CUQIpy samplers:
'pcn': Preconditioned Crank-Nicolson'cwmh': Component-wise Metropolis-Hastings'ula': Unadjusted Langevin algorithm'mala': Metropolis-adjusted Langevin algorithm'nuts': No-U-Turn Sampler'gibbs'/'gibbs_nuts': hierarchical Gibbs sampling where the GMRF smoothness precision is inferred from the data through a conjugate Gamma hyperprior (CUQIpyHybridGibbs)
The result contains the mean posterior spectrum, per-bin posterior standard deviations, 95% (configurable) HPD credible intervals and convergence diagnostics (ESS, R-hat, acceptance rate) under
result['cuqi_stats'].Requires the optional
cuqipypackage (pip install bssunfold[cuqi]orpip install cuqipy).- Parameters:
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Prior center guess for the spectrum. When None, the non-negative least-squares solution of
A @ x = bis used as the prior center.sampler (str, optional) – CUQIpy sampler (default:
'pcn').noise_level (float, optional) – Relative likelihood noise scale (default: 0.05).
prior (str, optional) – Log-spectrum prior:
'gmrf'(default) or'ou'.gmrf_order (int, optional) – GMRF operator order, 1 or 2 (default: 1); higher is smoother.
lengthscale (float, optional) – OU correlation length in energy bins (default: 3.0).
prec (float, optional) – Fixed prior precision scale (default: 1.0); inferred from the data by the hierarchical Gibbs samplers.
hierarchical (bool, optional) – Force the hierarchical Gibbs scheme (default: derived from
sampler).delta_alpha (float, optional) – Gamma hyperprior shape for the GMRF precision (default: 1.0).
delta_beta (float, optional) – Gamma hyperprior rate for the GMRF precision (default: 1e-4).
n_samples (int, optional) – Posterior samples per chain (default: 2000).
n_burnin (int, optional) – Warmup iterations per chain (default: 1000).
thin (int, optional) – Thinning interval (default: 1).
chains (int, optional) – Number of independent chains (default: 2).
scale (float, optional) – Proposal step size (default: 0.05).
max_depth (int, optional) – NUTS maximum tree depth (default: 8).
step_size (float, optional) – NUTS leapfrog step size (default: None, tuned by CUQIpy).
credible_level (float, optional) – Credible mass (%) of the HPD interval (default: 95).
calculate_errors (bool, optional) – Calculate additional Monte-Carlo errors (default: False).
mc_noise_level (float, optional) – Noise level for the additional Monte-Carlo loop (default: 0.01).
n_montecarlo (int, optional) – Number of additional Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
progressbar (bool, optional) – Present for API consistency (default: False).
max_neutron_energy (Optional[float], optional) – Truncate the response matrices above this energy (MeV).
- Returns:
Unfolding results dictionary. Includes the standard keys (
energy,spectrum,effective_readings,residual,residual_norm,method,doserates) plus CUQI-specific keysspectrum_uncertainty,spectrum_lower,spectrum_upperandcuqi_stats.- Return type:
Dict[str, Any]
- Raises:
ImportError – If CUQIpy is not installed.
RuntimeError – If MCMC sampling fails.
Examples
>>> from bssunfold import Detector >>> detector = Detector() >>> result = detector.unfold_cuqi( ... readings, ... sampler='gibbs_nuts', ... n_samples=1000, ... chains=2, ... ) >>> spectrum = result['spectrum'] >>> acc = result['cuqi_stats']['acc_rate']
See also
unfold_mcmcPyMC/NUTS Bayesian unfolding
unfold_bayesBayesian iterative unfolding (D’Agostini)
Unfold Methods#
The following unfolding methods are available through the Detector class:
- bssunfold.core.unfold_cvxpy.unfold_cvxpy(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, regularization: float = 0.0001, norm: int = 2, solver: str = 'default', calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, regularization_method: str = 'manual', noise_var: float | None = None, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold neutron spectrum using convex optimization (cvxpy).
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
regularization (float, optional) – Regularization parameter (default: 1e-4).
norm (int, optional) – Norm type (1 for L1, 2 for L2), default: 2.
solver (str, optional) – Solver to use (‘ECOS’ or ‘default’).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
regularization_method (str, optional) – Method for selecting regularization parameter.
noise_var (float, optional) – Noise variance for discrepancy principle.
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_landweber.unfold_landweber(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 1000, tolerance: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold using Landweber iteration method.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
max_iterations (int, optional) – Maximum iterations (default: 1000).
tolerance (float, optional) – Convergence tolerance (default: 1e-6).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_mlem.unfold_mlem(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 1000, tolerance: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold using MLEM algorithm.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
max_iterations (int, optional) – Maximum iterations (default: 1000).
tolerance (float, optional) – Convergence tolerance (default: 1e-6).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_qpsolvers.unfold_qpsolvers(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, regularization: float = 0.0001, norm: int = 2, solver: str = 'osqp', calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, regularization_method: str = 'manual', noise_var: float | None = None, smoothness_order: int = 0, smoothness_weight: float = 1.0, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using qpsolvers with regularization selection.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess.
regularization (float, optional) – Regularization parameter, default: 1e-4.
norm (int, optional) – Norm type (1 for L1, 2 for L2), default: 2.
solver (str, optional) – QP solver name, default: ‘osqp’.
calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty, default: False.
noise_level (float, optional) – Noise level for Monte-Carlo, default: 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples, default: 100.
save_result (bool, optional) – Save result to history, default: False.
regularization_method (str, optional) – Method for selecting regularization parameter.
noise_var (float, optional) – Noise variance for discrepancy principle (‘dp’ method).
smoothness_order (int, optional) – Smoothness constraint order (0, 1, or 2), default: 0.
smoothness_weight (float, optional) – Weight for smoothness term, default: 1.0.
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results including spectrum, residuals, and metadata.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_mystic.unfold_mystic(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, regularization: float = 0.0001, norm: int = 2, solver: str = 'fmin_powell', maxiter: int | None = 2000, maxfun: int | None = 20000, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, regularization_method: str = 'manual', noise_var: float | None = None, smoothness_order: int = 0, smoothness_weight: float = 1.0, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold using mystic with regularization selection.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess.
regularization (float, optional) – Regularization parameter, default: 1e-4.
norm (int, optional) – Norm type (1 for L1, 2 for L2), default: 2.
solver (str, optional) – Mystic solver name, default: ‘fmin_powell’.
maxiter (int, optional) – Maximum number of solver iterations, default: 2000.
maxfun (int, optional) – Maximum number of function evaluations, default: 20000.
calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty, default: False.
noise_level (float, optional) – Noise level for Monte-Carlo, default: 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples, default: 100.
save_result (bool, optional) – Save result to history, default: False.
regularization_method (str, optional) – Method for selecting regularization parameter.
noise_var (float, optional) – Noise variance for discrepancy principle (‘dp’ method).
smoothness_order (int, optional) – Smoothness constraint order (0, 1, or 2), default: 0.
smoothness_weight (float, optional) – Weight for smoothness term, default: 1.0.
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results including spectrum, residuals, and metadata.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_mystic.unfold_mystic_hybrid(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, regularization: float = 0.0001, norm: int = 2, global_solver: str = 'diffev2', local_solver: str = 'fmin_powell', global_maxiter: int | None = None, global_maxfun: int | None = None, local_maxiter: int | None = None, local_maxfun: int | None = None, npop: int | None = None, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, regularization_method: str = 'manual', noise_var: float | None = None, smoothness_order: int = 0, smoothness_weight: float = 1.0, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Two-stage hybrid unfolding: global search + local refinement.
Stage 1 uses a population-based solver (
diffev2by default) with automatically derived bounds to robustly locate the basin of the global minimum. Stage 2 feeds that result asx0into a local direct-search solver (fmin_powellby default) for precise final convergence. This combines the robustness of global optimization with the accuracy of local optimization.- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess for the global stage.
regularization (float, optional) – Regularization parameter, default: 1e-4.
norm (int, optional) – Norm type (1 for L1, 2 for L2), default: 2.
global_solver (str, optional) – Population-based solver for stage 1 (
'diffev'or'diffev2'), default:'diffev2'.local_solver (str, optional) – Local solver for stage 2 (
'fmin'or'fmin_powell'), default:'fmin_powell'.global_maxiter (int, optional) – Maximum iterations for the global stage (default: 200).
global_maxfun (int, optional) – Maximum function evaluations for the global stage.
local_maxiter (int, optional) – Maximum iterations for the local stage (default: 2000).
local_maxfun (int, optional) – Maximum function evaluations for the local stage.
npop (int, optional) – Population size for the global stage.
calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty, default: False.
noise_level (float, optional) – Noise level for Monte-Carlo, default: 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples, default: 100.
save_result (bool, optional) – Save result to history, default: False.
regularization_method (str, optional) – Method for selecting regularization parameter.
noise_var (float, optional) – Noise variance for discrepancy principle (‘dp’ method).
smoothness_order (int, optional) – Smoothness constraint order (0, 1, or 2), default: 0.
smoothness_weight (float, optional) – Weight for smoothness term, default: 1.0.
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results including spectrum, residuals, and metadata.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_genetic.unfold_genetic(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, solver: str = 'pso', epoch: int = 500, pop_size: int = 50, regularization: float = 0.01, norm: int = 2, smoothness_order: int = 2, smoothness_weight: float = 1.0, entropy_weight: float = 0.0, n_runs: int = 1, early_stop: int | None = None, half_range: float = 2.0, two_step: bool = False, n_coarse: int | None = None, smoother: str = 'none', sigma_smooth: float = 2.0, crossover: str = 'single', mutation: str = 'random', pareto_select: str = 'knee', calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, verbose: bool = False) dict[str, Any][source]#
Unfold a neutron spectrum using a meta-heuristic algorithm.
The optimizer searches in log space seeded with a Landweber warm-start solution (or the provided
initial_spectrum), bounded tolog(seed) +/- half_rangedecades, with a scale-consistent objective.- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess. If None, a Landweber warm-start solution is used to seed the population.
solver (str, optional) – Meta-heuristic algorithm: ‘pso’, ‘ga’, ‘de’, ‘es’, ‘ep’, ‘abc’, ‘gwo’, ‘cmaes’ or ‘nsga2’ (default: ‘pso’).
epoch (int, optional) – Maximum number of generations (default: 500).
pop_size (int, optional) – Population size (default: 50).
regularization (float, optional) – Tikhonov regularisation weight (default: 1e-2).
norm (int, optional) – Norm for the regularisation term (1 or 2), default: 2.
smoothness_order (int, optional) – Second-difference smoothing order (0, 1 or 2), default: 2.
smoothness_weight (float, optional) – Weight of the smoothing term (default: 1.0).
entropy_weight (float, optional) – Weight of the negative Shannon-entropy objective (default: 0).
n_runs (int, optional) – Number of independent runs to average (default: 1). Not used by the ‘nsga2’ solver.
early_stop (int, optional) – Early-stopping patience (epochs without improvement).
half_range (float, optional) – Half-width of the log-space search bounds in decades around the seed (default: 2.0).
two_step (bool, optional) – If True, run the two-step genetic scheme (TGASU-style) with a coarse first step seeding the full-resolution population (default: False).
n_coarse (int, optional) – Number of coarse bins for the
two_stepmode (default: None, i.e.max(8, n // 4)).smoother (str, optional) – Post-processing smoother: ‘none’, ‘gaussian’, ‘mbc’, ‘gaussian_mbc’ or ‘second_difference’ (default: ‘none’).
sigma_smooth (float, optional) – Gaussian filter sigma for the smoothers (default: 2.0).
crossover (str, optional) – GA crossover operator: ‘single’ or ‘arithmetic’ (TGASU); only used by the numpy GA engine (default: ‘single’).
mutation (str, optional) – GA mutation operator: ‘random’ or ‘iterative’ (TGASU, decreasing step); only used by the numpy GA engine (default: ‘random’).
pareto_select (str, optional) – Selection from the Pareto front for the ‘nsga2’ solver: ‘knee’, ‘min_residual’ or ‘max_entropy’ (default: ‘knee’).
calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty, default: False.
noise_level (float, optional) – Noise level for Monte-Carlo, default: 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples, default: 100.
save_result (bool, optional) – Save result to history, default: False.
random_state (int, optional) – Random seed for reproducibility.
verbose (bool, optional) – If True, print the MEALPY optimisation progress.
- Returns:
Unfolding results including spectrum, residuals, and metadata.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_gnowee.unfold_gnowee(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, population: int = 25, max_gens: int = 200, max_fevals: int = 5000, stall_limit: int = 200, conv_tol: float = 1e-06, opt_conv_tol: float = 0.01, frac_elite: float = 0.2, frac_levy: float = 1.0, frac_mutation: float = 0.2, alpha_levy: float = 1.5, gamma_levy: float = 1.0, n_levy: int = 1, scaling_factor: float = 10.0, init_sampling: str = 'lhc', regularization: float = 0.01, norm: int = 2, smoothness_order: int = 2, smoothness_weight: float = 1.0, entropy_weight: float = 0.0, half_range: float = 2.0, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, verbose: bool = False) dict[str, Any][source]#
Unfold a neutron spectrum using the Gnowee metaheuristic optimizer.
The optimizer searches in log space seeded with a Landweber warm-start solution (or the provided
initial_spectrum), bounded tolog(seed) ± half_rangedecades, with a scale-consistent objective combining the relative L2 residual, Tikhonov regularisation, second-difference smoothness and (optionally) negative Shannon entropy.- Parameters:
detector_names (list[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess. If
None, a Landweber warm-start solution is used to seed the population.population (int, optional) – Population size, default 25.
max_gens (int, optional) – Maximum generations, default 200.
max_fevals (int, optional) – Maximum fitness evaluations, default 5_000.
stall_limit (int, optional) – Stall-based termination threshold (evaluations), default 200.
conv_tol (float, optional) – Relative improvement tolerance for timeline extension, default 1e-6.
opt_conv_tol (float, optional) – Tolerance on the optimum value for fitness convergence, default 1e-2.
frac_elite (float, optional) – Elite fraction for crossover/scatter-search, default 0.2.
frac_levy (float, optional) – Lévy flight fraction, default 1.0.
frac_mutation (float, optional) – Mutation discovery probability, default 0.2.
alpha_levy (float, optional) – Lévy exponent, default 1.5.
gamma_levy (float, optional) – Lévy scale, default 1.0.
n_levy (int, optional) – Independent Lévy samples, default 1.
scaling_factor (float, optional) – Lévy step scale, default 10.0.
init_sampling (str, optional) – Initial sampler:
'lhc'or'random', default'lhc'.regularization (float, optional) – Tikhonov regularisation weight, default 1e-2.
norm (int, optional) – Norm for the regularisation term (1 or 2), default 2.
smoothness_order (int, optional) – Smoothness penalty order (0, 1 or 2), default 2.
smoothness_weight (float, optional) – Weight for the smoothness term, default 1.0.
entropy_weight (float, optional) – Weight of the negative Shannon-entropy objective (0 disables it).
half_range (float, optional) – Half-width of the log-space search bounds in decades, default 2.0.
calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty, default False.
noise_level (float, optional) – Noise level for Monte-Carlo, default 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples, default 100.
save_result (bool, optional) – Save result to history, default False.
random_state (int, optional) – Random seed for reproducibility.
verbose (bool, optional) – Print Gnowee progress.
- Returns:
Unfolding results including spectrum, residuals, and metadata.
- Return type:
dict[str, Any]
- bssunfold.core.unfold_nnqp.unfold_nnqp(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, regularization: float = 0.0001, smoothness_order: int = 0, smoothness_weight: float = 1.0, tol: float = 1e-06, max_iterations: int = 10000, floor: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold a neutron spectrum using NNQP (non-negative QP by coordinate descent).
Solves
minimize 1/2 · ||A x − b||² + α/2 · ||L x||² + α0/2 · ||x||² subject to x ≥ 0
where
Lis the finite-difference derivative matrix of ordersmoothness_order, using the coordinate-descent NNQP solver of Giovannucci & Pehlevan (simonsfoundation/NNQP).- Parameters:
detector_names (list[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Warm-start spectrum. If
Nonethe NNQP solver uses a uniform random initial guess.regularization (float, optional) – Tikhonov / smoothness regularisation weight (default 1e-4).
smoothness_order (int, optional) – Smoothness penalty order (0, 1 or 2), default 0.
smoothness_weight (float, optional) – Weight for the smoothness term (default 1.0).
tol (float, optional) – Convergence tolerance (default 1e-6).
max_iterations (int, optional) – Iteration cap (default 10 000).
floor (float, optional) – Diagonal regularisation floor added to
Qto guarantee strict positive-definiteness (default 1e-6).calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty, default False.
noise_level (float, optional) – Noise level for Monte-Carlo, default 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples, default 100.
save_result (bool, optional) – Save result to history, default False.
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results including spectrum, residuals, and metadata.
- Return type:
dict[str, Any]
- bssunfold.core.unfold_qpmad.unfold_qpmad(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, regularization: float = 0.0001, smoothness_order: int = 0, smoothness_weight: float = 1.0, floor: float = 1e-06, lb: ndarray | None = None, ub: ndarray | None = None, backend: str = 'python', tol: float = 1e-09, max_iterations: int = 10000, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold a neutron spectrum using qpmad (Goldfarb-Idnani dual active-set QP).
Solves
minimize 1/2 · ||A x − b||² + α/2 · ||L x||² + α0/2 · ||x||² subject to lb ≤ x ≤ ub (default: x ≥ 0)
by recasting it as the strictly-convex QP
min 0.5 xᵀHx + gᵀxand applying the qpmad algorithm of Sherikov (asherikov/qpmad).- Parameters:
detector_names (list[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Accepted for API compatibility (the Goldfarb-Idnani algorithm starts from the unconstrained minimum, not from
x0).regularization (float, optional) – Tikhonov / smoothness regularisation weight (default 1e-4).
smoothness_order (int, optional) – Smoothness penalty order (0, 1 or 2), default 0.
smoothness_weight (float, optional) – Weight for the smoothness term (default 1.0).
floor (float, optional) – Diagonal regularisation floor added to
H(default 1e-6).lb (np.ndarray, optional) – Simple bounds on the spectrum. If both are
None(default) the method enforcesx ≥ 0.ub (np.ndarray, optional) – Simple bounds on the spectrum. If both are
None(default) the method enforcesx ≥ 0.backend (str, optional) –
'python'(default) uses a pure-NumPy port of Goldfarb-Idnani;'qpmad'calls the upstream C++ library if its Python bindings are installed (falls back to'python'otherwise).tol (float, optional) – Numerical tolerance (default 1e-9).
max_iterations (int, optional) – Iteration cap for the Python backend (default 10 000).
calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty, default False.
noise_level (float, optional) – Noise level for Monte-Carlo, default 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples, default 100.
save_result (bool, optional) – Save result to history, default False.
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results including spectrum, residuals, and metadata.
- Return type:
dict[str, Any]
- bssunfold.core.unfold_pgd.unfold_pgd(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 1000, tolerance: float = 1e-06, regularization: float = 0.0, constraint: str = 'nonnegative', total_fluence: float | None = None, x_max: float = inf, backtracking: bool = False, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, variance_reduction: str = 'none', save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using projected gradient descent.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
max_iterations (int, optional) – Maximum iterations (default: 1000).
tolerance (float, optional) – Relative change tolerance (default: 1e-6).
regularization (float, optional) – Tikhonov regularization strength (default: 0.0).
constraint (str, optional) – Constraint set:
'nonnegative','box'or'simplex'(default: ‘nonnegative’).total_fluence (float, optional) – Total fluence for the simplex constraint (required for ‘simplex’).
x_max (float, optional) – Upper bound for the box constraint (default: inf).
backtracking (bool, optional) – Use Armijo backtracking (default: False).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
variance_reduction (str, optional) – Monte-Carlo variance reduction:
'none','antithetic','control'or'both'(default: ‘none’).save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_frank_wolfe.unfold_frank_wolfe(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, total_fluence: float | None = None, max_iterations: int = 1000, tolerance: float = 1e-08, away_steps: bool = True, line_search: str = 'exact', calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, variance_reduction: str = 'none', save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the Frank–Wolfe algorithm.
The spectrum is constrained to the simplex
{x >= 0, sum(x) = F}whereFdefaults to the total fluence implied by an initial uniform fit.- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess (projected onto the simplex).
total_fluence (Optional[float], optional) – Simplex level
F. If None, estimated from a uniform fit.max_iterations (int, optional) – Maximum iterations (default: 1000).
tolerance (float, optional) – Frank-Wolfe gap tolerance (default: 1e-8).
away_steps (bool, optional) – Use Wolfe away-steps (default: True).
line_search (str, optional) –
'exact'or'backtracking'(default: ‘exact’).calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
variance_reduction (str, optional) – Monte-Carlo variance reduction:
'none','antithetic','control'or'both'(default: ‘none’).save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_mirror_descent.unfold_mirror_descent(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 2000, tolerance: float = 1e-08, mirror_map: str = 'entropy', step_size: float | None = None, total_fluence: float | None = None, regularization: float = 0.0, p: float = 3.0, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, variance_reduction: str = 'none', save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using mirror descent.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess (strictly positive for ‘entropy’/’log’ maps).
max_iterations (int, optional) – Maximum iterations (default: 2000).
tolerance (float, optional) – Relative change tolerance (default: 1e-8).
mirror_map (str, optional) –
'entropy','log','l2'or'pnorm'(default: ‘entropy’).step_size (Optional[float], optional) – Mirror step size; default
1 / (||A||^2 + reg).total_fluence (Optional[float], optional) – Total fluence for the entropy map (default: sum of initial spectrum, estimated from a uniform fit when not provided).
regularization (float, optional) – Tikhonov regularization strength (default: 0.0).
p (float, optional) – Order of the p-norm mirror map (default: 3.0).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
variance_reduction (str, optional) – Monte-Carlo variance reduction:
'none','antithetic','control'or'both'(default: ‘none’).save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_admm.unfold_admm(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 500, tolerance: float = 1e-06, l1_penalty: float = 0.0, tv_penalty: float = 0.0, rho: float | None = None, adaptive_rho: bool = True, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, variance_reduction: str = 'none', save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using consensus ADMM.
Supports exact L1 (sparsity) and 1D total-variation penalties together with the hard non-negativity constraint; the x-subproblem is solved exactly by NNLS, so the physical constraint holds at every iteration.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
max_iterations (int, optional) – Maximum outer iterations (default: 500).
tolerance (float, optional) – Relative change tolerance (default: 1e-6).
l1_penalty (float, optional) – L1 (sparsity) penalty weight (default: 0.0).
tv_penalty (float, optional) – Total-variation penalty weight
||D x||_1(default: 0.0).rho (Optional[float], optional) – ADMM penalty parameter; adapted automatically when None.
adaptive_rho (bool, optional) – Adapt rho every 10 iterations (default: True).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
variance_reduction (str, optional) – Monte-Carlo variance reduction:
'none','antithetic','control'or'both'(default: ‘none’).save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_lbfgsb.unfold_lbfgsb(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 500, tolerance: float = 1e-08, regularization: float = 0.0, smoothness: float = 0.0, x_min: float = 0.0, x_max: float = inf, lbfgs_history: int = 10, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, variance_reduction: str = 'none', save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the L-BFGS-B quasi-Newton method.
Minimizes the smooth Tikhonov objective with analytic gradients under box bounds
x_min <= x <= x_max;smoothnessadds a discrete Laplacian penalty against oscillations.- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
max_iterations (int, optional) – Maximum iterations (default: 500).
tolerance (float, optional) – Gradient-norm stopping tolerance (default: 1e-8).
regularization (float, optional) – Tikhonov (L2) regularization strength (default: 0.0).
smoothness (float, optional) – Second-difference (curvature) penalty weight (default: 0.0).
x_min (float, optional) – Lower bound (default: 0.0).
x_max (float, optional) – Upper bound (default: inf).
lbfgs_history (int, optional) – L-BFGS memory (default: 10).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
variance_reduction (str, optional) – Monte-Carlo variance reduction:
'none','antithetic','control'or'both'(default: ‘none’).save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_coordinate_descent.unfold_coordinate_descent(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 2000, tolerance: float = 1e-08, l1_penalty: float = 0.0, l2_penalty: float = 0.0, selection: str = 'cyclic', calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, variance_reduction: str = 'none', save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using coordinate descent.
Exact closed-form coordinate minimization of the NNLS objective with optional L1/L2 penalties; O(m) per coordinate via a running residual.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
max_iterations (int, optional) – Maximum sweeps (default: 2000).
tolerance (float, optional) – Relative change tolerance (default: 1e-8).
l1_penalty (float, optional) – L1 penalty weight (default: 0.0).
l2_penalty (float, optional) – Ridge penalty weight (default: 0.0).
selection (str, optional) –
'cyclic'or'random'coordinate order (default: ‘cyclic’).calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
variance_reduction (str, optional) – Monte-Carlo variance reduction:
'none','antithetic','control'or'both'(default: ‘none’).save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility (also used by ‘random’ selection).
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_subgradient.unfold_subgradient(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 3000, tolerance: float = 1e-08, l1_penalty: float = 0.0, tv_penalty: float = 0.0, step_policy: str = 'diminishing', step_size: float = 1.0, decay: float = 1.0, polyak_margin: float = 0.05, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, variance_reduction: str = 'none', save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using projected subgradient descent.
Nonsmooth L1/TV penalties are handled natively via subgradients with Polyak / diminishing / fixed step-size policies; the best iterate by objective value is returned.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
max_iterations (int, optional) – Maximum iterations (default: 3000).
tolerance (float, optional) – Relative change tolerance (default: 1e-8).
l1_penalty (float, optional) – L1 penalty weight (default: 0.0).
tv_penalty (float, optional) – TV penalty weight (default: 0.0).
step_policy (str, optional) –
'polyak','diminishing'or'fixed'(default: ‘diminishing’).step_size (float, optional) – Base step size (default: 1.0).
decay (float, optional) – Diminishing-step decay rate (default: 1.0).
polyak_margin (float, optional) – Relative margin for the Polyak optimal-value estimate (default: 0.05).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
variance_reduction (str, optional) – Monte-Carlo variance reduction:
'none','antithetic','control'or'both'(default: ‘none’).save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_extragradient.unfold_extragradient(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 2000, tolerance: float = 1e-08, noise_level: float = 0.02, step_size: float | None = None, calculate_errors: bool = False, mc_noise_level: float = 0.01, n_montecarlo: int = 100, variance_reduction: str = 'none', save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Korpelevich’s extragradient method.
Solves the robust saddle formulation
min_{x>=0} 1/2||Ax-b||^2 + delta*||Ax-b||_2via its bilinear saddle form with the two-step extragradient scheme;delta = noise_level * ||b||_2bounds the assumed measurement-noise norm.- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
max_iterations (int, optional) – Maximum iterations (default: 2000).
tolerance (float, optional) – Relative change tolerance (default: 1e-8).
noise_level (float, optional) – Relative noise-ball radius (default: 0.02).
step_size (Optional[float], optional) – Extragradient step; auto from the Lipschitz bound when None.
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
mc_noise_level (float, optional) – Noise level for Monte-Carlo uncertainty (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
variance_reduction (str, optional) – Monte-Carlo variance reduction:
'none','antithetic','control'or'both'(default: ‘none’).save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_smt.unfold_smt(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, nonneg: bool = True, timeout_ms: int = 10000, objective: str = 'l2', calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold a neutron spectrum using an SMT solver.
Minimizes the L2 residual
||A x - b||_2(via the exact KKT characterization of the least-squares optimum) and then the total fluencesum(x). Falls back to the L1 residual on non-converging solves.- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess (accepted for API compatibility).
nonneg (bool, optional) – Constrain the spectrum to be non-negative (default: True).
timeout_ms (int, optional) – SMT solver timeout in milliseconds (default: 10000).
objective (str, optional) – Residual objective:
'l2'(default) or'l1'.calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty, default: False.
noise_level (float, optional) – Noise level for Monte-Carlo, default: 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples, default: 100.
save_result (bool, optional) – Save result to history, default: False.
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results including spectrum, residuals, and metadata.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_scip.unfold_scip(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, regularization: float = 0.0001, norm: int = 2, timeout: float = 10.0, smoothness_order: int = 0, smoothness_weight: float = 1.0, nonneg: bool = True, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, regularization_method: str = 'manual', noise_var: float | None = None, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold a neutron spectrum using the SCIP optimizer.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess.
regularization (float, optional) – Regularization parameter, default: 1e-4.
norm (int, optional) – Norm type (1 for L1, 2 for L2), default: 2.
timeout (float, optional) – Time limit in seconds, default: 10.0.
smoothness_order (int, optional) – Smoothness constraint order (0, 1, or 2), default: 0.
smoothness_weight (float, optional) – Weight for the smoothness term, default: 1.0.
nonneg (bool, optional) – Constrain the spectrum to be non-negative, default: True.
calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty, default: False.
noise_level (float, optional) – Noise level for Monte-Carlo, default: 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples, default: 100.
save_result (bool, optional) – Save result to history, default: False.
regularization_method (str, optional) – Method for selecting the regularization parameter (‘manual’, ‘cosine’, ‘lcurve’, ‘gcv’, ‘dp’).
noise_var (float, optional) – Noise variance for discrepancy principle (‘dp’ method).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results including spectrum, residuals, and metadata.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_docplex.unfold_docplex(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, regularization: float = 0.0001, norm: int = 2, timeout: float = 10.0, smoothness_order: int = 0, smoothness_weight: float = 1.0, nonneg: bool = True, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, regularization_method: str = 'manual', noise_var: float | None = None, random_state: int | None = None, max_neutron_energy: float | None = None) dict[str, Any][source]#
Unfold a neutron spectrum using CPLEX (docplex).
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess.
regularization (float, optional) – Regularization parameter, default: 1e-4.
norm (int, optional) – Norm type (1 for L1, 2 for L2), default: 2.
timeout (float, optional) – Time limit in seconds, default: 10.0.
smoothness_order (int, optional) – Smoothness constraint order (0, 1, or 2), default: 0.
smoothness_weight (float, optional) – Weight for the smoothness term, default: 1.0.
nonneg (bool, optional) – Constrain the spectrum to be non-negative, default: True.
calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty, default: False.
noise_level (float, optional) – Noise level for Monte-Carlo, default: 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples, default: 100.
save_result (bool, optional) – Save result to history, default: False.
regularization_method (str, optional) – Method for selecting the regularization parameter (‘manual’, ‘cosine’, ‘lcurve’, ‘gcv’, ‘dp’).
noise_var (float, optional) – Noise variance for discrepancy principle (‘dp’ method).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results including spectrum, residuals, and metadata.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_epic.unfold_epic(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, target_sigmas: ndarray | None = None, sigma_frac: float = 0.1, regularization_order: int = 1, non_neg: bool = True, noise_var: float | None = None, homogeneous_step: bool = True, regularize: dict[str, Any] | None = None, beta_shift_k: float = 0, beta_distance: float = 2, EPIC_bool: ndarray | None = None, V: ndarray | None = None, LSQpar: dict[str, Any] | None = None, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold a spectrum using EPIC Tikhonov regularization.
The EPIC weights are computed once from the response matrix and the resolved target sigmas (they do not depend on the measurements), and are reused by the Monte-Carlo uncertainty propagation.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess (unused by this method).
target_sigmas (np.ndarray, optional) – Target a posteriori standard deviations of the model parameters. If None, derived from
sigma_frac.sigma_frac (float, optional) – Fraction of the naive least-squares magnitude used to derive default target sigmas (default: 0.1).
regularization_order (int, optional) – Regularization operator order: 0 (identity), 1 (first derivative, default) or 2 (second derivative).
non_neg (bool, optional) – Apply non-negativity constraints (default: True).
noise_var (float, optional) – Variance of the i.i.d. misfit errors (default: None, identity Cx).
homogeneous_step (bool, optional) – Run a preliminary homogeneous Ch search (default: True).
regularize (dict, optional) – If given (can be empty), damp the EPIC weights.
beta_shift_k (float, optional) – Center shift for the beta bounds (default: 0).
beta_distance (float, optional) – Distance kept from the representability limit (default: 2).
EPIC_bool (np.ndarray, optional) – Boolean mask of which parameters are subject to the EPIC.
V (np.ndarray, optional) – Matrix mapping the searched betas to the regularization rows, beta = V @ y (shape (H.shape[0], len(y))).
LSQpar (dict, optional) – Tuning parameters for the nonlinear least-squares solver.
calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_cs.unfold_cs(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, n_atoms: int | None = None, sparsity: int | None = None, dictionary: ndarray | None = None, n_dictionary_iterations: int = 20, sigma_min: float = 0.01, sigma_decrease_factor: float = 0.5, mu_0: float = 1.0, L: int = 3, max_iterations: int = 1000, tolerance: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Compressive Sensing (CS).
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
n_atoms (int, optional) – Number of dictionary atoms.
sparsity (int, optional) – Target sparsity for dictionary learning.
dictionary (np.ndarray, optional) – Pre-learned dictionary (n x n_atoms).
n_dictionary_iterations (int, optional) – Number of K-SVD iterations (default: 20).
sigma_min (float, optional) – SL0 minimum sigma (default: 0.01).
sigma_decrease_factor (float, optional) – SL0 sigma decrease factor (default: 0.5).
mu_0 (float, optional) – SL0 step-size factor (default: 1.0).
L (int, optional) – SL0 inner iterations per sigma (default: 3).
max_iterations (int, optional) – SL0 maximum outer iterations (default: 1000).
tolerance (float, optional) – Convergence tolerance (default: 1e-6).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_doroshenko.unfold_doroshenko(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 1000, tolerance: float = 1e-06, regularization: float = 0.0, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the Doroshenko coordinate update method.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, uniform spectrum is used.
max_iterations (int, optional) – Maximum number of iterations, default: 1000.
tolerance (float, optional) – Convergence tolerance for solution change, default: 1e-6.
regularization (float, optional) – Regularization strength to prevent division by zero, default: 0.0.
calculate_errors (bool, optional) – Flag to calculate uncertainty via Monte-Carlo, default: False.
noise_level (float, optional) – Noise level for Monte-Carlo uncertainty calculation, default: 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples for error estimation, default: 100.
save_result (bool, optional) – If True, save result to internal history, default: False.
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Dictionary containing unfolding results.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_directed_divergence.unfold_directed_divergence(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 200, tol_chi2: float = 1.0, tol_rel: float = 1e-06, relative_uncertainty: float = 0.05, smoothness_order: int = 0, smoothness_weight: float = 0.0, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold Bonner-sphere readings using directed divergence.
- bssunfold.core.unfold_kaczmarz.unfold_kaczmarz(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 1000, omega: float = 1.0, tolerance: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the Kaczmarz algorithm (ART).
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, zero spectrum is used.
max_iterations (int, optional) – Maximum number of iterations, default: 1000.
omega (float, optional) – Relaxation parameter (0 < omega <= 2), default: 1.0.
tolerance (float, optional) – Convergence tolerance for solution change, default: 1e-6.
calculate_errors (bool, optional) – Flag to calculate uncertainty via Monte-Carlo, default: False.
noise_level (float, optional) – Noise level for Monte-Carlo uncertainty calculation, default: 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples for error estimation, default: 100.
save_result (bool, optional) – If True, save result to internal history, default: False.
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Dictionary containing unfolding results.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_lmfit.unfold_lmfit(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, method: str = 'lbfgsb', model_name: str = 'elastic', regularization: float = 0.0001, regularization2: float = 0.0001, l1_weight: float = 0.5, regularization_method: str = 'manual', lambda_range: tuple[float, float] = (1e-06, 0.1), n_lambda: int = 30, verbose: bool = True, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using lmfit with L1/L2/Elastic regularization.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, uniform spectrum based on mean readings.
method (str, optional) – lmfit solver name (leastsq, lbfgsb, etc.), default: “lbfgsb”.
model_name (str, optional) – Regularization model: elastic, lasso, ridge, default: “elastic”.
regularization (float, optional) – L1 regularization strength, default: 1e-4.
regularization2 (float, optional) – L2 regularization strength for elastic net, default: 1e-4.
l1_weight (float, optional) – L1 weight for elastic net (0=pure L2, 1=pure L1), default: 0.5.
regularization_method (str, optional) – How to choose the regularization parameter. Options: ‘manual’ (use the supplied
regularization/regularization2), or an information criterion ‘aic’, ‘aicc’ or ‘bic’. For non-manual selection the regularization parameter is swept overlambda_rangeand the candidate minimizing the chosen criterion is used. Default: ‘manual’.lambda_range (Tuple[float, float], optional) – Log-spaced range of lambda candidates for information-criterion selection, default: (1e-6, 1e-1).
n_lambda (int, optional) – Number of lambda candidates for information-criterion selection, default: 30.
verbose (bool, optional) – Print the regularization selection summary, default: True.
calculate_errors (bool, optional) – Flag to calculate uncertainty via Monte-Carlo, default: False.
noise_level (float, optional) – Noise level for Monte-Carlo uncertainty calculation, default: 0.01.
n_montecarlo (int, optional) – Number of Monte-Carlo samples for error estimation, default: 100.
save_result (bool, optional) – If True, save result to internal history, default: False.
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Dictionary containing unfolding results.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_mlem_odl.unfold_mlem_odl(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, tolerance: float = 1e-06, max_iterations: int = 1000, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold using MLEM with ODL (Operator Discretization Library).
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum approximation. If None, uniform spectrum is used.
tolerance (float, optional) – Convergence tolerance. Default is 1e-6.
max_iterations (int, optional) – Maximum number of iterations. Default is 1000.
calculate_errors (bool, optional) – Flag for calculating restoration errors. Default is False.
noise_level (float, optional) – Noise level for error calculation. Default is 0.01.
n_montecarlo (int, optional) – Number of Monte Carlo samples for error calculation. Default is 100.
save_result (bool, optional) – If True, save result to internal history. Default is False.
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Dictionary containing the spectrum restoration results.
- Return type:
Dict
- bssunfold.core.unfold_mlem_stop.unfold_mlem_stop(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 15000, cps_crossover: float = 30000.0, j_threshold: float | None = None, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold using MLEM-STOP algorithm with J-factor stopping criterion.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
max_iterations (int, optional) – Maximum iterations (default: 15000).
cps_crossover (float, optional) – Crossover CPS value for automatic J threshold (default: 30000).
j_threshold (float, optional) – J-factor stopping threshold. If None, computed automatically.
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_combined.unfold_combined(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], pipeline: list[dict[str, Any]], calculate_errors: bool = False, verbose: bool = True) dict[str, Any] | None[source]#
Combined unfolding method applying multiple methods sequentially.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
pipeline (List[Dict[str, Any]]) – List of methods for sequential application. Each dict should contain: - ‘method’: str - method name (e.g., ‘cvxpy’, ‘landweber’, ‘mlem’) - ‘params’: dict - parameters for the method - ‘use_as_initial’: bool (optional) - use result as initial guess - ‘store_intermediate’: bool (optional) - store intermediate result
calculate_errors (bool, optional) – Flag to calculate errors for the last method.
verbose (bool, optional) – Flag to print debug information.
- Returns:
Dictionary with unfolding results.
- Return type:
Dict
- bssunfold.core.unfold_interpret.unfold_interpret(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, regularization: float = 0.0001, norm: int = 2, smoothness_order: int = 0, smoothness_weight: float = 1.0, enforce_norm: bool = False, norm_value: float = 1.0, regularization_method: str = 'manual', noise_var: float | None = None, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, tolerance: float = 1e-08, ridge_coeff: Any = 'auto', interpret_options: dict[str, Any] | None = None) dict[str, Any][source]#
Unfold and interpret a neutron spectrum with pyoptexplain.
The unfolding QP (identical to
unfold_qpsolvers) is solved through pyoptexplain and the solution is interpreted. The returned dictionary is a standard bssunfold result dict with two extra keys:report– Markdown interpretation report.interpretation_metrics– JSON-friendly metrics dictionary.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess (used by some regularization methods).
regularization (float, optional) – Regularization parameter (default: 1e-4).
norm (int, optional) – Penalty norm, 1 or 2 (default: 2).
smoothness_order (int, optional) – Smoothness derivative order, 0, 1 or 2 (default: 0).
smoothness_weight (float, optional) – Weight of the smoothness term (default: 1.0).
enforce_norm (bool, optional) – Add
sum(x) == norm_value(default: False).norm_value (float, optional) – Target total fluence (default: 1.0).
regularization_method (str, optional) – Method for selecting the regularization parameter.
noise_var (float, optional) – Noise variance for the discrepancy principle (‘dp’ method).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
tolerance (float, optional) – Solver feasibility/optimality tolerance (default: 1e-8). Pyoptexplain’s backend may fail with
iteration_limiton large problems at the strictest tolerance; relax it (e.g. 1e-5) in that case.ridge_coeff (float or
"auto", optional) – Diagonal ridge added toQwhennorm == 1andsmoothness_order == 0to cure rank deficiency ofA'A."auto"(default) uses1e-8 * trace(Q) / n. Set to0.0to disable the ridge.interpret_options (dict, optional) – Extra keyword arguments forwarded to
interpret_qp().
- Returns:
Standardized unfolding result plus
reportandinterpretation_metricskeys.- Return type:
Dict[str, Any]
- bssunfold.core.unfold_gravel.unfold_gravel(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, tolerance: float = 1e-08, max_iterations: int = 1000, regularization: float = 0.0, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the GRAVEL algorithm.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
tolerance (float, optional) – Convergence tolerance (default: 1e-8).
max_iterations (int, optional) – Maximum iterations (default: 1000).
regularization (float, optional) – Regularization parameter (default: 0.0).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_maxed.unfold_maxed(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, sigma_factor: float = 0.1, max_iterations: int = 5000, tolerance: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the MAXED algorithm.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Reference spectrum. If None, a flat reference is used.
sigma_factor (float, optional) – Relative measurement uncertainty (default: 0.1). Larger values → smoother spectrum.
max_iterations (int, optional) – Maximum L-BFGS-B iterations (default: 5000).
tolerance (float, optional) – Convergence tolerance (default: 1e-6).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_tikhonov_legendre.unfold_tikhonov_legendre(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, delta: float = 0.05, n_polynomials: int = 15, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Tikhonov regularization with Legendre basis.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Not used (provided for API compatibility).
delta (float, optional) – Regularization parameter (default: 0.05).
n_polynomials (int, optional) – Number of Legendre polynomials (default: 15).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_bayes.unfold_bayes(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 4000, tolerance: float = 0.001, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Bayesian iterative unfolding.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Prior spectrum.
max_iterations (int, optional) – Maximum iterations (default: 4000).
tolerance (float, optional) – Convergence tolerance (default: 1e-3).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_bayes_spline_regularization.unfold_bayes_spline_regularization(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 4000, tolerance: float = 0.001, spline_degree: int = 3, spline_smooth: float = 0.01, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Bayes with spline regularization.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Prior spectrum.
max_iterations (int, optional) – Maximum iterations (default: 4000).
tolerance (float, optional) – Convergence tolerance (default: 1e-3).
spline_degree (int, optional) – Spline degree (default: 3).
spline_smooth (float, optional) – Spline smoothing parameter (default: 1e-2).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_statreg.unfold_statreg(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, unfoldermethod: str = 'EmpiricalBayes', regularization: float | None = None, basis_name: str = 'CubicSplines', boundary: str | None = None, derivative_degree: int = 2, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Turchin’s statistical regularisation.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
unfoldermethod (str, optional) – Regularisation method (default:
'EmpiricalBayes').regularization (float, optional) – Regularisation parameter for
'User'method.basis_name (str, optional) – Ignored (kept for API compatibility).
boundary (str, optional) – Ignored (kept for API compatibility).
derivative_degree (int, optional) – Derivative degree (default: 2).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_reconst.unfold_reconst(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, pp: float = 0.001, alpha: float = -1.0, beta: float = 0.0, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Turchin’s statistical regularization.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Ignored (API compatibility).
pp (float, optional) – PP parameter (default: 1e-3).
alpha (float, optional) – Regularization. <0 auto, >0 fixed (default: -1).
beta (float, optional) – Data fidelity. 0 auto, >0 fixed (default: 0).
calculate_errors (bool, optional) – Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result (default: False).
random_state (int, optional) – Random seed.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_scipy_direct_method.unfold_scipy_direct_method(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, tolerance: float = 1e-08, max_iterations: int = 4000, method: str = 'cg', calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using scipy direct solvers.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
tolerance (float, optional) – Solver tolerance (default: 1e-8).
max_iterations (int, optional) – Maximum solver iterations (default: 4000).
method (str, optional) – Solver method (default: ‘cg’).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_tsvd.unfold_tsvd(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, method: str = 'discrepancy', k: int | None = None, threshold: float | None = None, noise_level: float | None = None, svd_solver: str = 'full', calculate_errors: bool = False, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Truncated SVD (TSVD).
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
method (str, optional) – K-selection method (default: ‘discrepancy’).
k (int, optional) – Fixed truncation parameter.
threshold (float, optional) – Threshold ratio for truncation.
noise_level (float, optional) – Noise level estimate.
svd_solver (str, optional) – SVD backend:
'full'(default),'arpack'or'propack'.calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_lanczos.unfold_lanczos(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, regularization_method: str = 'gcv', max_iterations: int | None = None, regularization: float = 1e-08, noise_level: float | None = None, calculate_errors: bool = False, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold a neutron spectrum with the Lanczos-hybrid (Krylov) method.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess (accepted for API compatibility).
regularization_method (str, optional) – Method for selecting the regularization parameter. Only
'gcv'is supported (default: ‘gcv’).max_iterations (int, optional) – Maximum Krylov dimension. Defaults to
min(n_detectors, n_energy_bins).regularization (float, optional) – Fallback regularization parameter (default: 1e-8).
noise_level (float, optional) – Relative noise level used for discrepancy-principle early stopping.
calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty (default: False).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_cgls.unfold_cgls(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 100, tolerance: float = 1e-12, noise_level: float | None = None, regularization: float = 0.0, smoothness_order: int = 0, calculate_errors: bool = False, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold a neutron spectrum with the CGLS method.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess.
max_iterations (int, optional) – Maximum number of iterations (default: 100).
tolerance (float, optional) – Relative tolerance on the normal-equation residual (default: 1e-12).
noise_level (float, optional) – Relative noise level used for discrepancy-principle stopping.
regularization (float, optional) – Tikhonov regularization parameter (default: 0.0).
smoothness_order (int, optional) – Derivative order of the regularization operator L used when
regularizationis positive (default: 0).calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty (default: False).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_gks.unfold_gks(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, smoothness_order: int = 0, regularization_method: str = 'gcv', max_iterations: int | None = None, regularization: float = 1e-08, noise_level: float | None = None, calculate_errors: bool = False, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold a neutron spectrum with the Generalized Krylov Subspace method.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess (accepted for API compatibility).
smoothness_order (int, optional) – Derivative order of the regularization operator L (default: 0).
regularization_method (str, optional) – Method for selecting the regularization parameter:
'gcv','dp','lcurve'or'manual'(default: ‘gcv’).max_iterations (int, optional) – Maximum Krylov dimension. Defaults to
min(n_detectors, n_energy_bins).regularization (float, optional) – Manual/fallback regularization parameter (default: 1e-8).
noise_level (float, optional) – Relative noise level used by the Discrepancy Principle.
calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty (default: False).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_tikhonov_tv.unfold_tikhonov_tv(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, epsilon: float | None = None, mu: tuple[float, float, float] = (1.0, 1.0, 1.0), max_iterations: int = 100, type_: str = 'TT', beta: float = 1.0, zthr: float = 2.5, tolerance: float = 0.0001, noise_level: float | None = None, calculate_errors: bool = False, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold a neutron spectrum with noise-constrained Tikhonov-TV.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess (accepted for API compatibility).
epsilon (float, optional) – (Estimate of) the squared 2-norm of the noise. If None, derived from
noise_level((noise_level * ||b||)^2) or from the residuals of an unregularized least-squares solve.mu (tuple, optional) – Penalty parameters
(mu1, mu2, mu3)(default: (1.0, 1.0, 1.0)).max_iterations (int, optional) – Maximum number of ADMM iterations (default: 100).
type (str, optional) – Optimization problem:
'TT','TV'or'T'(default: ‘TT’).beta (float, optional) – Balancing parameter between TV and Tikhonov terms, or
'adapt'for adaptive estimation (default: 1.0).zthr (float, optional) – Threshold for the adaptive beta estimation (default: 2.5).
tolerance (float, optional) – Stabilization stopping criterion (default: 1e-4).
noise_level (float, optional) – Relative noise level used to derive a default
epsilon.calculate_errors (bool, optional) – If True, calculate Monte-Carlo uncertainty (default: False).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_sandii.unfold_sandii(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 50, tolerance: float = 0.001, chi_fac: int = 1, relative_uncertainty: float = 0.1, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the SAND-II algorithm.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, a flat spectrum is used.
max_iterations (int, optional) – Maximum number of iterations (default: 50).
tolerance (float, optional) – Maximum relative spectrum change used when
chi_fac=0(default: 1e-3).chi_fac (int, optional) – Convergence criterion (default: 1, chi-square based).
relative_uncertainty (float, optional) – Relative measurement uncertainty for the chi-square criterion (default: 0.1).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_crystal_ball.unfold_crystal_ball(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, regularization: float = 0.0, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the CRYSTAL BALL algorithm.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Unused; accepted for interface uniformity.
regularization (float, optional) – Tikhonov regularization strength for the Gram-matrix inversion (default: 0.0).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_rfsp_jul.unfold_rfsp_jul(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 200, tolerance: float = 0.0001, weights: ndarray | None = None, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the RFSP-JUL algorithm.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, a flat spectrum is used.
max_iterations (int, optional) – Maximum number of iterations (default: 200).
tolerance (float, optional) – Convergence tolerance on maximum relative spectrum change (default: 1e-4).
weights (np.ndarray, optional) – Per-detector weights for the residual term. None => equal weights.
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_staysl.unfold_staysl(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, relative_uncertainty: float = 0.1, prior_uncertainty: float = 1.0, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the STAY’SL Bayesian algorithm.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Prior spectrum guess. If None, a flat spectrum is used as the prior mean.
relative_uncertainty (float, optional) – Relative measurement uncertainty for
Cb(default: 0.1).prior_uncertainty (float, optional) – Relative prior uncertainty for
Cx(default: 1.0).calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_express.unfold_express(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, n_groups: int = 6, interval_boundaries: ndarray | None = None, max_iterations: int = 3, tol_iteration: float = 0.05, relative_uncertainty: float = 0.05, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold Bonner-sphere readings with a piecewise-exponential model.
- bssunfold.core.unfold_bunki.unfold_bunki(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, smoothing: float = 0.1, max_iterations: int = 1000, tolerance: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the BUNKI (SPUNIT) algorithm.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, a flat spectrum is used.
smoothing (float, optional) – Three-point smoothing factor (default: 0.1).
max_iterations (int, optional) – Maximum number of iterations (default: 1000).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 1e-6).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_bunkiut.unfold_bunkiut(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, smoothing: float = 0.05, max_iterations: int = 1000, tolerance: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the BUNKI-UT (BON31G) algorithm.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, a flat spectrum is used.
smoothing (float, optional) – Three-point smoothing factor (default: 0.05).
max_iterations (int, optional) – Maximum number of iterations (default: 1000).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 1e-6).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_osem.unfold_osem(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 50, n_subsets: int = 1, tolerance: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the OSEM algorithm.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, a flat spectrum is used.
max_iterations (int, optional) – Maximum number of iterations (default: 50).
n_subsets (int, optional) – Number of ordered subsets over the detector readings (default: 1, i.e. standard MLEM).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 1e-6).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_osem_anlm.unfold_osem_anlm(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 50, n_subsets: int = 1, tolerance: float = 1e-06, h: float | None = None, search_window: int = 11, similarity_window: int = 3, alpha: float = 1.0, anlm_mode: str = 'subset', log_space: bool = True, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the OSEM-ANLM algorithm.
Ordered-subset expectation maximisation with asymptotic non-local means regularization (Jamaati et al. 2026, https://doi.org/10.1038/s41598-026-70607-1), adapted to Bonner sphere spectra: the ANLM filter is applied to the intermediate spectrum after every OSEM subset update (
anlm_mode="subset") or once to the OSEM result (anlm_mode="post").- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, a flat spectrum is used.
max_iterations (int, optional) – Maximum number of iterations (default: 50).
n_subsets (int, optional) – Number of ordered subsets over the detector readings (default: 1, i.e. standard MLEM with per-iteration ANLM).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 1e-6).
h (float, optional) – Noise level for the ANLM filter. If None (default), it is estimated automatically from the intermediate spectra.
search_window (int, optional) – ANLM search window
N(default: 11, article optimum).similarity_window (int, optional) – ANLM similarity (patch) window
nu(default: 3, article optimum).alpha (float, optional) – Spread of the Gaussian kernel over the similarity window (default: 1.0).
anlm_mode (str, optional) –
'subset'— ANLM after every subset update (default, article pseudo-code);'post'— single ANLM application to the OSEM result.log_space (bool, optional) – Apply the ANLM filter to the logarithm of the spectrum (default: True, scale-free for spectra spanning orders of magnitude). See
anlm_filter_1d().calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_louhi.unfold_louhi(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, smoothness: float = 1.0, smooth_order: int = 1, auto_smooth: bool = False, chi2_target: float | None = None, max_iterations: int = 500, tolerance: float = 1e-06, relative_uncertainty: float = 0.1, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, variance_reduction: str = 'none', save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the LOUHI78 algorithm.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Default (a-priori) spectrum. If None, a flat spectrum is used.
smoothness (float, optional) – Smoothing weight
lambda(default: 1.0).smooth_order (int, optional) – Smoothing operator order 0/1/2 (default: 1, first differences).
auto_smooth (bool, optional) – Adjust the smoothing weight automatically to reach
chi2_target(default: False).chi2_target (Optional[float], optional) – Target data chi-square for
auto_smooth(default: number of detectors).max_iterations (int, optional) – Maximum number of Hildreth sweeps (default: 500).
tolerance (float, optional) – Relative objective change per sweep for convergence (default: 1e-6).
relative_uncertainty (float, optional) – Relative measurement uncertainty (default: 0.1).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
variance_reduction (str, optional) – MC variance reduction: ‘none’, ‘antithetic’, ‘control’, ‘both’ (default: ‘none’).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_mapem.unfold_mapem(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, prior: str = 'quadratic', beta: float = 0.001, prior_delta: float = 1.0, gamma: float = 1.0, max_iterations: int = 50, tolerance: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using penalised EM (MAP-EM).
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, a flat spectrum is used.
prior (str, optional) – Prior type:
'none','quadratic','logcosh'or'relative_difference'(default:'quadratic').beta (float, optional) – Prior weight (default: 1e-3).
prior_delta (float, optional) – Width parameter of the quadratic/logcosh priors and additive floor of the relative-difference prior (default: 1.0).
gamma (float, optional) – Edge-preservation parameter of the relative-difference prior (default: 1.0).
max_iterations (int, optional) – Maximum number of iterations (default: 50).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 1e-6).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_bsrem.unfold_bsrem(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, prior: str = 'none', beta: float = 0.001, prior_delta: float = 1.0, gamma: float = 1.0, max_iterations: int = 50, n_subsets: int = 1, tolerance: float = 1e-06, relaxation: float | Callable[[int], float] | None = None, addition_after_iteration: float = 0.0001, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the BSREM algorithm.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, a flat spectrum is used.
prior (str, optional) – Prior type:
'none','quadratic','logcosh'or'relative_difference'(default:'none').beta (float, optional) – Prior weight (default: 1e-3).
prior_delta (float, optional) – Width parameter of the quadratic/logcosh priors and additive floor of the relative-difference prior (default: 1.0).
gamma (float, optional) – Edge-preservation parameter of the relative-difference prior (default: 1.0).
max_iterations (int, optional) – Maximum number of iterations (default: 50).
n_subsets (int, optional) – Number of ordered subsets over the detector readings (default: 1).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 1e-6).
relaxation (float or callable, optional) – Relaxation sequence (default: None -> constant 1).
addition_after_iteration (float, optional) – Floor value for spectrum bins (default: 1e-4).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_sart.unfold_sart(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 50, tolerance: float = 1e-06, relaxation: float | Callable[[int], float] | None = None, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the SART algorithm.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, a flat spectrum is used.
max_iterations (int, optional) – Maximum number of iterations (default: 50).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 1e-6).
relaxation (float or callable, optional) – Relaxation sequence (default: None -> constant 0.8).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_ferdor.unfold_ferdor(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 100, tolerance: float = 0.001, smoothing: float = 0.001, chi_squared_target: float = 1.0, relative_uncertainty: float = 0.1, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the FERDOR algorithm.
- Parameters:
detector_names (list[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray | None, optional) – Initial spectrum guess. If None, a flat spectrum is used.
max_iterations (int, optional) – Maximum number of smoothing-weight iterations (default: 100).
tolerance (float, optional) – Relative tolerance on the reduced chi-square (default: 1e-3).
smoothing (float, optional) – Initial smoothing weight alpha (default: 1e-3).
chi_squared_target (float, optional) – Target reduced chi-square per degree of freedom (default: 1.0).
relative_uncertainty (float, optional) – Relative measurement uncertainty for the chi-square criterion (default: 0.1).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
dict[str, Any]
- bssunfold.core.unfold_rebunki.unfold_rebunki(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, smoothing: float = 0.1, max_iterations: int = 1000, tolerance: float = 0.01, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the ReBUNKI (SPUNIT) algorithm.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, a flat spectrum is used.
smoothing (float, optional) – Three-point smoothing factor (default: 0.1).
max_iterations (int, optional) – Maximum number of iterations (default: 1000).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 0.01).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_nsduaz.unfold_nsduaz(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, catalogue: dict[str, ndarray] | None = None, use_catalogue: bool = True, reference_name: str | None = None, smoothing: float = 0.1, max_iterations: int = 1000, tolerance: float = 0.01, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the NSDUAZ algorithm.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Explicit initial spectrum guess. When given, it overrides the catalogue selection.
catalogue (Optional[Dict[str, np.ndarray]], optional) – User-supplied catalogue of candidate initial spectra (label -> spectrum on the detector energy grid). When None, the built-in mini-catalogue is used.
use_catalogue (bool, optional) – If True (default), the initial spectrum is selected from the catalogue when
initial_spectrumis not provided; if False, a flat spectrum is used (NSDUAZ “flat spectrum” mode).reference_name (str, optional) – Reference sphere name for the catalogue statistical test (default: auto-detect 20.32 cm sphere).
smoothing (float, optional) – Three-point smoothing factor (default: 0.1).
max_iterations (int, optional) – Maximum number of iterations (default: 1000).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 0.01).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_parametric.unfold_parametric(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, initial_params: dict[str, float] | None = None, method: str = 'leastsq', optimizer: str = 'lmfit', alpha: float = 0.0001, alpha_auto: bool = False, solver_backend: str = 'auto', max_iter: int = 50, tol: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the FRUIT-based parametric method.
The spectrum is modelled as a weighted superposition of thermal, epithermal and fast components (Bedogni FRUIT / Pyshkina B3S).
The
optimizerparameter selects the backend:"lmfit"– classic lmfit least-squares (default)."cvxpy"– sequential QP via cvxpy (SQP)."qpsolvers"– sequential QP via qpsolvers (SQP)."combined"– lmfit first, then QP refinement.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid in MeV.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess (unused in parametric method).
initial_params (Optional[Dict[str, float]], optional) – Initial parameter values for the parametric model. Keys: b, beta_prime, alpha, beta, P_th, P_epi.
method (str, optional) – lmfit solver method (default: “leastsq”).
optimizer (str, optional) – Backend optimizer: “lmfit”, “cvxpy”, “qpsolvers”, or “combined” (default: “lmfit”).
alpha (float, optional) – Regularization weight for QP-based optimizers (default: 1e-4). Also used as initial alpha for lmfit when alpha_auto is True.
alpha_auto (bool, optional) – If True, select alpha automatically via GCV for the lmfit optimizer (default: False).
solver_backend (str, optional) – QP solver backend string: “auto”, “cvxpy”, “cvxpy:ECOS”, “qpsolvers”, “qpsolvers:osqp”, etc. (default: “auto”).
max_iter (int, optional) – Max SQP iterations for cvxpy/qpsolvers (default: 50).
tol (float, optional) – Convergence tolerance for SQP (default: 1e-6).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_parametric.solve_parametric_cvxpy(A_matrix, b_readings, E, log_steps, initial_params=None, alpha=0.0001, solver_backend='auto', max_iter=50, tol=1e-06)[source]#
Solve parametric unfolding via sequential QP using cvxpy.
The nonlinear parametric model is linearized at each iteration and the resulting QP is solved with cvxpy, including parameter bounds and a Tikhonov penalty on the parameter update.
- Parameters:
A_matrix (np.ndarray) – Response matrix (n_detectors x n_energy).
b_readings (np.ndarray) – Measured readings (n_detectors,).
E (np.ndarray) – Energy grid in MeV.
log_steps (np.ndarray) – Logarithmic energy steps (d(ln E)).
initial_params (dict, optional) – Initial parameter values.
alpha (float, optional) – Regularization weight for parameter penalty (default: 1e-4).
solver_backend (str, optional) – CVXPY solver backend: “auto”, “cvxpy”, or “cvxpy:ECOS” etc. (default: “auto”).
max_iter (int, optional) – Maximum SQP iterations (default: 50).
tol (float, optional) – Convergence tolerance on parameter update norm (default: 1e-6).
- Returns:
(spectrum, success, message, nfev)
- Return type:
Tuple[np.ndarray, bool, str, int]
- bssunfold.core.unfold_parametric.solve_parametric_qpsolvers(A_matrix, b_readings, E, log_steps, initial_params=None, alpha=0.0001, solver_backend='auto', max_iter=50, tol=1e-06)[source]#
Solve parametric unfolding via sequential QP using qpsolvers.
The nonlinear parametric model is linearized at each iteration and the resulting QP is solved with qpsolvers, including parameter bounds and a Tikhonov penalty on the parameter update.
- Parameters:
A_matrix (np.ndarray) – Response matrix (n_detectors x n_energy).
b_readings (np.ndarray) – Measured readings (n_detectors,).
E (np.ndarray) – Energy grid in MeV.
log_steps (np.ndarray) – Logarithmic energy steps (d(ln E)).
initial_params (dict, optional) – Initial parameter values.
alpha (float, optional) – Regularization weight (default: 1e-4).
solver_backend (str, optional) – QP solver backend: “auto”, “qpsolvers”, or “qpsolvers:osqp” etc. (default: “auto”).
max_iter (int, optional) – Maximum SQP iterations (default: 50).
tol (float, optional) – Convergence tolerance on parameter update norm (default: 1e-6).
- Returns:
(spectrum, success, message, nfev)
- Return type:
Tuple[np.ndarray, bool, str, int]
- bssunfold.core.unfold_parametric.solve_parametric_combined(A_matrix, b_readings, E, log_steps, initial_params=None, method='leastsq', alpha=0.0001, solver_backend='auto')[source]#
Solve parametric unfolding: lmfit first, then QP refinement.
Use lmfit to find the best-fit parametric shape parameters.
Take the resulting spectrum as a starting point and refine it with a QP solver (cvxpy or qpsolvers) that adds non-negativity and a penalty toward the lmfit solution.
- Parameters:
A_matrix (np.ndarray) – Response matrix (n_detectors x n_energy).
b_readings (np.ndarray) – Measured readings (n_detectors,).
E (np.ndarray) – Energy grid in MeV.
log_steps (np.ndarray) – Logarithmic energy steps (d(ln E)).
initial_params (dict, optional) – Initial parameter values for lmfit.
method (str, optional) – lmfit method (default: “leastsq”).
alpha (float, optional) – Regularization weight for QP refinement (default: 1e-4).
solver_backend (str, optional) – QP backend for refinement: “auto”, “cvxpy”, “qpsolvers”, etc. (default: “auto”).
- Returns:
(spectrum, success, message, nfev)
- Return type:
Tuple[np.ndarray, bool, str, int]
- bssunfold.core.unfold_parametric2.unfold_parametric2(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, optimizer: str = 'grid', b_range: tuple[float, float, int] = (0.5, 2.0, 5), Tf_range: tuple[float, float, int] = (0.5, 10.0, 5), c_range: tuple[float, float, int] = (0.5, 3.0, 4), alpha: float = 0.0001, solver_backend: str = 'auto', max_iter_qp: int = 50, tol_qp: float = 1e-06, noise_level: float = 0.05, max_iter: int = 200, tol_chi2: float = 1.0, calculate_errors: bool = False, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the BON95 parametric method.
Uses the four-component parameterization from Sannikov BON95: thermal (Maxwellian), epithermal (1/E), intermediate, and fast (evaporation/cascade) components. After parametric fitting, the result is refined by directed-divergence iterations.
The
optimizerparameter selects the parametric fit backend:"grid"– grid search + NLS (default, no extra deps)."cvxpy"– SQP via cvxpy."qpsolvers"– SQP via qpsolvers."combined"– grid search + SQP refinement.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid in MeV.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess (unused in parametric method).
optimizer (str) – Parametric fit optimizer (default: “grid”).
b_range (tuple) – Grid range for b: (min, max, n_points). Used by “grid”/”combined”.
Tf_range (tuple) – Grid range for Tf (MeV): (min, max, n_points). Used by “grid”/”combined”.
c_range (tuple) – Grid range for c: (min, max, n_points). Used by “grid”/”combined”.
alpha (float) – Tikhonov regularization for SQP (default: 1e-4).
solver_backend (str) – QP backend for SQP (default: “auto”).
max_iter_qp (int) – Max SQP iterations (default: 50).
tol_qp (float) – SQP convergence tolerance (default: 1e-6).
noise_level (float) – Relative uncertainty for measurements (default: 0.05 = 5%).
max_iter (int) – Max directed-divergence iterations (default: 200).
tol_chi2 (float) – Chi-squared convergence threshold (default: 1.0).
calculate_errors (bool) – Calculate Monte-Carlo errors (default: False).
n_montecarlo (int) – Number of Monte-Carlo samples (default: 100).
save_result (bool) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_parametric2.solve_parametric2(A_matrix: ndarray, b_readings: ndarray, E: ndarray, ln_steps: ndarray, b_meas: ndarray | None = None, optimizer: str = 'grid', b_range: tuple[float, float, int] = (0.5, 2.0, 5), Tf_range: tuple[float, float, int] = (0.5, 10.0, 5), c_range: tuple[float, float, int] = (0.5, 3.0, 4), alpha: float = 0.0001, solver_backend: str = 'auto', max_iter_qp: int = 50, tol_qp: float = 1e-06, max_iter: int = 200, tol_chi2: float = 1.0) tuple[ndarray, bool, str, int][source]#
Solve unfolding using the full BON95 parametric pipeline.
Parametric fit using the selected optimizer.
Directed-divergence iteration refinement.
- Parameters:
A_matrix (np.ndarray) – Response matrix (n_det x n_energy).
b_readings (np.ndarray) – Measured readings (n_det,).
E (np.ndarray) – Energy grid in MeV.
ln_steps (np.ndarray) – Logarithmic bin widths.
b_meas (np.ndarray, optional) – Measurement uncertainties for weighted NLS.
optimizer (str) – Parametric fit optimizer (default: “grid”): -
"grid"– grid search + NLS (default, no extra deps). -"cvxpy"– SQP via cvxpy. -"qpsolvers"– SQP via qpsolvers. -"combined"– grid search + SQP refinement.b_range (tuple) – Grid search ranges for shape parameters (used by “grid” and “combined”).
Tf_range (tuple) – Grid search ranges for shape parameters (used by “grid” and “combined”).
c_range (tuple) – Grid search ranges for shape parameters (used by “grid” and “combined”).
alpha (float) – Tikhonov regularization for SQP optimizers (default: 1e-4).
solver_backend (str) – QP backend for SQP optimizers (default: “auto”).
max_iter_qp (int) – Max SQP iterations for QP-based optimizers (default: 50).
tol_qp (float) – SQP convergence tolerance (default: 1e-6).
max_iter (int) – Max directed-divergence iterations (default: 200).
tol_chi2 (float) – Chi-squared convergence threshold (default: 1.0).
- Returns:
(spectrum, success, message, nfev)
- Return type:
Tuple[np.ndarray, bool, str, int]
- bssunfold.core.unfold_parametric2.solve_bon95_parametric(A_matrix: ndarray, b_readings: ndarray, E: ndarray, ln_steps: ndarray, b_range: tuple[float, float, int] = (0.5, 2.0, 5), Tf_range: tuple[float, float, int] = (0.5, 10.0, 5), c_range: tuple[float, float, int] = (0.5, 3.0, 4), b_meas: ndarray | None = None, top_n: int = 5) tuple[dict[str, float], float, list[dict[str, float]]][source]#
Grid search + NLS for the BON95 parametric model.
Scans over (b, Tf, c) shape parameters, solves for optimal linear coefficients (a1..a4) at each grid point via weighted NLS, and returns the best result.
- Parameters:
A_matrix (np.ndarray) – Response matrix (n_det x n_energy).
b_readings (np.ndarray) – Measured readings (n_det,).
E (np.ndarray) – Energy grid in MeV.
ln_steps (np.ndarray) – Logarithmic bin widths.
b_range (tuple) – (min, max, n_points) for each shape parameter.
Tf_range (tuple) – (min, max, n_points) for each shape parameter.
c_range (tuple) – (min, max, n_points) for each shape parameter.
b_meas (np.ndarray, optional) – Measurement uncertainties (sigma_i). Used as weights.
top_n (int) – Number of top candidates to return.
- Returns:
(best_params, best_chi2, top_candidates) best_params keys: b, Tf, c, a1, a2, a3, a4
- Return type:
Tuple[dict, float, list]
- bssunfold.core.unfold_parametric2.directed_divergence_iteration(A_matrix: ndarray, b_readings: ndarray, E: ndarray, ln_steps: ndarray, phi0: ndarray, b_meas: ndarray | None = None, max_iter: int = 200, tol_chi2: float = 1.0, tol_rel: float = 1e-06) tuple[ndarray, int, float, bool][source]#
Refine spectrum via directed-divergence (I-divergence) iterations.
Multiplicative update rule (Itakura-Saito / Csiszar-Tusnady):
phi_{k+1}(E_j) = phi_k(E_j) * numerator / denominator
- where:
numerator = sum_i [ A_i(E_j) * M_i / M_p_i ] denominator = sum_i [ A_i(E_j) ]
and M_p_i = sum_j A_i(E_j) * phi_k(E_j) * d(ln E)_j is the computed reading for detector i.
- Parameters:
A_matrix (np.ndarray) – Response matrix (n_det x n_energy).
b_readings (np.ndarray) – Measured readings (n_det,).
E (np.ndarray) – Energy grid in MeV.
ln_steps (np.ndarray) – Logarithmic bin widths.
phi0 (np.ndarray) – Initial spectrum guess (n_energy,).
b_meas (np.ndarray, optional) – Measurement uncertainties. If None, uniform weights.
max_iter (int) – Maximum iterations (default: 200).
tol_chi2 (float) – Stop when chi2 < tol_chi2 (default: 1.0).
tol_rel (float) – Stop when relative change in spectrum < tol_rel (default: 1e-6).
- Returns:
(spectrum, n_iterations, final_chi2, converged)
- Return type:
Tuple[np.ndarray, int, float, bool]
- bssunfold.core.unfold_parametric2.solve_bon95_cvxpy(A_matrix: ndarray, b_readings: ndarray, E: ndarray, ln_steps: ndarray, b_meas: ndarray | None = None, initial_params: dict[str, float] | None = None, alpha: float = 0.0001, solver_backend: str = 'auto', max_iter: int = 50, tol: float = 1e-06) tuple[ndarray, bool, str, int][source]#
Solve BON95 parametric fitting via sequential QP using cvxpy.
Optimizes shape parameters (b, Tf, c) via SQP. At each iteration, the nonlinear model is linearized w.r.t. shape params and the resulting QP is solved with cvxpy. The linear coefficients (a1..a4) are re-solved by NLS at each step.
- Parameters:
A_matrix (np.ndarray) – Response matrix (n_det x n_energy).
b_readings (np.ndarray) – Measured readings (n_det,).
E (np.ndarray) – Energy grid in MeV.
ln_steps (np.ndarray) – Logarithmic bin widths.
b_meas (np.ndarray, optional) – Measurement uncertainties for weighting.
initial_params (dict, optional) – Starting shape params {b, Tf, c}. If None, grid scan is used.
alpha (float) – Tikhonov regularization weight (default: 1e-4).
solver_backend (str) – CVXPY solver backend (default: “auto”).
max_iter (int) – Maximum SQP iterations (default: 50).
tol (float) – Convergence tolerance on parameter update norm (default: 1e-6).
- Returns:
(spectrum, success, message, nfev)
- Return type:
Tuple[np.ndarray, bool, str, int]
- bssunfold.core.unfold_parametric2.solve_bon95_qpsolvers(A_matrix: ndarray, b_readings: ndarray, E: ndarray, ln_steps: ndarray, b_meas: ndarray | None = None, initial_params: dict[str, float] | None = None, alpha: float = 0.0001, solver_backend: str = 'auto', max_iter: int = 50, tol: float = 1e-06) tuple[ndarray, bool, str, int][source]#
Solve BON95 parametric fitting via sequential QP using qpsolvers.
Same algorithm as solve_bon95_cvxpy but uses qpsolvers backends (OSQP, ECOS, etc.).
- Parameters:
A_matrix (np.ndarray) – Response matrix (n_det x n_energy).
b_readings (np.ndarray) – Measured readings (n_det,).
E (np.ndarray) – Energy grid in MeV.
ln_steps (np.ndarray) – Logarithmic bin widths.
b_meas (np.ndarray, optional) – Measurement uncertainties for weighting.
initial_params (dict, optional) – Starting shape params {b, Tf, c}.
alpha (float) – Tikhonov regularization weight (default: 1e-4).
solver_backend (str) – QP solver backend (default: “auto”).
max_iter (int) – Maximum SQP iterations (default: 50).
tol (float) – Convergence tolerance (default: 1e-6).
- Returns:
(spectrum, success, message, nfev)
- Return type:
Tuple[np.ndarray, bool, str, int]
- bssunfold.core.unfold_parametric2.solve_bon95_combined(A_matrix: ndarray, b_readings: ndarray, E: ndarray, ln_steps: ndarray, b_meas: ndarray | None = None, alpha: float = 0.0001, solver_backend: str = 'auto', max_iter_qp: int = 50, tol_qp: float = 1e-06) tuple[ndarray, bool, str, int][source]#
Solve BON95: grid search first, then SQP refinement.
Grid search for best starting (b, Tf, c).
SQP refinement via cvxpy or qpsolvers.
- Parameters:
A_matrix (as usual.)
b_readings (as usual.)
E (as usual.)
ln_steps (as usual.)
b_meas (np.ndarray, optional) – Measurement uncertainties.
alpha (float) – Tikhonov regularization for SQP (default: 1e-4).
solver_backend (str) – QP backend: “auto”, “cvxpy:ECOS”, “qpsolvers:osqp”, etc.
max_iter_qp (int) – Max SQP iterations (default: 50).
tol_qp (float) – SQP convergence tolerance (default: 1e-6).
- Returns:
(spectrum, success, message, nfev)
- Return type:
Tuple[np.ndarray, bool, str, int]
- bssunfold.core.unfold_fruit_like.unfold_fruit_like(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, initial_params: dict[str, float] | None = None, method: str = 'leastsq', calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using FRUIT-like parametric method.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid in MeV.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess (unused in parametric method).
initial_params (Optional[Dict[str, float]], optional) – Initial parameter values for the parametric model.
method (str, optional) – lmfit solver method (default: “leastsq”).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_hybrid_parametric.unfold_hybrid_parametric(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, refinement_method: str = 'landweber', max_iterations: int = 100, tolerance: float = 1e-06, step_size: float = 0.01, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using hybrid parametric-nonparametric method.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid in MeV.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
refinement_method (str, optional) – Refinement method: “landweber” or “mlem” (default: “landweber”).
max_iterations (int, optional) – Maximum iterations (default: 100).
tolerance (float, optional) – Convergence tolerance (default: 1e-6).
step_size (float, optional) – Step size for Landweber (default: 0.01).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_bayesian_parametric.unfold_bayesian_parametric(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, sigma: float = 0.02, n_samples: int = 1000, burn_in: int = 200, proposal_scale: float = 0.1, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Bayesian parametric method.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid in MeV.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess (unused).
sigma (float, optional) – Measurement uncertainty (default: 0.02).
n_samples (int, optional) – Number of MCMC samples (default: 1000).
burn_in (int, optional) – Burn-in samples (default: 200).
proposal_scale (float, optional) – Proposal scale (default: 0.1).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_imaxed.unfold_imaxed(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, sigma_factor: float = 0.1, max_iterations: int = 5000, tolerance: float = 1e-08, line_search_tol: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the IMAXED algorithm.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Reference spectrum. If None, a flat reference is used.
sigma_factor (float, optional) – Relative measurement uncertainty (default: 0.1).
max_iterations (int, optional) – Maximum Newton iterations (default: 5000).
tolerance (float, optional) – Convergence tolerance (default: 1e-8).
line_search_tol (float, optional) – Line search tolerance (default: 1e-6).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_amaxed.unfold_amaxed(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, sigma_factor: float = 0.1, target_chi2: float | None = None, max_iterations: int = 5000, tolerance: float = 1e-08, line_search_tol: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the AMAXED algorithm.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Reference spectrum. If None, a flat reference is used.
sigma_factor (float, optional) – Relative measurement uncertainty (default: 0.1).
target_chi2 (float, optional) – Target chi-squared value. If None, automatically determined.
max_iterations (int, optional) – Maximum Newton iterations (default: 5000).
tolerance (float, optional) – Convergence tolerance (default: 1e-8).
line_search_tol (float, optional) – Line search tolerance (default: 1e-6).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_amaxed_regularization.unfold_amaxed_regularization(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, sigma_factor: float = 0.1, tau: float = 1.0, max_iterations: int = 5000, tolerance: float = 1e-08, line_search_tol: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the AMAXED-Regularization algorithm.
This method combines the advantages of AMAXED with Tikhonov regularization, providing stable convergence without requiring manual chi-squared tuning.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Reference spectrum. If None, a flat reference is used.
sigma_factor (float, optional) – Relative measurement uncertainty (default: 0.1).
tau (float, optional) – Regularization parameter (default: 1.0). Larger values favor solutions closer to the prior.
max_iterations (int, optional) – Maximum Newton iterations (default: 5000).
tolerance (float, optional) – Convergence tolerance (default: 1e-8).
line_search_tol (float, optional) – Line search tolerance (default: 1e-6).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_fista.unfold_fista(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback: Callable | None = None, readings: dict[str, float] | None = None, initial_spectrum: ndarray | None = None, max_iterations: int = 500, tolerance: float = 1e-08, regularization: float = 0.0, l1_penalty: float = 0.0, tv_penalty: float = 0.0, nonnegativity: bool = True, x_min: float = 0.0, x_max: float = inf, noise_level: float | None = None, eta: float = 1.01, calculate_errors: bool = False, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using FISTA algorithm.
The Fast Iterative Shrinkage-Thresholding Algorithm (FISTA) is an accelerated proximal gradient method that achieves O(1/k^2) convergence rate for convex optimization problems. It can handle L1 regularization (sparsity), TV regularization, and box constraints.
- Parameters:
detector_names (List[str]) – Names of detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid in MeV.
sensitivities (Dict[str, np.ndarray]) – Sensitivity matrix as dictionary.
cc_icrp116 (Dict[str, np.ndarray]) – Dose conversion coefficients.
save_result_callback (callable, optional) – Callback to save results.
readings (Dict[str, float], optional) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial guess for spectrum.
max_iterations (int, optional) – Maximum number of iterations (default: 500).
tolerance (float, optional) – Convergence tolerance (default: 1e-8).
regularization (float, optional) – Tikhonov regularization parameter (default: 0.0).
l1_penalty (float, optional) – L1 regularization penalty parameter for sparsity (default: 0.0).
tv_penalty (float, optional) – Total variation penalty parameter (default: 0.0).
nonnegativity (bool, optional) – Apply nonnegativity constraints (default: True).
x_min (float, optional) – Lower bound for solution (default: 0.0).
x_max (float, optional) – Upper bound for solution (default: inf).
noise_level (float, optional) – Relative noise level for discrepancy principle stopping.
eta (float, optional) – Safety factor for discrepancy principle (default: 1.01).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_hybrid_gmres.unfold_hybrid_gmres(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback: Callable | None = None, readings: dict[str, float] | None = None, initial_spectrum: ndarray | None = None, max_iterations: int = 100, regularization_method: str = 'gcv', regularization: float = 0.0, noise_level: float | None = None, eta: float = 1.01, reorthogonalization: bool = True, calculate_errors: bool = False, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Hybrid GMRES method.
The hybrid GMRES method combines the GMRES iterative solver with Tikhonov regularization applied to the projected problem at each iteration. The regularization parameter is selected automatically using GCV or discrepancy principle.
- Parameters:
detector_names (List[str]) – Names of detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid in MeV.
sensitivities (Dict[str, np.ndarray]) – Sensitivity matrix as dictionary.
cc_icrp116 (Dict[str, np.ndarray]) – Dose conversion coefficients.
save_result_callback (callable, optional) – Callback to save results.
readings (Dict[str, float], optional) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial guess for spectrum.
max_iterations (int, optional) – Maximum Krylov dimension (default: 100).
regularization_method (str, optional) – Method for selecting regularization parameter: ‘gcv’, ‘modgcv’, ‘discrep’ (default: ‘gcv’).
regularization (float, optional) – Fixed regularization parameter (used if not auto-selected).
noise_level (float, optional) – Relative noise level for discrepancy principle.
eta (float, optional) – Safety factor for discrepancy principle (default: 1.01).
reorthogonalization (bool, optional) – Apply full reorthogonalization (default: True).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_mcmc.unfold_mcmc(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, sigma_prior: float = 0.05, lambda_prior: float = 0.5, lengthscale: float = 3.0, n_samples: int = 2000, tune: int = 1000, chains: int = 2, target_accept: float = 0.95, use_hierarchical: bool = False, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, progressbar: bool = False) dict[str, Any][source]#
Unfold neutron spectrum using Bayesian MCMC with NUTS sampler.
This method implements a full Bayesian approach to neutron spectrum unfolding using Markov Chain Monte Carlo (MCMC) methods. Unlike traditional methods that provide only point estimates, MCMC generates samples from the full posterior distribution, enabling comprehensive uncertainty quantification.
The implementation uses the No-U-Turn Sampler (NUTS), an adaptive variant of Hamiltonian Monte Carlo (HMC) that automatically tunes its parameters for efficient sampling.
Key Features#
Uncertainty Quantification: Provides 95% credible intervals (HPD) for each energy bin, showing where the spectrum is well-constrained vs uncertain.
Automatic Regularization: Through the log-space smoothness prior, the method keeps the underdetermined solution positive and smooth without the collapse seen with independent per-bin priors.
Convergence Diagnostics: Built-in R-hat and effective sample size (ESS) metrics ensure reliable posterior estimates.
Methodology#
The Bayesian model is defined as:
Likelihood: b ~ Normal(A @ f, sigma) where b is measured readings, A is response matrix, f is spectrum
Prior: f = exp(theta) with theta ~ MvNormal(mu_prior, s * C_ou), where mu_prior is the log of the data-driven prior center (non-negative least-squares solution or user
initial_spectrum), C_ou is the OU correlationexp(-|i-j|/lengthscale), and s ~ HalfNormal(lambda_prior).Hyperpriors (optional): when
use_hierarchical=Truethe relative likelihood noise is estimated as rel_noise ~ HalfNormal(sigma_prior).
- param detector_names:
Names of available detectors.
- type detector_names:
List[str]
- param n_energy_bins:
Number of energy bins.
- type n_energy_bins:
int
- param E_MeV:
Energy grid in MeV.
- type E_MeV:
np.ndarray
- param sensitivities:
Detector sensitivity arrays.
- type sensitivities:
Dict[str, np.ndarray]
- param cc_icrp116:
ICRP-116 conversion coefficients for dose calculation.
- type cc_icrp116:
Dict[str, np.ndarray]
- param save_result_callback:
Callback function to save result to history.
- type save_result_callback:
callable
- param readings:
Detector readings (counts or count rates).
- type readings:
Dict[str, float]
- param initial_spectrum:
Prior center guess for the spectrum. When None, the non-negative least-squares solution of A @ x = b is used as the prior center.
- type initial_spectrum:
Optional[np.ndarray], optional
- param sigma_prior:
Relative likelihood noise scale (default: 0.05). With
use_hierarchical=Falsethe noise is fixed atsigma_prior * |b|; withuse_hierarchical=Trueit is the prior scale of the estimated relative noise.- type sigma_prior:
float, optional
- param lambda_prior:
Prior scale of the log-spectrum spatial amplitude (default: 0.5).
- type lambda_prior:
float, optional
- param lengthscale:
OU smoothness correlation length in energy bins (default: 3.0).
- type lengthscale:
float, optional
- param n_samples:
Number of MCMC samples per chain after tuning (default: 2000).
- type n_samples:
int, optional
- param tune:
Number of tuning (warmup) samples per chain (default: 1000).
- type tune:
int, optional
- param chains:
Number of independent MCMC chains (default: 2).
- type chains:
int, optional
- param target_accept:
Target acceptance rate for NUTS (default: 0.95).
- type target_accept:
float, optional
- param use_hierarchical:
Estimate the likelihood noise from the data (default: False).
- type use_hierarchical:
bool, optional
- param calculate_errors:
Calculate additional Monte-Carlo errors (default: False).
- type calculate_errors:
bool, optional
- param noise_level:
Noise level for additional Monte-Carlo (default: 0.01).
- type noise_level:
float, optional
- param n_montecarlo:
Number of additional Monte-Carlo samples (default: 100).
- type n_montecarlo:
int, optional
- param save_result:
Save result to history (default: False).
- type save_result:
bool, optional
- param random_state:
Random seed for reproducibility.
- type random_state:
int, optional
- param progressbar:
Show sampling progress bar (default: False).
- type progressbar:
bool, optional
- returns:
Unfolding results dictionary containing:
‘energy’: Energy grid (MeV)
‘spectrum’: Mean posterior spectrum
‘spectrum_absolute’: Same as spectrum (for API consistency)
‘spectrum_uncertainty’: Standard deviation of posterior
‘spectrum_lower’: Lower bound of 95% HPD interval
‘spectrum_upper’: Upper bound of 95% HPD interval
‘effective_readings’: Computed readings from posterior mean
‘residual’: Difference between measured and computed readings
‘residual_norm’: L2 norm of residual
‘method’: ‘MCMC’
‘doserates’: Dose rates calculated from spectrum
‘mcmc_stats’: Dictionary with MCMC-specific information (samples, median, HPD bounds, rhat, ess, trace and sampling metadata)
- rtype:
Dict[str, Any]
- raises ImportError:
If PyMC or ArviZ is not installed.
- raises RuntimeError:
If MCMC sampling fails to converge.
Examples
>>> from bssunfold import Detector >>> detector = Detector() >>> readings = {'sphere_1': 100.5, 'sphere_2': 85.3, ...} >>> result = detector.unfold_mcmc( ... readings, ... n_samples=2000, ... chains=2, ... use_hierarchical=True, ... progressbar=True, ... ) >>> spectrum_mean = result['spectrum'] >>> spectrum_std = result['spectrum_uncertainty'] >>> rhat = result['mcmc_stats']['rhat'] >>> print(f"Max R-hat: {rhat.max():.3f}") # Should be < 1.1
See also
unfold_bayesBayesian iterative unfolding (D’Agostini)
unfold_bayesian_parametricBayesian parametric model with MCMC
- bssunfold.core.unfold_cuqi.unfold_cuqi(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, sampler: str = 'pcn', noise_level: float = 0.05, prior: str = 'gmrf', gmrf_order: int = 1, lengthscale: float = 3.0, prec: float = 1.0, hierarchical: bool | None = None, delta_alpha: float = 1.0, delta_beta: float = 0.0001, n_samples: int = 2000, n_burnin: int = 1000, thin: int = 1, chains: int = 2, scale: float | None = None, max_depth: int = 8, step_size: float | None = None, credible_level: float = 95.0, calculate_errors: bool = False, mc_noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, progressbar: bool = False) dict[str, Any][source]#
Unfold neutron spectrum using CUQIpy Bayesian samplers.
This is the workflow-level wrapper (same contract as
bssunfold.core.unfold_mcmc.unfold_mcmc()) aroundsolve_cuqi_bayesian(). It builds the system matrix from the detector readings, runs the requested CUQIpy MCMC sampler(s) on the log-scale Bayesian model and returns the standardized unfolding result enriched with posterior samples, credible intervals and convergence diagnostics.Supported samplers:
'pcn','cwmh','nuts','mala','ula','gibbs'(hierarchical, data-driven smoothing) and'gibbs_nuts'.- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid in MeV.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients for dose calculation.
save_result_callback (callable) – Callback function to save result to history.
readings (Dict[str, float]) – Detector readings (counts or count rates).
initial_spectrum (Optional[np.ndarray], optional) – Prior center guess for the spectrum. When None, the non-negative least-squares solution of
A @ x = bis used as the prior center.sampler (str, optional) – CUQIpy sampler (default:
'pcn').noise_level (float, optional) – Relative likelihood noise scale (default: 0.05).
prior (str, optional) – Log-spectrum prior:
'gmrf'(default) or'ou'.gmrf_order (int, optional) – GMRF operator order, 1 or 2 (default: 1).
lengthscale (float, optional) – OU correlation length in energy bins (default: 3.0).
prec (float, optional) – Fixed prior precision scale (default: 1.0); inferred from the data by the hierarchical Gibbs samplers.
hierarchical (bool, optional) – Force the hierarchical Gibbs scheme (default: derived from sampler).
delta_alpha (float, optional) – Gamma hyperprior shape (default: 1.0).
delta_beta (float, optional) – Gamma hyperprior rate (default: 1e-4).
n_samples (int, optional) – Posterior samples per chain (default: 2000).
n_burnin (int, optional) – Warmup iterations per chain (default: 1000). Increase for the Langevin samplers (
'mala'/'ula').thin (int, optional) – Thinning interval (default: 1).
chains (int, optional) – Number of independent chains (default: 2).
scale (float, optional) – Proposal step size (default: per-sampler
_DEFAULT_SCALES).max_depth (int, optional) – NUTS maximum tree depth (default: 8).
step_size (float, optional) – NUTS leapfrog step size (default: None, tuned by CUQIpy).
credible_level (float, optional) – Credible mass (%) of the HPD interval (default: 95).
calculate_errors (bool, optional) – Calculate additional Monte-Carlo errors (default: False).
mc_noise_level (float, optional) – Noise level for the additional Monte-Carlo loop (default: 0.01).
n_montecarlo (int, optional) – Number of additional Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
progressbar (bool, optional) – Present for API consistency (default: False).
- Returns:
Standardized unfolding result with the usual keys (
energy,spectrum,effective_readings,residual,residual_norm,method,doserates) plusspectrum_uncertainty,spectrum_lower,spectrum_upperandcuqi_stats(posterior samples, ESS, R-hat, acceptance rate, hyperparameter draws and sampling metadata).- Return type:
Dict[str, Any]
- Raises:
ImportError – If CUQIpy is not installed.
RuntimeError – If MCMC sampling fails.
Examples
>>> from bssunfold import Detector >>> detector = Detector() >>> result = detector.unfold_cuqi( ... readings, ... sampler='gibbs_nuts', ... n_samples=1000, ... n_burnin=500, ... chains=2, ... ) >>> spectrum = result['spectrum'] >>> acc = result['cuqi_stats']['acc_rate']
See also
unfold_mcmcPyMC/NUTS Bayesian unfolding
unfold_bayesBayesian iterative unfolding (D’Agostini)
- bssunfold.core.unfold_cuqi.solve_cuqi_bayesian(A_matrix: ndarray, b_readings: ndarray, E: ndarray | None = None, log_steps: ndarray | None = None, sampler: str = 'pcn', noise_level: float = 0.05, prior: str = 'gmrf', gmrf_order: int = 1, lengthscale: float = 3.0, prec: float = 1.0, hierarchical: bool | None = None, delta_alpha: float = 1.0, delta_beta: float = 0.0001, n_samples: int = 2000, n_burnin: int = 1000, thin: int = 1, chains: int = 2, scale: float | None = None, max_depth: int = 8, step_size: float | None = None, credible_level: float = 95.0, initial_spectrum: ndarray | None = None, random_state: int | None = None, progressbar: bool = False) tuple[ndarray, dict[str, Any]][source]#
Solve the unfolding problem with CUQIpy Bayesian samplers.
The spectrum is modelled on the log scale
f = exp(theta)with a smoothness prior centered on a data-driven guess (the non-negative least-squares solution ofA @ x = b, or the user-suppliedinitial_spectrum) and a Gaussian likelihood with relative noisesigma = noise_level * |b|.Priors#
prior='gmrf'(default):theta ~ GMRF(mu, prec)— CUQIpy finite-difference precision operator,gmrf_order= 1 or 2.prior='ou':theta ~ Gaussian(mu, C_ou / prec)— dense Ornstein-Uhlenbeck correlation withlengthscalebins.
Samplers#
'pcn','cwmh','nuts','mala','ula'sample the fixed-precision posterior;'gibbs'and'gibbs_nuts'sample the hierarchical model where the GMRF precision has a Gamma hyperprior (delta ~ Gamma(delta_alpha, delta_beta)) and is inferred jointly with the spectrum. Hierarchical sampling requires the'gmrf'prior.Internally each sampler uses the statistically equivalent formulation in which it mixes best on the severely ill-conditioned unfolding posterior: PCN/CWMH sample the centered log-spectrum
theta - mu(required for the correct pCN proposal scaling), MALA/ULA are automatically Laplace-whitened around a Gauss-Newton MAP estimate, and NUTS and the Gibbs samplers use the native CUQIpy model.- param A_matrix:
Response matrix (n_detectors x n_energy).
- type A_matrix:
np.ndarray
- param b_readings:
Measured readings (n_detectors,).
- type b_readings:
np.ndarray
- param E:
Energy grid in MeV (unused by the model, kept for API consistency).
- type E:
np.ndarray, optional
- param log_steps:
Logarithmic energy steps (unused by the model, kept for API consistency; the forward model follows the package convention
b = A @ spectrum).- type log_steps:
np.ndarray, optional
- param sampler:
CUQIpy sampler:
'pcn','cwmh','ula','mala','nuts','gibbs'or'gibbs_nuts'(default:'pcn').- type sampler:
str, optional
- param noise_level:
Relative measurement noise scale (default: 0.05); the likelihood standard deviation is
noise_level * |b|.- type noise_level:
float, optional
- param prior:
Log-spectrum prior:
'gmrf'(default) or'ou'.- type prior:
str, optional
- param gmrf_order:
Order of the GMRF finite-difference operator, 1 or 2 (default: 1). Higher order yields smoother spectra.
- type gmrf_order:
int, optional
- param lengthscale:
OU correlation length in energy bins for
prior='ou'(default: 3).- type lengthscale:
float, optional
- param prec:
Prior precision scale for
theta(default: 1.0). Ignored by the hierarchical Gibbs samplers, which infer it from the data.- type prec:
float, optional
- param hierarchical:
Convenience switch: when True the Gibbs samplers are used. If None (default) it is derived from
sampler.- type hierarchical:
bool, optional
- param delta_alpha:
Shape of the Gamma hyperprior on the GMRF precision (default: 1.0).
- type delta_alpha:
float, optional
- param delta_beta:
Rate of the Gamma hyperprior on the GMRF precision (default: 1e-4).
- type delta_beta:
float, optional
- param n_samples:
Number of posterior samples per chain (default: 2000).
- type n_samples:
int, optional
- param n_burnin:
Number of warmup/tuning iterations per chain (default: 1000). Increase (e.g. 3000+) for the Langevin samplers
'mala'/'ula'.- type n_burnin:
int, optional
- param thin:
Thinning interval kept between stored samples (default: 1).
- type thin:
int, optional
- param chains:
Number of independent chains (default: 2).
- type chains:
int, optional
- param scale:
Proposal step size. Defaults depend on the sampler (see
_DEFAULT_SCALES); for the whitened Langevin samplers the scale is in whitened units.- type scale:
float, optional
- param max_depth:
Maximum tree depth for NUTS (default: 8).
- type max_depth:
int, optional
- param step_size:
Fixed leapfrog step size for NUTS; None lets CUQIpy tune it during warmup (default: None).
- type step_size:
float, optional
- param credible_level:
Credible mass (%) of the reported HPD interval (default: 95).
- type credible_level:
float, optional
- param initial_spectrum:
Prior center guess (n_energy,). When None, the non-negative least-squares solution is used as the center.
- type initial_spectrum:
np.ndarray, optional
- param random_state:
Random seed for reproducibility.
- type random_state:
int, optional
- param progressbar:
Present for API consistency; CUQIpy progress bars are controlled via the
TQDM_DISABLEenvironment variable (default: False).- type progressbar:
bool, optional
- returns:
spectrum: Mean posterior spectrum (n_energy,)
stats: Dictionary with ‘samples’ (linear scale, chains * n_samples x n_energy), ‘theta_samples’, ‘mean’, ‘median’, ‘std’, ‘hpd_lower’/’hpd_upper’ (HPD interval), ‘ess’, ‘rhat’ (chains > 1), ‘acc_rate’, ‘delta_samples’ (hierarchical samplers), and sampling metadata (‘sampler’, ‘prior’, ‘n_chains’, …).
- rtype:
Tuple[np.ndarray, Dict[str, Any]]
- raises ImportError:
If CUQIpy is not installed.
- raises ValueError:
If
samplerorprioris unknown, or an invalid combination is requested.
- bssunfold.core.unfold_zfit.unfold_zfit(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 100, use_mcmc: bool = False, n_samples: int = 1000, regularization: float = 0.1, smoothness_weight: float = 0.01, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold using zfit Bayesian inference.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum approximation.
max_iterations (int, optional) – Maximum iterations (default: 100).
use_mcmc (bool, optional) – Use MCMC sampling (default: False).
n_samples (int, optional) – Number of MCMC samples (default: 1000).
regularization (float, optional) – Regularization strength (default: 0.1).
smoothness_weight (float, optional) – Smoothness prior weight (default: 0.01).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for error calculation (default: 0.01).
n_montecarlo (int, optional) – Number of MC samples (default: 100).
save_result (bool, optional) – Save to history (default: False).
random_state (int, optional) – Random seed.
- Returns:
Unfolding results dictionary.
- Return type:
Dict
- bssunfold.core.unfold_qubo.unfold_qubo(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, n_bits: int = 6, max_value: float | None = None, regularization: float = 0.01, max_iterations: int = 1000, annealing_time: int = 1000, num_reads: int = 10, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 50, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold using QUBO formulation with quantum-inspired annealing.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum approximation.
n_bits (int, optional) – Bits per energy bin (default: 6).
max_value (float, optional) – Maximum spectrum value for scaling.
regularization (float, optional) – Regularization parameter (default: 0.01).
max_iterations (int, optional) – Maximum iterations (default: 1000).
annealing_time (int, optional) – Annealing sweeps (default: 1000).
num_reads (int, optional) – Number of independent reads (default: 10).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for error calculation (default: 0.01).
n_montecarlo (int, optional) – Number of MC samples (default: 50).
save_result (bool, optional) – Save to history (default: False).
random_state (int, optional) – Random seed.
- Returns:
Unfolding results dictionary.
- Return type:
Dict
- bssunfold.core.unfold_maeo.unfold_maeo(detector: Any, readings: dict[str, float], n_cycles: int = 20, n_gen_per_cycle: int = 10, pop_size: int = 100, algorithms: list[str] | None = None, lambda_smooth: float = 0.01, prior_spectrum: ndarray | None = None, initial_spectrum: ndarray | None = None, convergence_assist_ratio: float = 0.2, seed: int | None = None, verbose: bool = False, **kwargs) dict[str, Any][source]#
Unfold neutron spectrum using MAEO ensemble optimization.
This is the high-level interface for MAEO unfolding that integrates with the Detector class.
- Parameters:
detector (Detector) – Detector instance with response matrix and energy grid.
readings (dict) – Dictionary mapping detector names to measured count rates.
n_cycles (int, optional) – Number of MAEO cycles (default: 20).
n_gen_per_cycle (int, optional) – Generations per cycle (default: 10).
pop_size (int, optional) – Population size per island (default: 100).
algorithms (list of str, optional) – Algorithms to use as islands. Default: [“nsga3”, “ctaea”, “agemoea2”, “spea2”].
lambda_smooth (float, optional) – Smoothness regularization weight (default: 0.01).
prior_spectrum (np.ndarray, optional) – Prior/guess spectrum for additional objective.
initial_spectrum (np.ndarray, optional) – Initial spectrum for warm-start.
convergence_assist_ratio (float, optional) – Fraction of cycles for convergence phase (default: 0.2).
seed (int, optional) – Random seed for reproducibility.
verbose (bool, optional) – Print progress information (default: False).
**kwargs – Additional keyword arguments.
- Returns:
Standardized result dictionary with spectrum, dose rates, etc.
- Return type:
dict
See also
solve_maeoLow-level solver function.
unfold_maeo_ensembleVariant with explicit ensemble control.
Examples
>>> from bssunfold import Detector >>> detector = Detector() >>> readings = { ... 'sphere_1': 100.5, ... 'sphere_2': 85.3, ... 'sphere_3': 72.1, ... 'sphere_4': 58.9, ... 'sphere_5': 45.2, ... 'sphere_6': 32.8, ... } >>> result = detector.unfold_maeo(readings, n_cycles=15, verbose=True) >>> print(f"Spectrum integral: {np.sum(result['spectrum']):.2f}") >>> print(f"Best algorithm: {result.get('best_algorithm', 'N/A')}")
- bssunfold.core.unfold_odl_advanced.unfold_odl_pdhg(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 100, tau: float | None = None, sigma: float | None = None, use_tv: bool = True, tv_weight: float = 0.1, nonnegativity: bool = True, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold using ODL PDHG with TV regularization.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum approximation.
max_iterations (int, optional) – Maximum number of iterations (default: 100).
tau (float, optional) – Primal step size.
sigma (float, optional) – Dual step size.
use_tv (bool, optional) – Use Total Variation regularization (default: True).
tv_weight (float, optional) – TV regularization weight (default: 0.1).
nonnegativity (bool, optional) – Enforce non-negativity (default: True).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for error calculation (default: 0.01).
n_montecarlo (int, optional) – Number of MC samples (default: 100).
save_result (bool, optional) – Save to history (default: False).
random_state (int, optional) – Random seed.
- Returns:
Unfolding results dictionary.
- Return type:
Dict
- bssunfold.core.unfold_odl_advanced.unfold_odl_douglas_rachford(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 100, use_tv: bool = True, tv_weight: float = 0.1, nonnegativity: bool = True, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold using ODL Douglas-Rachford splitting with TV regularization.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum approximation.
max_iterations (int, optional) – Maximum number of iterations (default: 100).
use_tv (bool, optional) – Use Total Variation regularization (default: True).
tv_weight (float, optional) – TV regularization weight (default: 0.1).
nonnegativity (bool, optional) – Enforce non-negativity (default: True).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for error calculation (default: 0.01).
n_montecarlo (int, optional) – Number of MC samples (default: 100).
save_result (bool, optional) – Save to history (default: False).
random_state (int, optional) – Random seed.
- Returns:
Unfolding results dictionary.
- Return type:
Dict
- bssunfold.core.unfold_cascade.unfold_cascade(detector, readings: dict[str, float], cascade_stages: list[CascadeStage] | None = None, calculate_errors: bool = False, verbose: bool = True, save_result: bool = False, multi_resolution: bool = False, coarse_bins: int | None = None) dict[str, Any][source]#
Perform cascade unfolding with sequential method refinement.
This function applies unfolding methods in sequence, where each method can use the result of the previous method as: 1. Initial guess (
use_as_initial=True) 2. Prior/reference spectrum (use_as_prior=Truefor thebayes*family) 3. Regularization targetThe cascade can stop early when a stage reaches
quality_threshold.- Parameters:
detector (Detector) – Configured Bonner-sphere detector.
readings (Dict[str, float]) – Detector readings.
cascade_stages (List[CascadeStage], optional) – Configuration for cascade stages. Defaults to
create_default_cascade("general").calculate_errors (bool) – Whether to calculate errors (only for final stage).
verbose (bool) – Print progress information.
save_result (bool) – Persist each stage’s result to the detector history.
multi_resolution (bool) – If True, run the first stage on a coarse energy grid and use its prolongated solution as the initial guess for the fine-grid stages. This stabilises ill-conditioned high-resolution inversions by resolving the low-frequency shape first.
coarse_bins (int, optional) – Coarse-grid resolution for
multi_resolution. Defaults tomax(8, n_energy_bins // 8).
- Returns:
Result dictionary with the final
spectrumand metadata (stages_run,method_sequence,convergence_history,quality_metrics,intermediate_results,status,message).- Return type:
dict
- bssunfold.core.unfold_composite.unfold_composite(detector, readings: dict[str, float], n_methods: int = 5, timeout_per_method: float = 30.0, save_result: bool = False, spectrum: ndarray | None = None, energy: ndarray | None = None, method_names: list[str] | None = None, ensemble_weights: dict[str, float] | None = None) dict[str, Any][source]#
Run an adaptive ensemble of unfolding methods and combine results.
- Parameters:
detector (Detector) – Configured Bonner-sphere detector.
readings (Dict[str, float]) – Detector readings.
n_methods (int) – Maximum number of methods to combine.
timeout_per_method (float) – Wall-clock timeout per individual method (seconds).
save_result (bool) – Persist each method’s result to the detector history.
spectrum (np.ndarray, optional) – Reference/estimated spectrum used to select the method pool by hardness. If omitted, a general robust pool is used.
energy (np.ndarray, optional) – Energy grid for
spectrum. Defaults todetector.E_MeV.method_names (list, optional) – Explicit list of method short names to run (overrides selection).
ensemble_weights (dict, optional) – Per-method base weights (defaults to
DEFAULT_ENSEMBLE_WEIGHTS).
- Returns:
Result dictionary with the combined
spectrumand metadata (successful_methods,consistency,weights,individual_spectra,status,message).- Return type:
dict
- bssunfold.core.unfold_binned.unfold_binned(detector, readings: dict[str, float], bin_lookup: dict[str, Any] | None = None, lookup_path: str | Path | None = None, timeout_per_method: float = 30.0, save_result: bool = False, **kwargs: Any) dict[str, Any][source]#
Bin-wise adaptive unfolding: best method per energy bin.
- Parameters:
detector (Detector) – Configured Bonner-sphere detector.
readings (Dict[str, float]) – Detector readings.
bin_lookup (dict, optional) – Pre-computed lookup table. If None, loaded from lookup_path (or the built-in default).
lookup_path (str or Path, optional) – Path to a JSON lookup file. Ignored when bin_lookup is provided.
timeout_per_method (float) – Wall-clock timeout per individual method (seconds).
save_result (bool) – Persist result to detector history.
- Returns:
Standard bssunfold result dict with extra keys
method_map,successful_methods,individual_spectra.- Return type:
dict
- bssunfold.core.unfold_ensemble.unfold_ensemble(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, methods: list[tuple[Callable, dict[str, Any]]] | None = None, weights: ndarray | None = None, combination: str = 'weighted_average', trim_fraction: float = 0.2, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using ensemble method.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess.
methods (list of (callable, dict), optional) – Solver functions and their keyword arguments.
weights (np.ndarray, optional) – Per-method weights for weighted average.
combination (str, optional) – Combination strategy (default:
'weighted_average').trim_fraction (float, optional) – Trim fraction for trimmed mean (default: 0.2).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_iterative_refinement.unfold_iterative_refinement(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, first_pass_kwargs: dict[str, Any] | None = None, second_pass_kwargs: dict[str, Any] | None = None, alpha: float | None = None, max_alpha_search: int = 20, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using iterative refinement.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess.
first_pass_kwargs (dict, optional) – Keyword arguments for first-pass solver.
second_pass_kwargs (dict, optional) – Keyword arguments for second-pass solver.
alpha (float, optional) – Blending factor (None = auto-select).
max_alpha_search (int, optional) – Number of alpha candidates for line search (default: 20).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_randomized_kaczmarz.unfold_randomized_kaczmarz(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, max_iterations: int = 1000, omega: float = 1.0, tolerance: float = 1e-06, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using the Randomized Kaczmarz algorithm.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess. If None, zero spectrum is used.
max_iterations (int, optional) – Maximum number of iterations (default: 1000).
omega (float, optional) – Relaxation parameter (default: 1.0).
tolerance (float, optional) – Convergence tolerance (default: 1e-6).
calculate_errors (bool, optional) – Calculate uncertainty via Monte-Carlo (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Dictionary containing unfolding results.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_eki.unfold_eki(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback, readings: dict[str, float], initial_spectrum: ndarray | None = None, n_ensemble: int = 50, n_iterations: int = 50, regularization: float = 0.0001, inflation: float = 1.02, noise_std: float | None = None, calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None) dict[str, Any][source]#
Unfold neutron spectrum using Ensemble Kalman Inversion.
- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray) – Energy grid.
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback to save result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (Optional[np.ndarray], optional) – Initial spectrum guess.
n_ensemble (int, optional) – Number of ensemble members (default: 50).
n_iterations (int, optional) – Number of EKI iterations (default: 50).
regularization (float, optional) – Regularization for covariance stability (default: 1e-4).
inflation (float, optional) – Covariance inflation factor (default: 1.02).
noise_std (float, optional) – Measurement noise std (default: None = auto).
calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Dictionary containing unfolding results.
- Return type:
Dict[str, Any]
- bssunfold.core.unfold_nnksvd.unfold_nnksvd(detector_names: list[str], n_energy_bins: int, E_MeV: ndarray, sensitivities: dict[str, ndarray], cc_icrp116: dict[str, ndarray], save_result_callback: Callable[[dict[str, Any]], str], readings: dict[str, float], initial_spectrum: ndarray | None = None, n_atoms: int = 15, sparsity: int = 2, dictionary: ndarray | None = None, training_signals: ndarray | None = None, n_dictionary_iterations: int = 80, lambda_tik: float = 0.01, prior_wt: float = 0.5, sparse_coder: str = 'nnls_topk', calculate_errors: bool = False, noise_level: float = 0.01, n_montecarlo: int = 100, save_result: bool = False, random_state: int | None = None, tolerance: float = 1e-06, n_nnls_iter: int | None = None) dict[str, Any][source]#
Detector-level wrapper for the non-negative K-SVD unfolding method.
See
solve_nnksvd_unfold()for the algorithmic details; this function adapts the solver to thebssunfold.core._base_unfolder.run_unfolding()workflow so that it integrates transparently withbssunfold.Detector.- Parameters:
detector_names (List[str]) – Names of available detectors.
n_energy_bins (int) – Number of energy bins.
E_MeV (np.ndarray, optional) – Energy grid (MeV).
sensitivities (Dict[str, np.ndarray]) – Detector sensitivity arrays.
cc_icrp116 (Dict[str, np.ndarray]) – ICRP-116 conversion coefficients.
save_result_callback (callable) – Callback used to save the result to history.
readings (Dict[str, float]) – Detector readings.
initial_spectrum (np.ndarray, optional) – Initial spectrum guess.
n_atoms (int, optional) – Number of dictionary atoms (default: 15).
sparsity (int, optional) – Target sparsity K (default: 2).
dictionary (np.ndarray, optional) – Pre-learned non-negative dictionary (n x p).
training_signals (np.ndarray, optional) – Training signals for online K-SVD (n x m). If not provided, log-spaced Gaussian bumps on the energy grid are used.
n_dictionary_iterations (int, optional) – K-SVD iterations (default: 80).
lambda_tik (float, optional) – Tikhonov regularization weight (default: 0.01).
prior_wt (float, optional) – Training-sample-driven prior weight (default: 0.5).
sparse_coder (str, optional) – Sparse-coding strategy (default:
"nnls_topk").calculate_errors (bool, optional) – Calculate Monte-Carlo errors (default: False).
noise_level (float, optional) – Noise level for Monte-Carlo (default: 0.01).
n_montecarlo (int, optional) – Number of Monte-Carlo samples (default: 100).
save_result (bool, optional) – Save result to history (default: False).
random_state (int, optional) – Random seed for reproducibility.
tolerance (float, optional) – Convergence tolerance (default: 1e-6).
n_nnls_iter (int, optional) – Maximum NNLS iterations.
E_MeV – Energy grid in MeV. Passed through to
solve_nnksvd_unfold()for log-spaced Gaussian training signal generation. WhenNone, the energy grid stored in theE_MeVparameter of this function (the detector grid) is used.
- Returns:
Unfolding results dictionary.
- Return type:
Dict[str, Any]
Core Functions#
Underlying solver functions:
- bssunfold.core.unfold_cvxpy.solve_cvxpy(A: ndarray, b: ndarray, alpha: float, norm: int = 2, solver: str = 'ECOS', x0: ndarray | None = None, ub: ndarray | None = None) ndarray[source]#
Solve unfolding problem using cvxpy.
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
alpha (float) – Regularization parameter.
norm (int, optional) – Norm type (1 for L1, 2 for L2).
solver (str, optional) – CVXPY solver name.
x0 (np.ndarray, optional) – Not used (provided for API compatibility).
- Returns:
Unfolded spectrum (n,).
- Return type:
np.ndarray
- bssunfold.core.unfold_landweber.solve_landweber(A: ndarray, b: ndarray, x0: ndarray, max_iterations: int = 1000, tolerance: float = 1e-06) tuple[ndarray, int, bool][source]#
Solve unfolding problem using Landweber iteration.
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Initial guess (n,).
max_iterations (int, optional) – Maximum iterations (default: 1000).
tolerance (float, optional) – Convergence tolerance (default: 1e-6).
- Returns:
Tuple of (solution, iterations, converged).
- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_mlem.solve_mlem(A: ndarray, b: ndarray, x0: ndarray, max_iterations: int = 1000, tolerance: float = 1e-06) tuple[ndarray, int, bool][source]#
Solve unfolding problem using MLEM iteration.
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Initial guess (n,).
max_iterations (int, optional) – Maximum iterations (default: 1000).
tolerance (float, optional) – Convergence tolerance (default: 1e-6).
- Returns:
Tuple of (solution, iterations, converged).
- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_mlem_stop.solve_mlem_stop(A: ndarray, b: ndarray, x0: ndarray, max_iterations: int = 15000, cps_crossover: float = 30000.0, j_threshold: float | None = None) tuple[ndarray, int, bool][source]#
Solve unfolding problem using MLEM with J-factor stopping criterion.
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Initial guess (n,).
max_iterations (int, optional) – Maximum iterations (default: 15000).
cps_crossover (float, optional) – Crossover CPS value for automatic J threshold (default: 30000). Used only when j_threshold is None.
j_threshold (float, optional) – J-factor stopping threshold. If None, computed as mean(b) / cps_crossover.
- Returns:
Tuple of (solution, iterations, converged).
- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_qpsolvers.solve_qpsolvers(A: ndarray, b: ndarray, alpha: float, norm: int = 2, solver: str = 'osqp', x0: ndarray | None = None, smoothness_order: int = 0, smoothness_weight: float = 1.0, ub: ndarray | None = None) ndarray | None[source]#
Solve unfolding problem using qpsolvers.
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
alpha (float) – Regularization parameter.
norm (int, optional) – Norm type (1 for L1, 2 for L2).
solver (str, optional) – QP solver name (default: ‘osqp’).
x0 (np.ndarray, optional) – Initial values.
smoothness_order (int, optional) – Smoothness constraint order (0, 1, or 2).
smoothness_weight (float, optional) – Weight for smoothness term.
- Returns:
Unfolded spectrum or None if solving failed.
- Return type:
Optional[np.ndarray]
- bssunfold.core.unfold_mystic.solve_mystic(A: ndarray, b: ndarray, alpha: float, norm: int = 2, solver: str = 'fmin_powell', x0: ndarray | None = None, maxiter: int | None = None, maxfun: int | None = None, smoothness_order: int = 0, smoothness_weight: float = 1.0, E_MeV: ndarray | None = None, max_neutron_energy: float | None = None) ndarray[source]#
Solve unfolding problem using mystic.
Minimizes
||A x - b||^2 + alpha * ||x||_normwith the non-negativity constraintx >= 0imposed via a quadratic penalty.- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
alpha (float) – Regularization parameter.
norm (int, optional) – Norm type (1 for L1, 2 for L2).
solver (str, optional) – Mystic solver name: ‘fmin’, ‘fmin_powell’, ‘diffev’ or ‘diffev2’ (default: ‘fmin_powell’).
x0 (np.ndarray, optional) – Initial values. Defaults to the zero vector.
maxiter (int, optional) – Maximum number of solver iterations.
maxfun (int, optional) – Maximum number of function evaluations.
smoothness_order (int, optional) – Smoothness constraint order (0, 1, or 2).
smoothness_weight (float, optional) – Weight for the smoothness term.
- Returns:
Unfolded spectrum (n,). Returns a zero vector if solving failed.
- Return type:
np.ndarray
- bssunfold.core.unfold_mystic.solve_mystic_hybrid(A: ndarray, b: ndarray, alpha: float, norm: int = 2, x0: ndarray | None = None, global_solver: str = 'diffev2', local_solver: str = 'fmin_powell', global_maxiter: int | None = None, global_maxfun: int | None = None, local_maxiter: int | None = None, local_maxfun: int | None = None, npop: int | None = None, smoothness_order: int = 0, smoothness_weight: float = 1.0, E_MeV: ndarray | None = None, max_neutron_energy: float | None = None) ndarray[source]#
Two-stage hybrid solver: global search then local refinement.
Stage 1 runs a population-based solver (default
diffev2) with automatically derived bounds to locate the basin of the global minimum. Stage 2 feeds that result asx0into a local direct-search solver (defaultfmin_powell) for precise convergence.This combines the robustness of global exploration with the accuracy of local optimization, which is a widely used practical strategy for ill-posed inverse problems like spectrum unfolding.
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
alpha (float) – Regularization parameter.
norm (int, optional) – Norm type (1 for L1, 2 for L2), default: 2.
x0 (np.ndarray, optional) – Initial values for the global stage. Defaults to the zero vector.
global_solver (str, optional) – Population-based solver for stage 1. Must be
'diffev'or'diffev2'(default:'diffev2').local_solver (str, optional) – Local solver for stage 2. Must be
'fmin'or'fmin_powell'(default:'fmin_powell').global_maxiter (int, optional) – Maximum iterations for the global stage. Defaults to 200.
global_maxfun (int, optional) – Maximum function evaluations for the global stage. Defaults to
10 * n * 20where n is the number of energy bins.local_maxiter (int, optional) – Maximum iterations for the local stage. Defaults to 2000.
local_maxfun (int, optional) – Maximum function evaluations for the local stage. Defaults to 20000.
npop (int, optional) – Population size for the global stage. Defaults to
min(10 * n, 200)where n is the number of energy bins.smoothness_order (int, optional) – Smoothness constraint order (0, 1, or 2), default: 0.
smoothness_weight (float, optional) – Weight for the smoothness term, default: 1.0.
- Returns:
Unfolded spectrum (n,). Returns a zero vector if both stages fail.
- Return type:
np.ndarray
- bssunfold.core.unfold_genetic.solve_genetic(A: ndarray, b: ndarray, x0: ndarray | None = None, solver: str = 'pso', epoch: int = 500, pop_size: int = 50, regularization: float = 0.01, norm: int = 2, smoothness_order: int = 2, smoothness_weight: float = 1.0, entropy_weight: float = 0.0, n_runs: int = 1, early_stop: int | None = None, half_range: float = 2.0, two_step: bool = False, n_coarse: int | None = None, smoother: str = 'none', sigma_smooth: float = 2.0, crossover: str = 'single', mutation: str = 'random', pareto_select: str = 'knee', random_state: int | None = None, verbose: bool = False, extra_starting: ndarray | None = None) ndarray[source]#
Solve the unfolding problem using a meta-heuristic optimizer.
The optimizer searches in log space (
y = log(x)) so that the wide dynamic range of neutron spectra is handled naturally. The population is seeded with a Landweber warm-start solution (or the providedx0) and bounded tolog(seed) +/- half_rangedecades. All objective terms are scale-consistent (dimensionless), which prevents the optimizer from producing a noisy, arbitrary spectrum.- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray, optional) – Initial spectrum guess. If None (or all zeros), a Landweber warm-start solution is used to seed the population.
solver (str, optional) – Meta-heuristic algorithm: ‘pso’, ‘ga’, ‘de’, ‘es’, ‘ep’, ‘abc’, ‘gwo’, ‘cmaes’ or ‘nsga2’ (default: ‘pso’).
epoch (int, optional) – Maximum number of generations/iterations (default: 500).
pop_size (int, optional) – Population size (default: 50).
regularization (float, optional) – Tikhonov regularisation weight alpha (default: 1e-2).
norm (int, optional) – Norm for the regularisation term (1 for L1, 2 for L2), default: 2.
smoothness_order (int, optional) – Second-difference smoothing order (0, 1 or 2), default: 2.
smoothness_weight (float, optional) – Weight of the smoothing term (default: 1.0).
entropy_weight (float, optional) – Weight of the negative Shannon-entropy objective (0 disables it).
n_runs (int, optional) – Number of independent optimisation runs; results are averaged (default: 1). Not used by the ‘nsga2’ solver.
early_stop (int, optional) – Stop if the global best does not improve for this many consecutive epochs (MEALPY early stopping). Not used by the numpy engines.
half_range (float, optional) – Half-width of the log-space search bounds in decades around the seed (default: 2.0).
two_step (bool, optional) – If True, run the two-step genetic scheme (TGASU-style): the problem is first solved on a coarse energy grid and the result is interpolated back to seed the full-resolution population (default: False).
n_coarse (int, optional) – Number of coarse bins for the
two_stepmode. When None, it is chosen asmax(8, n // 4).smoother (str, optional) – Post-processing smoother: ‘none’, ‘gaussian’, ‘mbc’, ‘gaussian_mbc’ or ‘second_difference’ (default: ‘none’).
sigma_smooth (float, optional) – Gaussian filter sigma for the smoothers (default: 2.0).
crossover (str, optional) – GA crossover operator: ‘single’ (single-point) or ‘arithmetic’ (beta-weighted, TGASU). Only used by the numpy GA engine (default: ‘single’).
mutation (str, optional) – GA mutation operator: ‘random’ or ‘iterative’ (generation-decreasing step, TGASU). Only used by the numpy GA engine (default: ‘random’).
pareto_select (str, optional) – Selection from the Pareto front for the ‘nsga2’ solver: ‘knee’, ‘min_residual’ or ‘max_entropy’ (default: ‘knee’).
random_state (int, optional) – Random seed for reproducibility.
verbose (bool, optional) – If True, MEALPY logs the optimisation progress to the console.
extra_starting (np.ndarray, optional) – Additional starting individual (in linear spectrum units) injected into the initial population without shifting the search box. Used internally by the two-step scheme.
- Returns:
Unfolded spectrum (n,). Returns a zero vector if solving failed.
- Return type:
np.ndarray
- bssunfold.core.unfold_smt.solve_smt(A: ndarray, b: ndarray, x0: ndarray | None = None, nonneg: bool = True, timeout_ms: int = 10000, random_state: int | None = None, objective: str = 'l2') ndarray[source]#
Solve the unfolding problem with an SMT solver.
Minimizes the L2 residual
||A x - b||_2and then the total fluencesum(x)over the non-negative orthant using the Z3 optimizer (via the exact KKT characterization of the non-negative least-squares optimum). If the L2 solve does not converge within its (bounded) time budget, e.g. on large systems, the solver falls back to the L1 residual||A x - b||_1.The system
A x = bis usually underdetermined (fewer detectors than energy bins), so the lexicographic objective selects a deterministic solution.- Parameters:
A (np.ndarray) – Response matrix of size (m, n).
b (np.ndarray) – Measurement vector of size (m,).
x0 (np.ndarray, optional) – Not used (provided for API compatibility). Z3 has no warm start.
nonneg (bool, optional) – Constrain the solution to
x >= 0(default: True).timeout_ms (int, optional) – SMT solver timeout in milliseconds (default: 10000).
random_state (int, optional) – Random seed for the SMT solver, for reproducibility.
objective (str, optional) – Residual objective:
'l2'(default, least squares) or'l1'. On a non-converging L2 solve the L1 objective is used as a fallback.
- Returns:
Unfolded spectrum (n,). Returns a zero vector if solving failed.
- Return type:
np.ndarray
- bssunfold.core.unfold_scip.solve_scip(A: ndarray, b: ndarray, x0: ndarray | None = None, alpha: float = 0.0001, norm: int = 2, timeout: float = 10.0, smoothness_order: int = 0, smoothness_weight: float = 1.0, nonneg: bool = True, random_state: int | None = None, ub: ndarray | None = None) ndarray | None[source]#
Solve the unfolding problem with the SCIP optimizer.
Minimizes
0.5 * ||A x - b||^2 + penalty(x)withpenaltygiven byalpha * ||x||^2(L2),alpha * sum(x)(L1, exact underx >= 0) or a derivative smoothness term, subject tox >= 0whennonneg.- Parameters:
A (np.ndarray) – Response matrix of size (m, n).
b (np.ndarray) – Measurement vector of size (m,).
x0 (np.ndarray, optional) – Initial values, used as a warm start for the solver.
alpha (float, optional) – Regularization parameter, default: 1e-4.
norm (int, optional) – Norm type (1 for L1, 2 for L2), default: 2.
timeout (float, optional) – Time limit in seconds, default: 10.0.
smoothness_order (int, optional) – Smoothness constraint order (0, 1, or 2), default: 0.
smoothness_weight (float, optional) – Weight for the smoothness term, default: 1.0.
nonneg (bool, optional) – Constrain the solution to
x >= 0, default: True.random_state (int, optional) – Random seed for the solver, for reproducibility.
- Returns:
Unfolded spectrum (n,), or None if solving failed.
- Return type:
Optional[np.ndarray]
- bssunfold.core.unfold_docplex.solve_docplex(A: ndarray, b: ndarray, x0: ndarray | None = None, alpha: float = 0.0001, norm: int = 2, timeout: float = 10.0, smoothness_order: int = 0, smoothness_weight: float = 1.0, nonneg: bool = True, random_state: int | None = None, ub: ndarray | None = None) ndarray | None[source]#
Solve the unfolding problem with CPLEX (docplex).
Minimizes
0.5 * ||A x - b||^2 + penalty(x)withpenaltygiven byalpha * ||x||^2(L2),alpha * sum(x)(L1, exact underx >= 0) or a derivative smoothness term, subject tox >= 0whennonneg.- Parameters:
A (np.ndarray) – Response matrix of size (m, n).
b (np.ndarray) – Measurement vector of size (m,).
x0 (np.ndarray, optional) – Initial values (accepted for API compatibility; CPLEX QP has no warm start for continuous models).
alpha (float, optional) – Regularization parameter, default: 1e-4.
norm (int, optional) – Norm type (1 for L1, 2 for L2), default: 2.
timeout (float, optional) – Time limit in seconds, default: 10.0.
smoothness_order (int, optional) – Smoothness constraint order (0, 1, or 2), default: 0.
smoothness_weight (float, optional) – Weight for the smoothness term, default: 1.0.
nonneg (bool, optional) – Constrain the solution to
x >= 0, default: True.random_state (int, optional) – Random seed for the solver, for reproducibility.
- Returns:
Unfolded spectrum (n,), or None if solving failed.
- Return type:
Optional[np.ndarray]
- bssunfold.core.unfold_epic.solve_epic(A: ndarray, b: ndarray, x0: ndarray | None = None, target_sigmas: ndarray | None = None, sigma_frac: float = 0.1, regularization_order: int = 1, non_neg: bool = True, noise_var: float | None = None, homogeneous_step: bool = True, regularize: dict[str, Any] | None = None, beta_shift_k: float = 0, beta_distance: float = 2, EPIC_bool: ndarray | None = None, V: ndarray | None = None, LSQpar: dict[str, Any] | None = None) ndarray[source]#
Solve the unfolding problem with EPIC Tikhonov regularization.
Selects the prior variances of the regularization operator H such that the a posteriori variances of the model parameters equal the squared target sigmas, then solves the weighted least squares problem.
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray, optional) – Not used (provided for API compatibility).
target_sigmas (np.ndarray, optional) – Target a posteriori standard deviations of the model parameters. If None, derived as
sigma_fractimes the magnitude of the naive least-squares solution. Must be strictly positive.sigma_frac (float, optional) – Fraction used to derive the default target sigmas (default: 0.1).
regularization_order (int, optional) – Regularization operator order: 0 (identity), 1 (first derivative, default) or 2 (second derivative).
non_neg (bool, optional) – Apply non-negativity constraints to the model parameters (default: True).
noise_var (float, optional) – Variance of the i.i.d. misfit errors used to build Cx (default: None, meaning Cx is the identity matrix).
homogeneous_step (bool, optional) – Run a preliminary homogeneous Ch search (default: True).
regularize (dict, optional) – If given (can be empty), damp the EPIC weights towards a minimum-norm solution. May carry
sigma_weight.beta_shift_k (float, optional) – Center shift for the beta bounds (default: 0).
beta_distance (float, optional) – Distance kept from the representability limit (default: 2).
EPIC_bool (np.ndarray, optional) – Boolean mask of which parameters are subject to the EPIC.
V (np.ndarray, optional) – Matrix mapping the searched betas to the regularization rows, beta = V @ y (shape (H.shape[0], len(y))).
LSQpar (dict, optional) – Tuning parameters for the nonlinear least-squares solver.
- Returns:
Unfolded spectrum (n,).
- Return type:
np.ndarray
- bssunfold.core.unfold_interpret.solve_interpret(A: ndarray, b: ndarray, alpha: float, norm: int = 2, smoothness_order: int = 0, smoothness_weight: float = 1.0, enforce_norm: bool = False, norm_value: float = 1.0, x0: ndarray | None = None, tolerance: float = 1e-08, variable_names: Sequence[str] | None = None, ridge_coeff: Any = 'auto') ndarray[source]#
Solve the unfolding QP through pyoptexplain and return the spectrum.
- Parameters:
A (np.ndarray) – Response matrix
(m, n).b (np.ndarray) – Measurement vector
(m,).alpha (float) – Regularization parameter.
norm (int, optional) – Penalty norm, 1 or 2 (default: 2).
smoothness_order (int, optional) – Smoothness derivative order, 0, 1 or 2 (default: 0).
smoothness_weight (float, optional) – Weight of the smoothness term (default: 1.0).
enforce_norm (bool, optional) – Add
sum(x) == norm_value(default: False).norm_value (float, optional) – Target total fluence for the norm equality (default: 1.0).
x0 (np.ndarray, optional) – Warm start, accepted for API compatibility (unused).
tolerance (float, optional) – Solver feasibility/optimality tolerance (default: 1e-8).
variable_names (sequence of str, optional) – Energy-group variable names.
ridge_coeff (float or
"auto", optional) – Diagonal ridge fornorm == 1(default:"auto").
- Returns:
Unfolded spectrum
(n,).- Return type:
np.ndarray
- Raises:
RuntimeError – If the solver does not return a primal solution.
- bssunfold.core.unfold_interpret.interpret_qp(A: ndarray, b: ndarray, alpha: float, *, norm: int = 2, smoothness_order: int = 0, smoothness_weight: float = 1.0, enforce_norm: bool = False, norm_value: float = 1.0, E_MeV: ndarray | None = None, detector_names: Sequence[str] | None = None, tolerance: float = 1e-08, ridge_coeff: Any = 'auto', relative_deltas: Sequence[float] = (-0.05, -0.01, 0.01, 0.05), relaxation_deltas: Sequence[float] = (0.0, 0.05, 0.1), nonneg_deltas: Sequence[float] = (0.0, 0.01, 0.05), sensitivity_deltas: Sequence[float] = (0.01, 0.05), regularization_sweep: Sequence[float] | None = None, run_robustness: bool = True, run_scenarios: bool = True, run_detector_sensitivity: bool = True, run_regularization_sweep: bool = True, run_nonnegativity_relaxation: bool = True) InterpretationResult[source]#
Solve and interpret the unfolding QP with pyoptexplain.
- Parameters:
A (np.ndarray) – Response matrix
(m, n).b (np.ndarray) – Measurement vector
(m,).alpha (float) – Regularization parameter.
norm (int, optional) – Penalty norm, 1 or 2 (default: 2).
smoothness_order (int, optional) – Smoothness derivative order, 0, 1 or 2 (default: 0).
smoothness_weight (float, optional) – Weight of the smoothness term (default: 1.0).
enforce_norm (bool, optional) – Add
sum(x) == norm_value(default: False).norm_value (float, optional) – Target total fluence for the norm equality (default: 1.0).
E_MeV (np.ndarray, optional) – Energy grid for the report tables.
detector_names (sequence of str, optional) – Names of the detector rows of
A/b.tolerance (float, optional) – Solver feasibility/optimality tolerance (default: 1e-8).
ridge_coeff (float or
"auto", optional) – Diagonal ridge added toQwhennorm == 1andsmoothness_order == 0to cure rank deficiency ofA'A."auto"(default) uses1e-8 * trace(Q) / n. Set to0.0to disable the ridge.relative_deltas (sequence of float, optional) – Relative perturbations for the robustness analysis (default: -5..5%).
relaxation_deltas (sequence of float, optional) – RHS deltas for the
normrelaxation curve (default: 0, 0.05, 0.1).nonneg_deltas (sequence of float, optional) – Allowed-negative magnitudes to probe (default: 0, 0.01, 0.05).
sensitivity_deltas (sequence of float, optional) – Per-detector relative perturbations (default: 1%, 5%).
regularization_sweep (sequence of float, optional) – Explicit alpha grid; default derives a grid around
alpha.run_robustness (bool, optional) – Run the perturbation robustness analysis (default: True).
run_scenarios (bool, optional) – Run the pyoptexplain structured scenarios (default: True).
run_detector_sensitivity (bool, optional) – Run the per-detector sensitivity analysis (default: True).
run_regularization_sweep (bool, optional) – Run the regularization sweep (default: True).
run_nonnegativity_relaxation (bool, optional) – Run the non-negativity relaxation analysis (default: True).
- Returns:
The interpreted solution (spectrum, report, metrics, tables).
- Return type:
InterpretationResult
- bssunfold.core.unfold_interpret.build_interpretation_qp(A: ndarray, b: ndarray, alpha: float, norm: int = 2, smoothness_order: int = 0, smoothness_weight: float = 1.0, enforce_norm: bool = False, norm_value: float = 1.0, lower_bound: float = 0.0, variable_names: Sequence[str] | None = None, equality_name: str = 'norm', ridge_coeff: Any = 'auto') Any[source]#
Build the pyoptexplain QP handle for the unfolding problem.
The quadratic program matches the model solved by
solve_qpsolvers(objective convention0.5 * x'Qx + c'x):norm == 2:Q = A'A + alpha*sw*L'L(smoothness_order1/2) orQ = A'A + alpha*I,c = -A'b.norm == 1:Q = A'A + alpha*sw*L'L,c = -A'b + alpha*1(the L1 penalty is linear and exact underx >= 0).
The spectrum is constrained to
x >= lower_bound. Whenenforce_norm=Truethe equalitysum(x) == norm_valueis added as a named block (default"norm").- Parameters:
A (np.ndarray) – Response matrix
(m, n).b (np.ndarray) – Measurement vector
(m,).alpha (float) – Regularization parameter (>= 0).
norm (int, optional) – Penalty norm, 1 or 2 (default: 2).
smoothness_order (int, optional) – Smoothness derivative order, 0, 1 or 2 (default: 0).
smoothness_weight (float, optional) – Weight of the smoothness term (default: 1.0).
enforce_norm (bool, optional) – Add
sum(x) == norm_value(default: False).norm_value (float, optional) – Target total fluence for the norm equality (default: 1.0).
lower_bound (float, optional) – Shared lower bound on every energy group (default: 0.0).
variable_names (sequence of str, optional) – Names of the energy-group variables (default:
E0..E{n-1}).equality_name (str, optional) – Name of the norm equality block (default:
"norm").ridge_coeff (float or
"auto", optional) – Diagonal ridge added toQwhennorm == 1andsmoothness_order == 0to cure rank deficiency ofA'A."auto"(default) uses1e-8 * trace(Q) / n. Set to0.0to disable the ridge.
- Returns:
A
pyoptexplainproblem handle; callhandle.quadratic_representation()for the analysis surface.- Return type:
QuadraticMatrixProblemHandle
- Raises:
ImportError – If
pyoptexplainis not installed.ValueError – If the arguments are invalid or
Qis not positive semidefinite.
- bssunfold.core.unfold_cs.solve_cs(A: ndarray, b: ndarray, x0: ndarray | None = None, n_atoms: int | None = None, sparsity: int | None = None, dictionary: ndarray | None = None, n_dictionary_iterations: int = 20, sigma_min: float = 0.01, sigma_decrease_factor: float = 0.5, mu_0: float = 1.0, L: int = 3, max_iterations: int = 1000, tolerance: float = 1e-06, random_state: int | None = None) tuple[ndarray, int, bool][source]#
Solve the unfolding problem using Compressive Sensing (CS).
The spectrum
xis represented sparsely in a learned dictionaryDasx = D @ alpha. The measurement equationb = A @ xbecomesb = (A @ D) @ alpha, which is solved for the sparsealphausing SL0. Finally the spectrum is reconstructed asx = D @ alpha.- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray, optional) – Initial guess (n,). Used to seed the dictionary training signals.
n_atoms (int, optional) – Number of dictionary atoms. Defaults to
max(n, 2 * m).sparsity (int, optional) – Target sparsity for dictionary learning. Defaults to
max(1, n // 20).dictionary (np.ndarray, optional) – Pre-learned dictionary (n x n_atoms). If provided, dictionary learning is skipped.
n_dictionary_iterations (int, optional) – Number of K-SVD iterations (default: 20).
sigma_min (float, optional) – SL0 minimum sigma (default: 0.01).
sigma_decrease_factor (float, optional) – SL0 sigma decrease factor (default: 0.5).
mu_0 (float, optional) – SL0 step-size factor (default: 1.0).
L (int, optional) – SL0 inner iterations per sigma (default: 3).
max_iterations (int, optional) – SL0 maximum outer iterations (default: 1000).
tolerance (float, optional) – Convergence tolerance (default: 1e-6).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Tuple of (solution, iterations, converged).
- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_cs.solve_omp(D: ndarray, y: ndarray, sparsity: int, tolerance: float = 1e-06) ndarray[source]#
Solve sparse coding problem using Orthogonal Matching Pursuit (OMP).
Finds a sparse coefficient vector
alphasuch thaty ~= D @ alphawith at mostsparsitynon-zero entries.- Parameters:
D (np.ndarray) – Dictionary matrix (n x k).
y (np.ndarray) – Signal to be represented (n,).
sparsity (int) – Maximum number of non-zero coefficients.
tolerance (float, optional) – Residual tolerance for early stopping (default: 1e-6).
- Returns:
Sparse coefficient vector (k,).
- Return type:
np.ndarray
- bssunfold.core.unfold_cs.solve_ksvd(signals: ndarray, n_atoms: int, n_iterations: int = 20, sparsity: int = 5, random_state: int | None = None) ndarray[source]#
Learn a dictionary using the K-SVD algorithm.
- Parameters:
signals (np.ndarray) – Training signals (n x m), one column per training sample.
n_atoms (int) – Number of dictionary atoms.
n_iterations (int, optional) – Number of K-SVD iterations (default: 20).
sparsity (int, optional) – Target sparsity for sparse coding (default: 5).
random_state (int, optional) – Random seed for reproducibility.
- Returns:
Learned dictionary (n x n_atoms).
- Return type:
np.ndarray
- bssunfold.core.unfold_cs.solve_sl0(A: ndarray, b: ndarray, sigma_min: float = 0.01, sigma_decrease_factor: float = 0.5, mu_0: float = 1.0, L: int = 3, max_iterations: int = 1000, tolerance: float = 1e-06) ndarray[source]#
Reconstruct a sparse signal using the Smoothed L0 (SL0) algorithm.
SL0 approximates the L0 norm by a smooth surrogate and performs a steepest-descent / projection iteration to find the sparsest solution of the underdetermined linear system
b = A @ x.- Parameters:
A (np.ndarray) – Sensing matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
sigma_min (float, optional) – Minimum value of the smoothing parameter sigma (default: 0.01).
sigma_decrease_factor (float, optional) – Factor by which sigma is decreased each outer iteration (default: 0.5).
mu_0 (float, optional) – Step-size factor for the steepest descent (default: 1.0). The effective step is
mu_0 * x * exp(-x^2 / (2 sigma^2));mu_0 = 1drives small coefficients toward zero without sign flips.L (int, optional) – Number of inner steepest-descent iterations per sigma (default: 3).
max_iterations (int, optional) – Maximum number of outer iterations (default: 1000).
tolerance (float, optional) – Convergence tolerance (default: 1e-6).
- Returns:
Reconstructed sparse signal (n,).
- Return type:
np.ndarray
- bssunfold.core.unfold_doroshenko.solve_doroshenko(A: ndarray, b: ndarray, x0: ndarray, max_iterations: int = 1000, tolerance: float = 1e-06, regularization: float = 0.0) tuple[ndarray, int, bool][source]#
Solve unfolding problem using Doroshenko coordinate update method.
Uses incremental residual update for O(n) per-coordinate complexity instead of O(n^2) from full matrix-vector products.
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Initial guess (n,).
max_iterations (int, optional) – Maximum iterations (default: 1000).
tolerance (float, optional) – Convergence tolerance (default: 1e-6).
regularization (float, optional) – Regularization strength to prevent division by zero (default: 0.0).
- Returns:
Tuple of (solution, iterations, converged).
- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_directed_divergence.solve_directed_divergence(A: ndarray, b: ndarray, x0: ndarray, max_iterations: int = 200, tol_chi2: float = 1.0, tol_rel: float = 1e-06, relative_uncertainty: float = 0.05, sigma: ndarray | None = None, smoothness_order: int = 0, smoothness_weight: float = 0.0) tuple[ndarray, int, bool][source]#
Solve a non-negative unfolding problem by directed divergence.
Amust be the response matrix used byDetector; its columns already include the energy-bin integration weights. Smoothing is the proximal Tikhonov stepargmin ||x-y||^2 + alpha ||Lx||^2.
- bssunfold.core.unfold_kaczmarz.solve_kaczmarz(A: ndarray, b: ndarray, x0: ndarray, max_iterations: int = 1000, omega: float = 1.0, tolerance: float = 1e-06) tuple[ndarray, int, bool][source]#
Solve unfolding problem using Kaczmarz algorithm (ART).
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Initial guess (n,).
max_iterations (int, optional) – Maximum iterations (default: 1000).
omega (float, optional) – Relaxation parameter (0 < omega <= 2), default: 1.0.
tolerance (float, optional) – Convergence tolerance (default: 1e-6).
- Returns:
Tuple of (solution, iterations, converged).
- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_lmfit.solve_lmfit(A: ndarray, b: ndarray, x0: ndarray, method: str = 'lbfgsb', model_name: str = 'elastic', regularization: float = 0.0001, regularization2: float = 0.0001, l1_weight: float = 0.5) tuple[ndarray, bool, str, int][source]#
Solve unfolding problem using lmfit with L1/L2/Elastic regularization.
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Initial guess (n,).
method (str, optional) – lmfit solver name (leastsq, lbfgsb, etc.), default: “lbfgsb”.
model_name (str, optional) – Regularization model: elastic, lasso, ridge, default: “elastic”.
regularization (float, optional) – L1 regularization strength, default: 1e-4.
regularization2 (float, optional) – L2 regularization strength for elastic net, default: 1e-4.
l1_weight (float, optional) – L1 weight for elastic net (0=pure L2, 1=pure L1), default: 0.5.
- Returns:
Tuple of (solution, success, message, nfev).
- Return type:
Tuple[np.ndarray, bool, str, int]
- bssunfold.core.unfold_lmfit.select_regularization_aic_bic(A: ndarray, b: ndarray, x0: ndarray, method: str = 'lbfgsb', model_name: str = 'elastic', regularization: float = 0.0001, regularization2: float = 0.0001, l1_weight: float = 0.5, criterion: str = 'aic', lambda_range: tuple[float, float] = (1e-06, 0.1), n_lambda: int = 30, verbose: bool = True) dict[str, Any][source]#
Select the lmfit regularization parameter by an information criterion.
Sweeps
n_lambdalog-spaced regularization candidates, solves the lmfit problem for each, scores it with AIC/AICc/BIC (effective degrees of freedom and Gaussian likelihood of the data residual), and returns the candidate minimizing the chosen criterion.- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Initial spectrum used for every candidate solve.
method (str, optional) – lmfit solver name, default: “lbfgsb”.
model_name (str, optional) – Regularization model: elastic, lasso, ridge, default: “elastic”.
regularization (float, optional) – Manual L1 regularization strength, used as fallback if every candidate solve fails, default: 1e-4.
regularization2 (float, optional) – L2 regularization strength for elastic net, default: 1e-4.
l1_weight (float, optional) – L1 weight for elastic net, default: 0.5.
criterion (str, optional) – Information criterion to minimize: ‘aic’, ‘aicc’ or ‘bic’, default: ‘aic’.
lambda_range (Tuple[float, float], optional) – Log-spaced range of lambda candidates, default: (1e-6, 1e-1).
n_lambda (int, optional) – Number of lambda candidates, default: 30.
verbose (bool, optional) – Print the selection summary, default: True.
- Returns:
Keys: best_lambda, best_lambda2, best_criterion_value, best_index, best_df, lambda_candidates, aic_values, aicc_values, bic_values, df_values, criterion_used, model_name.
- Return type:
Dict[str, Any]
- Raises:
ValueError – If criterion is not one of ‘aic’, ‘aicc’, ‘bic’.
- bssunfold.core.unfold_gravel.solve_gravel(A: ndarray, b: ndarray, x0: ndarray, tolerance: float = 1e-08, max_iterations: int = 1000, regularization: float = 0.0) tuple[ndarray, int, bool][source]#
Solve unfolding problem using the GRAVEL algorithm.
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Initial spectrum guess (n,).
tolerance (float, optional) – Convergence tolerance (default: 1e-8).
max_iterations (int, optional) – Maximum iterations (default: 1000).
regularization (float, optional) – Regularization parameter (default: 0.0).
- Returns:
Tuple of (solution, iterations, converged).
- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_maxed.solve_maxed(A: ndarray, b: ndarray, x0: ndarray, sigma_factor: float = 0.1, max_iterations: int = 5000, tolerance: float = 1e-06) tuple[ndarray, int, bool][source]#
Solve unfolding problem using MAXED (Maximum Entropy Deconvolution).
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Reference (prior) spectrum (n,).
sigma_factor (float, optional) – Relative measurement uncertainty (default: 0.1). Larger values → smoother spectrum (weaker data term).
max_iterations (int, optional) – Maximum L-BFGS-B iterations (default: 5000).
tolerance (float, optional) – Gradient convergence tolerance (default: 1e-6).
- Returns:
(solution spectrum, iterations used, converged flag).
- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_tikhonov_legendre.solve_tikhonov_legendre(A: ndarray, b: ndarray, x0: ndarray | None = None, delta: float = 0.05, n_polynomials: int = 15) ndarray[source]#
Solve unfolding using Tikhonov regularization with Legendre basis.
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray, optional) – Not used (provided for API compatibility).
delta (float, optional) – Regularization parameter (default: 0.05).
n_polynomials (int, optional) – Number of Legendre polynomials (default: 15).
- Returns:
Unfolded spectrum (n,).
- Return type:
np.ndarray
- bssunfold.core.unfold_bayes.solve_bayes(A: ndarray, b: ndarray, x0: ndarray | None = None, max_iterations: int = 4000, tolerance: float = 0.001) ndarray[source]#
Solve unfolding problem using Bayesian iterative unfolding (D’Agostini).
Pure numpy implementation of the D’Agostini algorithm. The response matrix is column-normalised so each column sums to 1 (conditional probability P(D_j | E_i)), then the result is rescaled to physical units via division by the column sums.
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray, optional) – Prior spectrum. If None, uniform prior is used.
max_iterations (int, optional) – Maximum iterations (default: 4000).
tolerance (float, optional) – Relative L2 convergence tolerance (default: 1e-3).
- Returns:
Unfolded spectrum (n,) in physical units.
- Return type:
np.ndarray
- bssunfold.core.unfold_bayes_spline_regularization.solve_bayes_spline(A: ndarray, b: ndarray, x0: ndarray | None = None, max_iterations: int = 4000, tolerance: float = 0.001, spline_degree: int = 3, spline_smooth: float = 0.01) ndarray[source]#
Solve unfolding problem using Bayes with spline regularization.
Implements the D’Agostini iterative Bayesian unfolding from scratch. The response matrix is column-normalised (each column sums to 1) so the algorithm works in effective-count space, but the UnivariateSpline smoother is applied to the physical spectrum to avoid boundary artifacts that appear when rescaling low-sensitivity bins back to physical units.
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray, optional) – Prior spectrum.
max_iterations (int, optional) – Maximum iterations (default: 4000).
tolerance (float, optional) – Relative L2 convergence tolerance (default: 1e-3).
spline_degree (int, optional) – Spline degree (default: 3).
spline_smooth (float, optional) – Spline smoothing parameter (default: 1e-2).
- Returns:
Unfolded spectrum (n,).
- Return type:
np.ndarray
- bssunfold.core.unfold_statreg.solve_statreg(A: ndarray, b: ndarray, x0: ndarray | None = None, E_MeV: ndarray | None = None, unfoldermethod: str = 'EmpiricalBayes', regularization: float | None = None, basis_name: str = 'CubicSplines', boundary: str | None = None, derivative_degree: int = 2) ndarray[source]#
Solve unfolding problem using Turchin’s statistical regularisation.
- Parameters:
A (np.ndarray) – Response matrix (m × n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray, optional) – Not used (provided for API compatibility).
E_MeV (np.ndarray, optional) – Energy grid (n,). Used for log-energy penalty scaling.
unfoldermethod (str, optional) – Regularisation method:
'EmpiricalBayes'(L-curve, default) or'User'(fixed α).regularization (float, optional) – Regularisation parameter α for
'User'method (default: 1e-4).basis_name (str, optional) – Ignored (kept for API compatibility).
boundary (str, optional) – Ignored (kept for API compatibility).
derivative_degree (int, optional) – Derivative order for penalty. Only 2 is implemented.
- Returns:
Unfolded spectrum (n,).
- Return type:
np.ndarray
- bssunfold.core.unfold_reconst.solve_reconst(A: ndarray, b: ndarray, x0: ndarray | None = None, E_MeV: ndarray | None = None, pp: float = 0.001, alpha: float = -1.0, beta: float = 0.0, sigma_b: ndarray | None = None) ndarray[source]#
Solve unfolding problem using Turchin’s statistical regularization.
Pure numpy implementation of the RECONST.FOR algorithm (STREG1). Solves (B * beta + Omega * alpha) * f = A_vec * beta.
- Parameters:
A (np.ndarray) – Response matrix (M, N).
b (np.ndarray) – Measurement vector (M,).
x0 (np.ndarray, optional) – Ignored (API compatibility).
E_MeV (np.ndarray, optional) – Ignored (API compatibility).
pp (float, optional) – PP parameter (default: 1e-3).
alpha (float, optional) – Regularization. >0 fixed, <0 auto (default: -1).
beta (float, optional) – Data fidelity. >0 fixed, <=0 auto (default: 0).
sigma_b (np.ndarray, optional) – Measurement uncertainties (M,). If None, sqrt(b) used.
- Returns:
Unfolded spectrum (N,).
- Return type:
np.ndarray
- bssunfold.core.unfold_scipy_direct_method.solve_scipy_direct(A: ndarray, b: ndarray, x0: ndarray | None = None, tolerance: float = 1e-08, max_iterations: int = 4000, method: str = 'cg') ndarray[source]#
Solve unfolding problem using scipy sparse linear solvers.
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray, optional) – Not used (provided for API compatibility).
tolerance (float, optional) – Solver tolerance (default: 1e-8).
max_iterations (int, optional) – Maximum solver iterations (default: 4000).
method (str, optional) – Solver method. One of: ‘cg’, ‘cgs’, ‘bicgstab’, ‘gmres’, ‘lgmres’, ‘minres’, ‘gcrotmk’, ‘qmr’, ‘tfqmr’, ‘lsqr’, ‘lsmr’ (default: ‘cg’).
- Returns:
Unfolded spectrum (n,).
- Return type:
np.ndarray
- bssunfold.core.unfold_tsvd.solve_tsvd(A: ndarray, b: ndarray, x0: ndarray | None = None, method: str = 'discrepancy', k: int | None = None, threshold: float | None = None, noise_level: float | None = None, svd_solver: str = 'full') ndarray[source]#
Solve unfolding problem using Truncated SVD (TSVD).
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray, optional) – Not used (provided for API compatibility).
method (str, optional) – K-selection method: ‘discrepancy’, ‘l_curve’, ‘gcv’, ‘energy’, ‘threshold_ratio’, ‘median_threshold’, ‘donoho’ (default: ‘discrepancy’).
k (int, optional) – Fixed number of singular values to keep. Overrides method.
threshold (float, optional) – Threshold ratio for singular value truncation.
noise_level (float, optional) – Noise level estimate for discrepancy principle.
svd_solver (str, optional) – SVD backend:
'full'(dense LAPACK, default),'arpack'or'propack'. The iterative backends are only used whenkis fixed; automatic k-selection falls back to the dense solver.
- Returns:
Unfolded spectrum (n,).
- Return type:
np.ndarray
- bssunfold.core.unfold_lanczos.solve_lanczos(A: ndarray, b: ndarray, x0: ndarray | None = None, max_iterations: int | None = None, regularization: float = 1e-08, noise_level: float | None = None) tuple[ndarray, int, bool][source]#
Solve the unfolding problem with a Lanczos-hybrid method.
Performs Golub-Kahan bidiagonalization of
A, generating a sequence of Krylov subspaces. On the projected problemmin ||B_k y - bhat||^2a Tikhonov termlambda * ||y||^2is added, wherelambdais selected automatically by GCV at each iteration. The iteratex_k = V_k y_kis an approximation in the Krylov subspace, so no a-priori spectrum is required (x0is accepted for API compatibility only).- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray, optional) – Initial spectrum (unused, kept for API compatibility).
max_iterations (int, optional) – Maximum Krylov dimension. Defaults to
min(A.shape).regularization (float, optional) – Fallback regularization parameter used if GCV returns a degenerate value; default: 1e-8.
noise_level (float, optional) – Relative noise level. If given, iterations stop early by the discrepancy principle
||A x - b|| <= noise_level * sqrt(m).
- Returns:
(spectrum, iterations, converged)whereconvergedreports whether the discrepancy-principle criterion was met (or the Krylov space was fully spanned).- Return type:
tuple
- bssunfold.core.unfold_cgls.solve_cgls(A: ndarray, b: ndarray, x0: ndarray | None = None, max_iterations: int = 100, tolerance: float = 1e-12, noise_level: float | None = None, regularization: float = 0.0, smoothness_order: int = 0) tuple[ndarray, int, bool][source]#
Solve the unfolding problem with the CGLS method.
Applies the conjugate gradient algorithm implicitly to the normal equations
A^T A x = A^T b. A regularized solution is obtained by stopping the iterations once the normal-equation residual is sufficiently small, or (ifnoise_levelis provided) once the discrepancy principle||A x - b|| <= eta * noise_level * ||b||is satisfied. Ifregularizationis positive, the Tikhonov regularized system(A^T A + regularization^2 L^T L) x = A^T bis solved instead.- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray, optional) – Initial guess (default: zero vector).
max_iterations (int, optional) – Maximum number of CGLS iterations (default: 100).
tolerance (float, optional) – Relative tolerance on the normal-equation residual norm (default: 1e-12).
noise_level (float, optional) – Relative noise level used for discrepancy-principle stopping (default: None).
regularization (float, optional) – Tikhonov regularization parameter.
0.0disables the Tikhonov term and uses iterative regularization (default: 0.0).smoothness_order (int, optional) – Derivative order of the regularization operator L used when
regularizationis positive: 0 (identity), 1 or 2 (default: 0).
- Returns:
(spectrum, iterations, converged)whereconvergedreports whether a stopping criterion was satisfied before reaching the maximum number of iterations.- Return type:
tuple
- bssunfold.core.unfold_gks.solve_gks(A: ndarray, b: ndarray, x0: ndarray | None = None, smoothness_order: int = 0, regularization_method: str = 'gcv', max_iterations: int | None = None, regularization: float = 1e-08, noise_level: float | None = None) tuple[ndarray, int, bool][source]#
Solve the unfolding problem with the Generalized Krylov Subspace method.
Performs Golub-Kahan bidiagonalization of
Aand projects bothAand the regularization operatorL(identity or a derivative matrix) onto the Krylov subspace. At each iteration the projected Tikhonov problemmin ||R_A y - bhat||^2 + lambda * ||R_L y||^2is solved, wherelambdais selected automatically by GCV, the Discrepancy Principle or the L-curve.- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray, optional) – Initial spectrum (unused, kept for API compatibility).
smoothness_order (int, optional) – Derivative order of the regularization operator L: 0 (identity), 1 or 2 (default: 0).
regularization_method (str, optional) – Method for selecting the regularization parameter:
'gcv','dp','lcurve'or'manual'(default: ‘gcv’).max_iterations (int, optional) – Maximum Krylov dimension. Defaults to
min(A.shape).regularization (float, optional) – Manual/fallback regularization parameter (default: 1e-8).
noise_level (float, optional) – Relative noise level used by the Discrepancy Principle.
- Returns:
(spectrum, iterations, converged)whereconvergedreports whether the Krylov space was fully spanned or a fixed point of the projected solution was reached.- Return type:
tuple
- bssunfold.core.unfold_tikhonov_tv.solve_tikhonov_tv(A: ndarray, b: ndarray, x0: ndarray | None = None, epsilon: float | None = None, mu: tuple[float, float, float] = (1.0, 1.0, 1.0), max_iterations: int = 100, type_: str = 'TT', beta: float = 1.0, zthr: float = 2.5, tolerance: float = 0.0001) tuple[ndarray, int, bool][source]#
Solve the noise-constrained Tikhonov-TV unfolding problem.
Solves
min f(m)subject to||A m - b||^2 = epsilonwith the ADMM scheme of Gazzola & Gholami adapted to 1D spectra.- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray, optional) – Initial spectrum guess (accepted for API compatibility; the iteration always starts from a zero vector like the original).
epsilon (float, optional) – (Estimate of) the squared 2-norm of the noise. If None, derived from the residuals of an unregularized least-squares solve.
mu (tuple, optional) – Penalty parameters for the Lagrangian terms,
(mu1, mu2, mu3)(default: (1.0, 1.0, 1.0)).max_iterations (int, optional) – Maximum number of ADMM iterations (default: 100).
type (str, optional) – Optimization problem to be solved:
'TT'(TV + Tikhonov),'TV'(pure total variation) or'T'(pure Tikhonov) (default: ‘TT’).beta (float, optional) – Balancing parameter between the TV and Tikhonov terms. A scalar fixes its value;
'adapt'estimates it adaptively (only fortype_='TT') (default: 1.0).zthr (float, optional) – Threshold used by the adaptive beta estimation (default: 2.5).
tolerance (float, optional) – Stopping criterion based on the relative change of the solution (default: 1e-4).
- Returns:
(spectrum, iterations, converged)whereconvergedreports whether the stabilization stopping criterion was reached.- Return type:
tuple
- bssunfold.core.unfold_sandii.solve_sandii(A: ndarray, b: ndarray, x0: ndarray, max_iterations: int = 50, tolerance: float = 0.001, chi_fac: int = 1, relative_uncertainty: float = 0.1, sigma: ndarray | None = None) tuple[ndarray, int, bool][source]#
Solve unfolding problem using the SAND-II algorithm.
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Initial spectrum guess (n,).
max_iterations (int, optional) – Maximum number of iterations (default: 50).
tolerance (float, optional) – Maximum relative spectrum change used when
chi_fac=0(default: 1e-3).chi_fac (int, optional) – Convergence criterion:
1= stop when chi-square of the fit is not greater than the number of detectors;0= stop when the maximum relative change of the spectrum is belowtolerance(default: 1).relative_uncertainty (float, optional) – Relative measurement uncertainty used to derive detector sigma values when
sigmais not supplied (default: 0.1).sigma (np.ndarray, optional) – Explicit per-detector measurement uncertainties (m,). When given, overrides
relative_uncertainty.
- Returns:
(solution spectrum, iterations used, converged flag).
- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_crystal_ball.solve_crystal_ball(A: ndarray, b: ndarray, x0: ndarray | None = None, regularization: float = 0.0) tuple[ndarray, int, bool][source]#
Solve unfolding problem using the CRYSTAL BALL algorithm.
The spectrum is approximated as a linear combination of the detector response functions (rows of
A). The coefficient vectoralphais obtained from the (regularized) normal equations(A A^T + lambda I) alpha = band the spectrum reconstructed asphi = A^T alpha.- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray, optional) – Unused by the direct CRYSTAL BALL method; accepted for a uniform solver signature.
regularization (float, optional) – Tikhonov regularization strength
lambdaadded to the diagonal ofA A^Tto stabilise the inversion of the (usually ill-conditioned) Gram matrix (default: 0.0).
- Returns:
(solution spectrum, 1, True). CRYSTAL BALL is a single-step method, so
iterationsis 1 andconvergedis always True.- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_rfsp_jul.solve_rfsp_jul(A: ndarray, b: ndarray, x0: ndarray, max_iterations: int = 200, tolerance: float = 0.0001, weights: ndarray | None = None) tuple[ndarray, int, bool][source]#
Solve unfolding problem using the RFSP-JUL algorithm.
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Initial guess (n,). Also used as the reference iterate
phi_prevat the first iteration.max_iterations (int, optional) – Maximum number of iterations (default: 200).
tolerance (float, optional) – Convergence tolerance on the maximum relative spectrum change (default: 1e-4).
weights (np.ndarray, optional) – Per-detector weights
W_ifor the residual term. When None, all detectors are weighted equally (W_i = 1).
- Returns:
(solution spectrum, iterations used, converged flag).
- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_staysl.solve_staysl(A: ndarray, b: ndarray, x0: ndarray, relative_uncertainty: float = 0.1, prior_uncertainty: float = 1.0, Cb: ndarray | None = None, Cx: ndarray | None = None, regularization: float = 1e-12) tuple[ndarray, int, bool][source]#
Solve unfolding problem using the STAY’SL Bayesian algorithm.
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Prior spectrum guess (n,). Used as the Bayesian prior mean.
relative_uncertainty (float, optional) – Relative measurement uncertainty used to build the diagonal measurement covariance
Cb = diag((rel * b)^2)whenCbis not supplied (default: 0.1).prior_uncertainty (float, optional) – Relative prior uncertainty used to build the diagonal prior covariance
Cx = diag((prior * x0)^2)whenCxis not supplied (default: 1.0, i.e. a broad prior).Cb (np.ndarray, optional) – Explicit measurement covariance matrix (m x m). Overrides
relative_uncertaintywhen given.Cx (np.ndarray, optional) – Explicit prior covariance matrix (n x n). Overrides
prior_uncertaintywhen given.regularization (float, optional) – Small Tikhonov term added to the bracket
(Cb + A Cx A^T)for numerical stability (default: 1e-12).
- Returns:
(solution spectrum, 1, True). STAY’SL is a single-step method, so
iterationsis 1 andconvergedis always True.- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_express.solve_express(A: ndarray, b: ndarray, E: ndarray, x0: ndarray | None = None, n_groups: int = 6, interval_boundaries: ndarray | None = None, max_iterations: int = 3, tol_iteration: float = 0.05, relative_uncertainty: float = 0.05) tuple[ndarray, int, bool][source]#
Fit a piecewise-exponential spectrum directly to sphere readings.
- bssunfold.core.unfold_bunki.solve_bunki(A: ndarray, b: ndarray, x0: ndarray, smoothing: float = 0.1, max_iterations: int = 1000, tolerance: float = 1e-06, lethargy_weights: ndarray | None = None) tuple[ndarray, int, bool][source]#
Solve unfolding problem using the BUNKI (SPUNIT) algorithm.
- Parameters:
A (np.ndarray) – Lethargy-weighted response matrix (m x n) as built by the Detector class (see
bssunfold.Detector()).b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Initial spectrum guess (n,).
smoothing (float, optional) – Three-point smoothing factor (default: 0.1).
max_iterations (int, optional) – Maximum number of iterations (default: 1000).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 1e-6).
lethargy_weights (np.ndarray, optional) – Per-bin lethargy widths. Only needed when
Ais supplied as a per-bin (non-lethargy-weighted) response matrix; the Detector-built matrix is already lethargy-weighted so this can be left as None.
- Returns:
(solution spectrum, iterations used, converged flag).
- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_bunkiut.solve_bunkiut(A: ndarray, b: ndarray, x0: ndarray, smoothing: float = 0.05, max_iterations: int = 1000, tolerance: float = 1e-06, lethargy_weights: ndarray | None = None) tuple[ndarray, int, bool][source]#
Solve unfolding problem using the BUNKI-UT (BON31G) algorithm.
- Parameters:
A (np.ndarray) – Lethargy-weighted response matrix (m x n) as built by the Detector class (see
bssunfold.Detector()).b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Initial spectrum guess (n,).
smoothing (float, optional) – Three-point smoothing factor (default: 0.05).
max_iterations (int, optional) – Maximum number of iterations (default: 1000).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 1e-6).
lethargy_weights (np.ndarray, optional) – Per-bin lethargy widths. Only needed when
Ais supplied as a per-bin (non-lethargy-weighted) response matrix; the Detector-built matrix is already lethargy-weighted so this can be left as None.
- Returns:
(solution spectrum, iterations used, converged flag).
- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_osem.solve_osem(A: ndarray, b: ndarray, x0: ndarray, max_iterations: int = 50, n_subsets: int = 1, tolerance: float = 1e-06) tuple[ndarray, int, bool][source]#
Solve unfolding problem using OSEM (ordered-subset EM).
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Initial spectrum guess (n,).
max_iterations (int, optional) – Maximum number of iterations (default: 50).
n_subsets (int, optional) – Number of ordered subsets over the detector readings (default: 1, i.e. standard MLEM).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 1e-6).
- Returns:
(solution spectrum, iterations used, converged flag).
- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_osem_anlm.solve_osem_anlm(A: ndarray, b: ndarray, x0: ndarray, max_iterations: int = 50, n_subsets: int = 1, tolerance: float = 1e-06, h: float | None = None, search_window: int = 11, similarity_window: int = 3, alpha: float = 1.0, anlm_mode: str = 'subset', log_space: bool = True) tuple[ndarray, int, bool][source]#
Solve the unfolding problem with OSEM-ANLM.
OSEM update (article eq. 3 / pseudo-code step 4):
x^{n+1} = x^n * A_m^T ( b_m / (A_m x^n + eps) ) / ( A_m^T 1 + eps )
followed by the ANLM filter (pseudo-code step 5,
f^{*(n+1,b)} = ANLMFilter(mu^{*(n+1,b)})) applied after every subset update whenanlm_mode="subset"(default, per the article pseudo-code). Withanlm_mode="post"the plain OSEM solution is produced first and the ANLM filter is applied once at the end (“OSEM reconstruction followed by ANLM regularization” in the article abstract). Withn_subsets=1the OSEM update reduces to standard MLEM.- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Initial spectrum guess (n,).
max_iterations (int, optional) – Maximum number of full iterations (sweeps over all subsets) (default: 50).
n_subsets (int, optional) – Number of ordered subsets over the detector readings (default: 1, i.e. standard MLEM with per-iteration ANLM).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 1e-6).
h (float, optional) – Noise level for the ANLM filter. If None (default), it is estimated automatically from each intermediate spectrum.
search_window (int, optional) – ANLM search window
N(default: 11, article optimum).similarity_window (int, optional) – ANLM similarity (patch) window
nu(default: 3, article optimum).alpha (float, optional) – Spread of the Gaussian kernel over the similarity window (default: 1.0).
anlm_mode (str, optional) –
'subset'— ANLM after every subset update (default, article pseudo-code);'post'— single ANLM application to the OSEM result.log_space (bool, optional) – Apply the ANLM filter to the logarithm of the spectrum (default: True, scale-free for spectra spanning orders of magnitude). See
anlm_filter_1d().
- Returns:
(solution spectrum, iterations used, converged flag).
- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_osem_anlm.anlm_filter_1d(x: ndarray, h: float | None = None, search_window: int = 11, similarity_window: int = 3, alpha: float = 1.0, log_space: bool = True) ndarray[source]#
Two-stage asymptotic non-local means filter for 1D spectra.
Implements the ANLM regularisation of Jamaati et al. (2026) (eqs. 4-6 and the ANLM filter section) adapted to a one-dimensional energy grid:
Patch (similarity-window) distances
d(i, j)are computed with a Gaussian kernel of spreadalphaover the similarity windownu; indices outside the signal are reflected at the borders.Stage 1 applies NLM with the uniform parameter
h1 = 0.5 * sigma, producing a lightly denoised intermediate spectrum and the “initial” normalised weightsw1(i, j).Stage 2 applies NLM with the point-wise parameter of article eq. 6,
h2(i) = sqrt(sum_j w1(i, j)^2 * sigma^2)— the noise standard deviation smoothed by the initial weights — to the stage-1 output, incrementally reducing the noise while preserving structure.
By default (
log_space=True) the filter operates on the logarithm of the spectrum: Bonner-sphere spectra span several orders of magnitude and the EM noise amplitude scales with the local fluence, so a single absolute filter parameter cannot match every bin. In log space the relative noise level is uniform across the grid, making the automatichestimate scale-free (the filtered value becomes a weighted geometric mean, which also preserves non-negativity). Setlog_space=Falseto filter in raw units exactly as the original CT formulation of the article.- Parameters:
x (np.ndarray) – Input spectrum (n,), typically non-negative.
h (float, optional) – Noise level
sigmaused by both stages (in log units whenlog_space=True). If None (default) the noise level is estimated automatically withestimate_noise_1d()(robust MAD on second differences).search_window (int, optional) – Size
Nof the search window around each bin (article optimum: 11). Must be a positive integer; even values are rounded down to the preceding odd size.similarity_window (int, optional) – Size
nuof the Gaussian-weighted similarity (patch) window (article optimum: 3). Must be a positive integer; even values are rounded down to the preceding odd size.alpha (float, optional) – Spread of the Gaussian kernel over the similarity window (default: 1.0). Must be positive.
log_space (bool, optional) – Filter the logarithm of the spectrum instead of the raw values (default: True, scale-free for spectra spanning orders of magnitude).
- Returns:
Filtered spectrum (n,). Non-negative when
log_space=True; reduces to the identity forsearch_window == 1.- Return type:
np.ndarray
- bssunfold.core.unfold_louhi.solve_louhi(A: ndarray, b: ndarray, x0: ndarray | None = None, smoothness: float = 1.0, smooth_order: int = 1, max_iterations: int = 500, tolerance: float = 1e-06, relative_uncertainty: float = 0.1, sigma: ndarray | None = None, auto_smooth: bool = False, chi2_target: float | None = None) tuple[ndarray, int, bool][source]#
Solve the unfolding problem with the LOUHI78 algorithm.
- Parameters:
A (np.ndarray) – Response matrix
(m, n).b (np.ndarray) – Measurement vector
(m,).x0 (np.ndarray, optional) – Default (a-priori) spectrum
(n,)used as the starting point and as the reference of the generalized smoothing term. When None, a flat unit spectrum is used.smoothness (float, optional) – Smoothing weight
lambdaof the generalized smoothing term (default: 1.0). Ignored whenauto_smoothis True.smooth_order (int, optional) – Order of the smoothing operator:
0(identity),1(first differences) or2(second differences); default 1.max_iterations (int, optional) – Maximum number of Hildreth coordinate sweeps (default: 500).
tolerance (float, optional) – Maximum relative change between sweeps for convergence (default: 1e-6).
relative_uncertainty (float, optional) – Relative measurement uncertainty used to derive detector sigma values when
sigmais not supplied (default: 0.1).sigma (np.ndarray, optional) – Explicit per-detector measurement uncertainties
(m,). When given, overridesrelative_uncertainty.auto_smooth (bool, optional) – Nonlinear regression mode of LOUHI78: adjust the smoothing weight by a golden-section search on
log10(lambda)so that the data chi-square reacheschi2_target(default False).chi2_target (float, optional) – Target data chi-square for
auto_smooth. Defaults to the number of detectors (the expected value of the chi-square).
- Returns:
(solution spectrum, sweeps used, converged flag).- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_louhi.louhi_smoothing_matrix(n: int, smooth_order: int = 1) ndarray[source]#
Build the generalized smoothing operator
Lof LOUHI.- Parameters:
n (int) – Number of energy bins.
smooth_order (int, optional) – Order of the smoothing functional:
0shrinks the solution toward the default spectrum (identity operator),1penalizes first differences of the deviation from the default spectrum and2penalizes second differences (default: 1).
- Returns:
The
(n, n)smoothing matrixL.- Return type:
np.ndarray
- bssunfold.core.unfold_louhi.louhi_covariance(A: ndarray, sigma: ndarray, smoothness: float, smooth_order: int, x0: ndarray, x: ndarray) ndarray[source]#
Propagate measurement uncertainties for the LOUHI solution.
Follows the statistical error analysis of LOUHI78: the covariance of the free (strictly positive) spectrum bins is the inverse of the Hessian restricted to the active set, while constrained bins at zero carry no variance in the first-order propagation.
- Parameters:
A (np.ndarray) – Response matrix
(m, n).sigma (np.ndarray) – Per-detector measurement uncertainties
(m,).smoothness (float) – Smoothing weight used for the solution.
smooth_order (int) – Order of the smoothing operator used for the solution.
x0 (np.ndarray) – Default spectrum used in the smoothing term.
x (np.ndarray) – LOUHI solution spectrum.
- Returns:
Standard deviations of the spectrum bins
(n,).- Return type:
np.ndarray
- bssunfold.core.unfold_mapem.solve_mapem(A: ndarray, b: ndarray, x0: ndarray, prior: str = 'quadratic', beta: float = 0.001, prior_delta: float = 1.0, gamma: float = 1.0, max_iterations: int = 50, tolerance: float = 1e-06) tuple[ndarray, int, bool][source]#
Solve unfolding problem using penalised EM (OSMAPOSL, one-step-late).
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Initial spectrum guess (n,).
prior (str, optional) – Prior type:
'none','quadratic','logcosh'or'relative_difference'(default:'quadratic').beta (float, optional) – Prior weight (default: 1e-3).
prior_delta (float, optional) – Width parameter of the quadratic/logcosh priors and additive floor of the relative-difference prior (default: 1.0).
gamma (float, optional) – Edge-preservation parameter of the relative-difference prior (default: 1.0).
max_iterations (int, optional) – Maximum number of iterations (default: 50).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 1e-6).
- Returns:
(solution spectrum, iterations used, converged flag).
- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_bsrem.solve_bsrem(A: ndarray, b: ndarray, x0: ndarray, prior: str = 'none', beta: float = 0.001, prior_delta: float = 1.0, gamma: float = 1.0, max_iterations: int = 50, n_subsets: int = 1, tolerance: float = 1e-06, relaxation: float | Callable[[int], float] | None = None, addition_after_iteration: float = 0.0001) tuple[ndarray, int, bool][source]#
Solve unfolding problem using BSREM.
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Initial spectrum guess (n,).
prior (str, optional) – Prior type:
'none','quadratic','logcosh'or'relative_difference'(default:'none').beta (float, optional) – Prior weight (default: 1e-3).
prior_delta (float, optional) – Width parameter of the quadratic/logcosh priors and additive floor of the relative-difference prior (default: 1.0).
gamma (float, optional) – Edge-preservation parameter of the relative-difference prior (default: 1.0).
max_iterations (int, optional) – Maximum number of iterations (default: 50).
n_subsets (int, optional) – Number of ordered subsets over the detector readings (default: 1).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 1e-6).
relaxation (float or callable, optional) – Relaxation sequence
alpha(n)as a constant or as a callable of the iteration number. If None, a constant 1 is used (default: None).addition_after_iteration (float, optional) – Floor value the spectrum is clamped to after every sub-iteration to prevent bins being locked at zero (default: 1e-4).
- Returns:
(solution spectrum, iterations used, converged flag).
- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_sart.solve_sart(A: ndarray, b: ndarray, x0: ndarray, max_iterations: int = 50, tolerance: float = 1e-06, relaxation: float | Callable[[int], float] | None = None) tuple[ndarray, int, bool][source]#
Solve unfolding problem using SART.
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Initial spectrum guess (n,). The value of the first (lowest-energy) bin is held fixed during iteration because the detector response is (near-)zero there and cannot constrain it.
max_iterations (int, optional) – Maximum number of iterations (default: 50).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 1e-6).
relaxation (float or callable, optional) – Relaxation sequence
alpha(n)as a constant or as a callable of the iteration number. If None, a constant 0.8 is used (default: None).
- Returns:
(solution spectrum, iterations used, converged flag).
- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_ferdor.solve_ferdor(A: ndarray, b: ndarray, x0: ndarray, max_iterations: int = 100, tolerance: float = 0.001, smoothing: float = 0.001, chi_squared_target: float = 1.0, relative_uncertainty: float = 0.1, sigma: ndarray | None = None, min_alpha: float = 1e-12, max_alpha: float = 1000000000000.0) tuple[ndarray, int, bool][source]#
Solve unfolding problem using the FERDOR algorithm.
The smoothing weight
alphais adjusted iteratively (bisection) so that the reduced chi-square of the fit approacheschi_squared_target(discrepancy principle).- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Initial spectrum guess (n,). Accepted for interface compatibility; the constrained least-squares solution does not depend on it.
max_iterations (int, optional) – Maximum number of smoothing-weight adjustment iterations (default: 100).
tolerance (float, optional) – Relative tolerance on the reduced chi-square used to stop the bisection (default: 1e-3).
smoothing (float, optional) – Initial value of the smoothing weight alpha (default: 1e-3).
chi_squared_target (float, optional) – Target reduced chi-square per degree of freedom (default: 1.0).
relative_uncertainty (float, optional) – Relative measurement uncertainty used to derive the per-detector sigma values when
sigmais not supplied (default: 0.1).sigma (np.ndarray, optional) – Explicit per-detector measurement uncertainties (m,). When given, overrides
relative_uncertainty.min_alpha (float, optional) – Lower bound of the smoothing-weight search bracket (default: 1e-12).
max_alpha (float, optional) – Upper bound of the smoothing-weight search bracket (default: 1e12).
- Returns:
(solution spectrum, iterations used, converged flag).
- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_rebunki.solve_rebunki(A: ndarray, b: ndarray, x0: ndarray, smoothing: float = 0.1, max_iterations: int = 1000, tolerance: float = 0.01, lethargy_weights: ndarray | None = None) tuple[ndarray, int, bool][source]#
Solve unfolding problem using the ReBUNKI (SPUNIT) algorithm.
This is the SPUNIT iteration of BUNKI/ReBUNKI; see
bssunfold.core.unfold_bunki.solve_bunki()for the algorithm description. The default tolerance matches the ~1% relative-error convergence recommended for ReBUNKI.- Parameters:
A (np.ndarray) – Lethargy-weighted response matrix (m x n) as built by the Detector class.
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Initial spectrum guess (n,).
smoothing (float, optional) – Three-point smoothing factor (default: 0.1).
max_iterations (int, optional) – Maximum number of iterations (default: 1000).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 0.01).
lethargy_weights (np.ndarray, optional) – Per-bin lethargy widths. Only needed when
Ais supplied as a per-bin (non-lethargy-weighted) response matrix.
- Returns:
(solution spectrum, iterations used, converged flag).
- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_nsduaz.solve_nsduaz(A: ndarray, b: ndarray, x0: ndarray, smoothing: float = 0.1, max_iterations: int = 1000, tolerance: float = 0.01, lethargy_weights: ndarray | None = None) tuple[ndarray, int, bool][source]#
Solve unfolding problem using the NSDUAZ (SPUNIT) iteration.
This is the SPUNIT iterative algorithm with the NSDUAZ default convergence tolerance (~1% relative change). See
bssunfold.core.unfold_bunki.solve_bunki()for the iteration details. The initial spectrumx0is typically obtained viaselect_catalogue_initial()(or provided by the user).- Parameters:
A (np.ndarray) – Lethargy-weighted response matrix (m x n) as built by the Detector class.
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Initial spectrum guess (n,).
smoothing (float, optional) – Three-point smoothing factor (default: 0.1).
max_iterations (int, optional) – Maximum number of iterations (default: 1000).
tolerance (float, optional) – Relative change tolerance for early stopping (default: 0.01).
lethargy_weights (np.ndarray, optional) – Per-bin lethargy widths. Only needed when
Ais supplied as a per-bin (non-lethargy-weighted) response matrix.
- Returns:
(solution spectrum, iterations used, converged flag).
- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_randomized_kaczmarz.solve_randomized_kaczmarz(A: ndarray, b: ndarray, x0: ndarray, max_iterations: int = 1000, omega: float = 1.0, tolerance: float = 1e-06, random_state: int | None = None) tuple[ndarray, int, bool][source]#
Solve unfolding problem using the randomized Kaczmarz algorithm.
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Initial guess (n,).
max_iterations (int, optional) – Maximum number of iterations (default: 1000).
omega (float, optional) – Relaxation parameter (0 < omega <= 2), default: 1.0.
tolerance (float, optional) – Convergence tolerance on
||x_k - x_{k-1}||checked after each full sweep through the rows (default: 1e-6).random_state (int, optional) – Random seed for reproducibility.
- Returns:
Tuple of (solution, iterations, converged).
- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_eki.solve_eki(A: ndarray, b: ndarray, x0: ndarray, n_ensemble: int = 50, n_iterations: int = 50, regularization: float = 0.0001, inflation: float = 1.02, noise_std: float | None = None, random_state: int | None = None) tuple[ndarray, int, bool][source]#
Solve unfolding problem using Ensemble Kalman Inversion.
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
x0 (np.ndarray) – Initial guess (n,). Used as the centre of the initial ensemble.
n_ensemble (int, optional) – Number of ensemble members (default: 50).
n_iterations (int, optional) – Number of EKI iterations (default: 50).
regularization (float, optional) – Tikhonov-style regularization added to the covariance diagonal for numerical stability (default: 1e-4).
inflation (float, optional) – Covariance inflation factor applied after each update step to prevent ensemble collapse (default: 1.02).
noise_std (float, optional) – Standard deviation of measurement noise. If None, estimated as 5 % of
||b|| / sqrt(m).random_state (int, optional) – Random seed for reproducibility.
- Returns:
Tuple of (mean_spectrum, n_iterations, True).
- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_binned.solve_binned(A: ndarray, b: ndarray, bin_lookup: dict[str, Any], methods: dict[str, tuple[callable, dict]], x0: ndarray | None = None, timeout_per_method: float = 30.0) tuple[ndarray, dict[str, Any]][source]#
Run candidate methods and assemble a spectrum bin-by-bin.
- Parameters:
A (ndarray, shape (m, n)) – Response matrix.
b (ndarray, shape (m,)) – Measurement vector.
bin_lookup (dict) – Pre-computed per-bin method ranking (from
build_bin_lookup()).methods (dict) – Mapping
method_short → (solver_callable, kwargs). Each callable must accept(A, b, x0=..., **kwargs)and return a spectrum array of shape(n,).x0 (ndarray, optional) – Initial guess forwarded to every solver.
timeout_per_method (float) – Wall-clock timeout per method (seconds).
- Returns:
spectrum (ndarray, shape (n,)) – Assembled spectrum.
meta (dict) – Metadata including
method_map,successful_methods, and per-method spectra.
- bssunfold.core.unfold_binned.build_bin_lookup(spectra_dir: str | Path, references_csv: str | Path, n_bins: int = 60, top_k: int = 5) dict[str, Any][source]#
Analyse benchmark unfolded spectra and build a per-bin method ranking.
- Parameters:
spectra_dir (path) – Directory containing per-method
.npzfiles (e.g.spectra/mc/).references_csv (path) – CSV with reference spectra. Must contain a
keycolumn (hash) and at leastn_binsnumeric energy columns (energy_1…energy_60or the first N numeric columns).n_bins (int) – Number of energy bins (default 60).
top_k (int) – Number of best methods to keep per bin.
- Returns:
Dict with keys
bin_to_methods(bin index -> list of(method_short, score)pairs),unique_methodsandn_bins.- Return type:
dict
- bssunfold.core.unfold_nnksvd.solve_nnksvd_unfold(A: ndarray, b: ndarray, x0: ndarray | None = None, n_atoms: int = 15, sparsity: int = 2, dictionary: ndarray | None = None, training_signals: ndarray | None = None, n_dictionary_iterations: int = 80, lambda_tik: float = 0.01, prior_wt: float = 0.5, sparse_coder: str = 'nnls_topk', random_state: int | None = None, tolerance: float = 1e-06, n_nnls_iter: int | None = None, E_MeV: ndarray | None = None) tuple[ndarray, int, bool][source]#
Unfold a neutron spectrum using the non-negative K-SVD pipeline.
Two operating modes:
Pre-learned dictionary (
dictionaryprovided): the dictionary is used as-is;training_signalsis ignored.Online dictionary learning (
training_signalsprovided orx0used to synthesize them): the dictionary is learned on the fly withsolve_nnksvd().
The forward model is
y = A @ phi + epsand the spectrum is represented asphi = D @ alphawhereDis the learned non-negative dictionary andalphais a non-negative sparse coefficient vector. Sparse coding on the equivalent detection dictionaryM_norm = normalize(A @ D)is performed with the selected sparse-coding strategy (NNLS+TopK, OMP, or NN-OMP).- Parameters:
A (np.ndarray) – Detector response matrix (m x n).
b (np.ndarray) – Measurement / count vector (m,).
x0 (np.ndarray, optional) – Initial spectrum guess (n,). Used to seed training signals when no
training_signalsis supplied.n_atoms (int, optional) – Number of dictionary atoms (default: 15, the article’s optimum).
sparsity (int, optional) – Target sparsity K (default: 2, the article’s optimum).
dictionary (np.ndarray, optional) – Pre-learned non-negative dictionary (n x p). Bypasses online K-SVD training.
training_signals (np.ndarray, optional) – Training signals for online K-SVD (n x m). If not provided, log-spaced Gaussian bumps on the energy grid plus the initial guess are used.
n_dictionary_iterations (int, optional) – K-SVD iterations (default: 80, as in the article).
lambda_tik (float, optional) – Tikhonov regularization weight (default: 0.01).
prior_wt (float, optional) – Training-sample prior weight (default: 0.5).
sparse_coder (str, optional) – Sparse-coding strategy (default:
"nnls_topk").random_state (int, optional) – Random seed for reproducibility (default: 42 in the article).
tolerance (float, optional) – Convergence tolerance for K-SVD and OMP-style coders.
n_nnls_iter (int, optional) – Maximum NNLS iterations (passed through to scipy.optimize.nnls).
E_MeV (np.ndarray, optional) – Energy grid in MeV (n,). When provided, the default training signals are log-spaced Gaussian bumps on the log-energy grid, which ensures the dictionary covers the full spectral range. Falls back to a uniform normalised index when not supplied.
- Returns:
Tuple
(spectrum, iterations, converged).- Return type:
Tuple[np.ndarray, int, bool]
- bssunfold.core.unfold_nnksvd.solve_nnksvd(signals: ndarray, n_atoms: int, n_iterations: int = 80, sparsity: int = 2, lambda_tik: float = 0.01, prior_wt: float = 0.5, sparse_coder: str = 'nnls_topk', random_state: int | None = None, tolerance: float = 1e-06) tuple[ndarray, ndarray][source]#
Non-negative K-SVD dictionary learning.
K-SVD variant with non-negativity constraints on both dictionary atoms and sparse coefficients, following Xu et al. (2026). The dictionary update stage applies non-negative truncation (
max(0, atom)) after the SVD rank-1 update of each atom, then re-normalizes. The sparse coding stage uses one of the three strategies supported by this module (nnls_topk,ompornn_omp).- Parameters:
signals (np.ndarray) – Training signals (n x m), one column per training sample. Must be non-negative (neutron spectra are physically non-negative).
n_atoms (int) – Number of dictionary atoms
P.n_iterations (int, optional) – Maximum K-SVD iterations (default: 80, as in the article).
sparsity (int, optional) – Target sparsity
Kfor sparse coding (default: 2).lambda_tik (float, optional) – Tikhonov weight for the NNLS+TopK sparse coder (default: 0.01).
prior_wt (float, optional) – Prior weight for the NNLS+TopK sparse coder (default: 0.5).
sparse_coder (str, optional) – Sparse-coding strategy:
"nnls_topk","omp"or"nn_omp"(default:"nnls_topk").random_state (int, optional) – Random seed for reproducibility.
tolerance (float, optional) – Early-stopping tolerance on dictionary change.
- Returns:
D (np.ndarray) – Learned non-negative dictionary (n x p), columns L2-normalized.
alpha_prior (np.ndarray) – Mean sparse code of the training signals (p,), used as the training-sample-driven prior during unfolding.
- bssunfold.core.unfold_nnksvd.solve_nnls_topk(M_norm: ndarray, y: ndarray, sparsity: int, lambda_tik: float = 0.01, prior_wt: float = 0.0, alpha_prior: ndarray | None = None, max_iter: int | None = None) ndarray[source]#
NNLS+TopK sparse coding strategy (Xu et al. 2026, proposed method).
Three-stage hierarchical sparse coding:
Global NNLS coarse solution: solve the Tikhonov-NNLS problem on the full dictionary.
Top-K atom screening: keep the
Katoms with the largest coefficients from the coarse solution.Local NNLS fine optimization: re-solve NNLS on the screened support for a refined, sparse, non-negative coefficient vector.
The hierarchical strategy avoids the cumulative selection error of greedy OMP-style algorithms and produces sparse, physically meaningful solutions.
- Parameters:
M_norm (np.ndarray) – Normalized equivalent detection dictionary (m x p).
y (np.ndarray) – Measurement / count vector (m,).
sparsity (int) – Target sparsity
K(number of non-zero coefficients).lambda_tik (float, optional) – Tikhonov smoothing weight (default: 0.01).
prior_wt (float, optional) – Training-sample-driven prior weight (default: 0.0).
alpha_prior (np.ndarray, optional) – Prior coefficient vector (p,). Required when
prior_wt > 0.max_iter (int, optional) – Maximum NNLS iterations.
- Returns:
Non-negative K-sparse coefficient vector (p,).
- Return type:
np.ndarray
- bssunfold.core.unfold_nnksvd.solve_nn_omp(D: ndarray, y: ndarray, sparsity: int, tolerance: float = 1e-06) ndarray[source]#
Non-negative Orthogonal Matching Pursuit (NN-OMP).
Greedy sparse coding with a non-negativity constraint on the coefficient vector. At each iteration:
Pick the atom whose (signed) projection onto the residual is the largest positive value – non-negativity forbids negative coefficients so we only accept positively-correlated atoms.
Solve NNLS on the selected support (instead of unconstrained LS).
Update the residual.
- Parameters:
D (np.ndarray) – Dictionary matrix (n x p).
y (np.ndarray) – Signal to be represented (n,).
sparsity (int) – Maximum number of non-zero coefficients (K in the article).
tolerance (float, optional) – Early-stopping residual tolerance (default: 1e-6).
- Returns:
Non-negative sparse coefficient vector (p,).
- Return type:
np.ndarray
- bssunfold.core.unfold_nnksvd.solve_tikhonov_nnls(M_norm: ndarray, y: ndarray, lambda_tik: float = 0.01, prior_wt: float = 0.0, alpha_prior: ndarray | None = None, max_iter: int | None = None) ndarray[source]#
Tikhonov-regularized Non-Negative Least Squares.
Solves Eq. (2.5) of the article
min || y - M_norm @ alpha ||^2 + lambda_tik * || alpha ||^2 s.t. alpha >= 0
via the augmented-matrix equivalent (Eq. 2.6)
min || [y; 0] - [M_norm; sqrt(lambda_tik) I] @ alpha ||^2 s.t. alpha >= 0
An additional training-sample-driven prior constraint
prior_wt * || alpha - alpha_prior ||^2(article Section 2.2.2, “training sample-driven prior constraints”) is appended to the augmented system whenprior_wt > 0andalpha_prioris given.- Parameters:
M_norm (np.ndarray) – Normalized equivalent detection dictionary (m x p).
y (np.ndarray) – Measurement / count vector (m,).
lambda_tik (float, optional) – Tikhonov smoothing regularization weight (default: 0.01, as in the article).
prior_wt (float, optional) – Training-sample-driven prior weight (default: 0.0). When > 0,
alpha_priormust be supplied.alpha_prior (np.ndarray, optional) – Prior coefficient vector (p,). Required when
prior_wt > 0.max_iter (int, optional) – Maximum NNLS iterations.
- Returns:
Non-negative sparse coefficient vector (p,).
- Return type:
np.ndarray
Comparison Methods#
- bssunfold.utils.comparison.compare_spectra(spectrum1: ndarray, spectrum2: ndarray, metrics: str | list[str] | None = None, bins: ndarray | None = None, energy: ndarray | None = None, cc_icrp116: dict[str, ndarray] | None = None, readings1: ndarray | None = None, readings2: ndarray | None = None, response_matrix: ndarray | None = None) dict[str, float][source]#
Compare two spectra using selected metrics.
- Parameters:
spectrum1 (np.ndarray) – 1-D arrays of the same length.
spectrum2 (np.ndarray) – 1-D arrays of the same length.
metrics (str, list of str, or None) – Metric name(s). If None, all available metrics are computed (simple metrics only; pass
energyto include EURADOS metrics).bins (np.ndarray, optional) – Energy bins (unused, reserved for future use).
energy (np.ndarray, optional) – Energy grid in MeV. When provided, EURADOS-style metrics (dose differences, peak errors, etc.) are included automatically.
cc_icrp116 (np.ndarray, optional) – ICRP-116 conversion coefficients for dose calculations.
readings1 (np.ndarray, optional) – Measured readings for response-matrix consistency check.
readings2 (np.ndarray, optional) – Measured readings for response-matrix consistency check.
response_matrix (np.ndarray, optional) – Response matrix for consistency check.
- Returns:
Mapping from metric name (short key) to computed value.
- Return type:
Dict[str, float]
- bssunfold.utils.comparison.compare_multiple(spectra: list[ndarray], metrics: str | list[str] | None = None, labels: list[str] | None = None) dict[str, dict[str, float]][source]#
Compare multiple spectra pairwise against the first one.
- Parameters:
spectra (list of np.ndarray) – List of spectra. First entry is treated as reference.
metrics (str, list of str, or None) – Metric name(s). If None, all available metrics are computed.
labels (list of str, optional) – Labels for each spectrum.
- Returns:
{label: {metric: value}} for each non-reference spectrum.
- Return type:
Dict[str, Dict[str, float]]
Comparison Metrics#
Entropy-based#
- bssunfold.utils.comparison.kl_divergence(p: ndarray, q: ndarray) float[source]#
Kullback–Leibler divergence D_KL(p || q).
Both inputs are normalized to probability distributions internally.
- bssunfold.utils.comparison.cross_entropy(p: ndarray, q: ndarray) float[source]#
Cross-entropy H(p, q) = -sum(p * log(q)).
Distribution distances#
- bssunfold.utils.comparison.wasserstein_dist(p: ndarray, q: ndarray) float[source]#
Wasserstein (earth mover’s) distance between two distributions.
Uses scipy.stats.wasserstein_distance.
Correlation#
Error metrics#
- bssunfold.utils.comparison.mean_squared_error(p: ndarray, q: ndarray) float[source]#
Mean squared error.
- bssunfold.utils.comparison.root_mean_squared_error(p: ndarray, q: ndarray) float[source]#
Root mean squared error.
- bssunfold.utils.comparison.mean_absolute_error(p: ndarray, q: ndarray) float[source]#
Mean absolute error.
- bssunfold.utils.comparison.mape(p: ndarray, q: ndarray) float[source]#
Mean absolute percentage error.
Returns percentage (0–100). Skips elements where p is near zero.
Kernel / similarity#
- bssunfold.utils.comparison.cosine_similarity(p: ndarray, q: ndarray) float[source]#
Cosine similarity between two vectors.
Returns 0 if either vector is zero-norm.
- bssunfold.utils.comparison.mmd_rbf(p: ndarray, q: ndarray, gamma: float | None = None) float[source]#
Maximum Mean Discrepancy with RBF kernel.
- Parameters:
p (np.ndarray) – 1-D arrays.
q (np.ndarray) – 1-D arrays.
gamma (float, optional) – RBF kernel width. If None, uses 1 / (2 * median_distance**2).
- bssunfold.utils.comparison.total_flux_ratio(p: ndarray, q: ndarray) float[source]#
Ratio of total fluxes: sum(p) / sum(q).
1.0 = perfect conservation of total flux. > 1.0 = p overestimates total flux relative to q. < 1.0 = p underestimates total flux relative to q. Returns 0.0 if q (reference) flux is zero.
Chi-squared family#
- bssunfold.utils.comparison.chi_squared(p: ndarray, q: ndarray) float[source]#
Pearson’s chi-squared test statistic.
Internally normalizes both inputs as probability distributions.
- bssunfold.utils.comparison.g_test(p: ndarray, q: ndarray) float[source]#
G-test (log-likelihood ratio) statistic.
Statistical tests#
- bssunfold.utils.comparison.anderson_darling(p: ndarray, q: ndarray) float[source]#
Anderson-Darling test statistic for k-samples.
Returns 0.0 if either input is constant (all identical values).
- bssunfold.utils.comparison.wilcoxon_test(p: ndarray, q: ndarray) float[source]#
Wilcoxon signed-rank test statistic.
Returns 0.0 if both inputs are identical (all differences zero).
Integral quantity metrics#
- bssunfold.utils.comparison.fluence_averaged_energy(spectrum: ndarray, energy: ndarray) float[source]#
Fluence-averaged energy <E> of a single spectrum (MeV).
<E> = sum(E_i * Phi_i) / sum(Phi_i)
Returns 0.0 for a zero-total-flux spectrum.
- bssunfold.utils.comparison.energy_group_fluence(spectrum: ndarray, energy: ndarray, thermal_max: float = 4e-07, epithermal_max: float = 0.1) dict[str, float][source]#
Fluence rate per energy group for a single spectrum.
Groups (EURADOS): thermal (E < 0.4 eV), epithermal (0.4 eV <= E < 0.1 MeV), fast (E >= 0.1 MeV). Returns absolute fluence sums (simple bin sums, matching
energy_group_fluence_diff).- Parameters:
spectrum (np.ndarray) – Fluence per energy bin.
energy (np.ndarray) – Energy grid in MeV.
thermal_max (float) – Upper bound of thermal group in MeV (default: 0.4e-6 = 0.4 eV).
epithermal_max (float) – Upper bound of epithermal group in MeV (default: 0.1).
- bssunfold.utils.comparison.dose_averaged_energy(spectrum: ndarray, energy: ndarray, cc_ade: dict[str, ndarray] | ndarray | None = None) float[source]#
Ambient dose equivalent-averaged energy <E>_H (MeV).
<E>_H = sum(E_i * H*(10)_i * Phi_i) / sum(H*(10)_i * Phi_i)
Uses ICRP-74 ADE conversion coefficients (ISO 2001) interpolated onto the energy grid, unless
cc_adeis provided. Returns 0.0 for a zero-dose-weight spectrum.
- bssunfold.utils.comparison.ambient_dose_equivalent_rate(spectrum: ndarray, energy: ndarray, cc_ade: dict[str, ndarray] | ndarray | None = None) float[source]#
Ambient dose equivalent rate H*(10) of a single spectrum.
H*(10) = sum(h*(10)_i * Phi_i * dlnE_i)
Uses ICRP-74 ADE conversion coefficients (ISO 2001) interpolated onto the energy grid, unless
cc_adeis provided. Returns 0.0 for a zero-total-flux spectrum.
Spectral diagnostics (energy grid required)#
These metrics compare two spectra in physically meaningful terms
(fluence, dose, energy groups, peaks) and are computed automatically by
compare_spectra() when an energy
grid is supplied.
- bssunfold.utils.comparison.fluence_difference_percent(spectrum1: ndarray, spectrum2: ndarray, energy_bins: ndarray | None = None) float[source]#
Relative difference in total fluence between two spectra (%).
As used in EURADOS comparison: Δ(%) = 100 * (Q_participant - Q_reference) / Q_reference
- Parameters:
spectrum1 (np.ndarray) – Spectra to compare (fluence per energy bin).
spectrum2 (np.ndarray) – Spectra to compare (fluence per energy bin).
energy_bins (np.ndarray, optional) – Energy bin widths. If None, assumes uniform weighting.
- bssunfold.utils.comparison.energy_group_fluence_diff(spectrum1: ndarray, spectrum2: ndarray, energy: ndarray, thermal_max: float = 4e-07, epithermal_max: float = 0.1) dict[str, float][source]#
Relative difference in fluence for three energy groups (%).
Groups: thermal (E < 0.4 eV), epithermal (0.4 eV <= E < 0.1 MeV), fast (E >= 0.1 MeV).
- Parameters:
spectrum1 (np.ndarray) – Spectra to compare.
spectrum2 (np.ndarray) – Spectra to compare.
energy (np.ndarray) – Energy grid in MeV.
thermal_max (float) – Upper bound of thermal group in MeV (default: 0.4e-6 = 0.4 eV).
epithermal_max (float) – Upper bound of epithermal group in MeV (default: 0.1).
- bssunfold.utils.comparison.dose_difference_percent(spectrum1: ndarray, spectrum2: ndarray, energy: ndarray, cc_icrp116: dict[str, ndarray] | None = None) float[source]#
Relative difference in ambient dose equivalent H*(10) (%).
- Parameters:
spectrum1 (np.ndarray) – Spectra to compare.
spectrum2 (np.ndarray) – Spectra to compare.
energy (np.ndarray) – Energy grid in MeV.
cc_icrp116 (np.ndarray, optional) – ICRP-116 conversion coefficients. If None, uses a simple approximation.
- bssunfold.utils.comparison.fluence_averaged_energy_diff(spectrum1: ndarray, spectrum2: ndarray, energy: ndarray) float[source]#
Relative difference in fluence-averaged energy (%).
<E> = sum(E_i * Phi_i) / sum(Phi_i)
- bssunfold.utils.comparison.dose_averaged_energy_diff(spectrum1: ndarray, spectrum2: ndarray, energy: ndarray, cc_icrp116: dict[str, ndarray] | None = None) float[source]#
Relative difference in H*(10)-averaged energy (%).
<E>_H = sum(E_i * H_i * Phi_i) / sum(H_i * Phi_i)
- bssunfold.utils.comparison.log_lethargy_correlation(spectrum1: ndarray, spectrum2: ndarray, energy: ndarray) float[source]#
Pearson correlation in log(E)*Phi(E) coordinates.
As used in EURADOS figures showing spectra in lethargy representation.
- bssunfold.utils.comparison.peak_location_error(spectrum1: ndarray, spectrum2: ndarray, energy: ndarray) float[source]#
Relative error in peak location (%).
Finds the energy of maximum flux in each spectrum and computes relative difference.
- bssunfold.utils.comparison.peak_width_error(spectrum1: ndarray, spectrum2: ndarray, energy: ndarray) float[source]#
Relative error in peak width at half maximum (%).
Computes FWHM for each spectrum and returns relative difference.
- bssunfold.utils.comparison.dose_weighted_error(spectrum1: ndarray, spectrum2: ndarray, energy: ndarray, cc_icrp116: dict[str, ndarray] | None = None) float[source]#
Dose-weighted mean squared error.
MSE weighted by dose contribution: sum(H_i * (s1_i - s2_i)^2) / sum(H_i)
- bssunfold.utils.comparison.response_matrix_consistency(spectrum: ndarray, readings: ndarray, response_matrix: ndarray) float[source]#
Consistency between unfolded spectrum and measured readings.
Computes chi-squared: sum((R_measured - R_computed)^2 / R_measured) where R_computed = response_matrix @ spectrum.
Regularization Selection#
- bssunfold.core.regularization.select_regularization_parameter(A: ndarray, b: ndarray, method: str = 'lcurve', noise_var: float | None = None, initial_spectrum: ndarray | None = None, **kwargs) float[source]#
Select regularization parameter using specified method.
- Parameters:
A (np.ndarray) – Response matrix (m x n).
b (np.ndarray) – Measurement vector (m,).
method (str, optional) – Selection method: ‘lcurve’, ‘gcv’, ‘dp’, ‘cosine’ (default: ‘lcurve’).
noise_var (float, optional) – Noise variance for discrepancy principle.
initial_spectrum (np.ndarray, optional) – Initial spectrum for cosine similarity method.
**kwargs (dict) – Additional method-specific arguments.
- Returns:
Selected regularization parameter (lambda).
- Return type:
float
- Raises:
ValueError – If method is unknown or selection fails.
- bssunfold.core.regularization.lcurve_selection(A: ndarray, b: ndarray, n_alphas: int = 50, alpha_range: tuple[float, float] = (1e-09, 100.0)) float[source]#
Select regularization parameter using L-curve corner heuristic.
- Parameters:
A (np.ndarray) – Response matrix.
b (np.ndarray) – Measurement vector.
n_alphas (int, optional) – Number of alpha values to test (default: 50).
alpha_range (Tuple[float, float], optional) – Range of alpha values (default: (1e-9, 1e2)).
- Returns:
Selected regularization parameter.
- Return type:
float
- bssunfold.core.regularization.gcv_selection(A: ndarray, b: ndarray, n_alphas: int = 50, alpha_range: tuple[float, float] = (1e-09, 100.0)) float[source]#
Select regularization parameter using Generalized Cross Validation.
- Parameters:
A (np.ndarray) – Response matrix.
b (np.ndarray) – Measurement vector.
n_alphas (int, optional) – Number of alpha values to test (default: 50).
alpha_range (Tuple[float, float], optional) – Range of alpha values (default: (1e-9, 1e2)).
- Returns:
Selected regularization parameter.
- Return type:
float
- bssunfold.core.regularization.discrepancy_principle_selection(A: ndarray, b: ndarray, noise_var: float | None = None, n_alphas: int = 50, alpha_range: tuple[float, float] = (1e-09, 100.0)) float[source]#
Select regularization parameter using Discrepancy Principle.
- Parameters:
A (np.ndarray) – Response matrix.
b (np.ndarray) – Measurement vector.
noise_var (float, optional) – Noise variance. If None, estimated from data.
n_alphas (int, optional) – Number of alpha values to test (default: 50).
alpha_range (Tuple[float, float], optional) – Range of alpha values (default: (1e-9, 1e2)).
- Returns:
Selected regularization parameter.
- Return type:
float
- bssunfold.core.regularization.cosine_similarity_selection(A: ndarray, b: ndarray, initial_spectrum: ndarray, n_alphas: int = 100, alpha_range: tuple[float, float] = (-9, 2), norm: int = 2) float[source]#
Select regularization parameter by maximizing cosine similarity.
Uses precomputed SVD for efficient evaluation across alpha values.
- Parameters:
A (np.ndarray) – Response matrix.
b (np.ndarray) – Measurement vector.
initial_spectrum (np.ndarray) – Initial/reference spectrum for similarity comparison.
n_alphas (int, optional) – Number of alpha values to test (default: 100).
alpha_range (Tuple[float, float], optional) – Log range of alpha values (default: (-9, 2)).
norm (int, optional) – Norm type for regularization (default: 2).
- Returns:
Selected regularization parameter.
- Return type:
float
- bssunfold.core.regularization.quasi_optimality_selection(A: ndarray, b: ndarray, n_alphas: int = 50, alpha_range: tuple[float, float] = (1e-09, 100.0)) float[source]#
Select regularization parameter using the quasi-optimality criterion.
The quasi-optimality criterion (Hochstenbach & Reichel, 2015) minimises the noise component of the Tikhonov solution in the SVD basis:
Q(alpha) = sum_i (alpha^2 / (s_i^2 + alpha^2))^2 * (U_i^T b / s_i)^2
The optimal alpha is the one that minimises Q(alpha).
- Parameters:
A (np.ndarray) – Response matrix.
b (np.ndarray) – Measurement vector.
n_alphas (int, optional) – Number of alpha values to test (default: 50).
alpha_range (Tuple[float, float], optional) – Range of alpha values (default: (1e-9, 1e2)).
- Returns:
Selected regularization parameter.
- Return type:
float
- bssunfold.core.regularization.ncp_selection(A: ndarray, b: ndarray, n_alphas: int = 50, alpha_range: tuple[float, float] = (1e-09, 100.0), significance: float = 0.05) float[source]#
Select regularization parameter using the Normalized Cumulative Periodogram.
The NCP criterion tests whether the residuals of the regularised solution are consistent with white noise. For each candidate alpha, the residual vector is computed, its periodogram is formed, and a Kolmogorov-Smirnov test is applied against the uniform distribution on [0, 1]. The alpha with the smallest KS statistic (i.e. whitest residuals) is selected.
- Parameters:
A (np.ndarray) – Response matrix.
b (np.ndarray) – Measurement vector.
n_alphas (int, optional) – Number of alpha values to test (default: 50).
alpha_range (Tuple[float, float], optional) – Range of alpha values (default: (1e-9, 1e2)).
significance (float, optional) – Reserved for future use (default: 0.05).
- Returns:
Selected regularization parameter.
- Return type:
float
- bssunfold.core.regularization.snr_criterion_selection(A: ndarray, b: ndarray, n_alphas: int = 50, alpha_range: tuple[float, float] = (1e-09, 100.0)) float[source]#
Select regularization parameter by maximising signal-to-noise ratio.
For each candidate alpha the Tikhonov solution is split into a signal component (projection onto the leading singular vectors) and a noise component (projection onto the trailing singular vectors). The SNR is defined as the ratio of their squared Frobenius norms.
- Parameters:
A (np.ndarray) – Response matrix.
b (np.ndarray) – Measurement vector.
n_alphas (int, optional) – Number of alpha values to test (default: 50).
alpha_range (Tuple[float, float], optional) – Range of alpha values (default: (1e-9, 1e2)).
- Returns:
Selected regularization parameter.
- Return type:
float
- bssunfold.core.regularization.weighted_gcv_poisson_selection(A: ndarray, b: ndarray, n_alphas: int = 50, alpha_range: tuple[float, float] = (1e-09, 100.0)) float[source]#
Select regularization parameter using weighted GCV for Poisson noise.
Under Poisson noise the variance of each measurement equals its expectation. The weighted GCV replaces the ordinary GCV denominator
||r||^2withsum(r_i^2 / w_i)wherew_i = max(b_i, 1)are the Poisson variance estimates, and the trace term is replaced bytr(W (I - H_alpha))withW = diag(1/w_i).- Parameters:
A (np.ndarray) – Response matrix.
b (np.ndarray) – Measurement vector.
n_alphas (int, optional) – Number of alpha values to test (default: 50).
alpha_range (Tuple[float, float], optional) – Range of alpha values (default: (1e-9, 1e2)).
- Returns:
Selected regularization parameter.
- Return type:
float
- bssunfold.core.regularization.kfold_cv_selection(A: ndarray, b: ndarray, n_folds: int = 5, n_alphas: int = 50, alpha_range: tuple[float, float] = (1e-09, 100.0), random_state: int | None = None) float[source]#
Select regularization parameter using K-fold cross-validation.
The data is split into K folds. For each alpha, the Tikhonov problem is solved on K-1 folds and the held-out residual is evaluated. The alpha with the smallest mean held-out prediction error is selected.
- Parameters:
A (np.ndarray) – Response matrix.
b (np.ndarray) – Measurement vector.
n_folds (int, optional) – Number of cross-validation folds (default: 5).
n_alphas (int, optional) – Number of alpha values to test (default: 50).
alpha_range (Tuple[float, float], optional) – Range of alpha values (default: (1e-9, 1e2)).
random_state (int, optional) – Random seed for fold assignment (default: None).
- Returns:
Selected regularization parameter.
- Return type:
float