Fitting Module

Bayesian fitting with NumPyro NUTS sampler and JAX-accelerated NLSQ warm-start.

Overview

The fitting module provides Bayesian parameter estimation using NumPyro’s NUTS sampler with JAX-accelerated nonlinear least squares (NLSQ) warm-start.

Key Features (NLSQ 0.6.0):

  • Enhanced statistical metrics: R², adjusted R², RMSE, MAE, AIC, BIC

  • Confidence intervals for parameters (95% level)

  • Prediction intervals accounting for observation noise

  • Automatic bounds inference

  • Numerical stability checks and fixes

  • Fallback strategies for difficult optimization problems

  • Model health diagnostics

Quick Start

Basic NLSQ fitting:

from xpcsviewer.fitting import nlsq_fit
import jax.numpy as jnp

def model(x, tau, baseline, contrast):
    return baseline + contrast * jnp.exp(-2 * x / tau)

result = nlsq_fit(
    model, x_data, y_data, y_errors,
    p0={'tau': 1.0, 'baseline': 1.0, 'contrast': 0.3},
    bounds={'tau': (0.01, 100), 'baseline': (0.9, 1.1), 'contrast': (0.1, 0.5)},
    workflow='auto_global',
)

print(f"R² = {result.r_squared:.4f}")
print(result.summary())

Bayesian fitting:

from xpcsviewer.fitting import fit_single_exp

result = fit_single_exp(delay_times, g2_values, g2_errors)
print(f"τ = {result.get_mean('tau'):.3f} ± {result.get_std('tau'):.3f}")

Public API

Fitting Functions

xpcsviewer.fitting.fit_single_exp(x, y, yerr=None, **kwargs)[source]

Fit single exponential decay model with Bayesian inference.

Model: y = baseline + contrast * exp(-2 * x / tau)

Parameters:
  • x (array_like) – Delay times

  • y (array_like) – G2 correlation values

  • yerr (array_like, optional) – Measurement uncertainties

  • **kwargs – Sampler configuration (see SamplerConfig)

Returns:

Posterior samples for tau, baseline, contrast

Return type:

FitResult

xpcsviewer.fitting.fit_double_exp(x, y, yerr=None, **kwargs)[source]

Fit double exponential decay model with Bayesian inference.

Model: y = baseline + c1*exp(-2x/tau1) + c2*exp(-2x/tau2)

Parameters:
  • x (array_like) – Delay times

  • y (array_like) – G2 correlation values

  • yerr (array_like, optional) – Measurement uncertainties

  • **kwargs – Sampler configuration (see SamplerConfig)

Returns:

Posterior samples for tau1, tau2, baseline, contrast1, contrast2

Return type:

FitResult

xpcsviewer.fitting.fit_stretched_exp(x, y, yerr=None, **kwargs)[source]

Fit stretched exponential (KWW) model with Bayesian inference.

Model: y = baseline + contrast * exp(-(2 * x / tau)^beta)

Parameters:
  • x (array_like) – Delay times

  • y (array_like) – G2 correlation values

  • yerr (array_like, optional) – Measurement uncertainties

  • **kwargs – Sampler configuration (see SamplerConfig)

Returns:

Posterior samples for tau, baseline, contrast, beta

Return type:

FitResult

xpcsviewer.fitting.fit_power_law(q, tau, tau_err=None, **kwargs)[source]

Fit power law Q-dependence of relaxation time.

Model: tau = tau0 * q^(-alpha)

Parameters:
  • q (array_like) – Q values

  • tau (array_like or FitResult) – Relaxation times (or FitResult with tau samples)

  • tau_err (array_like, optional) – Measurement uncertainties on tau values from G2 fitting

  • **kwargs – Sampler configuration (see SamplerConfig)

Returns:

Posterior samples for tau0, alpha

Return type:

FitResult

xpcsviewer.fitting.nlsq_fit(model_fn, x, y, yerr, p0, bounds, workflow='auto_global', *, auto_bounds=False, stability=False, fallback=False, compute_diagnostics=False, show_progress=False)[source]

JAX-accelerated nonlinear least squares with NLSQ 0.6.0 features.

Parameters:
  • model_fn (callable) – Model function taking x and parameter values. Uses JAX operations.

  • x (array_like) – Independent variable

  • y (array_like) – Dependent variable

  • yerr (array_like or None) – Measurement uncertainties

  • p0 (dict) – Initial parameter guess {name: value}

  • bounds (dict) – Parameter bounds {name: (min, max)}

  • workflow ({'auto', 'auto_global', 'hpc'}, optional) –

    NLSQ workflow configuration (default: ‘auto_global’):

    • ’auto’: Fast single-start

    • ’auto_global’: Robust multi-start (default)

    • ’hpc’: Streaming for large datasets

  • auto_bounds (bool, optional) – Enable automatic bounds inference (default: False)

  • stability ({'auto', 'check', False}, optional) –

    Numerical stability checks (default: False):

    • ’auto’: Check and apply fixes

    • ’check’: Check and warn only

    • False: Skip checks

  • fallback (bool, optional) – Enable fallback strategies for difficult problems (default: False)

  • compute_diagnostics (bool, optional) – Compute model health diagnostics (default: False)

  • show_progress (bool, optional) – Display progress bar (default: False)

Returns:

Enhanced result with R², RMSE, AIC, BIC, confidence intervals, predictions, and optional model diagnostics.

Return type:

NLSQResult

Examples

Basic usage:

>>> result = nlsq_fit(model_fn, x, y, yerr, p0, bounds)
>>> print(f"R² = {result.r_squared:.4f}")
>>> print(result.summary())

Robust fitting with diagnostics:

>>> result = nlsq_fit(
...     model_fn, x, y, yerr, p0, bounds,
...     workflow='auto_global',
...     stability='auto',
...     fallback=True,
...     compute_diagnostics=True,
... )
xpcsviewer.fitting.assemble_fit_summary(results, q_arr, t_el, fit_func_name, model_func, *, q_range='', t_range='', bounds=None, fit_flag='', label='')[source]

Convert per-Q Bayesian results into NLSQ-compatible fit_summary.

Parameters:
  • results (dict[int, FitResult | None]) – Mapping of Q-index to FitResult (None for failed Q-bins).

  • q_arr (ndarray) – Array of Q values (1D).

  • t_el (ndarray) – Array of delay times (1D).

  • fit_func_name (str) – "single" or "double".

  • model_func (callable) – Bayesian model function (single_exp_func or double_exp_func).

  • q_range (optional) – Metadata fields matching the NLSQ fit_summary format.

  • t_range (optional) – Metadata fields matching the NLSQ fit_summary format.

  • bounds (optional) – Metadata fields matching the NLSQ fit_summary format.

  • fit_flag (optional) – Metadata fields matching the NLSQ fit_summary format.

  • label (optional) – Metadata fields matching the NLSQ fit_summary format.

