Beyond peak picking: what Atlas can do with XRD
A practical tour from broad-peak GIXRD and multi-scan BRML files to phase evidence, strain, texture, rocking curves, and rotational twins.
Most XRD software stops after three steps: plot the diffractogram, find the peaks, convert 2θ to d-spacing. A modern diffractometer exports far more than that. A single Bruker archive can hold a coupled θ–2θ scan, a grazing-incidence scan, an ω rocking curve, and several φ scans, and each one answers a different question about the film — what phase is present, how it is oriented, whether the lattice is strained, how coherent the crystallites are, and whether rotated domains exist.
Atlas treats those scans as one workflow. This post follows a WS₂ film archive from the raw .brml file through phase, size, strain, texture, mosaic, and twinning analysis, showing the actual Block outputs at each step.
A note about the data
The figures below are captured Atlas report outputs. They come from a deterministic WS₂ epitaxy validation archive with known ground truth — four scans whose peak positions, line widths, twin fractions, and angular offsets we set when generating the file:
Synthetic data is the right choice for a validation post because it lets us check every reported number against the value baked into the fixture. The noise levels, backgrounds, scan geometry, and BRML metadata mimic a real D8 export, but the results describe the fixture rather than a measured sample.
Parsing keeps the scan geometry
A .brml file is a ZIP container of XML scan members. Flattening it straight to CSV throws away exactly the things later analysis depends on: which motor moved, which axes were held fixed and where, the anode wavelength, the instrument, the step time. A rocking curve without its fixed detector angle cannot be converted to mosaic tilt. A d-spacing computed with the wrong wavelength is systematically off everywhere.
The parse-brml-xrd Block reads the container structure directly. With no scan_index it picks the coupled 2θ member; scan_index 1–3 pull the ω scan and the two φ scans out as separate typed datasets, each keeping its own axis metadata. Counts are stored as measured — parsing never smooths, normalizes, or subtracts a background.
{
"dataset_id": "xrd_2theta_7c13",
"kind": "single_spectrum",
"data_type": "xrd",
"scan_axis": "two_theta",
"wavelength_angstrom": 1.5406,
"instrument": "D8 DISCOVER",
"available_scans": 4
}The default member is the coupled θ–2θ scan. Re-running with scan_index 1, 2, and 3 preserves the ω and φ axes plus their fixed-axis metadata.
Peak finding that survives broad film reflections
A film reflection can be 1–2° wide with counting noise riding along both shoulders. Run a plain prominence detector over that and you get dozens of local maxima where one physical peak sits. xrd-peak-finder separates detection from measurement:
- a short boxcar smooths only the copy of the trace used to locate candidates;
- candidates must clear a relative-prominence threshold and a robust local-noise σ gate;
- accepted peaks are snapped back to the unsmoothed trace, where 2θ, intensity, and FWHM are measured;
min_distance_degdecides whether nearby shoulders count as separate peaks.
All of these are ordinary Block parameters. Widen min_distance_deg for broad film peaks, narrow it for genuinely close doublets, and lower noise_significance only when a clean, high-count scan justifies keeping weaker lines.
Phase identification with a visible ranking
identify-phase detects the Bragg peaks, scores each catalogued phase against their positions and relative intensities, and returns the full candidate ranking with a per-reflection match table. Peaks that no candidate claims stay visible as unexplained.
There is no Rietveld refinement here, and the catalogue is small on purpose: 2H TMDs, graphite, h-BN, common substrates, and a few precursor oxides. A high score means the phase is the best explanation among the tested references. For film work that restriction is usually a feature — scoring against phases that could plausibly be in the chamber is more defensible than searching a huge database with no process context.
Crystallite size and microstrain
Broad peaks do not always mean small grains. Finite coherent-domain size, microstrain, the instrument response, overlapping phases, and rough backgrounds all widen lines. analyze-crystallite-size therefore reports three related quantities:
- a Scherrer size for every usable peak;
- a Williamson–Hall fit that separates size broadening from microstrain when at least three peaks carry resolvable sample width;
- a crystallinity fraction comparing Bragg-peak area with diffuse scattering.
The per-peak breakdown is what makes this useful for process comparisons. A layered film can be coherent over many layers along c while broken into much smaller in-plane domains, and only per-peak sizes show that anisotropy. The caveat is instrumental: the number is quantitative only when the instrument width was measured on a standard in the same geometry. Without that correction, Atlas labels every Scherrer size a lower bound.
Lattice strain from multiple reflections
A shifted (002) peak in a layered film gets called "strain" quickly, but the peak also moves if the sample sits above or below the diffractometer axis. analyze-film-strain refines the lattice against all matched reflections and reports each observed-versus-reference d-spacing, rather than converting one peak position into a strain value.
In a symmetric scan dominated by (00l) peaks the c axis is well constrained while the a axis may be invisible. Atlas requires at least two independent off-axis reflection families before it treats the refined a axis as a direct measurement; below that it falls back to the biaxial Poisson estimate from Δc/c and labels the method in the output.
The optional correct_displacement mode co-fits a constant zero offset and a cosθ sample-displacement term against the uncorrected baseline. The correction is kept only if the residual improves and no parameter saturates its bound, and when too few reflections are available to break the degeneracy between displacement and lattice terms, the output says so.
One more reason to look at Δc/c carefully: an expanded layer spacing can come from intercalation, trapped species, or turbostratic disorder as well as from elastic strain. XRD establishes that the spacing changed. Deciding why takes chemistry or microscopy.
Texture is not epitaxy
In a thin layered film, a towering (002) line with weak off-axis reflections usually means the basal planes lie on the substrate. analyze-texture-quality quantifies that preference three ways:
- Lotgering F measures how enriched the pattern is in (00l) intensity relative to a powder reference;
- Harris texture coefficients show which individual reflections are enhanced or depleted;
- March–Dollase r fits an orientation distribution, with r below 1 indicating basal preferred orientation.
A θ–2θ scan can only show that crystallites put their c axes normal to the surface; their in-plane azimuths could still be completely random. The strongest label Atlas will assign from a symmetric scan alone is strongly_c_axis_textured, with an instruction to run ω and φ scans before making any epitaxy claim.
Scan geometry feeds the classification directly rather than being a footnote:
For plain XY/CSV files with no geometry metadata, geometry_mode can be set explicitly. For BRML, auto uses the driven and fixed axes the instrument recorded, with an override for files whose metadata is wrong.
Rocking curves and mosaic spread
An ω rocking curve parks the detector on a Bragg reflection and rotates the sample through the diffraction condition. Its width measures the spread of out-of-plane crystallite orientations: the mosaic spread.
The standard summary is a single pseudo-Voigt FWHM, which hides a common situation — a narrow coherent core sitting on a broad diffuse shoulder. analyze-rocking-curve fits one- and two-component models, then uses the Bayesian information criterion to decide whether the lower residual justifies four extra parameters. A two-component result is accepted only when ΔBIC is at least 6, the widths differ by at least 1.5×, and each component carries at least 5% of the area.
The fixed detector angle recovered from BRML lets the Block compare the fitted curve center against the Bragg angle θ = 2θ/2. Here the two agree to within 10⁻⁴ degrees — no measurable tilt between the film normal and the goniometer axis, matching the fixture's ground truth of zero. When a phase or Burgers vector is supplied, the primary (narrow) width is also converted to a threading-dislocation density through the Dunn–Koch relation, here about 1.0 × 10⁹ cm⁻². Dunn–Koch assumes randomly tilted mosaic blocks and a particular dislocation model, so it is a screening number for comparing like-for-like films, not a substitute for TEM.
φ scans: in-plane registry and rotated domains
A φ scan rotates the sample about its surface normal while measuring an off-axis reflection, so the peak count and spacing reveal in-plane symmetry. For an epitaxial TMD film whose layers share one azimuthal orientation, an asymmetric reflection such as (103) carries the three-fold symmetry of the layer and gives three peaks 120° apart. Six peaks at 60° intervals mean two three-fold families rotated 60° from each other — antiparallel twin domains, the classic failure mode of TMD growth on sapphire. One caveat when reading the count: an ideally 2H-stacked bulk crystal is six-fold in diffraction on its own (Laue class 6/mmm), so interpreting six peaks as twinning assumes the film's layers are orientationally aligned rather than bulk-2H stacked. analyze-phi-scan reads that symmetry from the film scan, optionally paired with a substrate φ member.
The peak detector works on a periodic axis, so a reflection crossing the 0°/360° seam is neither split nor missed. Per-peak φ FWHM also gives an in-plane mosaic measure to set against the out-of-plane spread from the ω scan.
Read together, the four scans tell one story about this film. The coupled pattern shows strongly c-axis-oriented WS₂. The rocking curve resolves a coherent core plus a diffuse mosaic shoulder carrying nearly half the intensity. And the φ scan shows the film is not a single in-plane orientation: about a quarter of the twin-family diffracted intensity belongs to the 60°-rotated domain set.
Other useful XRD workflows
The same report layer covers several less obvious jobs:
- Simulate a reference pattern before measuring.
simulate-xrdcombines catalogued phases, a 2θ range, crystallite broadening, and (00l) texture — handy for choosing a scan window or checking whether two expected phases have separable lines before spending instrument time. - Track process drift with stable numbers. The refined lattice, Lotgering factor, rocking widths, diffuse area, and twin fraction are structured outputs. Comparing them across deposition runs beats comparing screenshots.
- Follow up on unexplained peaks. An unassigned line can trigger a restricted second pass over plausible substrate, precursor-oxide, and contamination phases instead of disappearing into a residual.
- Keep "aligned" split into its axes. Lotgering and Harris metrics measure out-of-plane preferred orientation, ω measures out-of-plane mosaic, and φ measures in-plane registry and twins. Related, but never interchangeable.
- Make broad-pattern settings reproducible. Smoothing width, minimum peak separation, and noise significance travel with the result as Block parameters, so a sensitive weak-line search cannot later be confused with the stricter production default.
- Catch geometry mistakes early. BRML metadata lets the workflow warn when a φ scan is sent to a rocking-curve analysis, route ω and φ members correctly, and suppress powder-reference texture classes for GIXRD.
What Atlas leaves to you
The most useful XRD output is often a qualified one. Atlas does not run Rietveld refinement against an exhaustive crystallographic database. It will not make a Scherrer size quantitative without an instrument standard, declare epitaxy from a θ–2θ scan, name the chemistry behind a c-axis expansion, or promote a Dunn–Koch estimate to a dislocation count.
What it does is keep the scan geometry and provenance attached to every dataset, route each member to the right calibrated analysis, show the intermediate evidence, and return structured quantities with their failure modes spelled out. For most film work, that is the difference between a peak list and an answer you can defend.
The pieces are documented in Parse Bruker BRML XRD, XRD Peak Finder, Identify Phase, Analyze Crystallite Size, Analyze Film Strain, Analyze Texture Quality, Analyze Rocking Curve, Analyze φ Scan, and Simulate XRD. Every figure above was generated from the fixture archives through the same Atlas analysis functions the Blocks run.

