Fit single peaks#
Goal: fit individual peaks, each with its own position, intensity and width, without a crystal structure. Use it for peaks of an unknown phase, or to measure peak positions and widths directly.
You need:
Your pattern and a starting position for each peak.
The instrument for your engine, ideally from a standard (Calibrate the instrument).
GSAS-II or TOPAS. easydiffraction has no single-peak workflow.
Single-peak fitting has its own workflow: gsasii.spf or topas.spf. A
recipe of that workflow has single_peaks instead of phases. If you know
the structure, refine it instead (Refine a structure).
A peak fit followed by a Rietveld refinement is two recipes and two runs.
1. Start from the example#
Copy the single-peak example for your engine into a folder of your own and
put your pattern into its xrd_data block.
examples/example_LaB6_singlepeakfit/input.json (gsasii.spf): 36 LaB6
peaks, a Chebyshev background and one background peak.
examples/example_LaB6_singlepeakfit/topas/input.json (topas.spf): the
same 36 peaks in TOPAS’s terms.
Not available: easydiffraction has no single-peak workflow.
2. List the peaks#
Every peak must lie inside the fit window (fit_range). The two engines
write peaks differently:
Four lists of the same length, one entry per peak:
"single_peaks": {
"positions": [[2.29, true], [3.25, true]],
"intensities": [[3000, true], [3000, true]],
"pv_gaussian_sigma_sq": [[1.0, true], [1.0, true]],
"pv_lorentzian_gamma": [[0.5, true], [0.5, true]]
}
positionsin degrees 2θ.pv_gaussian_sigma_sqis the Gaussian variance σ² in centidegrees².pv_lorentzian_gammais the Lorentzian width γ in centidegrees.Each width is at least 0.001, GSAS-II’s own floor.
refinement_controls chooses where the widths come from:
"refinement_controls": {
"refinement_cycles": 5,
"single_peak_fitting_mode": {"use_instrument_profile": false}
}
false: each peak has its own widths, which you may refine. The instrument’sU…Zmust then be held.true: the widths come from the instrument’sU…Z, which you may refine. The peaks’ own width flags must then befalse.
GSAS-II ignores a flag on the side not in use without saying so (EB-53), so such a flag is a validation error.
A list of peaks. Each is a TOPAS xo_Is peak, the instrument’s peak type
convolved with the peak’s own widths:
"single_peaks": [
{"xo": [2.29, true, null, null], "I": [3000, true, null, null],
"gauss_fwhm": [0.001, true, 0.0, null], "lor_fwhm": [0.001, true, 0.0, null]},
{"xo": [3.25, true, null, null], "I": [3000, true, null, null],
"gauss_fwhm": [0.001, true, 0.0, null], "lor_fwhm": [0.001, true, 0.0, null]}
]
xois the position in degrees 2θ,Ithe intensity.gauss_fwhmandlor_fwhmare the peak’s own Gaussian and Lorentzian FWHM in degrees 2θ, at least 0. Leave one out and it is not convolved.refinement_controlsstatesiters,chi2_convergence_criteriaandx_calculation_step.
The background works as in a Rietveld recipe. In gsasii.spf it can also
hold background peaks (background.single_peaks), written like the Peak
List peaks above.
3. Validate and run#
pixi run powderline my_peaks/input.json --validate-only
pixi run -e gsasii powderline my_peaks/input.json
pixi run powderline my_peaks/input.json --validate-only
pixi run powderline my_peaks/input.json --topas-version 6 --topas-dir C:/TOPAS6
See Run TOPAS recipes.
Not available.
4. Read the results#
single_peaks_report.txt: tab-separated, one row per peak. A comment line says how many peaks converged and how many have aphysical values. The columns areposition_2theta,intensity,sigma,sigma_squared,gamma, the Gaussian, Lorentzian and pseudo-Voigt FWHM and integral breadths,fwhm_gsas_verification,convergedandconvergence_detail.peak_convergence_diagnostics.txt: written only when a peak did not converge cleanly. One row per such peak:peak_index,position_2theta,final_sigma_sq,final_gamma,status,notes.fit_profile.txt,output_recipe.jsonandparameter_dispositions.csv, as for every run.
A gsasii.spf run writes no refined_parameters.csv, no unit-cell report
and no reflection list. In Python, result["peak_fit"] lists every
parameter GSAS-II’s peak fit varied, by GSAS-II’s own name, with its value
and ESD.
single_peaks_report.csv: one row per peak, withposition_2theta,intensity,gauss_fwhm,lor_fwhm,fwhmandintegral_breadth, each followed by its ESD.refined_parameters.csv,fit_profile.txt,output_recipe.jsonandparameter_dispositions.csv, and TOPAS’s own files.
No unit-cell report and no reflection list.
Not available.
In Python, result["spf_peaks"] holds the peak table and
result["spf_convergence_diagnostics"] the peaks that need a look.
Outputs describes every key and file.
Check: in single_peaks_report.txt (GSAS-II) the comment line reads
N of N peaks converged; 0 peaks have aphysical values. Plot y_obs and
y_calc from fit_profile.txt to see that each peak is matched.
Note
The committed GSAS-II example is a teaching example. Its background peak refines its σ² far below GSAS-II’s floor, so its output recipe is not valid as posed (KI-15). The 36 Peak List peaks converge cleanly.
If the fit misbehaves#
A peak has aphysical widths (GSAS-II)#
GSAS-II can refine a peak to a negative or zero σ², or a negative γ. A width
cannot be negative. The peak’s convergence_detail then reads
negative_gamma_warning, zero_or_negative_sigma_sq_warning or
negative_sigma_sq_and_gamma_warning, and the peak appears in
peak_convergence_diagnostics.txt.
Common causes:
a starting position far from the true peak, or unreasonable intensity or widths;
two peaks too close together, fitted as one;
a peak on a steep background slope, or a background model that is too simple;
a weak, noisy peak.
One weak peak with a tiny negative value (about −0.001) is often numerical noise. Several flagged peaks, or large negative values, point to a problem with the model.
What helps:
Start each peak at the visible maximum, with sensible widths.
Take the widths from the instrument: set
use_instrument_profiletotrueand the peaks’ width flags tofalse.Fit the strong, well-separated peaks first. Add the others later.
Give the background more Chebyshev terms.
Raise
refinement_cycles.
A peak did not converge (GSAS-II)#
A peak with status NaN_failed ended with σ² or γ not a number. Common
causes are a peak near the edge of the fit window, too few data points
around it, or extreme starting values.
What helps:
Keep each peak well inside the fit window, not within a degree or two of its edge.
Check the data around the peak.
Start the peak at the visible maximum.
Raise
refinement_cycles.
A TOPAS peak ends at a limit#
A refined value that ends at a stated bound or at a TOPAS default limit
gets the warning topas_parameter_at_limit. The peak also appears in
spf_convergence_diagnostics with status at_limit. Widen the bound, or
start the peak closer to the data.
Next: Simulate a pattern, Troubleshoot.