Returns:

fit_summary dict with keys: fit_func, fit_val, t_el, q_val, q_range, t_range, bounds, fit_flag, fit_line, fit_x, label, failed_mask. Failed Q-bins have NaN in fit_val/fit_line and failed_mask[q_idx] == True.

Return type:

dict

Result Classes

class xpcsviewer.fitting.NLSQResult(params, chi_squared, converged, pcov_valid=True, pcov_message='', native_result=None, is_fallback=False, _param_names=<factory>, _covariance=None, _residuals=None, _r_squared=nan, _adj_r_squared=nan, _rmse=nan, _mae=nan, _aic=nan, _bic=nan, _confidence_intervals=<factory>, _predictions=None)[source]

Bases: object

Result from nonlinear least squares fitting.

This class wraps NLSQ 0.6.0’s CurveFitResult and delegates statistical properties to the native result for accuracy and consistency.

Parameters:
params

Point estimates for each parameter

Type:

dict[str, float]

converged

Whether optimization converged

Type:

bool

chi_squared

Reduced chi-squared statistic

Type:

float

pcov_valid

Covariance validity flag (FR-021)

Type:

bool

pcov_message

Validation message describing covariance status

Type:

str

native_result

NLSQ 0.6.0 native result object for property delegation

Type:

CurveFitResult, optional

_param_names

Ordered parameter names for covariance indexing

Type:

list[str]

Properties(delegated to native_result when available)
------------------------------------------------------
r_squared

Coefficient of determination (R²). Range: (-∞, 1], where 1 is perfect fit.

Type:

float

adj_r_squared

Adjusted R² accounting for number of parameters.

Type:

float

rmse

Root mean squared error. Lower is better.

Type:

float

mae

Mean absolute error. Robust to outliers.

Type:

float

aic

Akaike Information Criterion. Lower is better for model selection.

Type:

float

bic

Bayesian Information Criterion. Penalizes complexity more than AIC.

Type:

float

residuals

Fit residuals as numpy array.

Type:

ndarray

predictions

Model predictions at input x values.

Type:

ndarray

covariance

Parameter covariance matrix (n_params x n_params).

Type:

ndarray

confidence_intervals

Parameter confidence intervals at 95% level.

Type:

dict[str, tuple[float, float]]

diagnostics

NLSQ model health diagnostics (if compute_diagnostics=True).

Type:

ModelHealthReport or None

is_healthy

Whether the fit passes all health checks.

Type:

bool

health_score

Health score (0-100).

Type:

int

condition_number

Condition number from identifiability diagnostics.

Type:

float

params: dict[str, float]
chi_squared: float
converged: bool
pcov_valid: bool = True
pcov_message: str = ''
native_result: CurveFitResult | None = None
is_fallback: bool = False
__post_init__()[source]

Initialize param names from params dict if not provided.

Return type:

None

property r_squared: float

Coefficient of determination (R²).

property adj_r_squared: float

Adjusted R² accounting for number of parameters.

property rmse: float

Root mean squared error.

property mae: float

Mean absolute error.

property aic: float

Akaike Information Criterion.

property bic: float

Bayesian Information Criterion.

property residuals: ndarray

Fit residuals as numpy array.

property predictions: ndarray | None

Model predictions at input x values.

property covariance: ndarray

Parameter covariance matrix.

property confidence_intervals: dict[str, tuple[float, float]]

Parameter confidence intervals at 95% level.

property diagnostics: ModelHealthReport | None

NLSQ model health diagnostics.

property is_healthy: bool

Whether the fit passes all health checks.

Uses an attribute-based check against the NLSQ diagnostics API (BUG-040). Avoids the fragile str(status) == “healthy” string comparison by: 1. Checking diagnostics.is_healthy attribute if available (NLSQ native), or 2. Using health_score >= 70 as a numeric fallback, or 3. Checking enum value via .value or .name attribute comparison.

property health_score: int

Health score (0-100).

property condition_number: float

Condition number from identifiability diagnostics.

get_param_uncertainty(param)[source]

Get standard error for a parameter from the covariance matrix.

Parameters:

param (str) – Parameter name

Returns:

Standard error (sqrt of diagonal covariance element)

Return type:

float

get_confidence_interval(param, alpha=0.05)[source]

Get confidence interval for a parameter.

Parameters:
  • param (str) – Parameter name

  • alpha (float) – Significance level (default: 0.05 for 95% CI)

Returns:

(lower, upper) bounds of confidence interval

Return type:

tuple[float, float]

get_prediction_interval(x, alpha=0.05)[source]

Get prediction interval at new x values.

Delegates to native_result.prediction_interval() when available.

Parameters:
  • x (array_like) – X values at which to compute prediction intervals

  • alpha (float) – Significance level (default: 0.05 for 95% PI)

Returns:

(lower, upper) bounds of prediction interval as numpy arrays

Return type:

tuple[ndarray, ndarray]

summary()[source]

Generate a formatted summary of the fit results.

Returns:

Formatted summary string

Return type:

str

plot(model, x_data, y_data, **kwargs)[source]

Plot fit with uncertainty band.

Parameters:
  • model (callable) – Model function

  • x_data (array-like) – Original data

  • y_data (array-like) – Original data

  • **kwargs – Additional arguments for visualization

Return type:

matplotlib.axes.Axes

__init__(params, chi_squared, converged, pcov_valid=True, pcov_message='', native_result=None, is_fallback=False, _param_names=<factory>, _covariance=None, _residuals=None, _r_squared=nan, _adj_r_squared=nan, _rmse=nan, _mae=nan, _aic=nan, _bic=nan, _confidence_intervals=<factory>, _predictions=None)
Parameters:
Return type:

None

class xpcsviewer.fitting.FitResult(samples, param_names=<factory>, summary=None, diagnostics=<factory>, nlsq_init=<factory>, arviz_data=None, config=None, x=None)[source]

Bases: object

Container for Bayesian fitting results.

Parameters:
  • samples (dict[str, np.ndarray])

  • param_names (list[str])

  • summary (pd.DataFrame | None)

  • diagnostics (FitDiagnostics)

  • nlsq_init (dict[str, float])

  • arviz_data (DataTree | None)

  • config (SamplerConfig | None)

  • x (np.ndarray | None)

samples

Posterior samples {param_name: (n_samples,)}

Type:

dict[str, ndarray]

param_names

Canonical parameter order matching the model function signature. Used by visualization to ensure correct positional argument mapping.

Type:

list[str]

summary

Summary statistics per parameter

Type:

DataFrame

diagnostics

Convergence diagnostics

Type:

FitDiagnostics

nlsq_init

NLSQ warm-start point estimates

Type:

dict[str, float]

arviz_data

ArviZ-compatible data for plotting (FR-015)

Type:

DataTree

config

Sampler configuration used for this fit (per Technical Guidelines)

