3. Peak Detection & Fitting
Learn how XRD Analyzer models diffraction reflections. Read the equations behind Gaussian, Lorentzian, and Pseudo-Voigt profiles.
Guides List
Why Peak Profiles Matter
Diffraction peaks are not perfect lines. They are broadened by the optical configuration of the diffractometer and by microstructural features like grain boundaries and lattice strain. To extract parameters like FWHM or exact peak centroids, you must fit these reflections with mathematical profiles.
Peak Profile Functions
Three equations are commonly used to model diffraction reflections:
- Gaussian Function: Models instrument-induced broadening. The Gaussian shape decays rapidly away from the center:
G(x) = (A / (σ √(2π))) * exp(-(x - xc)² / (2σ²)) - Lorentzian Function: Models sample-induced broadening (like small crystallite sizes). It features broader tails than the Gaussian profile:
L(x) = (A / π) * (γ / ((x - xc)² + γ²)) - Pseudo-Voigt Approximation: A linear combination of Gaussian and Lorentzian profiles. This is the standard model used in XRD analysis:
PV(x) = η · L(x) + (1 - η) · G(x)Whereη(eta) is the Lorentzian fraction, ranging from 0 (pure Gaussian) to 1 (pure Lorentzian).
Fitting with the lmfit Library
XRD Analyzer runs these profile fits inside a Web Worker. It crops a $2\theta$ window around each detected peak and optimizes the fit using Python's lmfit.models.PseudoVoigtModel. The solver adjusts the centroid, amplitude, FWHM, and Lorentzian fraction ($\eta$) using Levenberg-Marquardt least-squares regression.
Init Guess: xc = peak max, FWHM = 0.15°, eta = 0.5
Optimize Residuals: Sum((y_obs - y_calc)^2) -> Minimized
Python Code for Least-Squares Optimization
The Python code below runs inside the Web Worker to perform the least-squares optimization:
import lmfit model = lmfit.models.PseudoVoigtModel() params = model.guess(y, x=x) result = model.fit(y, params, x=x) fwhm = result.params['fwhm'].value center = result.params['center'].value eta = result.params['fraction'].value