Technical Overview & Methodology

This document is a technical reference for the Brutus powder indexing software. It explains the main algorithms, search parameters, and methodology, and is intended for users familiar with powder X-ray diffraction. As the name of the program suggests it, this is brute force method (force is not necessarily smart).

Core Goal

The aim of ab initio powder indexing is to determine the unit-cell parameters ($a, b, c, \alpha, \beta, \gamma$) from a list of observed diffraction peak positions ($2\theta$). Brutus performs this task using a system-specific, exhaustive search algorithm.

The central assumption is that a small subset of the most intense, low-angle reflections corresponds to simple crystal planes with low-integer Miller indices $(hkl)$. For a given crystal system, the program chooses exactly as many observed peaks as there are unknown lattice parameters, and solves the resulting system of linear equations.

Q-Space Formulation

All peak positions are first converted from $2\theta$ to Q-space, where $Q = 1/d^2$. The general quadratic relationship between $Q$, the Miller indices, and the reciprocal cell parameters ($A, B, C, D, E, F$) is

$$ Q_{hkl} = Ah^2 + Bk^2 + Cl^2 + Dkl + Ehl + Fhk $$

Brutus solves for these reciprocal parameters (or the subset relevant to the current crystal system), then converts them to real-space cell parameters. Each candidate cell is refined immediately and scored against the full peak list.

Quick Start Guide

Use the following workflow for a typical single-phase powder pattern.

  1. Load the data file. Click Select Data File. Supported formats include .xy, .xrdml, .ras, and others.
  2. Detect peaks. On the Peaks tab, adjust the Min peak (%), Radius (pts), and Points sliders until the automatically detected peaks match the visual pattern.
  3. Curate the peak list. Carefully review all peaks:
    • Edit $2\theta$ positions for accuracy.
    • Delete spurious peaks (noise, Kα2 shoulders if you are not stripping Kα2).
    • Add any missing reflections using Ctrl + Click on the chart.
    A clean list of about 15–20 peaks, free of impurities at low angle, is ideal.
  4. Set parameters. On the Parameters tab:
    • Select the correct X-ray Radiation Preset (e.g. Cu Kα).
    • Choose whether to enable Strip K-alpha2. This also updates the Ka1 Wavelength field. The default is OFF (average Kα wavelength).
    • Set a chemically reasonable Max Volume (ų) to limit the search space.
    • Set 2θ Error (°) according to your data quality (e.g. ≈0.02° for synchrotron, ≈0.05° for a typical lab diffractometer).
    • Leave Refine Zero-Point Error enabled unless you have a specific reason to turn it off.
    • Select the crystal systems to search. Enabling Orthorhombic, Monoclinic, or Triclinic activates GPU-accelerated searches.
  5. (Optional) Tune GPU Parameters. If searching Orthorhombic, Monoclinic, or Triclinic, a new box appears.
    • HKL Basis Size: Number of simple HKLs to use for the search (Defaults: Ortho 300, Mono 100, Tri 40).
    • Peaks to Combine: Number of observed peaks to use for combinations (Defaults: Ortho 7, Mono 7, Tri 9).
    • Leave these at their defaults unless you have trouble finding a solution.
  6. Start indexing. Click Start Indexing. Progress is shown on the main bar.
  7. Inspect solutions. On the Solutions tab:
    • Sort solutions by M(20).
    • Click a row to display calculated (blue) and observed (red) tick marks on the chart.
    • A plausible solution will show excellent alignment and reasonable space-group suggestions.

The User Interface

The application window is divided into a Controls Panel (left) and a Results Area (right).

Controls Panel

The controls are organized into three main tabs.

1. Peaks Tab

2. Parameters Tab

GPU Search Parameters

When Orthorhombic, Monoclinic, or Triclinic is selected, a dedicated panel appears. These four parameters control the scope, speed, and memory usage of the brute-force search.

Note: The status text at the bottom of the panel updates in real-time as you adjust these values, showing the total estimated number of cells to be tested. Ensure this number remains reasonable (e.g., under 500 Billion) for a timely result.