Type:

SamplerConfig | None

x

Input x data (for reproducibility metadata)

Type:

ndarray | None

samples: dict[str, np.ndarray]
param_names: list[str]
summary: pd.DataFrame | None = None
diagnostics: FitDiagnostics
nlsq_init: dict[str, float]
arviz_data: DataTree | None = None
config: SamplerConfig | None = None
__init__(samples, param_names=<factory>, summary=None, diagnostics=<factory>, nlsq_init=<factory>, arviz_data=None, config=None, x=None)
Parameters:
  • samples (dict[str, np.ndarray])

  • param_names (list[str])

  • summary (pd.DataFrame | None)

  • diagnostics (FitDiagnostics)

  • nlsq_init (dict[str, float])

  • arviz_data (DataTree | None)

  • config (SamplerConfig | None)

  • x (np.ndarray | None)

Return type:

None

x: np.ndarray | None = None
__post_init__()[source]

Validate samples invariants at construction (BUG-024).

Enforces: - samples dict is non-empty (no results without actual posterior draws) - all sample arrays have consistent shapes (same number of draws)

Return type:

None

get_mean(param)[source]

Get posterior mean for parameter.

Parameters:

param (str) – Parameter name

Returns:

Posterior mean

Return type:

float

get_std(param)[source]

Get posterior standard deviation for parameter.

Parameters:

param (str) – Parameter name

Returns:

Posterior standard deviation

Return type:

float

get_hdi(param, prob=0.94)[source]

Get highest density interval for parameter.

Uses ArviZ’s az.hdi() for the true HDI (shortest interval containing prob probability mass). Falls back to an equal-tailed percentile interval when ArviZ is unavailable.

Note

For skewed posteriors (e.g. LogNormal tau), the true HDI can be significantly narrower than the equal-tailed interval. The previous implementation always used percentiles, which over-estimated uncertainty for skewed parameters (BUG-C fix).

Parameters:
  • param (str) – Parameter name

  • prob (float) – Probability mass for HDI (default: 0.94)

Returns:

(lower, upper) bounds of HDI

Return type:

tuple[float, float]

get_samples(param)[source]

Get posterior samples for parameter.

Parameters:

param (str) – Parameter name

Returns:

Posterior samples array

Return type:

ndarray

predict(x)[source]

Generate posterior predictive samples.

Note

This method requires a model function which is not stored in FitResult. Use plot_posterior_predictive() with an explicit model function, or compute predictions manually from get_samples().

Parameters:

x (array-like) – X values for prediction

Returns:

(mean prediction, std prediction)

Return type:

tuple[ndarray, ndarray]

Raises:

NotImplementedError – Always raised. Use plot_posterior_predictive(model, x, y) or compute predictions from posterior samples directly.

to_dict()[source]

Convert to serializable dictionary.

Per Technical Guidelines, exports include: - versions: Package versions for reproducibility - sampler_config: Sampler parameters used - data_metadata: Data characteristics - diagnostics: Including BFMI

Returns:

Dictionary representation with full reproducibility metadata

Return type:

dict

plot_posterior_predictive(model, x_data, y_data, **kwargs)[source]

Plot posterior predictive with credible interval.

Parameters:
  • model (callable) – Model function

  • x_data (array-like) – Original data

  • y_data (array-like) – Original data

  • **kwargs – Additional arguments for visualization

Return type:

matplotlib.figure.Figure

generate_diagnostics(output_dir=None, formats=('pdf', 'png'))[source]

Generate ArviZ diagnostic plots.

Parameters:
  • output_dir (str or Path, optional) – Directory for output files

  • formats (tuple) – Output formats

Returns:

Mapping of plot type to figure or file path

Return type:

dict

class xpcsviewer.fitting.FitDiagnostics(r_hat=<factory>, ess_bulk=<factory>, ess_tail=<factory>, divergences=0, max_treedepth_reached=0, bfmi=None)[source]

Bases: object

Convergence diagnostics for MCMC sampling.

Parameters:
r_hat

Gelman-Rubin statistic per parameter

Type:

dict[str, float]

ess_bulk

Bulk ESS per parameter

Type:

dict[str, int]

ess_tail

Tail ESS per parameter

Type:

dict[str, int]

divergences

Number of divergent transitions

Type:

int

max_treedepth_reached

Count of max treedepth events

Type:

int

bfmi

Bayesian Fraction of Missing Information (mean across chains). Added per Technical Guidelines for Bayesian inference compliance.

Type:

float | None

Properties(computed)
---------------------
converged

True if all diagnostics pass thresholds (see below). This is a computed @property, not a stored field.

Type:

bool

Convergence Thresholds
----------------------
r_hat < 1.01
Type:

All parameters must converge

ess_bulk > 400
Type:

Sufficient effective samples

ess_tail > 400
Type:

Sufficient tail samples

divergences == 0
Type:

No divergent transitions

bfmi >= 0.2
Type:

Adequate exploration (if computed)

r_hat: dict[str, float]
ess_bulk: dict[str, int]
ess_tail: dict[str, int]
divergences: int = 0
max_treedepth_reached: int = 0
bfmi: float | None = None
__post_init__()[source]

Validate diagnostic invariants (BUG-025).

Enforces: - divergences >= 0 (negative divergences are physically meaningless) - all ess_bulk values are non-negative - all ess_tail values are non-negative

Return type:

None

property converged: bool

Check if all diagnostics pass thresholds.

__init__(r_hat=<factory>, ess_bulk=<factory>, ess_tail=<factory>, divergences=0, max_treedepth_reached=0, bfmi=None)
Parameters:
Return type:

None

class xpcsviewer.fitting.SamplerConfig(num_warmup=500, num_samples=1000, num_chains=4, target_accept_prob=0.8, max_tree_depth=10, random_seed=None)[source]

Bases: object

Configuration for NUTS sampler.

Parameters:
  • num_warmup (int)

  • num_samples (int)

  • num_chains (int)

  • target_accept_prob (float)

  • max_tree_depth (int)

  • random_seed (int | None)

num_warmup

Number of warmup (burn-in) samples (default: 500)

Type:

int

num_samples

Number of posterior samples per chain (default: 1000)

Type:

int

num_chains

Number of MCMC chains (default: 4)

Type:

int

target_accept_prob

Target acceptance probability for NUTS (default: 0.8)

Type:

float

max_tree_depth

Maximum tree depth for NUTS (default: 10)

Type:

int

random_seed

Random seed for reproducibility (default: None)

Type:

int or None

num_warmup: int = 500
num_samples: int = 1000
num_chains: int = 4
target_accept_prob: float = 0.8
max_tree_depth: int = 10
random_seed: int | None = None
__post_init__()[source]

Validate sampler configuration.

