Skip to content
XRD Analyzer

3. Peak Detection & Fitting

Learn how XRD Analyzer models diffraction reflections. Read the equations behind Gaussian, Lorentzian, and Pseudo-Voigt profiles.

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.

Crop Window: [xc - 1.5°, xc + 1.5°]
Init Guess: xc = peak max, FWHM = 0.15°, eta = 0.5
Optimize Residuals: Sum((y_obs - y_calc)^2) -> Minimized
Figure 3.1: Optimization flow of peak parameters.

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