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_funcordouble_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 infit_val/fit_lineandfailed_mask[q_idx] == True.- Return type:
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:
objectResult 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:
chi_squared (float)
converged (bool)
pcov_valid (bool)
pcov_message (str)
native_result (CurveFitResult | None)
is_fallback (bool)
_covariance (np.ndarray | None)
_residuals (np.ndarray | None)
_r_squared (float)
_adj_r_squared (float)
_rmse (float)
_mae (float)
_aic (float)
_bic (float)
_predictions (np.ndarray | None)
- converged
Whether optimization converged
- Type:
- chi_squared
Reduced chi-squared statistic
- Type:
- pcov_valid
Covariance validity flag (FR-021)
- Type:
- pcov_message
Validation message describing covariance status
- Type:
- native_result
NLSQ 0.6.0 native result object for property delegation
- Type:
CurveFitResult, optional
- Properties(delegated to native_result when available)
- ------------------------------------------------------
- r_squared
Coefficient of determination (R²). Range: (-∞, 1], where 1 is perfect fit.
- Type:
- adj_r_squared
Adjusted R² accounting for number of parameters.
- Type:
- rmse
Root mean squared error. Lower is better.
- Type:
- mae
Mean absolute error. Robust to outliers.
- Type:
- aic
Akaike Information Criterion. Lower is better for model selection.
- Type:
- bic
Bayesian Information Criterion. Penalizes complexity more than AIC.
- Type:
- 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.
- diagnostics
NLSQ model health diagnostics (if compute_diagnostics=True).
- Type:
ModelHealthReport or None
- is_healthy
Whether the fit passes all health checks.
- Type:
- health_score
Health score (0-100).
- Type:
- condition_number
Condition number from identifiability diagnostics.
- Type:
- 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 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.
- get_confidence_interval(param, alpha=0.05)[source]
Get confidence interval for a parameter.
- get_prediction_interval(x, alpha=0.05)[source]
Get prediction interval at new x values.
Delegates to native_result.prediction_interval() when available.
- summary()[source]
Generate a formatted summary of the fit results.
- Returns:
Formatted summary string
- Return type:
- 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:
- __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:
chi_squared (float)
converged (bool)
pcov_valid (bool)
pcov_message (str)
native_result (CurveFitResult | None)
is_fallback (bool)
_covariance (np.ndarray | None)
_residuals (np.ndarray | None)
_r_squared (float)
_adj_r_squared (float)
_rmse (float)
_mae (float)
_aic (float)
_bic (float)
_predictions (np.ndarray | None)
- 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:
objectContainer for Bayesian fitting results.
- Parameters:
- param_names
Canonical parameter order matching the model function signature. Used by visualization to ensure correct positional argument mapping.
- summary
Summary statistics per parameter
- Type:
DataFrame
- diagnostics
Convergence diagnostics
- Type:
FitDiagnostics
- 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
- summary: pd.DataFrame | None = None
- diagnostics: FitDiagnostics
- 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)
- 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.
- get_std(param)[source]
Get posterior standard deviation for parameter.
- get_hdi(param, prob=0.94)[source]
Get highest density interval for parameter.
Uses ArviZ’s
az.hdi()for the true HDI (shortest interval containingprobprobability 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).
- 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. Useplot_posterior_predictive()with an explicit model function, or compute predictions manually fromget_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:
- 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:
- class xpcsviewer.fitting.FitDiagnostics(r_hat=<factory>, ess_bulk=<factory>, ess_tail=<factory>, divergences=0, max_treedepth_reached=0, bfmi=None)[source]
Bases:
objectConvergence diagnostics for MCMC sampling.
- Parameters:
- divergences
Number of divergent transitions
- Type:
- max_treedepth_reached
Count of max treedepth events
- Type:
- 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:
- 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)
- divergences: int = 0
- max_treedepth_reached: int = 0
- __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.
- 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:
objectConfiguration for NUTS sampler.
- Parameters:
- num_warmup
Number of warmup (burn-in) samples (default: 500)
- Type:
- num_samples
Number of posterior samples per chain (default: 1000)
- Type:
- num_chains
Number of MCMC chains (default: 4)
- Type:
- target_accept_prob
Target acceptance probability for NUTS (default: 0.8)
- Type:
- max_tree_depth
Maximum tree depth for NUTS (default: 10)
- Type:
- 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
- __post_init__()[source]
Validate sampler configuration.
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:
- 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:
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:
- 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:
- 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:
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:
- 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:
- 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:
- 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 |
|---|---|---|
|
Coefficient of determination (R²) |
Model explanatory power (0-1, higher is better) |
|
Adjusted R² for model comparison |
Penalizes additional parameters |
|
Root mean squared error |
Fit quality in data units |
|
Mean absolute error |
Robust to outliers |
|
Akaike Information Criterion |
Model selection (lower is better) |
|
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 |
|---|---|---|
|
Automatic strategy selection |
Quick fits, good initial guess |
|
Multi-start global optimization (default) |
General use, robust fitting |
|
High-performance computing strategy |
Large datasets, batch fitting |
Models¶
The module provides four fitting models:
Single Exponential¶
Parameters: tau, baseline, contrast
Double Exponential¶
Parameters: tau1, tau2, baseline, contrast1, contrast2
Stretched Exponential (KWW)¶
Parameters: tau, baseline, contrast, beta
Power Law¶
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.
- 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.
- 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.
- 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.
- 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:
- xpcsviewer.fitting.robust_curve_fit(func, x, y, **kwargs)[source]¶
Simple wrapper around nlsq.curve_fit with error handling.
- 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.
- 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.
- 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.
- xpcsviewer.fitting.vectorized_residual_analysis(x, y_true, y_pred)[source]¶
Vectorized residual analysis.
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. IfNone, 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_summarywithsource='bayesian'.g2_data (ndarray, shape (num_t, num_q)) – Raw G2 correlation data.
data_t_el (ndarray or None) – Time axis matching
g2_datarows. When the caller applies at_rangefilter the resulting array may be shorter than the summary’st_el. Pass the filtered time array here so that data points are plotted at the correct times. Falls back tobayesian_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
statuscolumn when provided.
- Return type:
None
- xpcsviewer.fitting.viz.export_bayesian_diagnostics(path, bayesian_results)[source]¶
Export ArviZ DataTree to netCDF for all Q-bins.
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
- 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:
- 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:
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:
- 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:
- 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:
- 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:
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_funcordouble_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 infit_val/fit_lineandfailed_mask[q_idx] == True.- Return type:
See Also¶
Plotting - Additional visualization utilities
Analysis Modules - G2 correlation analysis module