__init__(num_warmup=500, num_samples=1000, num_chains=4, target_accept_prob=0.8, max_tree_depth=10, random_seed=None)
Parameters:
  • num_warmup (int)

  • num_samples (int)

  • num_chains (int)

  • target_accept_prob (float)

  • max_tree_depth (int)

  • random_seed (int | None)

Return type:

None

Visualization Functions

xpcsviewer.fitting.compute_uncertainty_band(model, x_pred, popt, pcov, confidence=0.95)[source]

Compute prediction uncertainty band via error propagation (FR-016).

Uses Jacobian-based error propagation to compute uncertainty bands.

Parameters:
  • model (callable) – Model function taking x and params

  • x_pred (ndarray) – X values for prediction

  • popt (ndarray) – Fitted parameters

  • pcov (ndarray) – Parameter covariance matrix (n_params x n_params)

  • confidence (float) – Confidence level (default: 0.95 for 95% CI)

Returns:

  • y_fit (ndarray) – Fitted curve values

  • y_lower (ndarray) – Lower bound of confidence band

  • y_upper (ndarray) – Upper bound of confidence band

xpcsviewer.fitting.compute_prediction_interval(model, x_pred, popt, pcov, residuals, confidence=0.95)[source]

Compute prediction interval including residual variance (NLSQ 0.6.0).

Prediction intervals are wider than confidence intervals because they account for both parameter uncertainty AND observation noise.

Adds residual standard deviation term to confidence interval width.

Parameters:
  • model (callable) – Model function taking x and params

  • x_pred (ndarray) – X values for prediction

  • popt (ndarray) – Fitted parameters

  • pcov (ndarray) – Parameter covariance matrix

  • residuals (ndarray) – Fit residuals (y - y_pred) from training data

  • confidence (float) – Confidence level (default: 0.95 for 95% PI)

Returns:

  • y_fit (ndarray) – Fitted curve values

  • pi_lower (ndarray) – Lower bound of prediction interval

  • pi_upper (ndarray) – Upper bound of prediction interval

xpcsviewer.fitting.plot_nlsq_fit(result, model, x_data, y_data, x_pred=None, confidence=0.95, ax=None, show_metrics=True, show_prediction_interval=False, xlabel='x', ylabel='y', title=None)[source]

Plot NLSQ fit with uncertainty band (FR-017, FR-021, NLSQ 0.6.0).

If covariance is invalid, logs warning and displays “Uncertainty unavailable” in legend.

Parameters:
  • result (NLSQResult) – Output from nlsq_fit()

  • model (callable) – Model function

  • x_data (ndarray) – Original data

  • y_data (ndarray) – Original data

  • x_pred (ndarray, optional) – X values for prediction curve

  • confidence (float) – Confidence level for band (default: 0.95)

  • ax (matplotlib.axes.Axes, optional) – Axes to plot on (creates new if None)

  • show_metrics (bool, optional) – Display R², RMSE, and χ² on the plot (default: True). Uses NLSQ 0.6.0 enhanced metrics from NLSQResult.

  • show_prediction_interval (bool, optional) – Show prediction interval in addition to confidence interval. Prediction intervals account for observation noise (default: False).

  • xlabel (str, optional) – X-axis label (default: “x”)

  • ylabel (str, optional) – Y-axis label (default: “y”)

  • title (str, optional) – Plot title (default: None)

Returns:

ax

Return type:

matplotlib.axes.Axes

xpcsviewer.fitting.plot_posterior_predictive(result, model, x_data, y_data, x_pred=None, credible_level=0.95, n_draws=100, ax=None, *, max_draws=None, subsample_seed=None)[source]

Plot Bayesian fit with posterior credible interval (FR-014).

Parameters:
  • result (FitResult) – Output from Bayesian fitting

  • model (callable) – Model function

  • x_data (ndarray) – Original data

  • y_data (ndarray) – Original data

  • x_pred (ndarray, optional) – X values for prediction (default: smooth range over x_data)

  • credible_level (float) – Credible interval level (default: 0.95)

  • n_draws (int) – Number of posterior samples for band calculation (legacy, prefer max_draws)

  • ax (matplotlib.axes.Axes, optional)

  • max_draws (int | None) – Maximum posterior draws to use. If None (default), uses all samples. When specified and n_samples > max_draws, subsamples with logging. Per Technical Guidelines, subsampling must be explicit and logged.

  • subsample_seed (int | None) – Random seed for reproducible subsampling. Only used when max_draws triggers subsampling.

Returns:

ax

Return type:

matplotlib.axes.Axes

Notes

Per Technical Guidelines, posterior subsampling is explicit and logged. When max_draws is None (default), all posterior samples are used.

xpcsviewer.fitting.plot_comparison(nlsq_result, bayesian_result, model, x_data, y_data, x_pred=None, confidence_level=0.95, band_alpha=0.25, ax=None)[source]

Overlay NLSQ confidence band and Bayesian credible interval (FR-020).

Parameters:
  • nlsq_result (NLSQResult) – NLSQ fitting result

  • bayesian_result (FitResult) – Bayesian fitting result

  • model (callable) – Model function

  • x_data (ndarray) – Original data

  • y_data (ndarray) – Original data

  • x_pred (ndarray, optional) – X values for prediction curves

  • confidence_level (float) – Confidence/credible level (default: 0.95)

  • band_alpha (float) – Transparency for bands (default: 0.25)

  • ax (matplotlib.axes.Axes, optional)

Returns:

ax

Return type:

matplotlib.axes.Axes

xpcsviewer.fitting.generate_arviz_diagnostics(trace, var_names=None, output_dir=None, formats=('pdf', 'png'), dpi=300, prefix='mcmc')[source]

Generate complete ArviZ diagnostic suite (FR-013).

Plots generated: 1. Pair plot (parameter correlations, divergences) 2. Forest plot (HDI intervals) 3. Energy plot (NUTS E-BFMI diagnostics) 4. Autocorrelation plot (chain mixing) 5. Rank plot (convergence check) 6. ESS plot (effective sample size)

Parameters:
  • trace (DataTree) – ArviZ DataTree object from MCMC

  • var_names (list, optional) – Parameter names to plot (default: all)

  • output_dir (str or Path, optional) – Directory for output files (None = return figures only)

  • formats (tuple) – Output formats (default: (“pdf”, “png”) per FR-018)

  • dpi (int) – Resolution for raster formats (default: 300 per FR-018)

  • prefix (str) – Filename prefix

Returns:

Mapping plot_type → figure (if output_dir is None) Mapping plot_type_format → file path (if output_dir provided)

Return type:

dict

xpcsviewer.fitting.save_figure(fig, filepath, formats=('pdf', 'png'), dpi=300)[source]

Save figure in multiple formats (FR-018).

Parameters:
  • fig (matplotlib.figure.Figure)

  • filepath (str or Path) – Base path (extension will be replaced)

  • formats (tuple) – Output formats (default: (“pdf”, “png”))

  • dpi (int) – Resolution for raster formats