When you select a GPU system, the status text at the bottom of the panel will show you the total number of cells to be tested, which is a direct result of these two parameters. Be careful, this number can increase very fast. For a regular GPU card at the time of this writting (like Nvidia 8Gb T1000) the search speed is in the range of millions/sec cells tested.

3. Solutions Tab

Results Area

Peak Finding in Detail

Accurate peak positions are the single most important input for successful indexing. Brutus uses a multi-step procedure to detect peaks from raw intensity data.

Algorithm Steps

  1. 2 stripping (optional): If Strip K-alpha2 is enabled, the Damped Richardson-Lucy algorithm is applied to the raw intensities. This separates the doublet based on the wavelength ratio; even the natural shape of the peak base is not preserved this is not important for this program.
  2. Background subtraction: A rolling-ball style algorithm estimates and removes the background. The Radius slider controls the ball radius.
  3. Data smoothing: A Savitzky–Golay filter is applied to the background-subtracted signal to reduce noise while preserving peak shapes. The Points slider sets the window width.
  4. Initial peak detection: Local maxima above the Min peak (%) threshold are identified.
  5. Position refinement: For each peak, a five-point least-squares quadratic fit (based on Savitzky–Golay coefficients) is carried out around the maximum to obtain a the position. If too close to the data edge, the algorithm falls back to a three-point fit.

Practical Recommendations

Indexing Algorithm and Search Parameters

Brutus uses an exhaustive, symmetry-specific trial-and-refine indexing algorithm. For each crystal system, the program generates trial solutions from combinations of the lowest-angle peaks and low-index Miller indices, solves the corresponding linear system of equations in reciprocal space, rejects unphysical cells, and finally performs a full refinement.

Linear System Formulation

The search is formulated as a system of linear equations based on the quadratic form:

$$ Q_{obs} = \sum P_i \cdot H_i $$

where $Q_{obs}$ are the observed $1/d^2$ values, $H_i$ are terms derived from trial Miller indices (e.g. $h^2$, $k^2$, $l^2$), and $P_i$ are the reciprocal lattice parameters (e.g. $A = 1/a^2$, $B = 1/b^2$, …).

CPU Searches (High Symmetry)

High-symmetry systems have fewer degrees of freedom and are solved instantly on the CPU.

GPU-Accelerated Searches (Low Symmetry)

For Orthorhombic, Monoclinic, and Triclinic systems, the combinatorial explosion makes CPU searching impractical. Brutus offloads these tasks to the WebGPU, allowing billions of cells to be tested in minutes.

The Combinatorial Search Space

The total number of cells tested depends on two user-configurable parameters:

Total Trials = Peak Combinations × HKL Combinations × Permutations

$$ N_{total} = C(N_{peaks}, k) \times C(N_{hkl}, k) \times k! $$

User Parameters

System Specifics

GPU Memory Management & "Safe Batching"

Testing 50+ billion cells generates massive amounts of data. To prevent crashing your browser or freezing your computer, Brutus utilizes a sophisticated Safe Batching architecture.

The program automatically splits the work into smaller chunks based on a "Dual Constraint" logic:

  1. Hardware Limit (VRAM): The program detects your GPU's available memory. If you are on a mobile device or a laptop with integrated graphics, the batch size is automatically reduced to fit within your specific VRAM limits.
  2. Time Limit (TDR Prevention): On Windows, if a GPU calculation takes longer than ~2 seconds, the Operating System assumes the driver has frozen and resets it (causing a DXGI_ERROR_DEVICE_HUNG crash). Brutus enforces a strict "Speed Limit" (e.g., max 100,000 trials per batch for Triclinic) to ensure the GPU stays responsive.
What this means for you: You do not need to configure memory settings. If you see the progress bar moving in many small steps, the safety system is working correctly.

