Version 0.3.5
Release Date: February 22, 2026
Status: Stable release
Overview
EPyR Tools v0.3.5 delivers major improvements to lineshape derivative fitting
and visualization defaults. The Voigt and pseudo-Voigt profiles now use
analytical derivatives, making fit_epr_signal() reliable for first and
second derivative EPR spectra. Plotting functions have been refined with
thinner lines, better color scales, and compatibility with recent matplotlib
versions.
Lineshape Fitting Improvements
Analytical Voigt Derivatives
Previous versions computed Voigt derivatives numerically using np.gradient.
During fitting, scipy.optimize.curve_fit also evaluates the Jacobian
numerically, resulting in a numerical derivative of a numerical derivative.
This compounded error prevented convergence for derivative Voigt signals.
v0.3.5 replaces the numerical approach with analytical derivatives of the Faddeeva function:
where \(z = (x - x_0 + i\gamma) / (\sigma\sqrt{2})\) and \(w(z)\) is
the Faddeeva function (scipy.special.wofz).
Impact: Voigt derivative fitting now converges reliably with R² > 0.99 on synthetic data.
Pseudo-Voigt Derivative and Phase Support
The pseudo_voigt lineshape in fit_epr_signal() previously ignored the
derivative parameter and emitted a false warning. The internal lshape()
function was also using a buggy Dawson function approximation that returned
complex values when phase != 0.
v0.3.5 fixes both issues:
derivativeandphaseare now passed directly topseudo_voigt()lshape()delegates to the canonicalgaussian()andlorentzian()functions, which handle derivatives and phase analytically
Initial Parameter Estimation for Derivative Signals
The automatic parameter estimator assumed absorption-like data (peak at center). For first derivative signals, this produced incorrect estimates (e.g., amplitude of 2.5 instead of 500, width of 117 instead of 15).
New estimation heuristics for derivative signals:
1st derivative: center at zero-crossing between extrema, width from peak separation, amplitude calibrated against unit-amplitude model
2nd derivative: center at central extremum, width from side lobe separation, amplitude from model comparison
Example usage:
from epyr.lineshapes import fit_epr_signal
# Fit 1st derivative Voigt - now works with auto parameter estimation
result = fit_epr_signal(x, y, 'voigt', derivative=1)
# Fit pseudo-Voigt with phase
result = fit_epr_signal(x, y, 'pseudo_voigt', derivative=1, fit_phase=True)
# Fine-tune optimizer settings
result = fit_epr_signal(x, y, 'voigt', derivative=1,
maxfev=50000, ftol=1e-12)
Visualization Improvements
plot_2d_map
Fixed colorbar crash with matplotlib 3.8+ (replaced
tight_layoutwithconstrainedlayout)Added
vminandvmaxparameters for color scale control
import epyr
# Symmetric color scale
m = np.max(np.abs(y))
epyr.plot_2d_map(x, y, parm, vmin=-m, vmax=m, cmap="RdBu_r")
plot_1d and plot_2d_waterfall
Default line width set to 0.75 (was ~1.5 matplotlib default)
plot_2d_waterfalldefaultmax_tracesreduced from 50 to 20plot_2d_waterfallaccepts alwparameter for custom line width
JPG Export
Default DPI increased from 150 to 200
2D map colormap changed to RdBu_r (diverging, suitable for EPR signals)
Color scale uses symmetric bounds from
np.percentile(np.abs(y), 98)
Bug Fixes
baseline_polynomial_2d: Fixed meshgrid shape mismatch.
np.meshgridarguments were swapped, producing arrays of shape(nx, ny)instead of(ny, nx)matching the data.
Upgrade Guide
No breaking changes. All existing code continues to work. The only visible differences are:
Thinner lines in plots (set
lw=1.5explicitly to restore previous width)Fewer traces in waterfall plots (set
max_traces=50to restore)Different JPG export appearance (colormap, DPI, color scale)