Returns:

Mapping format → saved file path

Return type:

dict

xpcsviewer.fitting.validate_pcov(pcov, param_names=None)[source]

Validate covariance matrix before computing uncertainty bands (FR-021).

Checks: - pcov is not None - All values are finite (no inf/nan) - Matrix is positive semi-definite

Parameters:
  • pcov (ndarray or None) – Covariance matrix to validate

  • param_names (list, optional) – Parameter names for error messages

Returns:

  • is_valid (bool) – True if covariance is valid

  • message (str) – Validation message (error description if invalid)

Return type:

tuple[bool, str]

xpcsviewer.fitting.apply_publication_style()[source]

Apply publication-quality matplotlib style (FR-019).

Gradient-Based Optimization

xpcsviewer.fitting.grad(func, argnums=0)[source]

Create a gradient function for a scalar-valued function.

Wraps JAX’s grad for user-defined objective functions.

Parameters:
  • func (callable) – Differentiable function that returns a scalar

  • argnums (int or tuple of int, optional) – Arguments to differentiate with respect to (default: 0)

Returns:

Function that computes gradients

Return type:

callable

Raises:

RuntimeError – If JAX backend is not available

Examples

>>> def loss(params, x, y):
...     pred = params[0] * x + params[1]
...     return jnp.sum((pred - y) ** 2)
>>> gradient_fn = grad(loss)
>>> gradient = gradient_fn(params, x, y)
xpcsviewer.fitting.value_and_grad(func, argnums=0)[source]

Create a function that computes both value and gradient.

Wraps JAX’s value_and_grad for user-defined objective functions. The wrapped function returns (value, gradient) tuple.

Parameters:
  • func (callable) – Differentiable function that returns a scalar

  • argnums (int or tuple of int, optional) – Arguments to differentiate with respect to (default: 0)

Returns:

Function returning (value, gradient) tuple

Return type:

callable

Raises:

RuntimeError – If JAX backend is not available

Examples

>>> def loss(params, x, y):
...     pred = params[0] * x + params[1]
...     return jnp.sum((pred - y) ** 2)
>>> val_grad = value_and_grad(loss)
>>> value, gradient = val_grad(params, x, y)
xpcsviewer.fitting.minimize_with_grad(objective, initial_params, max_iterations=500, tolerance=1e-08, learning_rate=0.01)[source]

Minimize objective function using gradient descent.

Simple gradient descent optimizer for user-defined differentiable objective functions. For more sophisticated optimization, consider using optimistix or scipy.optimize.

Parameters:
  • objective (callable) – Differentiable objective function: f(params) -> scalar

  • initial_params (array_like) – Initial parameter values

  • max_iterations (int, optional) – Maximum iterations (default: 500)

  • tolerance (float, optional) – Convergence tolerance for loss change (default: 1e-8)

  • learning_rate (float, optional) – Learning rate / step size (default: 0.01)

Returns:

(optimal_params, diagnostics_dict) where diagnostics contains: - iterations: Number of iterations performed - losses: Array of loss values at each iteration - converged: Whether optimization converged - final_loss: Final loss value

Return type:

tuple

Raises:

RuntimeError – If JAX backend is not available

Examples

>>> def loss(params):
...     return jnp.sum((params - target) ** 2)
>>> optimal, diag = minimize_with_grad(loss, initial_guess)
>>> print(f"Converged: {diag['converged']}, Loss: {diag['final_loss']}")

Constants

xpcsviewer.fitting.PUBLICATION_STYLE

Dictionary of matplotlib rcParams for publication-quality figures.

NLSQ 0.6.0 Features

Statistical Metrics

The NLSQResult class provides enhanced statistical metrics:

Metric

Description

Usage

r_squared

Coefficient of determination (R²)

Model explanatory power (0-1, higher is better)

adj_r_squared

Adjusted R² for model comparison

Penalizes additional parameters

rmse

Root mean squared error

Fit quality in data units

mae

Mean absolute error

Robust to outliers

aic

Akaike Information Criterion

Model selection (lower is better)

bic

Bayesian Information Criterion

Penalizes complexity more than AIC

Note

Weighted R² Behavior: When measurement uncertainties (yerr) are provided, NLSQ 0.6.0 computes R² using weighted residuals. This can result in negative R² values if the weighted model fit is worse than the weighted mean. For weighted fits, use chi_squared (reduced chi-squared should be ~1 for a good fit) rather than R² to assess fit quality.

Confidence vs Prediction Intervals

The module provides two types of uncertainty bands:

Confidence Intervals (via compute_uncertainty_band):

  • Represent uncertainty in the fitted curve

  • Account only for parameter covariance

  • Show where the “true” regression line likely falls

Prediction Intervals (via compute_prediction_interval):

  • Represent uncertainty for new observations

  • Account for parameter uncertainty AND observation noise

  • Always wider than confidence intervals

  • Show where new data points would likely fall

from xpcsviewer.fitting import compute_uncertainty_band, compute_prediction_interval

# Confidence band (parameter uncertainty only)
y_fit, ci_lower, ci_upper = compute_uncertainty_band(
    model, x, popt, pcov, confidence=0.95
)

# Prediction interval (includes observation noise)
y_fit, pi_lower, pi_upper = compute_prediction_interval(
    model, x, popt, pcov, residuals, confidence=0.95
)

Advanced Options

The nlsq_fit function supports advanced NLSQ 0.6.0 options:

result = nlsq_fit(
    model_fn, x, y, yerr, p0, bounds,
    workflow='auto_global',   # 'auto', 'auto_global', 'hpc'
    auto_bounds=True,         # Automatic bounds inference from data
    stability='auto',         # 'auto', 'check', or False
    fallback=True,            # Enable fallback strategies
    compute_diagnostics=True, # Model health diagnostics
    show_progress=True,       # Progress bar for long fits
)

# Access diagnostics
if result.diagnostics:
    print(result.diagnostics)

Workflows

Workflow

Description

Use Case

auto

Automatic strategy selection

Quick fits, good initial guess

auto_global

Multi-start global optimization (default)

General use, robust fitting

hpc

High-performance computing strategy

Large datasets, batch fitting

Models

The module provides four fitting models:

Single Exponential

\[G_2(\tau) = \text{baseline} + \text{contrast} \cdot \exp(-2\tau/\tau_c)\]

Parameters: tau, baseline, contrast

Double Exponential

\[G_2(\tau) = \text{baseline} + c_1 \exp(-2\tau/\tau_1) + c_2 \exp(-2\tau/\tau_2)\]

Parameters: tau1, tau2, baseline, contrast1, contrast2

Stretched Exponential (KWW)

\[G_2(\tau) = \text{baseline} + \text{contrast} \cdot \exp(-(2\tau/\tau_c)^\beta)\]

Parameters: tau, baseline, contrast, beta