If the search is too slow: Adjusting technical settings for the GPU is not useful, or not a lot. Some parameters are listed in the Console (if you really want to play with the memory and chunk parameters... you may gain 50-100 msec, is it worth it ?). Instead, curate the peak list, reduce the physics parameters: lower the HKL Basis Size or reduce Peaks to Combine.

Two-Stage Filtering

Most candidate cells are invalid. They are discarded directly on the GPU to save CPU time:

  1. Geometric Filter: Cells are rejected if they are singular, have unphysical edge lengths ($< 2Å$), invalid angles ($< 20^\circ$ or $> 160^\circ$), or exceed the user's Max Volume.
  2. Figure of Merit Filter: For surviving cells, the GPU calculates a fast internal score based on the match of the first 10 lines. Only the top candidates are sent back to the CPU for full refinement.

Computational Limits & The Scale of Search

Because Brutus performs a brute-force combinatorial search, the number of trial cells can become astronomical. While modern GPUs are incredibly fast, there are hard limits defined by both the hardware (WebGPU specifications) and practical time constraints.

The Hierarchy of Limits

The "Total Trials" displayed in the application is calculated as:

$$ \text{Trials} = \underbrace{\text{HKL Combos}}_{\text{Limit: } \approx 4.29 \times 10^9} \times \underbrace{\text{Peak Combos}}_{\text{User Dependent}} \times \underbrace{\text{Permutations}}_{\text{Constant}} $$

The HKL Combos count is the most critical hardware constraint. It maps directly to the number of GPU threads dispatched. Since WebGPU uses 32-bit integers (u32) for indexing, this value must strictly remain below $2^{32}-1$ (approx. 4.29 Billion).

Brutus automatically calculates this limit based on your "HKL Basis Size" and prevents the search from starting if you exceed it.

System-Specific Breakdown

Each crystal system scales differently based on the number of parameters ($k$). The maximum safe HKL Basis Size ($N_{hkl}$) is determined by the Combinatorial formula $C(N, k) < 2^{32}$.

1. Triclinic ($k=6$)

2. Monoclinic ($k=4$)

3. Orthorhombic ($k=3$)

Practical Implications

Is the "Trials" number real?
Yes. It represents the total number of mathematical checks the GPU would theoretically perform. However, Brutus uses a "Fail-Fast" optimization: most invalid cells are rejected after checking only the first 2 or 3 peaks, meaning the GPU rarely performs the full calculation for every trial.

Can you actually run 120 Quadrillion trials?
Technically yes—the "Safe Batching" system prevents your computer from crashing. However, even at a speed of 200 Million trials/sec, 120 Quadrillion trials would take ~19 years to finish.

Practical Limit: For a search to finish in a "coffee break" time frame (5–10 minutes), you generally want to keep the Total Trials count under 100–500 Billion.

If you obtain no solutions, or too many, consider the following adjustments.

If no solutions (or only poor ones) are found

If you get too many solutions (GPU buffer fills)

The GPU buffer is limited (user selected up to 200k, default 20,000) candidate solutions. If this buffer fills up, the search stops earlier than the full space requested. If you have no solution that appears valid:

GPU Buffers and Chunking

The total list of HKL combinations can be too large for a single GPU buffer. Brutus therefore:

  1. Generates HKL combinations in large JavaScript chunks in brutus.html.
  2. Further splits each of these into small “dispatch chunks” (e.g. 256 workgroups) in webgpu-engine.js before sending them to the GPU.

This two-level chunking avoids both memory overflow and long-running GPU commands.

Performance: WebGPU vs CPU

Cubic, Tetragonal, and Hexagonal searches run on the CPU (in a Web Worker) and are typically very fast (under a second).

Orthorhombic, Monoclinic, and Triclinic searches are offloaded to the GPU. This allows testing of billions of trial cells in a time frame (few minutes for 1 billion cells) that would be impractical on the CPU.

Note: at the end of a GPU search all candidates (up to 20 000) are passed to refinement, Niggli cell reduction, M(20) and F(N) calculations. These are made on the CPU so it might take a few minutes, be patient (or change the parameters, or decrease the number of peaks in the list).