Power Law

\[\tau = \tau_0 \cdot q^{-\alpha}\]

Parameters: tau0, alpha

Legacy Functions

For backward compatibility with older code:

xpcsviewer.fitting.single_exp(x, tau, bkg, cts)[source]

Single exponential model for G2 correlation function.

Delegates to a module-level closure created once via make_single_exp(). Uses jax.numpy directly for NLSQ JIT compatibility.

Parameters:
Return type:

ndarray[tuple[Any, …], dtype[floating[Any]]]

xpcsviewer.fitting.double_exp(x, tau1, bkg, cts1, tau2, cts2)[source]

Double exponential model for G2 correlation function.

Delegates to a module-level closure created once via make_double_exp(). Uses jax.numpy directly for NLSQ JIT compatibility.

Parameters:
Return type:

ndarray[tuple[Any, …], dtype[floating[Any]]]

xpcsviewer.fitting.single_exp_all(x, a, b_, c, d)[source]

Single exponential with all parameters.

Delegates to a module-level closure created once via make_single_exp_all(). Uses jax.numpy directly for NLSQ JIT compatibility.

Parameters:
Return type:

ndarray[tuple[Any, …], dtype[floating[Any]]]

xpcsviewer.fitting.double_exp_all(x, a, b_, c, d, e, f)[source]

Double exponential with all parameters.

Delegates to a module-level closure created once via make_double_exp_all(). Uses jax.numpy directly for NLSQ JIT compatibility.

Parameters:
Return type:

ndarray[tuple[Any, …], dtype[floating[Any]]]

xpcsviewer.fitting.fit_with_fixed(base_func, x, y, sigma, bounds, fit_flag, fit_x, p0=None, **kwargs)[source]

Fitting with fixed parameters using nlsq.curve_fit.

Parameters:
  • base_func (callable) – Function to fit

  • x (array) – Input data

  • y (array) – Output data

  • sigma (array) – Error bars

  • bounds (tuple) – (lower_bounds, upper_bounds)

  • fit_flag (array) – Boolean array indicating which parameters to fit

  • fit_x (array) – X values for output curve

  • p0 (array, optional) – Initial parameter values

  • kwargs (Any)

Returns:

(fit_line, fit_params)

Return type:

tuple

xpcsviewer.fitting.robust_curve_fit(func, x, y, **kwargs)[source]

Simple wrapper around nlsq.curve_fit with error handling.

Parameters:
Return type:

tuple[ndarray[tuple[Any, …], dtype[floating[Any]]], ndarray[tuple[Any, …], dtype[floating[Any]]]]

xpcsviewer.fitting.fit_with_fixed_parallel(base_func, x, y, sigma, bounds, fit_flag, fit_x, p0=None, max_workers=None, use_threads=True, **kwargs)[source]

Parallel version of fit_with_fixed for processing multiple q-values simultaneously.

Parameters:
Return type:

tuple[ndarray[tuple[Any, …], dtype[floating[Any]]], ndarray[tuple[Any, …], dtype[floating[Any]]]]

xpcsviewer.fitting.fit_with_fixed_sequential(base_func, x, y, sigma, bounds, fit_flag, fit_x, p0=None, **kwargs)[source]

Enhanced fitting with sequential method approach.

Parameters:
Return type:

tuple[ndarray[tuple[Any, …], dtype[floating[Any]]], ndarray[tuple[Any, …], dtype[floating[Any]]], list[str]]

xpcsviewer.fitting.sequential_fitting(func, x, y, sigma=None, p0=None, bounds=None, **kwargs)[source]

Robust fitting using NLSQ 0.6.0 with multistart and fallback strategies.

Replaces the legacy TRF → LM → DE chain with a single NLSQ call that handles fallback automatically.

Parameters:
Return type:

tuple[ndarray[tuple[Any, …], dtype[floating[Any]]], ndarray[tuple[Any, …], dtype[floating[Any]]], str]

xpcsviewer.fitting.vectorized_parameter_estimation(x, y, model_type='exponential')[source]

Vectorized parameter estimation.

Parameters:
Return type:

tuple | None

xpcsviewer.fitting.vectorized_residual_analysis(x, y_true, y_pred)[source]

Vectorized residual analysis.

Parameters:
Return type:

dict[str, float | ndarray[tuple[Any, …], dtype[floating[Any]]]]

NUTS Sampler

NumPyro NUTS sampler with NLSQ warm-start for Bayesian parameter estimation.

NumPyro NUTS sampler with NLSQ warm-start.

This module provides the MCMC sampling functionality using NumPyro’s NUTS sampler with JAX-accelerated NLSQ warm-start.

xpcsviewer.fitting.sampler.check_numpyro()[source]

Raise error if JAX, NumPyro, or ArviZ are not available.

Return type:

None

xpcsviewer.fitting.sampler.compute_bfmi(arviz_data)[source]

Compute BFMI from ArviZ DataTree.

Parameters:

arviz_data (DataTree) – ArviZ DataTree object from MCMC sampling

Returns:

Mean BFMI across chains, or None if computation fails

Return type:

float | None

Notes

Uses az.bfmi() which returns per-chain values. Returns mean across all chains. Logs warning if BFMI < 0.2 per Technical Guidelines.

xpcsviewer.fitting.sampler.run_single_exp_fit(x, y, yerr=None, stability='auto', auto_bounds=False, **kwargs)[source]

Run single exponential fit with NLSQ warm-start.

Parameters:
  • x (array_like) – Delay times

  • y (array_like) – G2 correlation values

  • yerr (array_like, optional) – Measurement uncertainties

  • stability (str, optional) – NLSQ stability mode: ‘auto’, ‘check’, or False (default: ‘auto’)

  • auto_bounds (bool, optional) – Use NLSQ auto-bounds inference (default: False)

  • **kwargs – Sampler configuration

Returns:

Posterior samples for tau, baseline, contrast

Return type:

FitResult

xpcsviewer.fitting.sampler.run_double_exp_fit(x, y, yerr=None, stability='auto', auto_bounds=False, **kwargs)[source]

Run double exponential fit with NLSQ warm-start.

Parameters:
  • x (array_like) – Delay times

  • y (array_like) – G2 correlation values

  • yerr (array_like, optional) – Measurement uncertainties

  • stability (str, optional) – NLSQ stability mode: ‘auto’, ‘check’, or False (default: ‘auto’)

  • auto_bounds (bool, optional) – Use NLSQ auto-bounds inference (default: False)

  • **kwargs – Sampler configuration

Returns:

Posterior samples for tau1, tau2, baseline, contrast1, contrast2

Return type:

FitResult

xpcsviewer.fitting.sampler.run_stretched_exp_fit(x, y, yerr=None, stability='auto', auto_bounds=False, **kwargs)[source]

Run stretched exponential fit with NLSQ warm-start.

Parameters:
  • x (array_like) – Delay times

  • y (array_like) – G2 correlation values

  • yerr (array_like, optional) – Measurement uncertainties

  • stability (str, optional) – NLSQ stability mode: ‘auto’, ‘check’, or False (default: ‘auto’)

  • auto_bounds (bool, optional) – Use NLSQ auto-bounds inference (default: False)

  • **kwargs – Sampler configuration

Returns:

Posterior samples for tau, baseline, contrast, beta

Return type:

FitResult

xpcsviewer.fitting.sampler.run_power_law_fit(q, tau, tau_err=None, stability='auto', auto_bounds=False, bounds=None, **kwargs)[source]

Run power law fit with NLSQ warm-start.

Parameters:
  • q (array_like) – Q values

  • tau (array_like or FitResult) – Relaxation times (or FitResult with tau samples)

  • tau_err (array_like, optional) – Measurement uncertainties on tau values from G2 fitting

  • stability (str, optional) – NLSQ stability mode: ‘auto’, ‘check’, or False (default: ‘auto’)

  • auto_bounds (bool, optional) – Use NLSQ auto-bounds inference (default: False)

  • bounds (dict, optional) – Override NLSQ warm-start bounds. Keys are parameter names ("tau0", "alpha"), values are (min, max) tuples. If None, uses defaults: tau0=(1e-6, 1e6), alpha=(0.0, 10.0).

  • **kwargs – Sampler configuration

Returns:

Posterior samples for tau0, alpha

Return type:

FitResult

Bayesian Visualization

Bayesian all-Q visualization and export utilities.

Provides matplotlib figures for batch Bayesian fitting results and export to CSV, PDF, and netCDF formats.

xpcsviewer.fitting.viz.plot_bayesian_all_q(bayesian_summary, g2_data, *, data_t_el=None)[source]

Generate all-Q overlay figure with Bayesian fit lines.

Parameters:
  • bayesian_summary (dict or None) – Output of assemble_fit_summary with source='bayesian'.

  • g2_data (ndarray, shape (num_t, num_q)) – Raw G2 correlation data.

  • data_t_el (ndarray or None) – Time axis matching g2_data rows. When the caller applies a t_range filter the resulting array may be shorter than the summary’s t_el. Pass the filtered time array here so that data points are plotted at the correct times. Falls back to bayesian_summary["t_el"] when None.

Returns:

Matplotlib figure, or None if no data.

Return type:

Figure or None

xpcsviewer.fitting.viz.export_bayesian_csv(path, fit_val, q_val, fit_func_name, *, failed_mask=None)[source]

Export Bayesian fit parameters to CSV.

Parameters:
  • path (Path) – Output CSV file path.

  • fit_val (ndarray, shape (num_q, 2, nparams)) – Parameter values (dim1=0) and std errors (dim1=1).

  • q_val (ndarray, shape (num_q,)) – Q values.

  • fit_func_name (str) – ‘single’ or ‘double’.

  • failed_mask (ndarray or None) – Boolean array (True = failed). Adds a status column when provided.

Return type:

None

xpcsviewer.fitting.viz.export_bayesian_diagnostics(path, bayesian_results)[source]

Export ArviZ DataTree to netCDF for all Q-bins.

Parameters:
  • path (Path) – Output netCDF file path.

  • bayesian_results (dict[int, FitResult]) – Per-Q FitResult objects with arviz_data attribute.

Return type:

None

Fitting visualization module (FR-013 to FR-021).

This module provides visualization functions for NLSQ and Bayesian fitting results, including uncertainty bands, diagnostic plots, and publication-quality output.

NLSQ 0.6.0 Enhanced Features: - Prediction interval visualization - R², RMSE, AIC/BIC display on plots - Confidence interval annotations - Model comparison with information criteria

xpcsviewer.fitting.visualization.apply_publication_style()[source]

Apply publication-quality matplotlib style (FR-019).

xpcsviewer.fitting.visualization.validate_pcov(pcov, param_names=None)[source]

Validate covariance matrix before computing uncertainty bands (FR-021).

Checks: - pcov is not None - All values are finite (no inf/nan) - Matrix is positive semi-definite

Parameters:
  • pcov (ndarray or None) – Covariance matrix to validate

  • param_names (list, optional) – Parameter names for error messages

Returns:

  • is_valid (bool) – True if covariance is valid

  • message (str) – Validation message (error description if invalid)

Return type:

tuple[bool, str]

xpcsviewer.fitting.visualization.compute_uncertainty_band(model, x_pred, popt, pcov, confidence=0.95)[source]

Compute prediction uncertainty band via error propagation (FR-016).

Uses Jacobian-based error propagation to compute uncertainty bands.

Parameters:
  • model (callable) – Model function taking x and params

  • x_pred (ndarray) – X values for prediction

  • popt (ndarray) – Fitted parameters

  • pcov (ndarray) – Parameter covariance matrix (n_params x n_params)

  • confidence (float) – Confidence level (default: 0.95 for 95% CI)

Returns:

  • y_fit (ndarray) – Fitted curve values

  • y_lower (ndarray) – Lower bound of confidence band

  • y_upper (ndarray) – Upper bound of confidence band

xpcsviewer.fitting.visualization.compute_prediction_interval(model, x_pred, popt, pcov, residuals, confidence=0.95)[source]

Compute prediction interval including residual variance (NLSQ 0.6.0).

Prediction intervals are wider than confidence intervals because they account for both parameter uncertainty AND observation noise.

Adds residual standard deviation term to confidence interval width.

Parameters:
  • model (callable) – Model function taking x and params

  • x_pred (ndarray) – X values for prediction

  • popt (ndarray) – Fitted parameters

  • pcov (ndarray) – Parameter covariance matrix

  • residuals (ndarray) – Fit residuals (y - y_pred) from training data

  • confidence (float) – Confidence level (default: 0.95 for 95% PI)

Returns:

  • y_fit (ndarray) – Fitted curve values

  • pi_lower (ndarray) – Lower bound of prediction interval

  • pi_upper (ndarray) – Upper bound of prediction interval

xpcsviewer.fitting.visualization.plot_nlsq_fit(result, model, x_data, y_data, x_pred=None, confidence=0.95, ax=None, show_metrics=True, show_prediction_interval=False, xlabel='x', ylabel='y', title=None)[source]

Plot NLSQ fit with uncertainty band (FR-017, FR-021, NLSQ 0.6.0).

If covariance is invalid, logs warning and displays “Uncertainty unavailable” in legend.