Evaluating Solutions

The indexing search usually produces several candidate cells. Brutus keeps at most the best 50, ranked by M20, after the search. Selecting the correct one requires interpreting figures of merit and checking the refined fit.

de Wolff Figure of Merit: M(20)

The primary ranking indicator is the de Wolff Figure of Merit, M(20), calculated from the first 20 observed reflections. It combines both positional accuracy and completeness. In the PDF report additional values are listed, for instance F(20).

M(20) valueInterpretation
> 20Very likely correct.
> 10Likely correct, provided the cell volume is chemically plausible.
5–10Plausible; requires further inspection.
< 5Probably spurious; treat with caution.

F(N) Figure of Merit

As a complementary metric, Brutus computes the F(N) figure of merit, usually with N = 20 (F(20)). While M(20) emphasizes the completeness of indexing, F(N) focuses on the average positional accuracy.

$$ F_N = \frac{N}{\langle |\Delta(2\theta)| \rangle \cdot N_{calc}} $$

A high F(20) indicates a precise fit with low average error. A solution with both high M(20) and high F(20) is usually reliable.

Least-Squares and Zero-Point Refinement

For each promising candidate, Brutus performs a two-stage refinement.

Stage 1: Internal zero-point correction

First, a constrained refinement is carried out including a zero-point error parameter. This internal zero correction is limited by the user-defined 2θ Error, which allows the algorithm to compensate for modest alignment errors without overfitting. The corrected peak positions are then used to refine a stable baseline cell.

Stage 2: Final refinement (optional)

If the Stage-1 cell achieves a sufficiently high M(20) and the Refine Zero-Point Error option is enabled, a second, full refinement (with an unconstrained zero-point) is performed. This yields the final reported parameters and standard deviations. If the option is disabled, the Stage-1 cell parameters are reported directly.

Space Group Analysis

After a high-quality unit cell is obtained, Brutus can suggest likely space groups based on systematic absences. This serves as input for subsequent structure solution or Rietveld refinement.

Method

  1. Generate unique reflections. Using the refined cell, Brutus computes a complete list of theoretical reflections and keeps only crystallographically unique ones (e.g. it includes (100) but omits Friedel equivalent (−100)).
  2. Index observed peaks. All peaks in the curated list are indexed against the theoretical pattern.
  3. Build a high-confidence subset. To avoid ambiguity due to overlapping lines, Brutus retains only reflections for which no other theoretical $(hkl)$ lies within the 2θ Error window of the observed peak.
  4. Determine centering and extinctions. This subset of unambiguous $(hkl)$ indices is compared with the extinction rules of candidate lattices (centerings and glide/screw symmetries). A rule is considered violated only if an observed unambiguous peak contradicts it.
  5. Rank space groups. Based on the crystal system and plausible centerings, the internal database is filtered. Each space group is assigned a violation count and ranked accordingly. The correct name of the space group is given, based on the orientation found by the program.

Interpreting the Output

Advanced Topics: Enhanced Search and Sieving

Beyond the core indexing routine, Brutus applies several “fishing” strategies and reduction steps to improve robustness and simplify the set of final solutions.

1. Swap Fishing for Ambiguity

For each promising solution, Brutus re-examines the indexing of the first four low-angle peaks. It identifies the two peaks closest in angle (a common source of mis-assignment) and creates a new hypothesis by swapping their HKL labels. The resulting cell is fully refined and rescored. If this swap resolves an ambiguity, the new solution might have a higher M(20) and this solution will be retained.

2. Matrix-Based Cell Transformations

Candidate cells are transformed using crystallographic matrices to test for related primitive or higher-symmetry descriptions. For example, a body-centered (I) cell can be mapped to an equivalent primitive (P) cell and evaluated.

3. HKL Divisor Analysis

The list of indexed HKLs is inspected for common divisors. If all indices along one axis (e.g. all h values) share a common factor, Brutus tests a cell with the corresponding axis shortened accordingly (sub-cell).