Parameters:
  • result (NLSQResult) – Output from nlsq_fit()

  • model (callable) – Model function

  • x_data (ndarray) – Original data

  • y_data (ndarray) – Original data

  • x_pred (ndarray, optional) – X values for prediction curve

  • confidence (float) – Confidence level for band (default: 0.95)

  • ax (matplotlib.axes.Axes, optional) – Axes to plot on (creates new if None)

  • show_metrics (bool, optional) – Display R², RMSE, and χ² on the plot (default: True). Uses NLSQ 0.6.0 enhanced metrics from NLSQResult.

  • show_prediction_interval (bool, optional) – Show prediction interval in addition to confidence interval. Prediction intervals account for observation noise (default: False).

  • xlabel (str, optional) – X-axis label (default: “x”)

  • ylabel (str, optional) – Y-axis label (default: “y”)

  • title (str, optional) – Plot title (default: None)

Returns:

ax

Return type:

matplotlib.axes.Axes

xpcsviewer.fitting.visualization.plot_posterior_predictive(result, model, x_data, y_data, x_pred=None, credible_level=0.95, n_draws=100, ax=None, *, max_draws=None, subsample_seed=None)[source]

Plot Bayesian fit with posterior credible interval (FR-014).

Parameters:
  • result (FitResult) – Output from Bayesian fitting

  • model (callable) – Model function

  • x_data (ndarray) – Original data

  • y_data (ndarray) – Original data

  • x_pred (ndarray, optional) – X values for prediction (default: smooth range over x_data)

  • credible_level (float) – Credible interval level (default: 0.95)

  • n_draws (int) – Number of posterior samples for band calculation (legacy, prefer max_draws)

  • ax (matplotlib.axes.Axes, optional)

  • max_draws (int | None) – Maximum posterior draws to use. If None (default), uses all samples. When specified and n_samples > max_draws, subsamples with logging. Per Technical Guidelines, subsampling must be explicit and logged.

  • subsample_seed (int | None) – Random seed for reproducible subsampling. Only used when max_draws triggers subsampling.

Returns:

ax

Return type:

matplotlib.axes.Axes

Notes

Per Technical Guidelines, posterior subsampling is explicit and logged. When max_draws is None (default), all posterior samples are used.

xpcsviewer.fitting.visualization.generate_arviz_diagnostics(trace, var_names=None, output_dir=None, formats=('pdf', 'png'), dpi=300, prefix='mcmc')[source]

Generate complete ArviZ diagnostic suite (FR-013).

Plots generated: 1. Pair plot (parameter correlations, divergences) 2. Forest plot (HDI intervals) 3. Energy plot (NUTS E-BFMI diagnostics) 4. Autocorrelation plot (chain mixing) 5. Rank plot (convergence check) 6. ESS plot (effective sample size)

Parameters:
  • trace (DataTree) – ArviZ DataTree object from MCMC

  • var_names (list, optional) – Parameter names to plot (default: all)

  • output_dir (str or Path, optional) – Directory for output files (None = return figures only)

  • formats (tuple) – Output formats (default: (“pdf”, “png”) per FR-018)

  • dpi (int) – Resolution for raster formats (default: 300 per FR-018)

  • prefix (str) – Filename prefix

Returns:

Mapping plot_type → figure (if output_dir is None) Mapping plot_type_format → file path (if output_dir provided)

Return type:

dict

xpcsviewer.fitting.visualization.plot_comparison(nlsq_result, bayesian_result, model, x_data, y_data, x_pred=None, confidence_level=0.95, band_alpha=0.25, ax=None)[source]

Overlay NLSQ confidence band and Bayesian credible interval (FR-020).

Parameters:
  • nlsq_result (NLSQResult) – NLSQ fitting result

  • bayesian_result (FitResult) – Bayesian fitting result

  • model (callable) – Model function

  • x_data (ndarray) – Original data

  • y_data (ndarray) – Original data

  • x_pred (ndarray, optional) – X values for prediction curves

  • confidence_level (float) – Confidence/credible level (default: 0.95)

  • band_alpha (float) – Transparency for bands (default: 0.25)

  • ax (matplotlib.axes.Axes, optional)

Returns:

ax

Return type:

matplotlib.axes.Axes

xpcsviewer.fitting.visualization.plot_diagnostics(result, model, x_data, y_data, figsize=(10, 8))[source]

Create 2x2 diagnostic plot for NLSQ fit (T081-T085).

Layout: - Top-left: Residuals plot (vs x) - Top-right: Parameter confidence intervals - Bottom-left: Diagnostic issues / health score - Bottom-right: Summary metrics (R², adj_R², RMSE, AIC, BIC)

Parameters:
  • result (NLSQResult) – Output from NLSQ fitting with native_result

  • model (callable) – Model function

  • x_data (ndarray) – Original data

  • y_data (ndarray) – Original data

  • figsize (tuple) – Figure size (default: (10, 8))

Returns:

fig

Return type:

matplotlib.figure.Figure

xpcsviewer.fitting.visualization.save_figure(fig, filepath, formats=('pdf', 'png'), dpi=300)[source]

Save figure in multiple formats (FR-018).

Parameters:
  • fig (matplotlib.figure.Figure)

  • filepath (str or Path) – Base path (extension will be replaced)

  • formats (tuple) – Output formats (default: (“pdf”, “png”))

  • dpi (int) – Resolution for raster formats

Returns:

Mapping format → saved file path

Return type:

dict

Bayesian Assembly

Batch all-Q Bayesian fitting coordinator. Converts per-Q NumPyro posteriors into the legacy FitResult format used by the GUI.

Assemble Bayesian fitting results into NLSQ-compatible fit_summary format.

Converts a dict of per-Q FitResult objects into the same fit_summary dict that XpcsFile.fit_g2() produces, enabling seamless integration with the tau-q diffusion pipeline and GUI plotting.

xpcsviewer.fitting.bayesian_assembly.assemble_fit_summary(results, q_arr, t_el, fit_func_name, model_func, *, q_range='', t_range='', bounds=None, fit_flag='', label='')[source]

Convert per-Q Bayesian results into NLSQ-compatible fit_summary.

Parameters:
  • results (dict[int, FitResult | None]) – Mapping of Q-index to FitResult (None for failed Q-bins).

  • q_arr (ndarray) – Array of Q values (1D).

  • t_el (ndarray) – Array of delay times (1D).

  • fit_func_name (str) – "single" or "double".

  • model_func (callable) – Bayesian model function (single_exp_func or double_exp_func).

  • q_range (optional) – Metadata fields matching the NLSQ fit_summary format.

  • t_range (optional) – Metadata fields matching the NLSQ fit_summary format.

  • bounds (optional) – Metadata fields matching the NLSQ fit_summary format.

  • fit_flag (optional) – Metadata fields matching the NLSQ fit_summary format.

  • label (optional) – Metadata fields matching the NLSQ fit_summary format.

Returns:

fit_summary dict with keys: fit_func, fit_val, t_el, q_val, q_range, t_range, bounds, fit_flag, fit_line, fit_x, label, failed_mask. Failed Q-bins have NaN in fit_val/fit_line and failed_mask[q_idx] == True.

Return type:

dict

See Also