4. Orthorhombic–Hexagonal Relationship

A hexagonal lattice can sometimes be indexed as C-centered orthorhombic with $b/a \approx \sqrt{3}$. All orthorhombic solutions are checked against this condition, and potential hexagonal equivalents are generated and evaluated.

5. Niggli Cell Standardization

For each high-ranking solution, Brutus computes the Niggli reduced cell, i.e. the standardized primitive cell describing the same lattice.

The conventional (possibly centered) cell identified by the program is first converted to a primitive cell using the detected centering (e.g. I, F, C). A reduction algorithm is then applied to obtain the most compact set of basis vectors ($a, b, c$) and angles ($\alpha, \beta, \gamma$) satisfying the Niggli conditions.

The Niggli cell is useful for:

Niggli cells are included in the detailed section of the PDF report for each major candidate.

6. Final Sieving

After all transformations and refinements, Brutus applies a final de-duplication step. If two solutions have volumes within 1% of each other, the one with higher symmetry is preferred.

If their symmetry is identical (e.g. two monoclinic cells), M(20) is compared. Cells with M(20) values within a small tolerance (e.g. ΔM(20) < 0.05) are considered equivalent in quality and the first solution found is retained.

Troubleshooting & FAQ

Error: "WebGPU not supported in this browser"

This error indicates a software or configuration issue, rather than a lack of hardware capability. Even integrated graphics (like Intel UHD) support WebGPU if configured correctly.

To verify: Type chrome://gpu in your address bar. Look for "WebGPU". If it says "Software only" or "Disabled", the program will not work.

Why were no solutions found?

Why is M(20) low although the fit looks good?

Test Files

References

Brutus was developed by Nita Dragoe at Université Paris-Saclay (2024–2025) as a successor to the earlier program Powder (1999–2000). If you use Brutus in your work, please cite:
https://doi.org/10.13140/RG.2.2.13443.57126

For further background on the methodology, the following references are recommended:

  1. M(20) figure of merit
    de Wolff, P. M. (1968). “A Simplified Criterion for the Reliability of a Powder Pattern Indexing.” Journal of Applied Crystallography 1, 108–113.
  2. F(N) figure of merit
    Smith, G. S. & Snyder, R. L. (1979). “F(N): A Criterion for Rating Powder Diffraction Patterns and Evaluating the Reliability of Powder-Pattern Indexing.” Journal of Applied Crystallography 12, 60–65.
  3. General powder diffraction text
    Klug, H. P. & Alexander, L. E. (1974). X-Ray Diffraction Procedures for Polycrystalline and Amorphous Materials, 2nd ed. New York: Wiley-Interscience.
  4. Deconvolution Algorithm (Richardson-Lucy):
    Richardson, W. H. (1972). “Bayesian-Based Iterative Method of Image Restoration.” Journal of the Optical Society of America, 62, 55–59.
    Lucy, L. B. (1974). “An iterative technique for the rectification of observed distributions.” The Astronomical Journal, 79, 745.
  5. Alternative indexing approaches
    Ito, T. (1949). “A General Powder X-ray Photography.” Nature 164, 755–756.
    Werner, P.-E., Eriksson, L. & Westdahl, M. (1985). “TREOR, a Semi-exhaustive Trial-and-Error Powder Indexing Program for All Symmetries.” Journal of Applied Crystallography 18, 367–370.
    Visser, J. W. (1969). “A Fully Automatic Program for Finding the Unit Cell from Powder Data.” Journal of Applied Crystallography 2, 89–95.
    Le Bail, A. (2004). “Monte Carlo Indexing with McMaille.” Powder Diffraction 19(3), 249–254.
    Boultif, A. & Louër, D. (2004). “Powder Pattern Indexing with the Dichotomy Method.” Journal of Applied Crystallography 37, 724–731.
  6. Previous software
    Dragoe, N. (2001). “PowderV2: A Suite of Applications for Powder X-Ray Diffraction Calculations.” Journal of Applied Crystallography 34, 535.