Introduction

This document serves as a scientific and technical guide for the powder5 web application, a tool for the analysis of powder X-ray diffraction (PXRD) data via whole-pattern fitting. This technique, also known as pattern decomposition, is a crucial method in materials science and crystallography for refining structural and microstructural parameters when a complete structural model is either unknown or unnecessary.

This application facilitates the extraction of precise lattice parameters, peak profile information, and integrated intensities of Bragg reflections. It implements two decomposition algorithms: the iterative Le Bail method for rapid and stable convergence, and the Pawley method for unbiased intensity extraction. Peak profiles are modeled using phenomenological functions, including a versatile Simple pseudo-Voigt, an Asymmetric Split pseudo-Voigt, and Anisotropic model (TCH) based on the Thompson-Cox-Hastings formulation with a Stephens model for anisotropic line broadening. The background is modeled using a monotonic cubic spline interpolation between user-defined anchors, which are held fixed or fitted during refinement.

Two independent routes to a structure are provided, and either can be used without the other. Charge flipping is a dual-space method: it solves for a density map with no model at all, and is the first move when the composition is unknown. The Wyckoff search is a direct-space method: it fits atoms on Wyckoff positions of a known composition directly to the extracted intensities, needs no map, and copes better with light atoms in the presence of heavy ones - where charge-flipping ripples can be as large as some light atoms.


Getting Started: Data Input

Analysis commences with the loading of a powder diffraction data file. The application is designed to automatically parse numerous common ASCII-based file formats from major instrument manufacturers and standard crystallographic software.

  • Supported Formats: Built-in parsers are included for Bruker (.brml, .uxd), PANalytical (.xrdml), Rigaku (.ras, .rasx), Philips (.udf), GSAS (.esd, .gsa, .std, .xra), and Jade (.mdi). Format detection is by content first and file extension second, so a correctly formatted file will usually be recognised even if it has been renamed. pdCIF files can also be read, at least those saved by this program or Brutus.
  • Scientific notation (1.5E+03, 1.2e4) is accepted in the intensity or 2θ column.
  • Ordering: data stored in descending 2θ is detected and sorted ascending on load. Duplicated 2θ values and non-finite points are removed, with a note in the browser console.
  • Generic Data: Standard two-column ASCII files (.xy, .csv, .txt, .dat, .asc etc.) containing $2\theta$ and intensity values are also supported. The parser accommodates space, comma, or semicolon delimiters. Comment lines prefixed with #, !, ; or // are ignored, as are non-numeric header lines.
  • Metadata Parsing: For many instrument-specific formats, instrument parameters such as the X-ray wavelength for Kα1 are read from the file's metadata and used to populate the relevant fields in the user interface. It is incumbent upon the user to verify the correctness of these automatically populated values.
Zipped formats: Rigaku .rasx and Bruker .brml. Both are ZIP archives rather than plain text, and both are read by unzipping them and parsing the pattern out of the archive - no conversion step is needed. The file is read as bytes and identified by its magic number, so an archive is recognised as one whatever it has been renamed to.
Before loading any data: the chart already shows a live theoretical stick pattern ($2\theta$ positions and relative Kα1/Kα2 markers) for the currently selected space group and lattice parameters, updating as you change them. The report button in the top-right corner works even without a data file, exporting that theoretical reflection list as a PDF - useful for previewing where reflections are expected for the selected symmetry.

Files & Offline Use

The application is a set of static files with no build step and no server-side component. Every file below must sit in the same directory:

The tree is:

PathPurpose
powder5.htmlThe application itself.
style.cssAll styling.
charge_flipping.wgslWebGPU kernels for the charge-flipping loop.
swarm_reflection.wgslWyckoff swarm kernel. Scores grouped |Fcalc|² against the Pawley intensities with the scale-only weighted wR2 objective and applies the ramped geometry penalties used during the global search.
js/All application modules - charting.js, constants.js, contacts.js, coord_refine.js, crystal.js, data_io.js, density3d.js, excluded.js, observations.js, parsers.js, pawley_linear.js, polarization.js, profile.js, profile_presets.js, refinement_controller.js, reporting.js, scatterers.js, sg_engine.js, simulation.js, spacegroup_ui.js, spline_background.js, state.js, status_bar.js, swarm_wyckoff.js, symmetry_utils.js, wyckoff_assign.js, wyckoff_report.js and the three Web Workers charge_flipping_worker.js, refinement_worker.js, and wyckoff_worker.js.
lib/Vendor bundles: chart.umd.min.js, three.min.js, jspdf.umd.min.js, html2canvas.min.js.
sg/Space-group database (all settings of the 230 groups).
scatters/Tabulated atomic scattering factors, with index.json naming the available tables.
Zero point in an exported pdCIF. The dictionary defines its offset as \(2\theta_{\text{calibrated}} = 2\theta_{\text{measured}} + 2\theta_{\text{offset}}\), whereas powder5 works with \(\text{zeroShift} = 2\theta_{\text{obs}} - 2\theta_{\text{calc}}\) - the instrument zero error, positive when the diffractometer reads high. The two are the same quantity with opposite signs, so _pd_calib_2theta_offset is written negated and read back negated. A private _powder5_2theta_zero_shift carries the unconverted value alongside it, so a file this program wrote round-trips exactly whichever tag a reader picks up.
The scattering tables are not optional for structure solution. If scatters/index.json cannot be read, the Wyckoff search and the coordinate refinement fall back to f = Z, a flat form factor with no angular fall-off. That makes every heavy atom too strong at high angle and no arrangement of atoms can fit the data; a warning is written to the console when it happens.
A local web server is required. You can run this program directly from the github server. If you want to have your own copy you'll need to download all the files in a given folder. Opening the file directly by double-clicking it (a file:// URL) will not work: browsers block both fetch() and Web Workers under that scheme, so the symmetry database never loads and no refinement can start. From the directory containing the files, run for example python3 -m http.server 8000 and then open http://localhost:8000/powder5.html.
Once those files are present the application makes no network requests at all during use. The only remaining external references are the two Google Fonts stylesheets; if they cannot be reached the interface falls back to Helvetica/Arial and Menlo/Consolas through the CSS font stacks, which changes nothing but the typeface.

Interactive Data Visualization

The diffraction pattern is rendered in an interactive plot to facilitate detailed inspection of the experimental data and the quality of the model fit. You can hide any of the plots by clicking on its legend at the top of the chart.

All navigation is implemented directly in the application, with no third-party charting plugin, so it behaves identically whether or not you have a network connection.

GestureAction
Drag a rectangle (left button) Zoom to the selected region. A box that is thin in one direction zooms only the other axis, so a horizontal swipe across a peak does not also crop the intensity scale.
Mouse wheel Zoom the $2\theta$ axis about the cursor. The value under the pointer stays fixed as the range expands or contracts around it.
Shift + wheel Zoom the intensity axis about the cursor.
Alt + drag Pan both axes.
Middle-button drag Pan. Provided because several Linux window managers intercept Alt+drag before the page ever sees it.
Shift + drag Pan (equivalent to Alt+drag).
Right-click Reset the view to the range currently set by the 2θ Min/Max sliders, with the intensity axis returned to full scale. Under Simulation with no data file open, the simulation restores its own vertical extent — the usual machinery needs a loaded pattern to work one out.
Ctrl + click Add or remove a background spline point at the nearest experimental point. Points cannot be added outside the current 2θ slider range, nor exactly at the edge indices.
Escape Abandon a zoom rectangle or pan in progress.
One-finger drag (touch)Pan.
Two-finger pinch (touch) Zoom both axes about the midpoint between the fingers.
  • Reflection Data: Hovering the cursor near a Bragg reflection marker (tick mark) displays a tooltip containing the corresponding Miller indices ($hkl$) and $d$-spacing.
  • Hiding curves: Click an entry in the legend at the top of the chart to toggle that curve.

One bar, at the foot of the results panel, reports whatever is running: a Le Bail or Pawley refinement, a charge-flipping run, or a Wyckoff search. It reads, for example

Wyckoff search: Z = 4 (2/3), wave 2/3, restart 1/4, gen 500/1000, wR2 13.0%
Charge flipping: start 2/4, cycle 1300/2000, R 0.2841
Refinement: 64%

A phase that cannot report a fraction - building the Wyckoff tables, compiling a GPU shader - shows a moving stripe rather than a bar stuck at zero. One-off messages (“Stopping…”, “complete - 3 solutions”) appear there too and clear themselves; warnings are also written to the Log tab and to Console, so anything important stays findable after the bar has moved on.

A plain left-click that does not move is not treated as a zoom, dragging less than about 8 pixels is likewise ignored.

Pattern Decomposition Methodologies

Pattern decomposition enables the fitting of a powder diffraction pattern based on a unit cell and space group, without requiring a full structural model (atomic coordinates). This is essential for the precise determination of lattice parameters and the extraction of integrated intensities, which are requisite for ab initio structure determination.

A Note on Intensity Parameter: In this application, the intensity parameter ($I_{hkl}$) associated with a Bragg reflection represents its maximum peak height. The integrated area is calculated internally by multiplying this height by the area of the normalized peak shape function. While the refinement optimizes the height parameter, the reported intensities ($I_{calc}$, $I_{obs}$) and their ESDs are correctly calculated and presented as integrated areas.

The Le Bail Method

The Le Bail method is an iterative, sequential algorithm known for its computational efficiency and robust convergence. The process is as follows:

  1. Initialization: A theoretical pattern is calculated from the user-supplied lattice, profile, and background parameters (defined by the spline points). Every reflection is given the same starting height. This flat start is deliberate: the method assumes no structural model, so the first decomposition partitions purely on profile overlap. Intensities are never carried over from a previous run, which would make the result depend on history rather than on the data.
  2. Seeding passes: Before any parameter is allowed to move, the decomposition alone is iterated a few times so the intensities settle. The partitioning is a fixed-point iteration and converges in a handful of passes.
  3. Intensity Extraction (Height Partitioning): The observed net intensity ($y_{i,obs} - y_{i,bkg}$) at each data point is partitioned among the calculated Bragg peaks contributing to that point. The contribution of each peak is proportional to its profile function value at that point. Summing these partitioned intensities for each reflection yields a new set of "observed" integrated intensities. These are then converted back to estimated peak heights using the current profile function's area.
  4. Extract, then refine: The intensities are re-extracted at the top of every optimizer iteration and then held fixed for the whole of that iteration - for the baseline residual, for every column of the Jacobian, and for the trial step. The optimizer adjusts only the lattice and profile parameters; the background stays fixed at the spline points throughout.
  5. Why not re-extract more often: Re-extracting inside the objective function (i.e. at every function evaluation) flattens the $\chi^2$ landscape: the peak widths can grow substantially while the extraction quietly compensates, so the residual barely responds and the width parameters become indeterminate. Holding the intensities fixed within an iteration keeps the minimum at the true width sharp. Alternating extraction with least-squares - rather than fusing them - is the actual Le Bail method.
  6. Convergence: Because the alternation happens inside the iteration loop, a single press of Run Le Bail converges self-consistently; you do not need to click repeatedly for the intensities and parameters to agree. Re-running is useful only to restart from a different algorithm (see Recommended Refinement Strategy) or after changing a fixed input such as the background points.
The extraction runs to convergence, not for a fixed number of passes. Each refinement cycle restarts the decomposition from a flat seed - which keeps the extracted intensities a deterministic function of the current parameters, rather than of the path taken to reach them - and then iterates until the relative change falls below a tolerance, with a floor of six passes and a cap of twenty-four. A fixed count is either wasteful on a well-separated pattern or short on a heavily overlapped one, and the overlapped case is exactly where being short matters: the profile parameters would otherwise be fitted against intensities that are still moving.

The Pawley Method

The Pawley method treats the peak height ($I_{hkl}$) of every Bragg reflection as a free variable, fitted at the same time as the cell and the profile. The pattern is linear in every intensity: $$y(x) = \sum_j I_j\,\phi_j(x;\theta) + b(x)$$ so for any given set of non-linear parameters $\theta$ - cell, zero-point, profile widths - the optimal intensities are not something to iterate towards but the exact solution of a linear least-squares problem. powder5 solves that problem outright at every step and lets the minimiser search only $\theta$. This is variable projection (Golub & Pereyra, 1973).

Two consequences matter in practice. The intensities are exactly optimal at every iteration rather than partly converged at the end, so the residual reported is the residual of the model actually fitted. And the search space is the dozen or so genuinely non-linear parameters instead of several thousand, which is what makes parallel tempering usable on a Pawley fit at all.

The normal matrix of the linear step is banded: it has a non-zero entry for two reflections only where their profile windows overlap, and the reflection list is sorted by $2\theta$. The solve is therefore $O(n\,b^2)$ in the bandwidth $b$, not $O(n^3)$ - a few tens of milliseconds and about a megabyte for a pattern with 2500 reflections. The background is a spline through the user-defined anchors, whose heights are refined only if you ask; see Background Modeling for what that costs.

Intensities are bounded at zero using Non-Negative Least Squares (NNLS). An integrated intensity is physically non-negative, but unconstrained least squares can split exactly overlapping reflections into large positive and negative values that sum correctly. Imposing non-negativity via an active-set NNLS algorithm removes this physically impossible region. Crucially, the Estimated Standard Deviations (ESDs) are extracted from the unconstrained normal equations matrix. This ensures that a reflection pinned to zero still reports the true uncertainty of the measurement, rather than falsely claiming an ESD of zero, preserving the statistical honesty required for weak or systematically absent reflections.

The intensity derivatives are analytic. \(\partial y_i / \partial I_j\) is the profile of reflection \(j\) at point \(i\) - exact, and non-zero only inside that reflection's profile window. Each intensity column is therefore stored as a slice covering only the points it touches, and \(J^{T}J\) is accumulated over the intersection of two slices, so two reflections that do not overlap contribute an exact zero without being visited. Profile, cell and zero-point parameters still use finite differences, which is where they genuinely belong.
  • Advantages: The Pawley method is considered more rigorous as it avoids the iterative bias of the Le Bail method, particularly in cases of severe peak overlap. It can yield more accurate and statistically sound integrated intensities (reported as areas) and parameter uncertainties.
  • Limitations: the cost is no longer the parameter count - the intensities are projected out rather than iterated - but the information content of the data is unchanged. Where reflections overlap severely their intensities remain strongly correlated, and where they are exactly coincident only the group sum is determined at all. See exactly coincident reflections below. A poor starting cell is still a poor starting cell: the separable form makes the surface in $\theta$ better behaved, not convex.
Which algorithm for a Pawley fit? Parallel tempering searches the same dozen non-linear parameters it searches in Le Bail mode, and is the better choice whenever the starting cell is uncertain. Use Levenberg-Marquardt alone when the model is already close; use Parallel Tempering (which finishes with an LM polish) when it is not.

Minimization Algorithms

The goal of refinement is to minimize the sum-of-squares objective function, $\chi^2 = \sum w_i (y_{i,obs} - y_{i,calc})^2$, where $w_i$ is the statistical weight of each data point (typically $w_i = 1/y_{i,obs}$). This application provides several algorithms to navigate the complex parameter space and find the minimum of this function.

Levenberg-Marquardt (LM)

The LM algorithm is a standard gradient-based method for non-linear least-squares problems. It effectively interpolates between the Gauss-Newton algorithm and the method of gradient descent. By calculating the Jacobian matrix (the matrix of first partial derivatives of the calculated pattern with respect to the parameters), it determines the most efficient path toward the nearest local minimum.

  • Characteristics: LM is a local minimizer, exhibiting rapid quadratic convergence when the initial parameters are close to the true minimum. It is the preferred method for final, high-precision refinement and is the only algorithm here that can calculate valid estimated standard deviations (ESDs) for the refined parameters from the covariance matrix.
  • Limitations: It is susceptible to converging to a local minimum if the starting model is far from the global solution.
  • Parameter bounds: several parameters are bounded - profile widths and Pawley intensities below at zero, the mixing parameter $\eta$ to $[0,1]$, cell angles to $(0^\circ, 180^\circ)$. A step that would cross a bound is clipped to it, and the gain ratio $\rho = \Delta\chi^2_{\mathrm{actual}} / \Delta\chi^2_{\mathrm{predicted}}$ is formed from the step that was actually applied. This matters in Pawley mode, where weak reflections routinely park at zero intensity: the damping parameter $\lambda$ is shared by the whole model, so measuring $\rho$ against a step that was never taken would let a handful of pinned intensities throttle the cell and profile terms as well.
  • Stopping at a bound: if an entire step is blocked - the model sitting in a corner of the bound box with the gradient pointing out of it - the refinement stops and reports it, rather than spending its remaining iterations raising $\lambda$ against a wall.
  • Pawley Mode: Generally the recommended algorithm for Pawley refinements due to stability and efficiency.
The normal equations are solved by Cholesky factorisation, with LU and partial pivoting retained as a fallback. The Marquardt-scaled matrix \(D^{-1}(J^{T}J)D^{-1} + \lambda I\) is symmetric and positive definite by construction; LU ignores both facts, does twice the arithmetic, and - the part that matters - returns a finite “solution” for an indefinite matrix. An indefinite matrix means the normal equations have been corrupted, and the step computed from one points in an arbitrary direction. Cholesky fails on exactly that case, which is what the loop wants: it raises \(\lambda\) and tries again.
Parameters with no effect are dropped. A parameter whose Jacobian column is identically zero is excluded from the solve and reported once by name. The test is on the column itself, not on its size relative to other columns: diagonals of \(J^{T}J\) are in different physical units - counts per Ångström for a cell edge, dimensionless for an intensity - so comparing them against each other says nothing about whether either is determined.

Parallel Tempering (Replica Exchange)

Parallel Tempering, also known as Replica Exchange MCMC, is an advanced stochastic algorithm designed to overcome the slow convergence of traditional search methods on complex landscapes. Instead of a single system, Parallel Tempering simulates multiple copies (or "replicas") of the system simultaneously, each at a different, fixed temperature in a predefined ladder ($T_1 < T_2 < ... < T_N$).

  • Mechanism: Each replica evolves independently according to a standard Monte Carlo or Simulated Annealing-like algorithm at its respective temperature. The high-temperature replicas explore the parameter space broadly (high mobility, escaping local minima), while the low-temperature replicas perform a fine-grained search of local minima (high precision).
  • The Swap Move: Periodically, the algorithm attempts to swap the entire set of parameters between adjacent replicas (e.g., between replica $i$ at temperature $T_i$ and replica $i+1$ at $T_{i+1}$). The swap is accepted with a Metropolis-like probability that depends on the energies (costs) and temperatures of the two replicas. This crucial step allows a good solution discovered by a high-temperature replica in a distant valley to "percolate down" to the low-temperature replicas, dramatically improving the efficiency of finding the global minimum compared to single-temperature methods.
  • Advantages: Significantly more efficient at global exploration than simpler stochastic methods, making it a robust choice for complex problems or when the starting model is highly uncertain (primarily in Le Bail mode).
  • Le Bail intensities under PT: Unlike the LM path, which re-extracts at the top of each iteration, the stochastic search extracts the intensities once before the run and holds them fixed throughout. A stochastic walker proposes many rejected moves, and re-extracting on each would make the cost function non-stationary and the Metropolis test meaningless.
  • Pawley mode: the intensities are not searched. They are solved exactly at each cost evaluation (see the Pawley method), so a replica walks the same non-linear parameters it would in Le Bail mode and the cost it reports is the reduced objective - the residual after the intensities have been optimised. That is the function whose minimum in $\theta$ is the true minimum, so the Metropolis test and the replica swaps mean what they are supposed to mean.

Guide to Refinable Parameters

This section provides a detailed breakdown of the parameters you can control and refine.

A Note on Parameter Scaling & GSAS Comparison

Following a long-standing convention in crystallographic software like GSAS, some refinable parameters in this program are internally scaled. This is done for user convenience, allowing you to work with manageable numbers (e.g., 1.0) instead of very small decimals (e.g., 1.0e-4). The documentation below provides the exact formulas used, allowing for direct comparison with physical models and values from other software.

Crystal System & Space Group

These parameters define the crystallographic symmetry of the material.

  • The System selection imposes metrical constraints on the lattice parameters (e.g., for Cubic, $a=b=c$, $\alpha=\beta=\gamma=90^\circ$).
  • The Space Group selection determines the systematic reflection conditions ($hkl$ absences) used to generate the list of Bragg peaks. The underlying logic for these conditions is consistent with established crystallographic libraries and was taken from Computational Crystallography Toolbox (cctbx).
  • Space groups are chosen from a searchable modal listing every setting of all 230 groups. Where a group has several settings (for example No. 62: $Pnma$, $Pmnb$, $Pbnm$, $Pcmn$, $Pmcn$, $Pnam$) each is offered separately, since the reflection conditions differ between them. Rhombohedral groups are offered on hexagonal axes only, because the $d$-spacing formula is written for that indexing.
  • Monoclinic settings. All three unique-axis choices are supported. The unique axis is read from the symmetry operators of the setting you select, and the lattice panel then offers the one angle that is free: $\beta$ for unique axis $b$ ($P12_1/c1$), $\gamma$ for unique axis $c$ ($P112_1/b$), $\alpha$ for unique axis $a$ ($P2_1/b11$). The other two are fixed at $90^\circ$ and are neither shown nor refined. The reciprocal metric, the reflection orbits and the multiplicities all follow that same axis, so the three settings of one lattice give identical peak positions and identical intensities. Switching between settings carries the angle across, so the cell is not lost.
  • Startup default: the application opens on $Pnma$ (No. 62, standard setting) with an orthorhombic cell of $a = 8.478$, $b = 5.397$, $c = 6.958$ Å. This is only a starting point - change it to match your material before refining.

Reflection List & Multiplicities

The Bragg peak list is built from the rotation operators of the selected space-group setting. Every candidate $hkl$ inside the resolution sphere is mapped onto its orbit under the Laue group; the orbit is kept once, labelled by a canonical member, and its size becomes the multiplicity $m$ that scales the intensity, $I \propto m \cdot LP \cdot |F|^2$. Systematic absences are then tested on that representative, which decides the whole orbit, since an absence is a property of the orbit and not of any one index triple.

Working from the operators rather than from a fixed index range per crystal system matters wherever two Laue classes share a system, because the two classes have genuinely different sets of independent reflections:

SystemLaue classesWhat separates them
Cubic$m\bar{3}m$ / $m\bar{3}$ $m\bar{3}$ permutes the axes cyclically only, so $(210)$ and $(201)$ are independent reflections. In $m\bar{3}m$ they are equivalent.
Tetragonal$4/mmm$ / $4/m$ $4/m$ has no mirror exchanging $a$ and $b$, so $(hkl)$ and $(khl)$ are independent.
Hexagonal$6/mmm$ / $6/m$ As above: in $6/m$, $(hkl)$ and $(khl)$ are independent.
Trigonal$\bar{3}m$ / $\bar{3}$ In $\bar{3}$ the orbit is generated by the 3-fold and inversion alone, and is half the size.
Trigonal$\bar{3}m1$ / $\bar{3}1m$ The two settings differ in which form is special: $\bar{3}m1$ gives $h0l$ multiplicity 6 and $hhl$ multiplicity 12, $\bar{3}1m$ the reverse.

In the hexagonal and trigonal systems the special forms are set by the Bravais–Miller index $i = -(h+k)$ as much as by $h$ and $k$: a reflection lies on a mirror whenever any two of $h$, $k$, $i$ are equal in magnitude, so $(1\bar{2}l)$ and $(2\bar{4}l)$ are special even though $|h| \neq |k|$. The orbit calculation accounts for this automatically.

Operators are taken from the sym_ops field of the space-group database (or the older rotations field, which serves equally well here - only the rotation parts affect a reflection orbit). The closed group is checked against the order_p recorded for the setting before it is used. If the database carries no operators, a built-in table of the Laue-class generators is used instead; if the Laue class itself cannot be identified, the generator falls back to the lowest Laue class of the crystal system. That last case is safe rather than wrong: orbits split into smaller ones at identical $d$, so peak positions and total intensities are unaffected, and only the number of listed entries changes. The browser console records which source was used whenever it is not the first.

Completeness

The sum of the multiplicities over the generated list equals the number of reciprocal-lattice points inside the limiting sphere, exactly, for every Laue class. A reflection cannot be missed and cannot be counted twice without breaking that identity, which makes it a usable self-check if you modify the symmetry data.

Instrumental Parameters

Found under the "Sample" tab, these parameters model the diffractometer configuration.

  • Radiation 1/2 (Å) & Ratio: Defines the X-ray source. For divergent-beam laboratory instruments, a Kα1/Kα2 doublet is typically used. For synchrotron radiation, the Ratio is set to 0.
  • Polarisation: Selects the polarisation model used in the Lorentz–polarisation factor - Lab (default), Synchrotron, or None. A second field appears beside it: the monochromator angle $2\theta_M$ for a laboratory source, or the polarised fraction $f$ for a synchrotron. This setting does not affect the fit; it governs how an extracted intensity is converted into $|F|$. See Lorentz–Polarisation Factor.
  • Zero: A refinable parameter that corrects for instrumental zero-point error in the $2\theta$ axis. It is highly correlated with lattice parameters and must be refined with caution.
  • 2θ Min / Max: These sliders define the refinement range. It is standard practice to exclude regions of low signal-to-noise or known artifacts from the calculation.

Lorentz–Polarisation Factor (Lp)

The integrated intensity of a powder reflection is not $|F|^2$ alone. It carries two geometric weights - the multiplicity $m$ of the reflection and the Lorentz–polarisation factor $Lp$ - on top of an arbitrary overall scale $s$:

$$I(hkl) \;=\; s \cdot m \cdot Lp(2\theta) \cdot |F(hkl)|^2$$

$Lp$ is therefore the last thing standing between an extracted Le Bail or Pawley intensity and a structure factor, and it is the reason the reflection table in the report prints $m$, $Lp$ and $|F_o|$ next to the intensity rather than the intensity on its own.

Lp does not affect the refinement

In both Le Bail and Pawley the intensity of every peak is a free quantity: it is re-partitioned from the observation each cycle, or refined as a least-squares parameter. Either way it absorbs $Lp$ completely. Changing the polarisation model therefore cannot move a lattice parameter, a profile coefficient, $R_{wp}$ or $\chi^2$ by so much as a digit - and if it appears to, something else changed at the same time. What it changes is the meaning of the refined intensities: $|F_o|$, the input to charge flipping, the Wilson prior behind the French–Wilson correction, and the space-group probability test. Because nothing needs re-refining, Powder 5 applies a change of model retroactively to the live fit and to every run in the history, so re-exporting an old run uses the model currently on screen.

The Lorentz factor

For a conventional $\theta$–$2\theta$ powder scan, Powder 5 uses

$$L(2\theta) \;=\; \frac{1}{\sin^2\theta \, \cos\theta}$$

This lumps together the rate at which a crystallite passes through the reflecting condition and the fraction of the Debye–Scherrer ring intercepted by the detector. It is often written $1/(4\sin^2\theta\cos\theta)$; the factor of 4 is a constant and is swallowed by $s$, so it makes no difference to anything reported here. $L$ has no adjustable parameters and is applied for every polarisation setting, including None.

The polarisation factor

All three models are the same expression with one constant $K$, normalised so that $P(0) = 1$ in every case:

$$P(2\theta) \;=\; \frac{1 + K\cos^2 2\theta}{1 + K} \qquad\qquad Lp = L \cdot P$$
Setting$K$Use it when
Lab (default) $\cos^2 2\theta_M$, or $1$ if $2\theta_M = 0$ Any sealed-tube or rotating-anode instrument. Leave $2\theta_M$ at 0 for a plain unpolarised source; enter the monochromator angle if there is one.
Synchrotron $(1-f)/f$ A polarised source. $f$ is the fraction of the beam polarised perpendicular to the diffraction plane.
None $0$, so $P \equiv 1$ Neutron data, intensities that have already been corrected elsewhere, or a deliberate test of how much the correction is worth.

With $2\theta_M = 0$ the Lab setting reduces to $P = \tfrac12(1 + \cos^2 2\theta)$, the classical unpolarised expression, and this is what Powder 5 uses by default. Note that a fully perpendicular-polarised synchrotron beam ($f = 1$) gives $K = 0$ and therefore exactly the same arithmetic as None; the two settings are kept distinct because they describe different geometry and are labelled differently in the report.

Choosing $2\theta_M$ for a laboratory monochromator

$2\theta_M$ is the take-off angle of the monochromator crystal at the wavelength in use, not a free parameter. It follows from Bragg's law applied to the monochromator itself,

$$ 2\theta_M \;=\; 2\,\arcsin\!\left(\frac{\lambda}{2 d_M}\right) $$

where $d_M$ is the interplanar spacing of the reflection the crystal is cut for. The same crystal therefore gives a different angle on every anode: a graphite (002) monochromator sits at 26.6° on Cu but at 12.2° on Mo, and $K$ rises from 0.800 to 0.956 with it. Change the tube and this field must change too.

Each cell below gives $2\theta_M$ in degrees, with the resulting $K = \cos^2 2\theta_M$ in brackets. Enter the angle, not $K$ - Powder 5 squares the cosine for you. Angles are computed from the K$\alpha$ weighted-mean wavelengths ($\alpha_1{:}\alpha_2 = 2{:}1$); a monochromator that passes K$\alpha_1$ alone shifts $2\theta_M$ by less than 0.05°, which is far below anything $P$ can resolve.

Optic ($d_M$, Å) Cr K$\alpha$
2.2910
Fe K$\alpha$
1.9374
Co K$\alpha$
1.7903
Cu K$\alpha$
1.5418
Mo K$\alpha$
0.7107
Ag K$\alpha$
0.5608
Graphite (002), pyrolytic - the usual diffracted-beam crystal (3.354) 39.9 (0.588)33.6 (0.694)31.0 (0.735) 26.6 (0.800)12.2 (0.956)9.6 (0.972)
Quartz (10$\bar{1}$1) (3.343) 40.1 (0.585)33.7 (0.692)31.1 (0.734) 26.7 (0.799)12.2 (0.955)9.6 (0.972)
Ge (111) - Johansson incident-beam (3.266) 41.1 (0.569)34.5 (0.679)31.8 (0.722) 27.3 (0.790)12.5 (0.953)9.8 (0.971)
Si (111) (3.136) 42.9 (0.537)36.0 (0.655)33.2 (0.701) 28.5 (0.773)13.0 (0.949)10.3 (0.968)
LiF (200) (2.014) 69.3 (0.124)57.5 (0.288)52.8 (0.366) 45.0 (0.500)20.3 (0.879)16.0 (0.924)
Ge (220) (2.000) 69.9 (0.118)57.9 (0.282)53.2 (0.359) 45.3 (0.494)20.5 (0.878)16.1 (0.923)
Si (220) (1.920) 73.3 (0.083)60.6 (0.241)55.6 (0.320) 47.3 (0.459)21.3 (0.868)16.8 (0.917)
Graded multilayer mirror (Göbel and similar) Enter 0. The beam meets the multilayer at grazing incidence, so $2\theta_M$ is a couple of degrees and $K > 0.997$ - indistinguishable from an unpolarised source.
None - K$\beta$ filter (Ni, Fe, …), or no filter at all Enter 0 ($K = 1$). A filter absorbs; it does not diffract, so it does not polarise.

$d_M$ is quoted so you can check an optic that is not listed: Ge $a = 5.6575$ Å and Si $a = 5.4310$ Å give $d_{hkl} = a/\sqrt{h^2+k^2+l^2}$, and graphite's $d_{002}$ is half its $c$ axis.

An incident-beam monochromator must lie in the same plane as the diffractometer. The formula Powder 5 uses, $P = (1 + K\cos^2 2\theta)/(1 + K)$, is the parallel case - the monochromator diffracts in the equatorial plane, the same plane in which the sample then diffracts. That is how a Johansson Ge (111) or a diffracted-beam graphite crystal is mounted on essentially every laboratory instrument, so the table above applies as it stands.

If a monochromator is instead mounted with its diffraction plane perpendicular to the equatorial plane, the polarisation factor becomes $P = (K + \cos^2 2\theta)/(1 + K)$ - a different function, not a different $K$, and one this single-parameter model cannot express. There is no value of $2\theta_M$ that stands in for it. The arrangement is rare outside purpose-built instruments; if you have one, treat the extracted $|F|$ as carrying a known angular bias rather than entering an angle that would hide it.

Mosaic versus perfect crystals. $K = \cos^2 2\theta_M$ is the ideally mosaic result, which is the right one for graphite and for ordinary pyrolytic monochromators. A genuinely perfect crystal diffracts in the dynamical regime and the correct constant is $K = |\cos 2\theta_M|$ instead - 0.894 rather than 0.800 for graphite geometry. Powder 5 implements the mosaic convention. If you need the perfect-crystal value, enter the equivalent angle $2\theta_{M}^{\,\mathrm{eff}} = \arccos\sqrt{K}$ (for $K = 0.894$, that is 19.1°). In practice the two differ by well under 2% in $P$ at any angle, which is smaller than most other systematic errors in a laboratory pattern.

Choosing $f$ for a synchrotron

Bending-magnet and undulator radiation is polarised in the horizontal plane, with $f$ typically between 0.90 and 0.98 in the plane of the orbit. What matters is the orientation of the diffractometer relative to that:

  • Vertical scattering plane (the usual arrangement for high-resolution powder diffraction): the electric field is perpendicular to the scattering plane, so $f \approx 0.95$–$1.0$ and $P$ is nearly flat. The correction is almost pure Lorentz, and this is precisely why the geometry is chosen.
  • Horizontal scattering plane: the field lies in the scattering plane. Enter $f \approx 0.05$–$0.1$, which gives $P \to \cos^2 2\theta$ - a severe correction that goes to zero at $2\theta = 90^\circ$. Getting this backwards is a much worse error than misjudging $f$ by a few per cent.

How large is the effect?

$Lp$ falls steeply with angle whatever the model, and the polarisation term adds a further factor of two by $2\theta = 90^\circ$ for an unpolarised source. Values for Cu K$\alpha$:

$2\theta$ (°)$L$ $Lp$, Lab (no mono)$Lp$, graphite $Lp$, synchrotron $f=0.95$$Lp$, None
10132.15130.16130.38131.95132.15
2033.6831.7131.9333.4833.68
3015.4613.5213.7415.2615.46
457.395.545.757.217.39
604.622.893.084.454.62
902.831.411.572.692.83
1202.671.671.782.572.67
1504.143.623.684.094.14

$Lp$ spans a factor of about 90 between $2\theta = 10^\circ$ and $90^\circ$. Omitting it does not perturb a structure-solution calculation slightly - it weights the first few peaks roughly two orders of magnitude too heavily, and a charge-flipping map built on uncorrected intensities is dominated by them. The choice between models is a much smaller effect: at most a factor of two, and concentrated near $2\theta = 90^\circ$. Getting the correction on at all matters more than getting the model exactly right, but the models are cheap to select correctly.

Where it is applied

ConsumerWhat $Lp$ does there
Reflection table in the report Printed as its own column, and used for $|F_o| = \sqrt{I_{hkl} / (m \cdot Lp \cdot (1 + I_2/I_1))}$.
Charge flipping Each observed intensity is divided by $Lp$ before it becomes a target amplitude. Without it the map is dominated by the low-angle peaks.
French–Wilson correction The Wilson prior is estimated from $I/(m\,Lp)$, which is the quantity actually proportional to $|F|^2$, rather than from raw areas.
Space-group probability test Intensities are normalised by $m \cdot Lp$ before the Wilson-like scale $\tau_j$ is estimated, so the extinction evidence is not confounded with the $Lp$ fall-off.
Theoretical (data-free) export $Lp$ and $m \cdot Lp$ are tabulated per reflection. With no structure factors available, $m \cdot Lp$ is the whole of the predicted relative intensity.

All of these read one shared calculation, evaluated at the corrected $2\theta$ - the same angle printed in the reflection table, including the zero shift and any displacement or transparency term. The charge-flipping worker takes the per-reflection value computed by the refinement rather than recomputing its own, so the map, the report and the prior cannot disagree about it. The charge-flipping summary panel reports the model the worker actually used, which is the check that they have not.

A note on $|F_o|$ and the Kα doublet

With a K$\alpha_1$/K$\alpha_2$ source the integrated area of a reflection is the sum over the pair, so it exceeds the single-wavelength intensity by $(1 + I_2/I_1)$. The $|F_o|$ column divides that back out, which makes the printed structure factors comparable with a monochromatic or synchrotron measurement instead of carrying a source-dependent constant. It is a single global factor and so has no effect on relative $|F_o|$; the report states the divisor it used. The overall scale remains arbitrary in any case: $|F_o|$ is on the scale of the observed pattern, not on an absolute electron scale.

Background Modeling (Spline Interpolation)

The background contribution is modeled using a monotonic cubic Hermite spline interpolation between a series of user-defined points (spline points or knots). This approach provides flexibility and ensures a smooth, physically realistic background shape without introducing refinable background parameters into the least-squares minimization. The background shape is therefore considered fixed during the refinement process based on the current spline points.

Control of the background spline is located under the "Background" tab:

  • Auto-generation: The application automatically estimates background points immediately upon loading a data file. You can adjust the density of these points using the Auto-points slider (10-40 points). Adjusting the slider automatically recalculates the points based on local intensity minima within intervals distributed across the current 2θ Min/Max slider range. The points at the exact 2θ Min and Max slider positions are always included and fixed to these $2\theta$ values.
  • Manual Addition: Add individual points by holding Ctrl and clicking on the chart. The closest experimental point will be added to the list, provided it's within the current slider range and not an edge point.
  • Editable List: The generated and manually added points appear in a list below the controls.
    • You can directly edit the $2\theta$ and Intensity values for any point, except for the $2\theta$ values of the first (Min) and last (Max) points, which are fixed by the sliders. Edits trigger recalculation of the spline.
    • Points can be deleted using the × button, except for the first and last points.
  • Chart Display: The spline points can be toggled on/off on the chart using the "Show Points on Chart" checkbox. The calculated spline curve is always shown.
Anchors outside the fitted range are removed. Narrowing the \(2\theta\) range deletes any anchor that now falls outside it, and a message says how many went. Leaving them would let a point at 160° go on shaping the baseline for a fit that stops at 158° - data explicitly excluded, still pulling the background under the data that was kept. Widening the range again does not bring them back; add new ones, or press Auto-points.
Fit background. With the checkbox ticked, the height \(y\) of every anchor becomes a refined parameter, bounded below at zero since a negative background has no physical meaning. The \(2\theta\) positions stay where you put them: the anchors are where you have decided the baseline can be read, you can move them but their x positions is not fitted.

Whether you tick it changes what the numbers in the report mean.

Background fittedBackground fixed
ESDs Include background uncertainty. Each anchor contributes a column to \(J\), so the covariance knows that a baseline free to move absorbs some of what the peaks would otherwise have to explain. The background contributes no column to \(J\), so every \(\sigma\) is conditional on the anchors being exactly right.
\(P\) and \(\chi^2\) The anchors are counted in \(P\), so the degrees of freedom are honest. They are not counted, so \(\chi^2\) - and every ESD scaled by it - is optimistic by roughly the number of anchors.
Extracted intensities The baseline adjusts with the fit, so a slightly misplaced anchor corrects itself instead of being absorbed. Any error in the anchors goes straight into the extracted intensities, because the decomposition works on \(y_{obs} - y_{bkg}\).

The statistics block states which of the two applied on every run.

Fitting the background does not excuse you from placing the anchors well. A refined anchor moves in \(y\) only, so a point put in the middle of a peak will be pulled up to sit under it and the peak will lose intensity to the baseline. With few reflections, or a strongly sloping background sampled by too few anchors, a fitted background and a broad low-angle peak describe the same data equally well and the refinement cannot tell them apart. Fit the background when the anchors are already close and you want their uncertainty in the ESDs; leave it fixed while the cell and the profile are still moving.

Simple pVoigt

This function models the peak shape as a linear combination of a Gaussian and a Lorentzian function: $pV(x) = \eta L(x) + (1-\eta)G(x)$. The angular dependence of the Full Width at Half Maximum (FWHM) for each component is modeled empirically. $$H_G^2 = GU \tan^2\theta + GV \tan\theta + GW + GP / \cos^2\theta$$ $$H_L = LX / \cos\theta$$

  • GU, GV, GW, GP: Parameters describing the Gaussian FWHM ($H_G$). The terms are associated with strain ($GU$), instrumental factors ($GV, GW$), and particle size effects ($GP$). Note that $GU$, $GW$, and $GP$ should physically be non-negative.
  • LX: Describes the Lorentzian FWHM ($H_L$), primarily associated with crystallite size broadening ($LX > 0$).
  • eta: A simple linear mixing parameter ($0 \le \eta \le 1$; $\eta=0$ for pure Gaussian, $\eta=1$ for pure Lorentzian).
  • shft & trns: Corrects for peak position shifts due to sample displacement and transparency, respectively.
    Unit and Scaling for the shft parameter:
    The refined shft parameter is a dimensionless, scaled coefficient, not a direct physical length. Its relationship to the physical specimen displacement ($s$) and the goniometer radius ($R$) is defined as follows:
    • The physical peak shift in radians is: $\Delta(2\theta)_{\text{rad}} = -2 \frac{s}{R} \cos(\theta)$
    • The program calculates this shift (in degrees) using the formula: $\Delta(2\theta)_{\text{deg}} = -(\text{shft} / 1000) \times \cos(\theta) \times (180 / \pi)$
    • Therefore, the relationship is: $\frac{\text{shft}}{1000} = \frac{2s}{R}$
    • To find the physical displacement $s$ from the refined parameter, use: $s = R \times (\text{shft} / 2000)$.
      Example: For a typical instrument with $R=240$ mm, a refined shft value of 1.0 corresponds to a physical displacement $s$ of $240 \times (1/2000) = 0.12$ mm.

TCH (Size/Strain/Aniso)

This is a physically rigorous profile function adapted from GSAS, convoluting a Thompson-Cox-Hastings (TCH) pseudo-Voigt with a Stephens model for anisotropic strain broadening.

Isotropic Broadening (TCH Model)

The TCH formulation models the FWHM of the Gaussian ($H_G$) and Lorentzian ($H_L$) components based on physical contributions to line broadening: $$H_G^2 = U \tan^2\theta + V \tan\theta + W$$ $$H_L = X \tan\theta + Y / \cos\theta$$

The total FWHM ($H$) and pseudo-Voigt mixing parameter ($\eta$) are then derived from these components using polynomial approximations. The final shape is $pV(x) = \eta L(x, H) + (1-\eta)G(x, H)$, where both functions share the same convoluted FWHM.

  • U, V, W: Gaussian broadening parameters related to strain ($U, V$) and instrumental resolution ($W$). Physically, $U$ and $W$ should be non-negative.
  • X, Y: Lorentzian broadening parameters related to strain ($X$) and crystallite size ($Y$). Physically, $X$ and $Y$ should be non-negative.

Peak Asymmetry

The S/L and H/L parameters introduce an angle-dependent asymmetry, primarily correcting for axial divergence effects at low $2\theta$.

Anisotropic Broadening (Stephens Model)

Anisotropic microstrain, where broadening varies with crystallographic direction, is modeled by adding terms to the Lorentzian component ($H_L$) that are dependent on the Miller indices ($hkl$). The model is a fourth-order polynomial in the reciprocal lattice vectors.

The refinable parameters (S400, S040, etc.) are the non-zero, symmetry-unique coefficients of this polynomial. The application automatically applies symmetry constraints based on the Laue class of the selected space group (e.g., for cubic, $S400=S040=S004$).

Unit and Scaling for Stephens S_hkl parameters:
The user-inputted S_hkl parameters are scaled for convenience. The dimensionless anisotropic broadening term ($H_{aniso}$) is calculated from these parameters, and its contribution to the total Lorentzian width (in degrees $2\theta$) is scaled by a factor of 1000. $$H_L(\text{total}) = H_L(\text{isotropic}) + \frac{|H_{aniso}|}{1000}$$ This scaling allows the user to refine values in a manageable range (e.g., -10 to +10) rather than requiring input of very small decimals (e.g., 1e-4), a convention common in other refinement software.

Split pVoigt (Asymmetric)

This profile function is a modification of the Simple pseudo-Voigt designed to model asymmetric peaks (e.g., from axial divergence or stacking faults). It achieves this by defining independent sets of profile width parameters for the left side (at $2\theta$ values less than the peak center) and the right side of the peak.

The shape is still a linear combination $pV(x) = \eta L(x) + (1-\eta)G(x)$, but the $H_G$ and $H_L$ parameters used in the calculation depend on whether $x$ is to the left or right of the peak center.

Gaussian Broadening (Left & Right)

The Gaussian FWHM ($H_G$) for each side is modeled as:

$$H_{G, \text{side}}^2 = GU_{\text{side}} \tan^2\theta + GV_{\text{side}} \tan\theta + GW_{\text{side}}$$

(Note: This model does not use the $GP$ term used in the Simple pVoigt profile.)

  • GU-L, GV-L, GW-L: Parameters describing the Gaussian FWHM for the left side of the peak.
  • GU-R, GV-R, GW-R: Parameters describing the Gaussian FWHM for the right side of the peak.

Lorentzian Broadening (Left & Right)

The Lorentzian FWHM ($H_L$) for each side is modeled as:

$$H_{L, \text{side}} = LX_{\text{side}} / \cos\theta$$

  • LX-L: Describes the Lorentzian FWHM for the left side, primarily associated with size broadening.
  • LX-R: Describes the Lorentzian FWHM for the right side, primarily associated with size broadening.

Peak Shape & Position

  • eta (Mixing) (param: eta_split): A simple linear mixing parameter ($0 \le \eta \le 1$; $\eta=0$ for pure Gaussian, $\eta=1$ for pure Lorentzian). This single value is used for both sides of the peak.
  • shft (Displ.) (param: shft_split): Corrects for peak position shifts due to sample displacement.
  • trns (Transp.) (param: trns_split): Corrects for peak position shifts due to transparency.
    Unit and Scaling for the shft_split parameter:
    This parameter is a dimensionless, scaled coefficient, identical in function to the shft parameter in the Simple pVoigt profile.
    • The physical peak shift in radians is: $\Delta(2\theta)_{\text{rad}} = -2 \frac{s}{R} \cos(\theta)$
    • The program calculates this shift (in degrees) using the formula: $\Delta(2\theta)_{\text{deg}} = -(\text{shft\_split} / 1000) \times \cos(\theta) \times (180 / \pi)$
    • Therefore, the relationship is: $\frac{\text{shft\_split}}{1000} = \frac{2s}{R}$
    • To find the physical displacement $s$ from the refined parameter, use: $s = R \times (\text{shft\_split} / 2000)$.

Forward Simulation: Calculating a Pattern from a Structure

Every other mode in this program starts from a measured pattern and works backwards. Le Bail and Pawley extract intensities from it; charge flipping and the Wyckoff search turn those intensities into a structure. Simulation runs the same physics forwards — atoms in, pattern out — and needs no data file at all.

It is selected from the Method box on the control panel (the block previously headed “Refinement”), where it sits last, after Levenberg–Marquardt and Parallel Tempering. Those two are minimisers; this one is not, and the controls that only make sense during a refinement hide themselves when it is chosen.

Nothing is lost when the fitting controls disappear. The Background, Charge Flipping and Wyckoff tabs, the Run buttons, the iteration count, the R-factor cards and every per-parameter Fit checkbox are hidden, never disabled and never removed. Their inputs keep their values, so switching into Simulation and back leaves your background anchors, your charge-flipping settings, your Wyckoff composition and every refinement flag exactly as they were. There is no separate store to save them into — the DOM is the store.

What it shares with the fit

The simulation contains no profile function, no background, no Lorentz–polarisation factor, no hkl generator and no peak-area integral. Every one of those already exists in this program, is already used by the refinement, and is called here unchanged:

StepFunctionWhere it lives
Reflections and systematic absencesgenerateAndCacheHklIndices()powder5.html
2θ and d for each reflectionupdateHklPositions()js/crystal.js
|F|2 → peak heightreflectionHeightsFromFsq()js/data_io.js
Heights → profilecalculatePatternCPU()js/profile.js
BackgroundcalculateTotalBackground()js/profile.js

This is the whole point of the design. The header of js/profile.js records what happened the last time this program had two implementations of the pattern: the preview drew one and the fit minimised another, and every report was self-consistent about the wrong answer. A simulation with its own profile function would be a third such copy, and the failure would be worse than a drifting fit — a simulated pattern that cannot be compared with a measured one is not a simulation of anything. Because the two share the chain, a simulated pattern and a Rietveld calculation of the same model are computed through identical code.

The only new physics

The one thing the fit did not already have is the structure factor. For each reflection, summed over every atom in the unit cell:

$$F(hkl) = \sum_j n_j\, f_j(s)\, \exp\!\left(-B_j s^2/4\right)\, \exp\!\left(2\pi i\,(hx_j + ky_j + lz_j)\right)$$

with $n_j$ the site occupancy, $f_j$ the atomic scattering factor and $B_j$ the isotropic displacement parameter. $|F|^2$ is then handed to reflectionHeightsFromFsq(), which applies the multiplicity, the Lorentz–polarisation factor and the Kα2 doublet exactly as the Pawley extraction does in reverse.

$s$ versus $s/2$. The Gaussian scattering coefficients are tabulated against $\mathrm{stol} = \sin\theta/\lambda = s/2$, where $s = 1/d$. The Debye–Waller factor uses the same argument, so $\exp(-B\,\mathrm{stol}^2) = \exp(-B s^2/4)$. Getting this wrong leaves $f(0)$ untouched — so it survives a casual check — while making every atom fall off at four times the correct rate.

Occupancy and the Debye–Waller factor both belong to the site and depend on the reflection only through $s$, so they are folded into the site's scattering factor once per reflection rather than once per atom. For a high-symmetry structure that is the difference between 192 exponentials and one.

The Atoms tab

A new tab appears in the left panel while Simulation is active. It holds the asymmetric unit — the only thing none of the other tabs already carry. The cell, the space group, the wavelengths, the zero point and the peak shape all come from the Sample and Profile tabs as usual.

Each atom is one collapsed line: its label, its Wyckoff position, and its fractional coordinates. Clicking the line expands it into the editable fields; clicking again folds it away. Expand all / Collapse all appears once there is more than one atom. A newly added atom opens automatically, since you are almost certainly about to adjust it; a structure loaded from a CIF arrives collapsed, because expanding fifty sites at once buries the thing you actually want to see.

The collapsed line keeps the coordinates visible because that is what gets compared down a list. Occupancy and $B$ appear there only when they differ from 1.000 and 0.50, so an unusual value stands out instead of being lost in twenty identical repetitions.

Every field is live: x, y, z, occupancy, $B_{iso}$ and the element are edited in place and the pattern follows through a short debounce. Watching an intensity change as an atom moves is how a structure gets understood, and no dialog that has to be opened and dismissed per edit can give you that.

Physical ranges

FieldRangeWhy
Occupancy0 to 1 A fraction of a site. Outside that interval it is not a small error but a different quantity.
$B_{iso}$0 to 10 Å2 Above roughly 10 the form factor has fallen so far by mid-angle that the atom stops contributing anything the pattern can show. Values above it are almost always a typo, or a $U$ entered into a $B$ box — note $B = 8\pi^2 U$, so a perfectly ordinary $U$ of 0.0063 becomes a $B$ of 0.50, while a $U$ mistaken for a $B$ gives 79.
Out-of-range values are clamped for the calculation immediately, and the box is corrected only on commit. Rewriting the field on every keystroke fights the typist: clearing it to type “0.75” passes through the empty string, and typing “10” into a field capped at 10 passes through “1”. So the value the pattern uses is always inside the physical range, while the text stays whatever you are typing until focus leaves or you press Enter — at which point the box is rewritten to the value that was actually used. The two can never disagree about the pattern at any moment, and can never disagree about anything once you stop typing.

Adding an atom

Add atom opens a picker. Type into the search box to filter the scattering table: T gives Ti, Ti2+, Ti3+, Ti4+, Tc, Te, Tb, Tm, Ta, Tl, Tl1+, Th. Ions are listed immediately after the neutral atom they came from rather than in a separate block, because someone typing “T” is looking for an element and then deciding its charge. Matching is on the prefix, not a substring, so typing O gives O and O2− and not Co, Mo, Ho and Po. Typing a complete label selects it, so Ti4+ followed by Enter adds the atom without touching the mouse.

The dialog shows, live, which Wyckoff position the coordinates you are entering will land on — you find out what the symmetry does to them before committing, rather than asserting a position and meeting the mismatch later in the pattern.

The Wyckoff position is derived, never entered

The letter beside each atom's name is computed from its coordinates and the current space group. It is not a label you assert. The pattern is calculated from the coordinates either way, so a typed letter could only ever be an assertion the coordinates might not support; showing the derived value instead makes the constraint visible. Move an atom onto a mirror and watch the multiplicity halve.

The multiplicity decides and the projection only breaks ties. The orbit of the point under the full operator set is the multiplicity — it is the number of atoms the structure factor will actually sum over — so the letter is looked up among the positions of that multiplicity and nowhere else. Several positions can share one multiplicity (Pnma has 4a, 4b and 4c), and those are separated by projecting onto each candidate's special_op. The test runs over every symmetry image of the point, not just the coordinates as typed, because special_op describes one representative: a point at $(0,0,\tfrac{1}{2})$ in $P112_1/a$ is on 2c, but its representative is $(\tfrac{1}{2},0,0)$ and only an image of the point ever reaches it.

One tolerance, used twice. The atom orbit and the Wyckoff letter are computed with the same distance tolerance, 0.02 Å. They have to be: if the orbit merged two images that the Wyckoff test called distinct, the panel would report a multiplicity the pattern was not computed with. A site on a mirror scatters half as strongly as one that is merely near it, so the disagreement would be a factor of two in that atom's contribution with nothing on screen to show for it. The practical consequence is that coordinates snap onto a special position within 0.02 Å — about 0.007 fractional in a 3 Å cell — so scanning an atom off a mirror has a discontinuity there.

Centring is handled by crossing the setting's sym_ops with its centring_translations and deduplicating, which is correct whether or not the database already folds centring into the operator list. Dropping the centring would not be a subtle error: an F-centred cell has four times the atoms of its primitive subgroup, so the pattern would come out with the right peak positions and uniformly wrong intensities — the hardest kind of error to see.

Load CIF

Load CIF reads an ordinary crystal-structure CIF and populates the atom list. It is a structure reader, not a pattern reader — parsePdCifFile() in js/data_io.js handles powder profiles, this handles the _atom_site_ loop and the cell.

  • Standard uncertainties are stripped, both from tags and from inside loops: 0.30478(5) is a value, not a syntax error.
  • Semicolon text fields are folded before parsing, so a publication title containing the words loop_ or data_ cannot derail the reader.
  • Only the first data block is read. Multi-block CIFs are common, and silently merging their atom lists would produce a structure that exists in none of them. The status line says how many blocks were found.
  • $U$ is converted to $B$ when the file carries _atom_site_U_iso_or_equiv, using $B = 8\pi^2 U$.
  • The scatterer is resolved from _atom_site_type_symbol first, verbatim, since ionic spellings such as Ti4+ already match the table. Failing that the charge is dropped, because a table without Ti4+ still scatters perfectly well as Ti and a site contributing nothing is a worse answer than one with a slightly wrong form factor. The site label is a last resort — Ca1 carries the element only by convention, and that convention breaks often enough (M1, OW) that guessing silently would be worse than reporting the site as unidentified. Two-letter readings are tried before one-letter ones, so OW1 resolves to O.

The cell and the space group are applied with the atoms. Fractional coordinates are fractions of a particular cell under a particular set of operators and mean nothing apart from those two, so the whole triple loads together. The space group goes first, because it decides which lattice boxes exist — a cubic group leaves only a, and writing the angles before the system is set would put them into inputs that are about to be destroyed.

An IT number does not name a setting. Space group 14 has six of them, with different operators and different absences from the same cell. The Hermann–Mauguin string picks the setting and the number only narrows the search; falling straight to the first listed setting would silently load P21/c for a file that said P21/n — a structure that still produces a perfectly plausible pattern.

Loading a CIF replaces the atom list. A CIF is one whole structure, and merging it into whatever was already there would build a phase that exists in neither file.

Pattern controls

ControlRangeMeaning
Step0.0001 to 0.1° Step of the calculated 2θ axis. Used only when no data file is open.
Background0 to 100 A flat background under the pattern, in the same units as Max intensity. Used only when no data file is open.
Noise0 to 10 Counting statistics, in units of themselves. See below. Used only when no data file is open.
Max intensity> 0 The pattern is normalised so its tallest peak reaches this height above background.
Match dataon / off With a pattern loaded, scale the simulation so its tallest peak sits on the tallest measured peak above background.

The 2θ range is the one on the Sample tab. Those sliders are normally disabled until a file is loaded, because outside Simulation they select a slice of the data; here they are enabled with no file open, since the range is the only thing that says how much pattern to compute. With data loaded they are left completely alone, which is what makes the simulated pattern come out on the same interval a fit would use.

Why the background and the noise switch off when a file is open. With a measurement on screen the background under the curve is the real one, from the spline; adding a synthetic constant on top of it would be inventing counts. And scattering a calculated curve that is being compared against data destroys the comparison. Both are tools for generating a synthetic dataset, which is a thing you do when there is no real one.
The step is capped at 20 000 points. 0.0001° across 5–120° is 1.15 million points, and the profile is the most expensive part of a redraw — that request would freeze the tab for the best part of a minute on every keystroke. The fine end of the range is meant for a narrow window, where it fits under the cap comfortably (0.0001° across 2° is exact). Ask for it across the whole pattern and you get the finest step that does fit, and the status line tells you which.

Counting noise

The physics settles the design here. A diffractometer counts photons, and photon counting is a Poisson process: the variance of a measured intensity is the intensity, so the scatter goes as $\sqrt{I}$. That single fact is what makes a simulated pattern behave like a real one — strong peaks noisy in absolute terms and clean in relative terms, weak peaks the other way round, and a background whose own scatter sets the detection limit.

Gaussian noise of one fixed width reproduces none of that. It would swamp the weak reflections and be invisible on the strong ones, and any program weighting by $1/\sigma^2$ — which is what a Rietveld refinement does — would be handed a wrong weight at every point.

So the field is expressed in units of the counting statistics themselves:

ValueMeaning
0A clean calculated curve. The default.
1Exactly the scatter a real detector would give for this many counts, $\sigma = \sqrt{I}$.
> 1A noisier measurement at the same intensity scale — a shorter count, a worse instrument.

Noise is applied to peaks plus background, because the detector counts both: a background of 10 carries its own scatter of about 3, and that is what sets how weak a peak can be and still be seen.

The draw is deterministic, and that is deliberate twice over. On screen, noise redrawn on every keystroke would make the whole curve shimmer while you type an occupancy — burying the change you are looking for in the one you are not. In the file, a synthetic dataset whose noise cannot be reproduced is a poor test case: with a fixed seed, a disagreement between two programs reading it is a disagreement about the programs and not about which random numbers each run happened to draw.
Gaussian approximation, not a true Poisson draw. A Poisson variate has no free width — its scatter is fixed by the count — so the only way to ask for “twice the noise at this intensity” is to widen a Gaussian. The approximation is good above roughly 10 counts, which is where the default background deliberately sits. Negative results are clipped to zero, since counts cannot be negative and some readers reject them; at default settings that fires on about 0.08% of points and biases those slightly upward, which is the honest trade against writing a physically impossible number.

Exporting: the report button writes a pdCIF

On the Plot tab, while the Method is Simulation, the report button produces a pdCIF instead of a PDF. Every other tab, and every other Method, prints exactly what it printed before.

A PDF of a calculated curve is a picture of something the program can state exactly, and the numbers are the point of a simulation — they are what gets compared against a measurement, fed to another program, or checked by hand. The file carries the 2θ axis, the intensities, the reflection list with |F|2, the cell, the space group with its Hall symbol, and the asymmetric unit.

SituationAngle tagIntensity tags
Noise = 0, no data file _pd_proc_2theta_corrected _pd_calc_intensity_total
Noise > 0, no data file _pd_meas_2theta_scan _pd_meas_intensity_total (noisy) and _pd_calc_intensity_total (clean)
Data file loaded _pd_meas_2theta_scan _pd_meas_intensity_total (your data) and _pd_calc_intensity_total (the simulation)

A simulation with no measurement must not claim one. _pd_meas_2theta_scan and _pd_meas_intensity_total are measured quantities; writing a calculated axis under a _meas_ tag with a column of ? beside it would state that a scan was performed and its intensities lost, which is a different thing from a scan that never happened.

With noise switched on, though, the pattern is a synthetic observation — that is what noise means — so it is written as the observed column with the noise-free curve alongside as the calculated one. That is exactly the pair another Rietveld program needs: fit the observation, and check that it recovers the model that produced it. The block carries an explicit “these intensities are SIMULATED, not measured” comment, because tags alone would be indistinguishable from a real scan and a file that quietly claims to be a measurement is the kind of thing that ends up in a paper.

The atom-site loop uses standard core-CIF tags rather than pdCIF ones, which is correct: the structural model and the powder profile are different dictionaries describing the same block, exactly as in a Rietveld pdCIF. $B$ is written rather than $U$, because $B$ is what the panel holds and what the structure factor used; converting here would put a different number in the file from the one the pattern was computed with, distinguishable only by knowing which convention the writer chose. _atom_site_Wyckoff_symbol gets the letter and _atom_site_symmetry_multiplicity gets the number, per the dictionary.

The file this program writes is a file this program can read. parsePdCifFile() previously required a measured intensity column and would reject a noise-free simulation — the writer and the reader disagreed about what a valid file is. The calculated column now serves as the profile when there is no measured one, without being double-reported as a fit.

Scattering factors

Tables live in scatters/, with index.json naming what is available and which is preferred. They are five-term Gaussian parameterisations, $f(\mathrm{stol}) = c + \sum_i a_i \exp(-b_i\,\mathrm{stol}^2)$, loaded lazily on first entry into Simulation so that a user who never opens it pays nothing.

The picker lists exactly what is tabulated, which is the quickest way to find out whether a particular ion is present. Not every oxidation state is: the ion lists in these tables are finite, and a highly charged cation such as S6+ is often absent. That is usually not a problem. A bare S6+ is a closed-shell Ne core, which describes a covalently bonded sulfate sulfur poorly, and the difference between the ionic and neutral form factors is confined to low $\sin\theta/\lambda$ — well below what a powder pattern distinguishes. Neutral S is standard practice for sulfates. If an ion you want is missing from the preferred table, the other table in scatters/ has a different ion list.

A missing scatterer contributes nothing, and says so. The status line names any label that could not be found rather than silently substituting a point atom. Point atoms are not a degraded pattern, they are a different one — no angular fall-off means every high-angle reflection comes out several times too strong — and a user comparing that against a measurement would read the discrepancy as a wrong structure.

Only X-ray scattering is wired up. The neutron table loads but there is no radiation selector, so neutron simulation is not yet available.

Reading the plot

The simulation draws into the chart's existing Simulation dataset rather than adding a tenth curve — that dataset already means “a pattern computed from the model rather than fitted to the data”, and a second curve with the same meaning could only ever disagree with the first.

With no atoms defined the plot falls back to a stick pattern of reflection positions. That is the honest answer as well as a convenient one: with no atoms, the positions are the whole of what the model predicts.

Above 2000 reflections the Kα tick strip shows only the strongest, and the status line says how many were omitted. The pattern always uses all of them — the cap is on the tick marks only. Past that density the ticks are a solid band that tells the eye nothing, while handing the renderer one layout element per reflection is what turns a large cell over a wide range from slow into unusable.

Right-click resets the view, as everywhere else. With no data file open the simulation restores its own axes, since the usual machinery needs a loaded pattern to work out the vertical extent.

The session log

Entering and leaving Simulation is logged, along with the full model at the moment of entry; so is every atom added, edited, removed or loaded from a CIF, and every pdCIF written. Edits are logged on commit rather than per keystroke — a line for every character typed into a coordinate box is not a record of what you did, it is a record of you typing, and it would bury the entries that matter.

Limitations

The simulation is deliberately a simple one. It is a forward calculation of an ideal powder from an ideal specimen, and the following are not modelled:

Not modelledConsequence
Preferred orientation Intensities are those of a perfectly random powder. Plate-like or needle-like specimens will not match.
Absorption and microabsorption No $\mu R$ correction; no allowance for contrast between phases.
Anomalous dispersion ($f'$, $f''$) Form factors are the real, wavelength-independent tabulated values. Near an absorption edge this is wrong, and Friedel pairs are exactly equal regardless.
Anisotropic displacement parameters One isotropic $B$ per site. A structure with strongly anisotropic motion will show intensity errors that grow with angle.
Multiple phases One structure at a time. There is no phase-fraction machinery.
Charge balance Occupancies are whatever you type. Nothing checks that the composition is electroneutral or that partial occupancies on shared sites sum sensibly.
Neutron scattering X-ray only, as noted above.

What it is good for: checking that a candidate structure produces the pattern you measured, seeing which reflections a particular atom controls, generating clean or noisy test data for other software, and building intuition about how coordinates, occupancies and displacement parameters move intensity around.

Probabilistic Space-Group Determination

Once a Pawley refinement has completed, a small ? button becomes active on the space-group line of the control panel. It scores every space group compatible with the current Laue class against the extracted intensities and returns a ranked list of posterior probabilities. The method follows Markvardsen, David, Johnson & Shankland (2001).

The Principle

A candidate space group $S$ makes exactly one testable statement about a powder pattern: a particular subset $e$ of the reflections is systematically absent, so their true integrated intensities are identically zero. Everything else it leaves free. The question is therefore not “does this space group fit?” but “are the reflections it forbids consistent with zero, given how well the data actually determine them?”

A Pawley refinement is what makes this answerable. Because every intensity is a free least-squares parameter, the refinement returns not only the intensities $\hat{\mathbf{I}}$ but the normal matrix behind them, and therefore their full covariance. That matters enormously: in a powder pattern reflections overlap, and overlapping intensities are strongly correlated. A reflection that should be absent can carry a large apparent intensity purely by borrowing it from a neighbour it cannot be resolved from. Judging each reflection on its own $I/\sigma$ ignores this and can be badly misleading in either direction.

Why Le Bail cannot be used here. Le Bail intensities are not least-squares parameters - they are re-partitioned from the observed profile at each cycle. They have no normal matrix and no covariance, so there is no way to ask how well any of them is determined. The test therefore requires a Pawley refinement run with the Levenberg-Marquardt algorithm; the button stays disabled otherwise.

The Statistical Model

The true intensities are given a prior that encodes what the space group claims. Writing $\mathbf{P}_S$ for a diagonal matrix,

$$\mathbf{I} \sim N(\mathbf{0}, \mathbf{P}_S), \qquad (\mathbf{P}_S)_{jj} = \begin{cases} 0 & j \text{ absent under } S \\ \tau_j^2 & \text{otherwise} \end{cases}$$

A variance of exactly zero forces that intensity to vanish; $\tau_j$ is the local Wilson-like intensity scale for reflections the group allows. The refinement itself contributes $\hat{\mathbf{I}} \mid \mathbf{I} \sim N(\mathbf{I}, \mathbf{Q}^{-1})$, where $\mathbf{Q}$ is the intensity precision matrix. Marginalising over the unknown true intensities collapses these into a single multivariate normal,

$$\hat{\mathbf{I}} \sim N\!\left(\mathbf{0},\; \mathbf{Q}^{-1} + \mathbf{P}_S\right)$$

so the evidence for $S$ is one density evaluation. Writing $f$ for the set of reflections the group allows and dropping every term that does not depend on $S$:

$$-2\ln P(D \mid S) = \sum_{j \in f} \ln \tau_j^2 \;+\; \ln \det \mathbf{B}_S \;-\; \mathbf{b}_S^{\mathsf{T}} \mathbf{B}_S^{-1} \mathbf{b}_S$$ $$\mathbf{B}_S = \mathbf{Q}_{ff} + \operatorname{diag}(1/\tau_f^2), \qquad \mathbf{b}_S = (\mathbf{Q}\hat{\mathbf{I}})_f$$

The quadratic form is the evidence carried by the would-be-absent reflections, evaluated with the full correlation structure rather than reflection by reflection. The log-determinant is an Occam factor: it rewards a group for explaining more absences, and without it the group with no extinction conditions at all would win by construction, since it is never contradicted by anything.

Posterior probabilities follow by normalising over the candidate list.

Reading the Result

Each row of the table is a distinct extinction symbol, not a single space group. Powder diffraction cannot separate groups that predict identical absences - centrosymmetric and non-centrosymmetric pairs, for instance - so those share one probability and are listed together. Clicking any symbol adopts that setting. Note that the setting matters: $Pnma$ and $Pbnm$ are the same group but predict different absences relative to the fixed axes, so they appear separately.

  • P(SG | data) - the posterior for that extinction symbol.
  • absent - how many of the refined reflections the group forbids. A group forbidding nothing is always in the list as a baseline.
  • ⟨I/σ⟩ and worst I/σ - diagnostics over the would-be-absent set, using diagonal errors only. These are the numbers a crystallographer looks at first, but they are not what drives the ranking; the probability uses the full correlation structure.

Requirements and Limitations

Run the Pawley refinement in a condition-free group. A reflection can only be tested if it was actually a parameter of the fit. If the refinement is run in, say, $Pnma$, every reflection $Pnma$ forbids was never refined and carries no information - so the test is blind exactly where it matters. Use the group of the correct Laue class that imposes no reflection conditions: $P\bar{1}$, $P2/m$, $Pmmm$, $P4/m$, $P4/mmm$, $P\bar{3}$, $P\bar{3}m1$, $P6/m$, $P6/mmm$, $Pm\bar{3}$ or $Pm\bar{3}m$. The test detects this situation, names the group you should re-run in, and marks affected candidates as partial.

Two further points are worth keeping in mind.

  • The Laue class is not under test. Only the absences are. The Laue class is fixed by the diffraction symmetry you have already chosen, since it determines the reflection orbits and the multiplicities. Running the test from $Pm\bar{3}m$ can never return a group belonging to Laue class $m\bar{3}$, such as $Pa\bar{3}$. If the Laue class itself is in doubt, run the test from each candidate in turn.
  • Exact reflection coincidences are handled, but weaken the diagnostics. In cubic and rhombohedral cells reflections such as $(333)/(511)$ or $(300)/(221)$ fall at identical $2\theta$. Their individual intensities are then not separately determined and no covariance matrix exists. The test is formulated in precision space precisely so that it does not need one - $\mathbf{Q}$ may be singular while $\mathbf{B}_S$ never is - so the probabilities remain valid. The $I/\sigma$ columns fall back to conditional estimates in this case and are flagged as such.
Implementation notes. The intensity block is marginalised over the lattice, profile and background parameters via a Schur complement, so their uncertainties are folded in rather than treated as exactly known. The scale $\tau$ is estimated separately for each candidate from the reflections that candidate says are present: a single global estimate collapses in centred lattices, where most reflections are genuinely absent, and would then stop rewarding the group that correctly explains them. The original paper uses a Wilson (exponential) intensity prior; a Gaussian of the same scale is used here because it makes the marginalisation exact in closed form. Rankings are essentially unchanged, but absolute probabilities should be read as approximate.

Ab Initio Structure Solution: Charge Flipping

Once a Pawley refinement has extracted a set of individual integrated intensities, Powder 5 can attempt to solve the crystal structure ab initio - with no starting model - using the dual-space charge-flipping algorithm of Oszlányi and Sütő. The result is an electron-density map and a list of atomic positions, obtained purely from the diffraction intensities and the unit cell.

Charge Flipping is only available after a converged Pawley fit. The tab stays disabled until one exists, because the method needs the individual reflection intensities that only Pawley - not Le Bail - provides, together with the normal matrix produced by a Levenberg-Marquardt step (Parallel Tempering supplies this through its LM polish).

The Principle

A diffraction experiment measures the amplitudes \(|F_{hkl}|\) but not the phases \(\phi_{hkl}\); recovering those phases is the phase problem. Charge flipping solves it by iterating between real space (the electron density \(\rho\)) and reciprocal space (the structure factors \(F\)), enforcing one simple constraint in each:

  1. Real space. A correct electron density is non-negative almost everywhere. Every voxel whose density falls below a small positive threshold \(\delta\) has its sign flipped: \(\rho \rightarrow -\rho\). This deliberately wrong perturbation is what drives the phases toward consistency.
  2. Reciprocal space. Fourier-transform the flipped density, then reimpose everything that is actually known about the structure factors: the measured amplitudes, the point-group symmetry, and the systematic absences. The calculated phases are kept. Reflections that were never measured are left free - that freedom is what lets the map extend beyond the data.

Transforming back gives an improved density, and the cycle repeats. The threshold is expressed in units of the map's own RMS density \(\sigma\), so \(\delta\) is scale-independent; values around \(0.8\sigma\)–\(1.2\sigma\) work for most problems. The agreement between calculated and observed amplitudes,

\( R = \dfrac{\sum_{c} \left| \sqrt{I^{calc}_{c}} - \sqrt{I^{obs}_{c}} \right|}{\sum_{c} \sqrt{I^{obs}_{c}}} \)

is tracked each iteration. The sum runs over measured peaks \(c\), not over individual reflections: a powder pattern cannot distinguish reflections that overlap in \(2\theta\), so scoring them separately would be scoring noise. \(I^{calc}_{c}\) is the total calculated intensity of everything under peak \(c\). A run that has found the structure typically drops below \(R \approx 0.15\) and then oscillates. Powder 5 keeps the best iterate of the run, not the last.

Space-Group Constraints

Classical charge flipping deliberately works in \(P1\): it throws the symmetry away and lets the algorithm rediscover it, which is a useful safeguard when the space group is uncertain. Powder 5 keeps that mode available, but by default it uses the selected space group inside the iteration. Five separate constraints come out of it, and they are worth distinguishing because they behave very differently.

1. Orbits: symmetry equivalents share one intensity

A Pawley fit reports one intensity per symmetry-unique reflection. Its equivalents \(hR\) must be placed on the \(P1\) grid before a transform is possible, and they are generated from the actual symmetry operators of the selected group. The distinction matters: the Laue class is not the holohedry of the crystal system. \(P4\) has Laue class \(4/m\), so a general reflection has 8 equivalents, not the 16 that \(4/mmm\) would give; the same applies to \(\bar 3\) versus \(\bar 3 m\), \(6/m\) versus \(6/mmm\) and \(m\bar 3\) versus \(m\bar 3 m\). Spreading one measured intensity over twice as many positions as really exist puts half of it onto reflections that are not equivalent at all.

Within an orbit the amplitudes are equal by symmetry: \(|F| = \sqrt{I^{obs}/m}\), where \(m\) is the orbit size. This is a hard constraint, applied every cycle. Only the phases are free.

2. Overlap: distinct reflections may share one peak

The genuinely powder-specific ambiguity is different. Reflections that are not symmetry equivalent can still fall at the same \(2\theta\), either exactly (511/333 in a cubic cell) or accidentally. The pattern gives only their sum. Powder 5 groups such reflections into a cluster and re-partitions the cluster's total intensity between them each cycle in proportion to the current calculated values - the same idea as Le Bail extraction, applied inside the flipping loop. The split is free; the total is fixed.

These two mechanisms are easy to confuse and they pull in opposite directions. Symmetry equivalents must be equal (constraint); overlapping distinct reflections are free to differ (unknown). Letting the members of an orbit float would discard exactly the information the space group provides.

3. Systematic absences are excluded and held at zero

Reflections forbidden by lattice centring, screw axes or glide planes are removed before the charge-flipping orbits are built, and their reciprocal-grid points are forced to \(F = 0\) every cycle. They are found directly from the operators: \(h\) is extinct if some operator \((R,\mathbf{t})\) satisfies \(hR = h\) with \(h \cdot \mathbf{t}\) non-integral. Leaving them free lets the density break the lattice centring outright, and for an \(F\) or \(I\) lattice that is most of the reciprocal grid.

The raw, signed Pawley area and its ESD are retained long enough to test the selected space group. A forbidden fitted HKL never becomes an ordinary CF reflection. If it overlaps an allowed reflection, however, its corrected intensity remains in the measured cluster total and is re-partitioned only among the allowed orbits; this preserves what the powder peak measured without assigning amplitude to a forbidden reciprocal point.

An isolated forbidden reflection with raw \(I/\sigma \geq 3\) is inconsistent with strict symmetry. A Strict run (\(\lambda = 1\)) is therefore refused and names an example. None or Damped symmetry may still be run for diagnosis, and the result records how many forbidden fitted HKLs were excluded, transferred from overlapping clusters, and significant while isolated.

4. Symmetrisation of the phases

For a real-space operator \(\mathbf{x}' = \mathbf{x}R + \mathbf{t}\), the structure factors of a correctly positioned structure satisfy

\( F(hR) = F(h)\,\exp(-2\pi i\, h \cdot \mathbf{t}) \)

Each cycle the members of an orbit are reduced to a common representative, averaged, and pushed back out. The Symmetry in loop control sets how strongly: \(F \leftarrow (1-\lambda)F + \lambda F_{sym}\). At \(\lambda = 0\) nothing is imposed and the run is classical \(P1\) charge flipping. At \(\lambda = 1\) the projection is exact, which converges faster and has a useful side effect: the solution comes out on a standard origin instead of a random one, so the automatic origin search in the Structure block becomes a verification rather than a necessity.

The trade-off. Strict symmetry cannot recover from a wrong space group - it will happily converge to a low \(R\) for a structure that does not exist. If the group is uncertain, run at \(\lambda = 0\) as well and compare: a density that is genuinely consistent with the group will symmetrise well afterwards (high symmetry correlation) without having been forced to.
Full translations are required for in-loop phase symmetry. If the space-group database does not supply complete sym_ops, Powder 5 may still use Laue rotations to expand equivalent amplitudes, but it forces the effective \(\lambda\) to 0. Applying a non-zero \(\lambda\) with zero translations would impose wrong phase relations in a nonsymmorphic group. The result reports the value actually used.

5. Weak reflections are freed, not forced

The rules above impose \(|F_{\text{obs}}|\) on every ordinary reflection. The Weak Fraction control exempts the selected weakest units: their calculated moduli are kept and their phases are advanced by a constant \(\Delta\varphi = \pi/2\) each cycle instead (Oszlányi & Sütő, 2005). Their measured intensity is then used only for the knowledge that they are weak.

Weak classification chooses those units. The default, Unresolved clusters, ranks each measured peak cluster by its total observed intensity per reciprocal-grid member and assigns the same immutable weak flag to every orbit in a selected cluster. This avoids classifying an arbitrary, dynamically changing overlap partition as if it were an independent measurement. Individual reflections instead ranks each orbit by its own initial target intensity per orbit member. In both modes the classification is made once before iteration and cannot change as overlaps are re-partitioned.

The \(\pi/2\) rotation perturbs the iteration and can help it escape the flat, featureless maps the 2004 algorithm can settle into. The CPU and WebGPU paths apply the same immutable classification and phase operation, including the conjugate mate needed for a real density map.

This is a different mechanism from the overlap handling in rule 2, and the two are not alternatives. Overlap re-partitioning frees a reflection's share of a cluster while holding the cluster total; the weak flip frees a reflection's modulus entirely and perturbs its phase. A reflection can be subject to both.

Intensity scaling

The refined Pawley parameter is a peak height, because the profile functions Powder 5 uses are normalised to unit height, not unit area. What charge flipping needs is the integrated intensity, so each height is multiplied by the area of its own profile (summed over the Kα1/Kα2 doublet) before it is used. Skipping that step underweights the high-angle reflections by the full Caglioti broadening, which is roughly a factor of two across a typical scan.

The signed fitted height is preserved during that conversion. In particular, a negative Pawley estimate is not clipped before French–Wilson correction: both the integrated value and its ESD are transformed by the same profile-area factor, so weak and negative observations retain their statistical meaning. If French–Wilson cannot be applied, only then are non-positive amplitudes unavailable to the CF modulus constraint, and the result reports that fact.

The integrated intensity then carries \(I \propto m \cdot LP \cdot |F|^2\). The multiplicity \(m\) is absorbed by spreading the intensity across the \(m\) grid points of the orbit, but the Lorentz-polarisation factor \(LP = (1+\cos^2 2\theta)/(2\sin^2\theta\cos\theta)\) is divided out explicitly. Without it the low-angle reflections are weighted several times too heavily and the map is dominated by the first few peaks.

All of this needs the full symmetry operators, i.e. the sym_ops field of the space-group database. If they are missing, Powder 5 falls back to a Laue-class table with no translations: equivalent amplitudes can still be expanded, but screw and glide absences cannot be detected and in-loop phase symmetrisation is disabled by forcing the effective \(\lambda\) to 0. The solution summary states the expansion source and the symmetry strength actually used.

Workflow & Controls

The controls sit in the left panel; results appear in the Charge Flipping tab of the right panel.

ControlMeaning
Grid Size (N³)Edge of the density grid. Must be a power of two (the FFT is radix-2). 32³ is fast and usually sufficient; 64³ and 128³ resolve finer detail at rapidly increasing cost.
Threshold (δ/σ)Flipping level in units of the map RMS. 0 flips every negative voxel and rarely converges; 0.8–1.2 is the working range.
Max IterationsCycles per random start. A few hundred to ~1000 is typical.
Random StartsThe method begins from random phases and does not converge every time. Each start is an independent trial; the map with the lowest measured-cluster amplitude R is kept.
Peak Merge (Å)Maxima closer than this are treated as one atom.
Symmetry in loopHow strongly the space group is imposed on the structure factors each cycle (\(\lambda\), see Space-Group Constraints). None is classical \(P1\) charge flipping; Damped (\(\lambda = 0.5\)) is the default; Strict (\(\lambda = 1\)) is fastest and fixes the origin, but assumes the space group is right.
Weak classificationUnresolved clusters (default) selects whole measured peak clusters as weak; Individual reflections selects separate symmetry orbits. Classification uses the initial observed targets and remains fixed throughout the run.
Weak FractionThe weakest this fraction of the selected classification units keep their calculated moduli and have their phases advanced by \(\pi/2\) each cycle instead of being forced onto \(|F_{\text{obs}}|\) (see rule 5). Range 0–0.33, default 0.15. At 0 the readout says off, and the run is the original 2004 algorithm.
Overlap (°2θ)Reflections closer than this in \(2\theta\) are treated as one measured peak and share their intensity dynamically. Exact overlaps are always caught regardless of the setting. Symmetry equivalents are unaffected - they are constrained to equal \(|F|\).
A live time estimate is shown beneath the controls. Because the transform dominates the cost and scales as \(N^3\log N\), moving from 64³ to 128³ is roughly an eight-fold increase in run time. The iteration runs inside a Web Worker so the interface stays responsive, and it uses WebGPU when the browser provides it - the entire dual-space loop executes on the GPU, uploading the grid once and reading it back once, which is many times faster than the CPU for the transform-heavy inner loop. On browsers or devices without WebGPU it falls back automatically to an equivalent CPU implementation. The two paths run the same algorithm in the same order, but the GPU works in single precision and the CPU in double, so the maps agree closely rather than exactly; a difference in the last digit of \(R\) between backends is normal. The reported Compute field in the solution shows which path was used. Every control affects both backends alike - including Weak Fraction and Weak classification, which are implemented in the CPU loop as well, so a machine without WebGPU does not quietly solve a different problem. The threshold itself is computed identically on both. The GPU path requires the file charge_flipping.wgsl to be served alongside charge_flipping_worker.js; if it fails to load or compile, a message says so and the run continues on the CPU rather than failing.
Stopping keeps what has finished. The Stop button ends the run and reports the best of the trials that completed; only the trial still in flight is lost. The run appears in the history labelled stopped.
Sync batching is measured, not assumed. The GPU path chooses the best iterate on the device and reads the R factor back in batches, so the host is not a bottleneck. How many cycles may be queued before a sync is decided by timing the previous batch: too few and the run is dominated by round-trip latency, too many and the GPU spends seconds in one uninterrupted burst, which is how a driver watchdog decides the device has stopped responding and resets it. The controller starts at one cycle, so the first measurement is safe on any device, and sizes from a decaying worst-case estimate so a device that slows down mid-run - thermal throttling, another application taking the GPU - is caught before the next burst rather than after it. A device loss is now detected and reported; previously a reset left a pending read that never settled, and the run hung with no error at all.

Recommended Settings

The defaults are chosen to solve a typical small inorganic structure from good laboratory data. The table below is a starting point by problem type; the paragraphs after it explain what to change when a run fails.

SituationGridδ/σIterationsStartsλOverlap
First attempt (space group known, \(d_{min}\) ~1.0 Å)32³1.150030.50.05°
Small cell (\(V \lesssim 500\) Å³, few atoms)32³1.0–1.1300–50031.00.05°
Medium cell (500–2000 Å³)64³1.0–1.2100050.50.05°
Large / organic cell (>2000 Å³)64–128³0.9–1.11500–300010–200.50.08°
Space group uncertain32–64³1.110001000.05°
Heavy overlap (high symmetry, broad peaks)as above1.11500101.00.10–0.15°
Poor / low-resolution data (\(d_{min} > 1.5\) Å)32³0.8–1.02000201.00.10°

Choosing the grid

The grid must be large enough to hold every reflection in the fit: an index \(h_{max}\) needs \(N \geq 2h_{max}+2\). If it is too small the summary reports how many reflections did not fit and what \(N\) they would need, and those reflections are simply lost. Beyond that requirement, aim for a voxel of roughly 0.25–0.35 Å (the summary prints the spacing). Finer than ~0.2 Å buys nothing when the data stop at 1 Å resolution and costs \(N^3\log N\): 64³ to 128³ is about an eight-fold increase in run time.

A 128³ grid holds about 50 MB of GPU memory and pushes several dispatches close to the WebGPU ceiling of 65535 workgroups per dimension. Powder 5 checks every dispatch against the adapter's reported limits before it encodes anything; if the device cannot take the grid, the run falls back to the CPU with a message saying so rather than producing a map that was never computed. The CPU path at 128³ is slow - expect minutes per random start - so on a constrained device it is usually better to stay at 64³.

Choosing the threshold

\(\delta/\sigma\) is the single most sensitive parameter. Too low and almost nothing is flipped, so the iteration stalls with \(R\) flat and high; too high and the perturbation is so violent that the phases never settle, giving an \(R\) that jumps around without trend. The working range is 0.8–1.2 and 1.1 is a good default. If \(R\) plateaus above 0.3 with no oscillation, lower it in steps of 0.1; if \(R\) is erratic from the first cycles, raise it. Weak or noisy data generally want a slightly lower threshold.

Iterations and random starts

Charge flipping does not converge gradually - it stays flat and then drops abruptly when the phases lock in, often after several hundred cycles. Judge a run by whether that drop happened, not by the final \(R\). More starts is usually a better investment than more iterations: a run that has not found the solution by ~1000 cycles is unlikely to find it by 3000, whereas a fresh random start might find it immediately. For a difficult problem, 10–20 starts of 1000 cycles beats 2 starts of 10000.

Choosing λ

Use \(\lambda = 1\) when the space group is established (a clean space-group test, a known compound, an unambiguous extinction pattern): it converges in fewer cycles, needs fewer random starts, and delivers the map already on a standard origin. Use \(\lambda = 0\) when the group is in doubt, or as an independent check on a \(\lambda = 1\) solution - if the \(P1\) map symmetrises to a high correlation without having been forced to, the group is right. \(\lambda = 0.5\) is the compromise and the default: it accelerates convergence appreciably while still allowing the density to disagree with a slightly wrong group.

Choosing the overlap tolerance

Set it to roughly half the FWHM of a mid-angle peak. Too small and truly overlapped reflections are treated as independently measured, which imposes intensities the data never determined; too large and reflections that were resolved get to trade intensity freely, discarding real information. 0.05° suits sharp laboratory data; broad peaks or a high-symmetry cell with many coincidences want 0.10–0.15°. The summary reports how many reflections ended up sharing a peak - if that number is close to the total, the tolerance is almost certainly too large.

Order of attack when a run fails. (1) Check the reflection-count warnings: a grid too small, or intensities on systematically absent reflections, are input problems and no parameter will fix them. (2) Add random starts. (3) Adjust \(\delta/\sigma\) by ±0.1. (4) Try \(\lambda = 0\) and \(\lambda = 1\) - a solution that appears at \(\lambda = 0\) but not at \(\lambda = 1\) is telling you the space group is wrong. (5) Only then increase the grid or the iteration count.

Choosing the weak fraction

Scan it; do not tune it. The published range is broad - the precursor experiment worked with anything from 10% to 50% of the data inside the resolution sphere - so the setting has a plateau rather than an optimum. Try 0, 0.10, 0.20 and 0.30 and compare across all random starts, not one. If 0.15 and 0.20 give visibly different answers, that difference is trial-to-trial scatter and not the parameter.

With the default cluster classification, the fraction is a fraction of unresolved peak clusters, not a fraction of individual HKLs. Exactly \(\lfloor fN\rfloor\) clusters are selected after ranking their total observed intensity per reciprocal-grid member; every orbit in those clusters receives the weak operation. Consequently the reported number of phase-shifted orbits can exceed the number of selected clusters. Individual mode instead selects exactly \(\lfloor fN\rfloor\) reflection orbits by initial target intensity per orbit member. Neither membership changes during the run.

A run at 0 and a run at 0.15 are the 2004 and 2005 algorithms and are not trials of the same thing. The result therefore records the fraction, the classification mode, the selected-unit count and the number of affected orbits rather than leaving them to memory.

Reading the Solution

Each run appends a timestamped entry to the Charge Flipping history, so earlier attempts remain available from the run selector. A solution contains:

  • Best R. The amplitude agreement of the retained map, summed over measured peaks. Below ~0.15 is promising; above ~0.30 usually means the run has not converged - add random starts, adjust the threshold by ±0.1σ, or see Recommended Settings.
  • Electron-density peaks. Fractional coordinates. At \(\lambda = 0\) the map is in \(P1\) with an arbitrary origin and hand, so absolute positions are meaningless - compare interatomic distances. At \(\lambda > 0\) the origin is pinned by the symmetrisation and the coordinates are directly comparable to the space group's Wyckoff positions. Read the Charge column, not Height, to tell a heavy atom from a light one - see the column descriptions for why height gets this backwards.
  • Symmetry and absence diagnostics. The summary reports whether full operators or a Laue fallback expanded the data, the requested and effective in-loop symmetry, how many reciprocal points were forced to zero, how many forbidden fitted HKLs were excluded from the CF orbits, how many of those shared a cluster whose intensity was transferred to allowed orbits, and how many isolated ones had raw \(I/\sigma \geq 3\). A large systematic-zero count is normal for a centred lattice. A significant isolated forbidden observation is a direct inconsistency to investigate; a forbidden HKL inside an unresolved allowed peak may instead be an artefact of the Pawley partition.
  • Density section. A slice through the map, with selectable axis and depth. The colour bar under the image is an absolute scale taken from the whole map, not from the slice on screen, so slices are directly comparable and an empty one looks empty. The caption gives the slice maximum in units of the map's \(\sigma\); anything under about 3σ is ripple, not an atom. The Stretch each slice to its own range checkbox restores per-slice auto-contrast, which is occasionally useful for tracing weak features but makes noise look like structure - the caption says so whenever it is on.
  • 3D isosurface. The same map drawn as a surface of constant density, at a level you set in units of the map's \(\sigma\) — the same units as the section caption, so the two views can be read against each other. Drag to rotate, scroll to zoom. At 1–2σ you will see mostly noise; real atoms usually appear as isolated closed blobs somewhere above 3σ.
    • As solved is the raw charge-flipping density, exactly what the algorithm produced.
    • Symmetry-averaged is the same density after the Structure step has shifted it onto the space-group origin and averaged it over the symmetry operators. It is much cleaner, because averaging \(n\) equivalent copies of the cell suppresses the noise by \(\sqrt{n}\) — but it assumes the space group is right, so judge the solution on the raw map and use this one to read it. It only becomes selectable once the structure has been built.
    • None (atoms only) draws no density at all - just the cell edges and the atom spheres. Once the map has done its job and you trust the solution, the surface is mostly in the way: it hides the spheres it is there to justify, and judging bond geometry or spotting an impossible contact is far easier without it. Selecting it greys out the Level slider, since there is nothing for it to act on.

      This is also the fastest option, not merely the tidiest: the surface extraction is skipped outright rather than being computed and hidden, so switching to it is instant even at 128³. The atom coordinates are those of the symmetry-averaged frame, the same as for Symmetry-averaged - with no map on screen there is nothing for them to be aligned against, so the structure's own frame is the only meaningful choice.

    • Atom positions is a list under the viewer controls, one row per unique site from the Structure block: rank, colour, peak height, multiplicity, and a show/hide toggle. Every site starts hidden, so the density can be judged on its own first; click a row to bring one in, or use hide all / show all. Ten rows are shown at a time and the list scrolls beyond that. The header counts what is visible, and the caption under the viewer says how many positions are drawn and how many sites are hidden. Two buttons sit on the row beneath the header, each under the column it acts on: reset colours on the left, over the swatches, and hide all on the right, over the visibility markers.

      Each site is drawn expanded over the symmetry operators: a site of multiplicity 4 appears four times, once beside each of its four density lobes, and hiding its row removes the whole orbit at once. The Structure table lists only one representative per orbit, so drawing that list directly would leave most of the lobes bare. The sphere radius follows the peak height, so in PbSO4 the four Pb lobes are obvious against the lighter atoms.

      Site colours can be changed. The swatch in each row is a colour picker: click it and the spheres recolour as you drag, so you can match the picture to what you believe the structure to be. The default palette holds sixteen distinct colours, enough that a solution with more than eight sites does not reuse one, but the defaults carry no chemical meaning - they are assigned in order of peak height and nothing more. That is exactly why recolouring is useful: charge flipping gives you density, not elements (see the note under Building a Structure), so the identification of which lobe is which atom is yours to make, and colour is the natural way to record it. Giving the two sites you read as oxygen the same red, or the heavy atom a colour that stands out from its neighbours, makes a crowded cell legible in a way the rank ordering cannot.

      The colour belongs to the site, not to the individual sphere, so every symmetry image of that atom follows at once - the same grouping the show/hide toggle uses. Clicking the swatch opens the picker without hiding the row, so recolouring and hiding stay independent. Reset colours puts every site back to its palette default and is available only once something has actually been changed.

      Nothing has been least-squares refined at this stage; these are located peaks. Seeing them sit centred inside the density lobes is the quickest visual confirmation that the solution hangs together, and bringing them in one at a time is the easiest way to tell which lobe belongs to which site when the cell is crowded.

    The three cell edges meeting at the origin are coloured and labelled a / b / c, so you can tell which axis you are looking down.

The two buttons beside the section viewer write the peak list (.csv) and the full density grid (.grd); the refined sites are exported separately, from the button under the Structure block.

Site colours are a viewing aid only. They are not written to the .cif, the .csv or the report, and they are not stored with the run - so they are cleared whenever a new structure appears, which includes re-selecting an earlier run from the history. That is deliberate rather than an omission: colours are keyed by site rank, and rank 3 of one solution has nothing to do with rank 3 of the next. Carrying them over would relabel the new structure in the one way you could not check, and it would look intentional. If a colour assignment matters, record it outside the program - or take a screenshot before switching runs.
The surface is extracted with Surface Nets rather than Marching Cubes. Its lookup tables are generated from the geometry of the cube at load time instead of being transcribed, so there is no 2500-entry triangle table to get subtly wrong, and it places one vertex per cell at the centroid of the edge crossings — which gives a smoother mesh with far fewer sliver triangles on noisy data. A charge-flipping map near the noise floor is very noisy. Extraction always runs on the full grid: even 128³, which is two million cells, takes well under a second.

3D Center of Mass Peak Picking

The 3D view puts c vertical, following crystallographic convention, and is lit differently in light and dark mode - the canvas is transparent and inherits the page, so colours tuned against black wash out against white. The axis letters and cell edges are coloured at build time, so switching theme with a scene already on screen re-lights it but leaves those until the next rebuild.

When dealing with heavy scatterers (such as Pb or U) and truncated high-angle diffraction data, Fourier series termination artifacts frequently cause the electron density map to form hollow "donuts" or rings rather than ideal 3D Gaussian spheres.

To prevent standard 1D parabolic interpolation from erroneously placing atomic coordinates on the rim of these donuts, Powder 5 evaluates candidate peak locations using a 3D Center of Mass (CoM) calculation over a $5 \times 5 \times 5$ voxel window ($\Delta h, \Delta k, \Delta l \in [-2, 2]$):

$$\mathbf{r}_{\text{center}} = \frac{\sum_{i,j,k \in [-2, 2]} \max(0, \rho_{i,j,k}) \cdot \mathbf{d}_{i,j,k}}{\sum_{i,j,k \in [-2, 2]} \max(0, \rho_{i,j,k})}$$

By weighting positive density across the entire $5 \times 5 \times 5$ neighborhood, the algorithm geometrically averages out the ring artifact and places the peak coordinate directly in the true center of the atomic site.

Building a Structure in the Space Group

This runs automatically at the end of every charge-flipping run, and again whenever a run is re-selected from the history (the result is cached, so re-selecting is instant). It takes the actual space-group symmetry operators, read from the bundled database, and:

  1. finds the origin shift that makes the map obey those operators - computed in closed form from a single Fourier transform, then validated by symmetrising the map and measuring the correlation;
  2. averages the density over the symmetry operators;
  3. reduces the peaks to one representative per symmetry orbit, reporting the site multiplicity of each (a peak that maps onto itself sits on a special position).
This step does different work depending on \(\lambda\). At \(\lambda = 0\) the map is in \(P1\) and step 1 is doing the real job: it is the only thing that places the structure on a crystallographic origin. At \(\lambda = 1\) the map already sits on a standard origin, the shift found should be near zero, and the step is effectively an independent check - but it is worth having either way, because the symmetry correlation it reports is the best single quality indicator, and the reduction to the asymmetric unit with site multiplicities is what produces the CIF.

The symmetry correlation reported alongside the sites is the number to trust: a high value means the density is genuinely consistent with the chosen space group; a low one means either the run has not converged or the space group is wrong. The resulting sites can be exported as a .cif file.

Charge flipping yields electron density, not chemistry. The peaks are labelled generically (Q1, Q2, …) with unit occupancy; assigning element types and refining occupancies is left to the user. The .cif is a starting model for Rietveld refinement, not a finished structure.
The space-group database must include the full symmetry operators (the sym_ops field). If the status line under the Structure heading reports them missing, regenerate the JSON with the current cctbx_generate_sg_harker script; an older database that carries only rotations will index reflections but cannot build a structure.
This step ends at a peak list. It does not place atoms of a given composition, and giving it one is refused rather than accepted: the Wyckoff search is a separate method with its own tab, and it must not be handed this map. Two methods that agree are evidence only if neither saw the other's answer.

Result Fields Explained

The Charge Flipping results tab reports the quantities below. The Wyckoff search has its own results tab, with its own history selector and its own PDF and CIF exports; it reports an assignment, a free-coordinate count and \(wR(F^2)\), and it has no origin, hand or symmetry correlation to report because the Wyckoff operators fix those by construction.

FieldMeaning
Best RThe lowest residual reached during the run, for the map that is kept. Summed over measured peaks rather than individual reflections, because overlapping reflections are not separately observable. Below ~0.15 suggests a solution; above ~0.30 usually means non-convergence.
Reached at iterationWhich cycle produced that best map. Powder 5 retains the best iterate, not the last, because the algorithm oscillates once it has converged.
Random startsHow many independent random-phase trials were run; the best across all of them is shown.
Grid / spacingThe density-grid edge and the corresponding real-space voxel size in Ångström.
Unique reflections usedHow many allowed Pawley reflections entered the CF orbits after intensity preparation and grid-range checks. Negative fitted values are retained through integrated-area conversion and French–Wilson correction rather than being clipped prematurely.
Grid points filledTotal reciprocal-grid points carrying an observed amplitude, i.e. the sum of all orbit sizes. Much larger than the number of unique reflections in a high-symmetry group.
Space groupThe group whose operators were used. This is the group the Pawley fit ran in, not necessarily the current selection.
Expansion symmetryHow the orbits were generated: the number of full space-group operators and the Laue class, or - if the database lacks sym_ops - a note that only the Laue-class fallback was available. In the fallback case screw and glide absences cannot be derived.
Symmetry in loopThe effective \(\lambda\) actually used. none means the map was solved in \(P1\) and its origin is arbitrary. If a non-zero value was requested but full translations were unavailable, the effective value is reported as zero because in-loop phase symmetry was safely disabled.
Lorentz-polarisationThe $Lp$ model the worker actually divided by, reported back by the worker itself rather than restated from the control panel - so a mismatch between the two would be visible here instead of silent. Where the counts differ, it also says how many reflections took the value computed by the refinement and how many the worker had to recompute. See Lorentz–Polarisation Factor.
Systematic zerosHow many reciprocal-grid points were held at \(F = 0\) as systematically absent. Expect roughly half the grid for an \(I\) lattice and three quarters for \(F\); zero for a primitive group with no screws or glides.
Forbidden fitted HKLsHow many Pawley HKLs carried positive raw fitted intensity but were excluded from CF because the selected space group forbids them.
Transferred overlapsHow many forbidden HKLs shared a measured cluster with an allowed reflection. Their corrected intensity remains in the cluster total but is assigned only to allowed orbits.
Significant isolatedHow many isolated forbidden HKLs had raw \(I/\sigma \geq 3\). Strict symmetry refuses such a run; softer symmetry modes retain this prominent diagnostic.
Overlapping reflectionsHow many of the reflection orbits share a measured peak with at least one other, and how many distinct peaks they occupy. If this approaches the total, either the sample really is heavily overlapped or the overlap tolerance is set too wide.
Weak classification / selectionWhether weak units were unresolved clusters or individual reflections, followed by the requested fraction, selected units out of the total, and the number of orbits receiving the \(\pi/2\) phase shift. Results made before this selector existed correspond to individual-reflection classification.
Symmetry correlation(From the automatic structure build.) The correlation between the map and its symmetrised copy in the chosen space group. This is the primary quality indicator: near 1 means the density genuinely obeys the symmetry; a low value means either non-convergence or a wrong space group.
Origin shift / hand(From the automatic structure build.) The translation applied to bring the map onto the space-group origin, and whether the inverted solution was chosen. At \(\lambda = 0\) both are arbitrary and are resolved here against the symmetry. At \(\lambda = 1\) the shift should already be close to zero - a large shift then means the in-loop symmetrisation and the origin search disagree, which is worth investigating. Hand is only shown for a chiral setting. A centrosymmetric group contains inversion, so a map and its mirror image are the same structure and reporting “inverted” would invite the reader to wonder what went wrong when nothing did.
Lp model / French-WilsonHow the intensities handed to the solver were prepared, reported as its own lines rather than buried in a single sentence. French-Wilson replaces every weak reflection with a Bayesian posterior mean using the correct centric or acentric distribution, and needs at least eight reflections carrying a usable \(\sigma\); when it does not apply, the report says NOT APPLIED with the reason. A map solved from corrected amplitudes and one solved from raw amplitudes are different results, and which one you have should not depend on a console line.
Clamped to zeroHow many non-positive intensities were forced to zero before solving.
Multiplicity warningPresent only when the supplied multiplicities disagree with the space-group operators. The observed intensity is \(m \cdot Lp \cdot |F|^2\) and the map divides \(m\) out by spreading it over the orbit, so a disagreement scales every \(|F|\) by the square root of the ratio - silently, and with nothing else in the output to show it.

Peak and site table columns

ColumnMeaning
#Peak rank by height (1 = strongest).
x, y, zFractional coordinates. In the raw peak list these are in \(P1\) with an arbitrary origin; in the built structure they are placed on the space-group origin.
HeightThe map value at the peak, relative to the strongest (set to 1). It does not rank atoms by atomic number. It is one voxel: it depends on where the atom falls relative to the grid, on its displacement parameters, and on the series-termination ripples of its neighbours - and the heaviest atom, having the largest ripples, erodes its own maximum. On a real PbSO4 solution the sulfur came out at 1.000 and the lead at 0.728.
ChargeThe map integrated over a 0.65 Å sphere with a local baseline removed, relative to the largest integral. This is the column that tracks atomic number. Both columns are on an arbitrary scale - \(F(000)\) is held at zero throughout charge flipping, so the map has zero mean - and only ratios mean anything. The radius stays below half the shortest bond you expect to resolve, or the integral swallows the neighbours. Empty on a Wyckoff structure - that method has no map, and filling this in would mean scoring it against the charge-flipping one.
Nearest peak (Å)(Peak list.) Distance to the closest other peak in the list. Not a resolution limit and not a bond length: it says how isolated each peak is. A value far below any real bond means the peak is a ripple beside a stronger neighbour, not an atom.
MultSite multiplicity: how many symmetry-equivalent copies of this site exist in the unit cell. See the note on the asterisk below.
Element(Site table.) Blank as ? on a charge-flipping structure, which yields density and not chemistry. Filled in on a Wyckoff structure, where the element on each site is part of the model being fitted rather than something read off a map.
The asterisk (*) on a multiplicity marks a special position. A site lying on a symmetry element - a mirror plane, rotation axis or inversion centre - maps onto itself under one or more symmetry operators, so it has fewer equivalent copies than a general position. Its multiplicity is therefore smaller than the space group's general multiplicity, and the asterisk flags exactly that: this atom sits on a special position and its coordinates are constrained by symmetry. For example, in \(Pnma\) a general site has multiplicity 8; an atom on the mirror at \(y=\tfrac14\) has multiplicity 4, shown as 4*. Special positions are common and expected - many atoms in real structures sit on them - and recognising them is the first step toward assigning Wyckoff letters.

Requirements and Limitations

  • Data quality. The solution is only as good as the extracted intensities. Severe peak overlap, a poor background, or an incorrect cell will all degrade or prevent a solution.
  • Resolution. Atomic-resolution data (roughly \(d \lesssim 1.2\) Å) is normally needed to resolve individual atoms; lower resolution gives a blurred map.
  • The space group is an assumption. With \(\lambda > 0\) it is imposed, not tested. A wrong group can still produce a low \(R\), because the constraint makes the calculated intensities agree with the observed ones by construction. Cross-check with a \(\lambda = 0\) run and with the symmetry correlation from the Structure block.
  • Non-uniqueness. Random starts can land on different origins or the inverted structure. This is expected at \(\lambda = 0\); the structure builder resolves origin and hand against the space-group symmetry.
  • Light atoms near heavy ones. As with any Fourier method, light atoms sitting close to much heavier ones may be lost in truncation ripples.
  • Overlap is modelled, not solved. Re-partitioning the intensity of a cluster in proportion to the calculated values is a reasonable guess, not a measurement. Structures whose solution depends on resolving a specific pair of overlapped reflections may be beyond reach from powder data alone.

Direct-Space Structure Solution: Wyckoff Search

The Wyckoff search has its own tab in the left panel and its own results tab on the right. It is a peer of charge flipping, not a step inside it: it consumes a space group, a cell, a composition and the Pawley intensities, and not one of those comes from a density map. It does not require a charge-flipping run, and it cannot read one. The two methods share only the Pawley intensity list - the same measurement, seen independently.

The independence is enforced, not merely intended. The structure builder refuses a target composition, and the Wyckoff search takes no density-map argument at all, so neither can be given the other's answer even by accident. This is what makes agreement between them worth something: if two methods that never communicated place the same atoms in the same places, that is evidence. If one had been seeded with the other's solution, it would not be.

This is direct-space (global-optimisation) structure solution, the family that includes FOX, EXPO, DASH and TOPAS's simulated annealing. It works where charge flipping struggles on powder data because of parameter counting: PbSO4 in \(Pnma\) has nine free positional parameters against a few hundred observations, whereas charge flipping solves for thousands of grid amplitudes and phases from the same data. It has no phase problem, no origin ambiguity, no hand ambiguity and no series-termination ripples - and because the composition is enforced by construction, it cannot invent an atom where there is nothing to explain it.

The objective

A WebGPU swarm (replica-exchange MCMC) places atoms on trial Wyckoff assignments that satisfy the stoichiometry exactly. Each candidate is scored by $$f = (1 - wR2) - \text{pen}$$ where wR2 is the scale-only weighted residual between \(|F_{\text{calc}}|^2\) and the observed intensities, taken over groups of reflections the powder pattern cannot separate. An optimal multiplicative scale is eliminated analytically; no additive intensity intercept is fitted, because a constant shift in extracted reflection intensities is not a physical structure factor. The observed intensity of a group is \(\sum m |F_o|^2\) and the calculated one is accumulated the same way, so the comparison is made where the measurement actually exists. See the scoring section for the formula.

Scattering factors are the tabulated \(f(s)\) with an overall temperature factor folded in as \(f(s)\exp(-Bs^2/4)\), pre-computed per (reflection, element) on the host. \(B\) is estimated by a Wilson plot over resolution shells from the extracted intensities themselves. The Pawley intensities do not lack a temperature factor - they contain the real one, because they are a measurement - so the model needs one to reproduce their fall-off.

Penalties and hard constraints

Clash, bond-window and coordination penalties are soft and ramped during the search, which is correct while the swarm still needs to move through crowded configurations. They are not how the answer is decided. A candidate whose final geometry breaks any stated floor, upper bound, exact-count or at-least-count rule is rejected outright, and candidates are walked in score order until one passes; if every candidate fails, that is reported rather than swallowed, because it is a statement about the composition, \(Z\), or the constraints.

The same test is applied after the coordinate refinement. The refinement moves every free coordinate with no geometry term at all, so guarding only its input guards nothing: a refinement that breaks any rule is discarded and the search positions are kept, with the reason recorded.

Resolution ramp - and why the running wR2 is not the final one

The swarm starts on a subset of the reflection groups - as few as a quarter - and reaches the full set part-way through each restart. The figure shown while a search runs is computed on whatever subset is active, so it reads considerably lower than the final value and is labelled wR2 (partial res.). Only the full-resolution figure from the closing quench, shown in the results panel as Search: wR2, is comparable with anything. A running 0.99 alongside a final \(wR\) of 50% is not a contradiction; it usually means the low-order reflections line up and the light atoms are not yet placed.

Controls

ControlDescription & defaults
FormulaTarget composition, e.g. PbSO4. Required; the Search button stays disabled and says why until one is entered.
ZFormula units per cell, as a whole number of 1 or more. Blank means Auto, which is a scan over every plausible \(Z\) rather than a single estimate - see Z, the density window and the scan. A typed \(Z\) is used exactly as typed, and the panel shows the density it implies as you type it.
Max sites / elemMost distinct Wyckoff positions one element may occupy, as a whole number of 1 or more; blank means Auto. This is a per-element cap and says nothing about the total - see the capacity note below.
Max reuse / posMost independent atoms sharing one Wyckoff position, as a whole number of 1 or more; blank means Auto.
Density min / max (g/cm³)The window \(Z\) = Auto scans, in whole g/cm³, from 1 to 22, default 2 to 10. The minimum is held strictly below the maximum. Ignored when \(Z\) is typed. Narrowing it is the cheapest way to shorten a scan: it is the only part of the calculation that knows what kind of material you have.
Max Z searchedHow many values of \(Z\) one scan may search (1–12, default 3). Each is a full swarm run, so this is what bounds the total time. The candidates dropped are the least plausible on volume per atom, and the log names them.
ChainsIndependent trial structures. Capped automatically against the device's storage-buffer and dispatch limits; the UI offers multiples of 64 for convenient sizing. In the kernel, one chain is one workgroup, so the dispatch limit is applied directly and is not multiplied by the workgroup width.
IterationsSteps per chain (100–10000, default 2000).
RestartsIndependent restarts (1–20, default 4).
Min contact (Å)Floor applied to every unlike pair, default 1.0 Å. A literal value of 0 disables the global floor; it is not replaced by the default.
Distance constraintsElemA ElemB N dmin/dmax, one per line, e.g. S O 4 1.40/1.80. They provide soft search guidance and hard final validation of every stated floor, upper bound and coordination count. The grammar, costs and common mistakes are in Distance constraints below.
Capacities, and what happens when you exceed one. The search kernel holds at most 32 independent atomic sites in one assignment, 8 distinct elements, 8 distance rules, and 64 coordination slots shared across all rules. These are fixed array sizes, not preferences.

Read the first two carefully, because neither counts what its name suggests:
  • 32 sites counts independent atoms in the asymmetric unit, summed over every element - not Wyckoff letters. A position used three times counts three, because each use is an atom with its own free coordinates.
  • 8 elements counts distinct chemical elements, not atoms and not sites. An element occupying nine positions is still one element.
  • 64 slots is the sum of the coordination numbers over every line that states one, not a per-line limit. S O 4 1.40/1.80 plus Pb O 8 2.00/3.00 plus Pb S 8 2.00/4.00 spends 4 + 8 + 8 = 20 of the 64. Lines that state no coordination number spend none. Since no line can ask for more than it can fit and there are only 8 rules, 64 is enough for eight simultaneous 8-coordinate shells - in practice this limit no longer binds, and the rule count is what you will hit first.
So the two limits are close to independent, and a single-element structure can use the whole site budget. C60 in \(Pa\bar{3}\) is the illustrative case: 240 carbons per cell, the molecule on a \(\bar{3}\) site, so its 60 atoms split into \(60/6 = 10\) orbits - 1 element and 10 sites, inside both caps with room to spare.

In practice the kernel caps are rarely what stops you. Max sites / elem and Max reuse / pos bind first: at their default of 4 the enumeration is raised only as far as the composition strictly requires, and for C60 that yields the single 10×24d assignment. Raising both to 16 finds six candidates; raising them past 32 is where the kernel cap finally starts dropping assignments. If a plausible assignment is missing, check those two sliders before the capacities.

These four limits belong to the Wyckoff search alone. Charge flipping has no composition, no elements and no Wyckoff positions, so none of them applies to it - it can return more than 32 sites, and routinely does before the spurious peaks are weeded out.
  • Sites. Assignments needing more than 32 are dropped during enumeration and the count is reported, because an over-wide assignment is one candidate among many. If every assignment needs more, the run stops and says so - which normally means \(Z\) is too large for the group. See how many sites a structure needs for the arithmetic behind that message.
  • Elements, rules and slots. The run is refused before it starts, with a message naming the limit. Note that a bare upper bound such as Pb O 0/3.0 is applied in both directions and therefore costs two rules; the constraint box counts rules, not lines, and tells you the total.
Nothing is silently truncated. A restraint you typed and the search did not apply is the worst failure mode available here: it costs a full run, the answer looks reasonable, and the structure then violates a constraint the report correctly flags - which reads as a bad structure rather than a dropped rule.
Loading a new pattern resets this panel. The formula, \(Z\), the two site caps, the minimum contact, the distance constraints and the density window all describe the sample, and carried across to a different diffractogram every one of them is a statement about the wrong material - the formula worst of all, because the search will run happily on it and return a structure. The run histories go with them. What is deliberately kept is everything describing the machine or your patience: chains, iterations, restarts and Max Z searched were set once for this computer and are still true of it afterwards.
Packed Miller-index range. The Wyckoff GPU format stores each Miller index from −511 to +511. Input outside that range is rejected with an explicit error before dispatch. It is never skipped after group metadata has been written, so an out-of-range row cannot make a powder group point into the next group or into nonexistent reflection data.
Stopping returns the best structure found so far. The swarm keeps a running best for every assignment, so pressing Stop finishes the run early and reports what it had rather than discarding it.
What a stop skips, precisely. Only the closing full-resolution quench inside the swarm. The coordinate refinement below runs afterwards and is unaffected, so a stopped run still reports \(wR(F^2)\) and a Refined positions table, and those are real. What is not final is the Search: wR2 - without the quench it carries whatever subset of reflections the resolution ramp had reached, so it is not a full-resolution figure and is not comparable with \(wR\) - and the ranking that chose this candidate over the others, which was made on the same partial figure. Treat a stopped run as a preview of where the search was heading rather than as a finished answer.

Distance constraints

One rule per line, blank lines and lines starting with # ignored. Element symbols are matched case-insensitively and must appear in the target formula; anything else is inert and is reported as an error rather than skipped. The general form is

ElemA ElemB [count] dmin/dmax

and every field except the two symbols is optional, which is why the same intention can be written several ways. What matters is which of three different mechanisms a line ends up switching on:

FieldWhat it does
dminA hard floor on the pair. It replaces the Min contact slider for this pair - not the larger of the two, not the smaller, in either direction - so a constraint can hold one pair further apart than the slider or admit an approach the slider would forbid. Charged as a clash penalty that grows with the depth of the overlap. Costs no rule.
dmaxWith no count: the nearest partner must be within it. A pure nearest-neighbour condition, symmetric, so it is applied in both directions and costs two rules. With a count: the upper edge of the window the shell is measured against.
countA coordination number. The kernel keeps the count nearest partners and charges each one by how far it misses the window, so the penalty is graded by distance rather than by a bare tally - a partner at 2.5 Å when you asked for 1.80 is not scored the same as no partner at all. Directed and never mirrored: costs one rule and count slots.

Worked examples

Rule and slot costs are shown against the budget of 8 rules and 64 slots. The constraint box totals them live and refuses the run before it starts rather than dropping the surplus.

LineMeaningRulesSlots
S O 4 1.40/1.80Every S wants exactly four O between 1.40 and 1.80 Å. Also floors S–O at 1.40.14
S O 4+ 1.40/1.80The same, but at least four - a fifth O in the window is not penalised. Use this when the coordination is uncertain; the bare number also charges for excess.14
Pb O 8 2.00/3.00Every Pb wants eight O in 2.00–3.00 Å.18
O O 2.40O–O no closer than 2.40 Å. A floor and nothing else - the cheapest kind of line.00
O O - 2.40/Identical to the above. The - is an explicit “no count” and the empty right-hand side an explicit “no upper bound”; both are optional.00
Pb O /3.00The nearest O to any Pb must be within 3.00 Å, and vice versa. No count, so it is mirrored - which is where the two rules go.20
Pb O 2.00 3.00The same window written without a slash. Two bare numbers are read as dmin then dmax.20
# Pb S: no bond expectedA comment. Useful for parking a rule you may want back.00

A complete example: PbSO4

# anglesite, Pnma, Z = 4
S  O   4  1.40/1.80     # sulfate tetrahedron
Pb O   8  2.00/3.00     # lead coordination shell
O  O      2.40          # keep the tetrahedra from interpenetrating

Two rules and twelve slots, well inside both budgets. The third line costs nothing at all: it is a floor, and floors live in the clash matrix rather than in the rule table. Note what is not constrained - no Pb–S rule, because there is no Pb–S bond and the O–O floor plus the two coordination shells already fix the packing. Constraining a distance you have no chemical reason to constrain is the commonest way to make the right answer unreachable.

Direction is not decoration

A coordination number is tested from its first element outward. S O 4 1.40/1.80 asks every sulfur for four oxygens; O S 4 1.40/1.80 asks every oxygen for four sulfurs, which in a sulfate is false and will be paid for on every single evaluation. Writing both is not one bond counted once - they are two independent demands costing two rules and eight slots, and the box warns when it sees the pair. Put the count on the centre of the polyhedron.

Upper bounds without a count are the exception: they are symmetric statements about nearest neighbours, so they are applied both ways automatically. That is convenient and it is also why one typed line becomes two rules.

Running out of budget. With 8 rules and 64 slots the rule count is the binding constraint, and almost always because of mirrored upper bounds. In order of what to try:
  • Drop upper bounds you do not need. Pb O /3.00 costs two rules; if what you actually meant was “Pb has eight oxygens around it”, Pb O 8 2.00/3.00 says it better and costs one.
  • Turn windows you only care about the near side of into floors. A line with a dmin and no dmax and no count is free.
  • Constrain the cation polyhedra, not the anion–anion contacts. The latter follow from the former.
Nothing is silently truncated at either limit - the run is refused with a message naming the total and the limit it passed.
A count with no upper distance counts the whole cell. S O 4 1.40/ asks for four oxygens further than 1.40 Å from each sulfur, which every oxygen in the structure satisfies, so the demand is met by any arrangement and constrains nothing. The box warns about this. A bare integer with no distance at all - S O 4 - is rejected outright rather than guessed at, because it is equally readable as a 4 Å distance.
Constraints are soft during the search and hard afterwards. The clash, bond-window and coordination penalties are ramped in as the search proceeds, so early generations can pass through geometry the constraints forbid; that is deliberate, and it is what lets a chain cross a barrier instead of being trapped behind it. Every floor, bare nearest-neighbour upper bound, exact coordination count and at-least count is then applied as a hard filter when candidates are ranked and again after coordinate refinement. Mirrored bare upper bounds are checked in both directions. A structure violating any rule is rejected rather than reported. If an expected candidate is missing, inspect all of the rules, not only the contact floor.

\(Z\), the density window, and the scan

\(Z\) is the number of formula units in the cell, and it is the one input to this search that is neither measured nor refined. Get it wrong and everything downstream is wrong in a way no figure of merit will name: the stoichiometry is enforced by construction, so the swarm will dutifully fit the wrong number of atoms and report a residual for it.

Leaving the box blank selects Auto, which does not estimate \(Z\) - it scans. Every plausible value is searched in full and the best structure for each is offered, because a rule of thumb about cell volume is a prior and the intensities are evidence, and the evidence has to be allowed to overrule the prior.

Where the candidate list comes from

The crystallographic density fixes the relationship between \(Z\) and the cell:

\( \rho = \dfrac{Z M}{N_A V} \qquad\Longleftrightarrow\qquad Z = \dfrac{\rho V}{1.66054\, M} \)

with \(M\) the formula mass in g/mol, \(V\) the cell volume in Å3 and \(\rho\) in g/cm3. Inverting it turns a density window into a \(Z\) range. The candidate list is then cut down twice more before any GPU time is spent:

  1. The density window. Two sliders, whole g/cm3, 1 to 22, default 2 to 10. The bounds are rounded inward, so every candidate's density genuinely lies inside what the sliders say - a maximum of 10 will not admit a \(Z\) at 10.3. This is the only step that uses knowledge the program does not have, so it is the one you set.
  2. What the space group permits. Pure arithmetic, described below, and in a centred or high-symmetry setting it removes most of the window at a stroke.
  3. Whether a legal assignment exists. Each survivor is put through the same assignment enumeration the search itself uses, capped at one solution, so a \(Z\) that cannot be built at all is discarded in milliseconds instead of failing half a second into a run.

What the space group says about \(Z\)

Every atom of one element occupies some set of Wyckoff positions, so the number of them in the cell is a sum of multiplicities, repeats allowed. Let \(g\) be the greatest common divisor of every multiplicity the setting offers. A sum of multiples of \(g\) is a multiple of \(g\), so for each element with subscript \(k_e\) in the formula unit,

\( Z\,k_e \equiv 0 \pmod{g} \qquad\Longrightarrow\qquad Z \equiv 0 \pmod{\;\operatorname{lcm}_e \dfrac{g}{\gcd(g,\,k_e)}\;} \)

Worked through for a pyrochlore A2B2O7 in \(Fd\bar{3}m\): the multiplicities are 8, 16, 32, 48, 96 and 192, so \(g = 8\). The oxygen requires \(7Z \equiv 0 \pmod 8\), and since 7 and 8 are coprime, \(Z\) must be a multiple of 8. A 2–10 g/cm3 window spans \(Z = 3\ldots11\) for a typical pyrochlore cell; the rule removes ten of those eleven before anything is enumerated, and \(Z = 8\) is the only candidate left.

The step and \(g\) are not always the same number. They coincide whenever some element has a subscript coprime to \(g\), which is the common case, but not otherwise: in \(Pnma\) (\(g = 4\)) a formula like Fe2O4 gives a step of 2, not 4, because both subscripts already share a factor with \(g\). The log states the derivation rather than just the answer, so the two can be told apart.
In \(P1\) and \(P\bar{1}\) the rule says nothing, because \(g = 1\). That is correct and not a gap: a triclinic cell really can hold any \(Z\), and pruning there would risk discarding the true answer to save time. It is also why low-symmetry problems are the expensive ones - the space group offers no help, and Max Z searched is what bounds the run instead. A fractional subscript (a solid solution written Fe0.5Ni0.5) also voids the argument, which is an integer one, and the rule is skipped.

One search per \(Z\), and a list of solutions

Every surviving \(Z\) gets its own complete search - all the restarts, the resolution ramp, the closing quench, the contact filter and the coordinate refinement - and the best structure it produced is kept. The plausibility ranking (volume per atom nearest 16 Å3, with a mild preference for a \(Z\) commensurate with the group order) decides only the order of the searches, so stopping part-way through means the most likely candidates have already been done.

The results tab then opens with a Solutions table: one row per \(Z\), with its density, atoms per cell, assignment, search wR2 and \(wR(F^2)\). Click a row and everything below it - the coordinate tables, the R factor, the CIF export, the contacts, the bond valences, the structure plot and the PDF report - switches to that solution. The run-history label carries both numbers: Z=8/3 means the best of three solutions was \(Z = 8\).

The ranking is by \(wR(F^2)\). A solution whose refinement did not run has no \(wR\), and is placed below every solution that has one and ranked among its peers on search wR2 - the two are different quantities measured against different things, and mixing them on a common scale would invent a comparison that does not exist. Values of \(Z\) that produced nothing are listed with their reasons rather than quietly omitted.

A better \(wR\) does not by itself make a \(Z\) right. More atoms means more free parameters, so a larger \(Z\) has more freedom to fit the same data and will often score better for that reason alone. Read the solutions table alongside the density - which you know something about and the refinement does not - and the contacts and bond valences below it. Two values of \(Z\) that both fit respectably is a real result and the reason the list exists; it is not something the program should resolve on your behalf.
A scan costs roughly \(N\) times a single run. With the default 2–10 window a typical compound yields one to four candidates, but a light formula in a low-symmetry group can fill the cap. If a scan is taking too long, narrow the density window first - it is the only control that carries information about your sample - then lower Max Z searched.

Typing a \(Z\) instead

A typed \(Z\) is honoured exactly as typed and the density window is not consulted. The panel still computes what that \(Z\) implies and shows it as you type, in either order - entering the formula after the \(Z\) works as well as before it:

Z = 8 gives a density of 6.73 g/cm³ (Gd2Ti2O7, 522.23 g/mol, cell 1030.3 ų).

A \(Z\) implying an impossible density is refused before the run starts. Lithium is 0.53 g/cm3 and osmium 22.59, so outside 0.5 to 22.5 g/cm3 the \(Z\), the formula and the cell are not describing the same solid. The search would still produce a structure - nothing in the objective knows what a density is - after several minutes of GPU time, so it is refused instead, with a toast naming the number. The commonest cause by far is \(Z\) counting atoms rather than formula units; the next is a formula that is the cell contents rather than the formula unit.
A typed \(Z\) that breaks the space-group rule is warned about, not blocked. If it is not a multiple of the step derived above, the search will almost certainly find no legal assignment - but it runs anyway, because you asked for that \(Z\), and swapping in a different one behind your back would be worse than failing.

How many sites a structure needs

Worth checking before a run rather than after, because the answer is one division and it decides whether the search can represent your structure at all:

\( \text{sites} \ \ge\ \left\lceil \dfrac{\text{atoms per cell}} {\text{largest multiplicity in the group}} \right\rceil \)

Atoms per cell is the formula unit times \(Z\), counting hydrogen. The largest multiplicity is the general position, which for a symmorphic group is the group order. Take cimetidine, C10H16N6S with \(Z = 2\) - 66 atoms per cell:

Group orderExampleSites needed
2\(P\bar{1}\), \(P2_1\), \(Pc\)33beyond the limit
4\(P2_1/c\), \(P2_12_12_1\)17fits
8\(Pnma\), \(C2/c\)9fits easily

So the same compound is solvable or not depending on the space group, and the cliff is steep: one step down in symmetry doubles the requirement. In \(P2_1/c\) the narrowest assignment cimetidine admits is 5×4e C, 8×4e H, 3×4e N and one sulfur on a 2-fold inversion site - 17 sites. The odd sulfur is what makes 66, which is not divisible by 4, work out at all.

Fitting is not the same as solving. Every extra site adds three free coordinates for the swarm to fit, so 17 sites is around fifty parameters against however many reflections your pattern resolves. A structure that clears the capacity check by a wide margin can still be out of reach of the data, and nothing in the search will tell you which of the two happened. If the reflection independently weighted powder-group count is not comfortably larger than the true Wyckoff free-coordinate count plus the fitted scale, treat a good wR2 with suspicion. Final coordinate refinement is refused unless it retains at least one residual degree of freedom.

Final coordinate refinement

The search finishes with a least-squares refinement of the free Wyckoff coordinates against \(|F_{\text{obs}}|^2\), with an overall intensity scale eliminated analytically and each atom re-projected onto its symmetry element every step. It uses the same reflection groups, scattering factors, \(B\) value and weighting policy as the search. If at least one complete powder group has a usable ESD, complete groups receive \(1/\sigma^2\) and incomplete groups receive zero weight; if none has a usable ESD, all groups receive unit weight. Positive weights are normalised internally without changing their ratios. If the search and refinement ever disagree on the scattering or weighting model, they are not fitting the same problem and their figures cannot be compared.

Both answers are reported: the search positions and the refined positions, in separate tables, with the second appearing only when the refinement actually moved something. They optimise different quantities, and when they disagree that disagreement is the interesting part. If you intend to run a Rietveld refinement afterwards, the search positions are usually the cleaner starting point.

The free-parameter count is the constrained one. A \(4c\) site in \(Pnma\) is \((x,\tfrac14,z)\) and contributes 2, an \(8d\) general site contributes 3, and a fixed site such as \(4b\) at \((0,0,\tfrac12)\) contributes 0. Putting atoms on Wyckoff positions is the method, so reporting \(3N\) would understate the constraint that does the work. The count is taken as the rank of each site's projection matrix, which for an idempotent projector is its trace.
Underdetermination is tested on independent quantities. Let \(N_{obs}\) be the number of powder groups with positive weight and \(N_{free}\) the sum of the ranks of the true Wyckoff projection matrices. The fitted scale consumes one additional degree of freedom, so refinement requires \(N_{obs} > N_{free}+1\). Raw HKL rows and \(3\times\)site counts are not used for this decision. If the test fails, the search positions remain available and the refinement reports why it did not run.
The Charge column is empty on a Wyckoff structure, and the Element column is filled. Both follow from the same fact: the elements here are an input to the model, not something inferred from density, and there is no map to integrate. On a charge-flipping structure it is the other way round.

Structure plot, contacts and bond valence

Everything above this point on the Wyckoff results tab answers one question: how well do these coordinates reproduce the measured intensities. That is not the same question as whether they are chemistry. A structure can reach a respectable \(wR(F^2)\) with an oxygen 1.3 Å from its sulfur, or with a cation whose coordination sphere is a physical impossibility, and no R factor will mention it. The block below the coordinate tables is the independent check: it uses no intensities at all, only the cell, the space group and the atom positions.

What is displayed

  • Cell content, volume and calculated density. The formula per cell is built from the multiplicity counted from the symmetry expansion, not read off the Wyckoff label - a site that has drifted onto a special position during refinement generates fewer distinct images, and the counted value is the one the contacts and the mass are actually built from. A density far from what the compound should have usually means the wrong \(Z\), not a wrong coordinate - and if the search ran on \(Z\) = Auto, the other values of \(Z\) are already sitting in the Solutions table above.
  • Structure plot. Drag to rotate, wheel to zoom, click an atom to list its contacts. Sites can be hidden individually, the cell frame and labels toggled, boundary images switched off, and the view saved as a PNG. Bonds are drawn between counter-ions closer than 1.4 × the sum of their covalent radii; they are a drawing convention, not part of the analysis.
  • Contacts. Every neighbour of the selected site within the cutoff, sorted, tagged with the site it belongs to, with a rule drawn where the distance jumps by more than 0.45 Å. The gap after the first coordination sphere is what a reader is looking for, and a flat list hides it.
  • Structure quality. Coordination number, mean bond length, the spread of those lengths, the bond-valence sum against the formal valence, and a verdict.

Coordination number

Taken over the counter-ions - anions around a cation, cations around an anion - and cut at the first clear break in the sorted distances rather than at the cutoff, separately for each neighbouring element. This info is not relevant for molecular structures.

Both of those choices are forced. A single cutoff cannot serve both a sulfate sulfur and a twelve-coordinate lead in the same structure: at 3.5 Å the sulfur is reported as CN 5 or 6, with a mean bond length halfway between the SO4 tetrahedron and the next oxygen in the lattice and a spread that describes nothing. And an oxygen in that same sulfate sits 1.5 Å from its sulfur and 2.4 Å from the nearest lead, so a break taken over the merged list would stop at the S–O bond and report CN 1 - the sulfate group, not the oxygen's coordination. Per-element breaks give CN 12 for the lead, 4 for the sulfur and 4 for the oxygen, which is the structure as a chemist would describe it.

The spread is the standard deviation of the distances in that shell. On a cation surrounded by one element it is a distortion measure and a large value is worth a look. On an anion coordinated by two different elements it mixes two bond types and will be large for a perfectly good structure; the shell composition is given beside the CN for that reason.

Bond-valence sums

Each contact between a cation and an anion is assigned a valence from its length alone,

\( s_{ij} = \exp\!\left( \dfrac{R_0 - d_{ij}}{b} \right), \qquad V_i = \sum_j s_{ij} \)

with \(b = 0.37\) Å and \(R_0\) tabulated per cation–anion pair and oxidation state. In a correct structure the sum \(V_i\) over a site recovers that ion's formal valence. The sum runs over every counter-ion inside the cutoff rather than over the coordination shell defined above: the exponential already makes distant contacts negligible, so the sum does not need a shell boundary and is better off without one.

Reported as “V of n expected”, with a verdict that is nothing more than the relative deviation:

VerdictConditionReading
plausiblewithin 15% The site is where an ion of that charge would sit.
borderlinewithin 30% Common on a powder solution before Rietveld refinement, and on light atoms whose positions the data barely constrain.
checkworse than 30% Either the coordinate is wrong, or the oxidation state assumed for it is. An under-valued cation is usually one that has been placed too far from its anions; a badly over-valued one is usually too close.
no parameters- No tabulated \(R_0\) for one of the pairs involved. The pair is left out of the sum and the site is not judged. An invented \(R_0\) would produce a number that looks like a measurement and is not one.

Which atoms are anions, and in what oxidation state

Decided per structure, not from a fixed list: the candidate anions present are compared by electronegativity, and those within 0.5 units of the most electronegative species in the cell act as the anions. Sulfur is therefore an anion in PbS and a cation in PbSO4, which a fixed list gets wrong one way or the other every time. Oxidation states are taken from the common state of each element. They are no longer editable, and the net cell charge is no longer reported: both summed a default state over every site, which means something only for a simple ionic solid with one state per element. For a mixed-valence compound, a molecular or covalent structure, or anything with partial occupancy the total was arbitrary, and it marked sound structures as suspect. The per-site bond-valence sums below answer the same question from the geometry that was actually refined, and answer it honestly.

This is a plausibility check, not a figure of merit. Nothing here is fitted, and none of it should be reported as evidence that a structure is correct - a bond-valence sum can be satisfied by a wrong structure with roughly the right coordination distances. It is reliable in the other direction: a site that comes out at half its formal valence is telling you something real about that site, and it will keep telling you after Rietveld refinement has driven \(R_{wp}\) down. Read it alongside the \(wR(F^2)\) above, not instead of it.
Three limits worth knowing. Site occupancies are taken as 1, so a partially occupied or mixed site will not balance. Hydrogen is not located by these methods at all, so hydrogen-bond contributions are missing from every oxygen sum in a hydrate or a hydroxide - expect those to read low. And the coordination number, though not the valence sum, depends on the contact cutoff you set; the value in force is stated under the table.

What the search actually maximises: (1 − wR2) − pen

Every candidate structure is scored by a single number, \\( \\text{score} = (1 - wR2) - \\mathrm{pen} \\), and the candidate list is ordered by it.

wR2 is the scale-only weighted residual over the observed group intensities. Eliminating the optimal multiplicative scale gives

\( wR2 = \sqrt{1- \dfrac{\left(\sum_i w_i I_{c,i}I_{o,i}\right)^2} {\left(\sum_i w_i I_{c,i}^2\right) \left(\sum_i w_i I_{o,i}^2\right)}} \)

This is invariant to overall intensity scale but deliberately not to an additive shift. Centering the intensities would silently fit a constant structure-factor intercept, which has no physical place in this model. The CPU check, WebGPU kernel and coordinate refinement use the same scale-only form.

Reflections the powder pattern cannot separate are summed into one group first, so the comparison is made where the measurement exists. Each group is weighted by \( 1/\sigma^2 \) on its total when usable Pawley ESDs exist. If at least one complete group has an ESD, incomplete groups receive zero weight rather than unit or \(1/I\) weight. Only when no group has a usable ESD is the whole problem unweighted. The same policy is used in final coordinate refinement.

pen is the geometry penalty, summed over every atom in the trial cell. It is what stops the diffraction score buying a chemically impossible structure. It has exactly three components:

TermDefaultCharged
penClash0.05 Per pair closer than the contact floor \(d_{\min}\), as \( 0.05 \times (1 + 9\,\delta) \) with \( \delta = (d_{\min}-d)/d_{\min} \). A pair barely touching costs one unit, a fully collapsed pair ten: a soft wall that steepens, not a hard rejection.
penBond0.10 Per bond outside a distance window. A bare nearest-neighbour rule charges the overshoot in ångström. A coordination-shell rule charges each of its \(n\) slots by \( \text{miss}\,(1 + \text{miss}/\text{soft}) \), so being slightly out is cheap and being wildly out is not; a slot with no partner at all costs a flat maximum.
penCoord0.03 Per neighbour in excess of the coordination number you asked for. Note the asymmetry: a shortfall is charged through penBond's empty-slot route, a surplus here.

The total is then multiplied by penScale, which ramps from 0.2 at the start of a run to 4.0 at the end. Geometry is nearly free early, so the swarm can move through crowded configurations that lie between two good basins, and expensive late, so the answer has to be physically legal. Archived bests are stored with the penalty unscaled and re-scored at the current weight whenever they are compared, so a candidate found early is never judged against a rival on a different scale.

A stated geometry rule is a constraint, not a preference. Because every geometry term is soft during the search, a winning candidate can still be illegal. The result stage therefore re-checks floors, bare upper bounds and exact or at-least coordination counts and rejects violations outright. It repeats the same validation after refinement, which is why a run can report “search positions kept” after refinement broke a rule.

When the ranking is withheld

A high fitness is not by itself evidence that a structure is right, and the search now says so when it cannot be. Two properties of the weighted residual make this necessary.

First, wR2 compares a DISTRIBUTION of intensity, and a model can reproduce the few highest-leverage points while every other reflection is wrong by any amount. A search figure and a refinement \( wR(F^2) \) can therefore disagree sharply: they are computed over different weightings of the same data, and when the effective observation count is small the search figure is constrained by very little.

Second, the number of reflections is not the number of observations. Because the residual is weighted, a group counts for its share of the observed denominator, \( w_i I_i^2 \), not merely for being in the list. Those shares are very uneven: \(1/\sigma^2\) rewards sharp low-angle reflections, whose ESDs are small, and all but erases high-angle overlaps a Pawley fit could not partition, whose ESDs can exceed their own values. The search reports the effective number of observations

\( N_{\text{eff}} = 1 / \sum_i p_i^2, \qquad p_i = w_i I_i^2 / \sum_j w_j I_j^2 \)

which equals \(N\) when all shares are equal and 1 when a single group is everything. A list of 35 groups is routinely 5 or 6 effective observations.

Distance constraints count as observations. A window is information about the structure that did not come from the pattern, and a fit that uses it rests on more than the reflections alone — the same reason Rietveld practice has counted restraints in the observation total for decades. A coordination-shell rule asking for \(n\) partners contributes \(n\) pseudo-observations per independent site, not per atom in the cell: the symmetry images of a site are the same distance seen again, and counting the orbit would inflate the total by the multiplicity. They are reported separately from \(N_{\text{eff}}\), because a structure held up by restraints is a different claim from one determined by the data.

Below three effective observations per free parameter, the ranking is withheld. A model with more free parameters than effective observations reproduces them exactly whatever the structure, so every candidate scores near 1 and the ordering between them is noise. The candidates are still returned and still worth testing — the coordinates are real — but the result panel says one candidate, not a solution, and no best is claimed. The threshold is SW_DEFAULTS.minObsPerParam. This ranking diagnostic is separate from the final refinement's strict residual-degree-of-freedom test. It is a test of meaningfulness, not of quality: above it a low score is still a real answer, and below it a high one is not.

To lift a withheld ranking, give the search more to work with: extract more reflections, particularly at high angle where severe overlap leaves \(\sigma/I\) near or above 1 and the weighting correctly discards them; or add distance constraints, which count. Reducing the free-parameter count — a smaller \(Z\), or sites of higher symmetry — works from the other side.


Recommended Refinement Strategy

A sequential and hierarchical refinement strategy is crucial for achieving a stable and physically meaningful solution. Attempting to refine all parameters simultaneously from a poor starting model will likely lead to divergence or convergence to a false minimum.

Phase 1: Initial Model Setup

  1. Define the Model: Load data, select the crystal system and space group, and define the refinement range using the $2\theta$ sliders.
  2. Set Background Points: The background is automatically estimated upon loading. Adjust the Auto-points slider under the "Background" tab to optimize the density of points so that they reasonably follow the experimental background. You can also edit the points manually or use Ctrl+Click on the chart. This background shape is fixed during refinement.
  3. Peak Position Refinement: Using the Le Bail and LM algorithms, refine only the Lattice Parameter(s) and, if necessary, the instrumental Zero Shift. The goal is to align the calculated Bragg positions with the observed peak maxima.

Phase 2: Peak Profile Refinement

  1. Isotropic Broadening: Once positions are correct, refine the primary isotropic peak shape parameters (e.g., W, Y, U, X in TCH, or GW, LX in Simple/Split pVoigt). This will account for the dominant size and strain contributions.
  2. Asymmetry and Shape: Introduce asymmetry parameters (S/L in TCH, shft/trns in Simple/Split pVoigt) if there is a clear misfit, particularly at low angles. Refine the mixing parameter (eta) if needed.
  3. Anisotropic Broadening (TCH only): If systematic misfits remain (e.g., some peaks are consistently broader than the model), introduce the anisotropic Stephens parameters (e.g., S400). Refine only the symmetry-independent terms.

Phase 3: Finalization and Intensity Extraction

  1. Global Optimization (Optional): If the LM algorithm converges to a poor solution during the Le Bail steps, switch to Parallel Tempering (PT) for one or more Le Bail cycles to perform a global search. Afterwards, switch back to LM for a final, precise local minimization.
  2. Pawley Refinement: With a stable and well-refined model from the Le Bail method, perform a final refinement using the Pawley method. It is generally recommended to use the Levenberg-Marquardt (LM) algorithm for stability, though Parallel Tempering (PT) can also be used (potentially requiring more iterations). This will provide the most statistically robust set of integrated intensities, suitable for subsequent structure solution.

Technical Note on Calculation Parameters

The pattern calculation runs on the CPU, in double precision, always. There is one implementation of it, in profile.js, shared by the on-screen preview and the refinement worker. An earlier version also carried a WebGPU kernel; it was removed because it was a second implementation of the same model - a place for the two to drift apart, which had already happened once - and because it returned single precision into a double-precision pipeline, so every derivative, every ESD and therefore every refined parameter depended on whether WebGPU happened to initialise. WebGPU is still used where the arithmetic is genuinely heavy and the output is not a refined number with an uncertainty attached: charge flipping and the Wyckoff search.

Each reflection is evaluated only within a finite window around its centre, set by CALCULATION_WINDOW_MULTIPLIER (currently 8.0 × the peak FWHM, doubled when an asymmetry correction is active). This radius is the single authoritative truncation distance, shared by the preview and the refinement worker.

Rather than discarding contributions below a fixed fraction of peak height, the profile value at the truncation radius is subtracted from the whole peak as a small constant “pedestal”. The profile therefore reaches zero continuously at the window edge instead of stepping off a cliff. An earlier version used a separate height cutoff, which put a small discontinuity in the calculated pattern - and hence in the derivatives - wherever a peak was truncated.


Interpretation of Results

Assessing the quality of a refinement requires both statistical analysis and critical visual inspection of the fit.

Figures of Merit

Standard crystallographic R-factors are provided to quantify the quality of the fit.

  • R-pattern ($R_p$): The unweighted residual error based on net intensities, sensitive primarily to the fit of high-intensity reflections. $$R_p = \frac{\sum |(y_{i,obs} - y_{i,bkg}) - (y_{i,calc} - y_{i,bkg})|}{\sum |y_{i,obs} - y_{i,bkg}|} \times 100\%$$
  • Weighted R-pattern ($R_{wp}$): The primary figure of merit, weighted by the inverse of the observed gross intensities ($w_i = 1/y_{i,obs}$), which properly accounts for the counting statistics across the entire pattern. $$R_{wp} = \left[ \frac{\sum w_i (y_{i,obs} - y_{i,calc})^2}{\sum w_i y_{i,obs}^2} \right]^{1/2} \times 100\%$$
  • Reduced Chi-squared ($\chi^2$, Goodness of Fit): The most statistically rigorous indicator. For a statistically perfect fit where the model correctly describes the data and the weights are accurate, $\chi^2$ should approach 1.0. $$\chi^2 = \frac{1}{N - P} \sum w_i (y_{i,obs} - y_{i,calc})^2 = \left(\frac{R_{wp}}{R_{exp}}\right)^2$$ where $N$ is the number of data points, $P$ is the number of refined parameters, and $R_{exp}$ is the statistically expected minimum $R_{wp}$.

Weighting, and what an ESD means here

Two different weights appear in the program and they are not interchangeable.

  • Profile fitting weights each data point by counting statistics, \(w_i = 1/\max(y_i, \text{floor})\), the right model for a measured count.
  • Structure fitting - the Wyckoff search and the final coordinate refinement - weights each observation by \(1/\sigma^2\) from the Pawley decomposition. Counting statistics are the wrong model there: the uncertainty on an extracted intensity comes from the decomposition, not from how many photons arrived, and for a heavily overlapped reflection it is far larger than \(\sqrt{I}\). A measured 200 with an ESD of 500 gets weight \(1/200\) under counting statistics and \(1/500^2\) from its real uncertainty - three orders of magnitude of difference in how much a number consistent with anything from −300 to 700 is allowed to say.

Mixed ESD availability has one rule in both Wyckoff stages. If at least one complete unresolved group has a usable ESD, only complete groups are weighted: they receive \(1/\sigma^2\), while incomplete groups receive zero weight. If no group has a usable ESD, all groups receive unit weight. Missing uncertainties are never replaced by \(1/I\), and positive weights are normalised only for numerical conditioning, without changing their relative influence.

The residual reported for a structure is therefore \(wR(F^2)\), the weighted residual actually minimised. An unweighted figure printed next to a weighted refinement describes a fit nobody performed.

How values and uncertainties are printed

A refined value is given in the crystallographic compact form, $a = 5.5139(3)$ Å: the parenthesis is the standard uncertainty in units of the last digit shown, so this reads $5.5139 \\pm 0.0003$.

The value is rounded to the digit its uncertainty reaches, and no further. A cell edge printed as 5.439771388246059 with the su in a separate column asks you to do that rounding yourself, and everything past the fifth decimal there is the binary representation of a double rather than a measurement. The raw su is still given in its own column for anyone who needs it arithmetically.

The su itself is quoted to one significant figure, except where its leading digit is 1, which gets two: rounding 0.00012 to 0.0001 misstates the uncertainty by 17%, and 0.00010 and 0.00019 would be indistinguishable. With a leading digit of 9 the same rounding is worth at most 5%.

Where the su reaches 10 or more the compact form has no last decimal to refer to, and the report falls back to $6 \\pm 2$. An su that large means the parameter is not determined, and the notation should not disguise it.

These uncertainties come from the diagonal of the covariance matrix, scaled by the reduced $\\chi^2$. They are the precision of the fit, not the accuracy of the measurement: they exclude sample displacement not modelled by the zero-point, and any systematic error in the wavelength. They include background uncertainty only if the background was fitted; with it fixed, every one of them is conditional on the anchors being exactly right. A cell edge good to $3 \\times 10^{-4}$ Å by this measure can still be wrong in the third decimal for reasons the refinement cannot see.

Parameters constrained by symmetry

In the parameter table, the Fitted column distinguishes three things, not two:

FittedMeaningESD
YesRefined against the data. Its own.
= aNot refined independently - set equal to another parameter every time the model changes. In a hexagonal cell $b$ is not an assumption, it is $a$. That of its master, and exactly so: the same parameter has the same uncertainty, not merely a similar one.
NoHeld at a constant - $\\gamma = 120^\\circ$ in that same cell, or anything you left unticked. None. The data did not determine it.

The middle row used to be printed as No with a blank ESD, which understated the fit: it read as though $b$ had been assumed when it was determined precisely as well as $a$. The distinction matters if you quote a cell edge with its uncertainty, and it is invisible in the fit flags, where a slaved parameter and a fixed one look identical.

The same applies to the Stephens anisotropic terms: $S_{040} = S_{400}$ in a hexagonal or tetragonal cell, and $S_{202} = S_{220}$ as well in a cubic one.

χ² well below 1 means the weights are wrong, not that the fit is good

\(\chi^2 \approx 1\) is the right target, but only when \(w_i\) is the real variance of \(y_i\). The profile weight above assumes \(\sigma^2 = y\), which is exact for raw counts and for nothing else. If the intensities on the vertical axis are not counts, the weights are wrong by whatever factor separates the two scales, and \(\chi^2\) is wrong by the same factor.

Three ways a real dataset stops being counts:

  • Normalisation. Synchrotron data are routinely divided by a monitor, the ring current or the exposure time, and the result is written in arbitrary units. A pattern whose strongest peak reads 100 “a.u.” would, if those were counts, scatter by \(\pm 10\) at the peak and by about a quarter of its own height in the background. If the trace on screen is visibly smoother than that, the numbers are not counts.
  • Averaging. Multi-analyser crystals, strip and area detectors, and repeated scans all average many measurements into each point. That cuts the true noise by \(\sqrt{n}\) while leaving the intensity scale alone, so \(\sqrt{y}\) overstates \(\sigma\) by the same \(\sqrt{n}\).
  • Smoothing or rebinning. Both correlate neighbouring points, which removes point-to-point scatter without touching \(y\). This one cannot be undone after the fact - fit the unsmoothed data if you still have it.
χ² is itself the diagnostic, because the relationship is linear. Under \(w_i = 1/y_i\), multiplying every intensity by \(k\) multiplies \(\chi^2\) by exactly \(k\). So a run reporting \(\chi^2 = 0.05\) is telling you its data sit about twenty times below a count scale: scale the intensities up by twenty before loading and \(\chi^2\) arrives near 1. If you know the original counts - 500 000 at the strongest peak, normalised to 100 - that ratio should agree with the one \(\chi^2\) implies, and it is worth checking that it does.

What a wrong weighting scale does and does not change.

  • Unaffected: the refined parameters. Multiplying every weight by a constant does not move the minimum, so the cell, the profile terms and the extracted intensities are exactly what they would have been.
  • Unaffected: \(R_{wp}\) and \(R_p\). Both are ratios in which the scale cancels, which is why they remain usable while \(\chi^2\) does not.
  • Unaffected: the ESDs. Powder 5 reports \(\sigma(p) = \sqrt{\chi^2 \, C_{pp}}\), and scaling the covariance by \(\chi^2\) cancels the weighting error exactly. Cell and profile ESDs come out independent of the intensity scale; intensity ESDs scale with the intensities, so relative ESDs are invariant. That is the correct behaviour, not a lucky accident, and it is why a low \(\chi^2\) is not a reason to distrust the numbers in the table.
  • Broken: \(\chi^2\) as a figure of merit, and with it \(R_{exp} = R_{wp}/\sqrt{\chi^2}\) and any judgement of the form “\(\chi^2\) is near 1, so the model is adequate”. Until the scale is right, read \(R_{wp}\) and the difference curve instead.
The failure is asymmetric, and only one direction is safe to ignore. A \(\chi^2\) far below 1 is almost always this scale problem and leaves the model intact. A \(\chi^2\) far above 1 can also come from an over-optimistic \(\sigma\), but it is much more often a real deficiency - a missing phase, a wrong peak shape, an unmodelled background - and should not be scaled away.

Overlap clusters: which intensities mean anything

Two reflections closer together than their profile width have nearly parallel derivatives. Intensity can move from one to the other with almost no change to the calculated pattern, so the data cannot say how it divides between them: the normal matrix is near-singular in that direction and the diagonal of its inverse blows up. A large ESD there is the fit reporting, correctly, that this reflection's share is undetermined - not a failed fit, and the peak may look perfect on screen.

What is determined is the direction along which the reflections move together, so the report adds an Overlap Clusters section giving the cluster total and its ESD. That total uses the full covariance, \(\operatorname{var} = \sum_{ij}\mathrm{cov}[i][j]\), not the sum of the individual variances: the off-diagonal terms are large and negative, and it is that cancellation which makes the sum well determined. Adding variances in quadrature, as if the reflections were independent, gives a hugely pessimistic total and misses the point.

2 is included when deciding what overlaps - at high angle the satellite is displaced by several FWHM and lands on unrelated reflections, correlating pairs that look well separated in a list of Kα1 positions. Members whose \(\sigma\) exceeds their intensity are marked with an asterisk. Use the cluster total, not the individual values, for anything downstream.

Exactly coincident reflections

An overlap cluster is a set of reflections the data separates badly. This is a set it cannot separate at all. In a cubic $F$ cell, $333$ and $511$ have the same $h^2+k^2+l^2$ and therefore the same $2\theta$, the same profile, and identical columns in the normal matrix. So do $700$ and $522$, and a dozen more pairs besides. Every lattice produces them, and accidental coincidences in low-symmetry cells do the same thing.

The linear system is then exactly singular in those directions. Powder 5 factors it with a modified Cholesky that repairs only the pivots that fail, so the several hundred intensities that are determined come back untouched - a single damping term large enough to get past every coincidence would have biased those too. The affected reflections are listed in the report under Exactly Coincident Reflections, with the group total.

The split within such a group is arbitrary; the sum is not. The solver typically places the whole group intensity on one member and leaves the others near zero. That number is not a measurement, and nothing in the pattern distinguishes it from any other division adding to the same total. Read the group line, not the rows. Without this section a coincident pair reads as one strong reflection and one absent one - which, for a space-group test or a structure solution, is a conclusion the data never supported.

Calculating Observed Intensities ($I_{obs}$) for Overlapping Peaks

A simple numerical integration over a fixed angular range is insufficient for accurately determining the observed integrated intensity ($I_{obs}$) of overlapping peaks. This tool employs a more robust intensity partitioning method.

At each point in the diffraction pattern, the net observed intensity ($y_{obs} - y_{bkg}$) is distributed among all contributing Bragg reflections. This distribution is proportional to the value of each peak's calculated profile function (including both Kα1 and Kα2 components, scaled by the refined peak height) at that specific point. By integrating these partitioned "slices" of intensity for each reflection across the entire pattern (using the trapezoidal rule), the method yields a reliable $I_{obs}$ value (reported as integrated area) that correctly deconvolutes contributions from neighboring peaks.

Visual Inspection

Numerical indicators can be misleading. Visual inspection of the difference plot (observed minus calculated) is the most critical step in evaluating the fit.

  • The Difference Plot: A successful refinement should yield a difference plot that consists of random, uncorrelated noise centered on zero. The plot is scaled relative to the main pattern for visibility.
  • Systematic Residuals: The presence of structured, non-random features in the difference plot (e.g., "M-shaped" residuals around peaks, broad humps where the spline is inadequate, or un-indexed peaks) is a clear indication of systematic errors in the model. These may arise from an incorrect peak shape, unmodeled anisotropy or asymmetry, an inadequate background model (requiring adjustment of spline points), or the presence of an unaccounted-for impurity phase.

Williamson-Hall Size-Strain Analysis

For refinements utilizing the TCH (Size/Strain/Aniso) profile function, the application can automatically perform a Williamson-Hall analysis to extract approximate microstructural information. This method separates the contributions of crystallite size and microstrain to the total peak broadening by analyzing their different dependencies on the diffraction angle, $\theta$.

The analysis is based on the linear Williamson-Hall equation, where $\beta$ is the total physical peak breadth (FWHM) in radians derived from the refined sample-only broadening parameters (U, X, Y), excluding instrumental contributions (V, W): $$\beta \cos(\theta) = \frac{K\lambda}{L} + 4\epsilon \sin(\theta)$$

This equation describes a straight line when plotting $\beta \cos(\theta)$ vs. $4\sin(\theta)$. The software performs a linear least-squares fit on the relevant data points (within the fitted 2θ range) to determine the y-intercept (related to crystallite size, $L$) and the slope (related to microstrain, $\epsilon$).

Two independent estimates are reported. The TCH profile already separates the two effects analytically - $Y$ broadens as $1/\cos\theta$ (size) while $X$ and $U$ broaden as $\tan\theta$ (strain) - so size and strain can be read straight off the refined parameters with no linear fit at all. The report prints these as from Y directly (nm) and from X,U directly (%) alongside the fitted Williamson-Hall values. Close agreement between the two is a good sign; a large discrepancy usually means the broadening is anisotropic and neither isotropic number should be trusted.

Reported Values

  • Apparent Crystallite Size (nm): An estimate of the average size of the coherently scattering domains, calculated from the y-intercept of the Williamson-Hall plot (using $K=0.9$).
  • Apparent Microstrain (%): An estimate of the root-mean-square strain within the crystallites, calculated from the slope of the plot.
  • Linear Fit R²: The coefficient of determination for the linear regression. A value close to 1.0 indicates that the isotropic size/strain model is a good fit for the observed peak broadening. Values significantly less than 1.0 may suggest that broadening is anisotropic or that the model is otherwise inadequate.
Note: This Williamson-Hall analysis provides an approximation based only on the isotropic TCH parameters (U, X, Y). It does not account for anisotropic broadening effects (Stephens parameters) or instrumental contributions (V, W). For rigorous quantitative analysis, dedicated size/strain analysis software should be employed.

Data Export

One report button sits in the top-right corner of the right panel, between the light/dark toggle and the help icon. It reports whichever tab is in front, as a PDF:

Tab in frontWhat the button produces
PlotThe pattern, never a refinement. With data loaded: the calculated reflection list and the plot. With no data: the theoretical reflection list alone - h k l, the $d$-spacing, the Kα1 (and Kα2) positions, the multiplicity and $Lp$ - and no plot page, because there is nothing to plot.
Le Bail resultsThe run selected in that tab's history, with the fit to the pattern.
Pawley resultsThe run selected in that tab's history, with the fit to the pattern.
Charge FlippingThe selected run: map statistics, the built structure, and the electron-density peak table with each peak’s distance to its nearest neighbour. The peaks are the observation and the structure is an interpretation of them, so the report carries both. No powder plot - that is the Plot tab’s report.
WyckoffThe selected solution: refined positions, and the structure quality table - coordination number, mean contact distance, spread and bond-valence sum per site. The wR says the fit converged; this table says whether the result is chemistry. For a $Z$ scan, the solution currently displayed, not necessarily the best. No powder plot.
LogThe whole session: the log, followed by the most recent run from each of the four histories that has one. The per-tab reports answer “what does this run say”; this one answers “what did I do today”. Only the last run of each history is included - thirty Pawley attempts would make a document nobody reads, and the earlier ones are still reachable one at a time from their own tab.

A refinement is reported only from its own tab, and only for the run selected in that tab's history selector. The Plot tab reports the pattern and nothing else - otherwise the same button on the same tab would produce a Le Bail report after a Le Bail run and a Pawley one after a Pawley run, with nothing on screen saying which you were about to get.

It is never greyed out. Press it where there is nothing to report and it says what is missing, which is more than a disabled button ever conveyed. This replaces the four separate Generate PDF buttons that used to sit one per results tab, each with its own enabled/disabled rule to keep in step with the run history.

Save report on the Le Bail and Pawley tabs still writes the plain-text version: all statistical indicators, refined parameters with their ESDs, the Williamson-Hall results where applicable, the declared Lorentz–polarisation model, the background spline points, the reflection table below, and a point-by-point list of observed, calculated, background and difference intensities across the fitted range. The PDF carries the same reflection table; rows too wide for the page are set smaller rather than clipped.

The reflection table

Both the text and PDF reports list every reflection inside the fitted range with the complete chain from peak to structure factor. Le Bail and Pawley share the same columns; Pawley adds one.

ColumnMeaning
h,k,l Canonical member of the reflection orbit. One row per orbit, not per index triple.
2th_corr Peak position after the zero shift and any displacement or transparency correction - where the peak actually sits, not the ideal Bragg angle.
dInterplanar spacing in Ångström.
m Powder multiplicity: the size of the orbit under the Laue group. See Reflections & Multiplicities.
Lp Lorentz–polarisation factor, evaluated at 2th_corr with the declared model. See Lorentz–Polarisation Factor.
I_hkl Integrated intensity of the whole reflection - peak height times profile area, summed over the Kα1/Kα2 pair, with the scale factor applied. This is an area, not a height: a height underweights the high-angle reflections by the full profile broadening, which typically doubles across a scan.
sigma(I) Standard uncertainty on the area. For Pawley it comes from the covariance matrix, converted from a height ESD; for Le Bail it is the counting statistics of the observed points propagated through the partition fractions.
|Fo| $\sqrt{I_{hkl} / (m \cdot Lp \cdot (1 + I_2/I_1))}$, on an arbitrary scale. Blank for a non-positive intensity - see the note below.
I_obs (Pawley only) The same reflection re-integrated from the observed pattern by partitioning the net counts over the calculated profile. A cross-check on the refined parameter, which is what I_hkl holds for a Pawley fit. Large disagreement points at an overlap the fit has resolved badly. For Le Bail the two are the same integral by construction, so the column is omitted.

A legend above the table restates the polarisation model, the formulae and the value of $K$ actually used, so every $|F_o|$ can be reproduced from the printed numbers without knowing which convention the program follows.

Weak reflections and Non-Negative Least Squares (NNLS)

A Pawley intensity can naturally tend below zero when the background runs above the data across a peak's window. The NNLS solver actively bounds these intensities at zero (so I_hkl is reported as 0), preventing unphysical negative ripples. However, the corresponding standard uncertainty sigma(I) is correctly derived from the unconstrained covariance matrix. This tells downstream methods (like the French–Wilson correction used in charge flipping) exactly how poorly determined that zero value is, preventing the upward bias that a naive zero-clipping would introduce.


References & Further Reading

Pawley Method:
Pawley, G. S. (1981). "Unit-cell refinement from powder diffraction scans". Journal of Applied Crystallography, 14(6), 357-361.
Le Bail Method:
Le Bail, A., Duroy, H. & Fourquet, J.L. (1988). "Ab-initio structure determination of LiSbWO6 by X-ray powder diffraction". Materials Research Bulletin, 23(3), 447-452.
Charge Flipping:
Oszlányi, G. & Sütő, A. (2004). "Ab initio structure solution by charge flipping". Acta Crystallographica Section A, 60(2), 134-141.
Charge Flipping - practice and variants:
Oszlányi, G. & Sütő, A. (2008). "The charge flipping algorithm". Acta Crystallographica Section A, 64(1), 123-134.
Charge Flipping with symmetry and powder data:
Palatinus, L. & Chapuis, G. (2007). "SUPERFLIP – a computer program for the solution of crystal structures by charge flipping in arbitrary dimensions". Journal of Applied Crystallography, 40(4), 786-790.
Charge Flipping from powder data (intensity repartitioning):
Baerlocher, C., McCusker, L. B. & Palatinus, L. (2007). "Charge flipping combined with histogram matching to solve complex crystal structures from powder diffraction data". Zeitschrift für Kristallographie, 222(2), 47-53.
Polarisation with a crystal monochromator:
Azaroff, L. V. (1955). "Polarization correction for crystal-monochromatized X-radiation". Acta Crystallographica, 8(11), 701-704.
Lorentz and polarisation factors for powders:
Klug, H. P. & Alexander, L. E. (1974). X-Ray Diffraction Procedures for Polycrystalline and Amorphous Materials, 2nd ed. Wiley, New York.
Polarisation conventions in modern refinement software:
Toby, B. H. & Von Dreele, R. B. (2013). "GSAS-II: the genesis of a modern open-source all purpose crystallography software package". Journal of Applied Crystallography, 46(2), 544-549. (Source of the single-parameter polarisation convention used here.)
Posterior intensities for weak and negative reflections:
French, S. & Wilson, K. (1978). "On the treatment of negative intensity observations". Acta Crystallographica Section A, 34(4), 517-525.
GSAS Profile Functions:
Larson, A. C. & Von Dreele, R. B. (2004). "General Structure Analysis System (GSAS)". Los Alamos National Laboratory Report LAUR 86-748.
TCH Profile Function:
Thompson, P., Cox, D. E. & Hastings, J. B. (1987). "Rietveld refinement of Debye-Scherrer synchrotron X-ray data from Al2O3". Journal of Applied Crystallography, 20(2), 79-83.
Stephens Anisotropy Model:
Stephens, P. W. (1999). "Phenomenological model of anisotropic peak broadening in powder diffraction". Journal of Applied Crystallography, 32(2), 281-289.
Parallel Tempering:
Swendsen, R. H., & Wang, J. S. (1986). "Replica Monte Carlo simulation of spin-glasses". Physical Review Letters, 57(21), 2607.
Non-negative Least Squares (NNLS):
Lawson, C. L. & Hanson, R. J. (1974). Solving Least Squares Problems. Prentice-Hall, Englewood Cliffs, NJ.
Separable least squares (variable projection):
Golub, G. H. & Pereyra, V. (1973). "The differentiation of pseudo-inverses and nonlinear least squares problems whose variables separate". SIAM Journal on Numerical Analysis, 10(2), 413–432.
Kaufman, L. (1975). "A variable projection method for solving separable nonlinear least squares problems". BIT Numerical Mathematics, 15(1), 49–57. (The approximation used when differentiating the reduced objective: the linear parameters are held fixed inside each finite-difference probe, and re-solved at the trial point.)
Modified Cholesky (rank-deficient normal matrices):
Gill, P. E. & Murray, W. (1974). "Newton-type methods for unconstrained and linearly constrained optimization". Mathematical Programming, 7(1), 311–350. (Used to repair only the pivots that fail, so exactly coincident reflections do not damp the intensities that are determined.)
Monotonic Splines:
Fritsch, F. N., & Carlson, R. E. (1980). "Monotone Piecewise Cubic Interpolation". SIAM Journal on Numerical Analysis, 17(2), 238–246.
Probabilistic Space-Group Determination:
Markvardsen, A. J., David, W. I. F., Johnson, J. C. & Shankland, K. (2001). "A Probabilistic Approach to Space-Group Determination from Powder Diffraction Data". Acta Crystallographica Section A, 57(1), 47-54.
Bond-valence method:
Brown, I. D. & Altermatt, D. (1985). "Bond-valence parameters obtained from a systematic analysis of the inorganic crystal structure database". Acta Crystallographica Section B, 41(4), 244-247.
Bond-valence parameters used here:
Brese, N. E. & O'Keeffe, M. (1991). "Bond-valence parameters for solids". Acta Crystallographica Section B, 47(2), 192-197. (Source of the \(R_0\) table and of \(b = 0.37\) Å.)
Bond valence as a structure-validation tool:
Brown, I. D. (2009). "Recent developments in the methods and applications of the bond valence model". Chemical Reviews, 109(12), 6858-6919.
Covalent radii (bond drawing in the structure plot):
Cordero, B., Gómez, V., Platero-Prats, A. E., Revés, M., Echeverría, J., Cremades, E., Barragán, F. & Alvarez, S. (2008). "Covalent radii revisited". Dalton Transactions, (21), 2832-2838.
cctbx - Computational Crystallography Toolbox:
Grosse-Kunstleve, R. W., Sauter, N. K., Moriarty, N. W., & Adams, P. D. (2002). "The Computational Crystallography Toolbox: crystallographic algorithms in a reusable software framework". Journal of Applied Crystallography, 35(1), 126-136. (Used for space group systematic absence rules).

About This Tool

The powder5 toolkit was developed by Nita Dragoe from Université Paris-Saclay as a simple browser-based implementation of powder pattern decomposition methods. It is a long-time successor of PowderV2 (Dragoe, N. (2001). J. Appl. Cryst., 34, 535) and has been updated to include the Pawley method and modern global optimization algorithms.

All numerical work - the skyline Cholesky behind the covariance matrix and the ESDs, the banded solver for the separable Pawley intensities, and the least-squares machinery itself - is implemented locally. An earlier version depended on math.js for these; it was removed so that a refinement can never be blocked by a content-delivery network, and so the application works fully offline. Charting uses Chart.js; all pan, zoom and pinch behaviour is implemented directly against the chart's scales, with no plugin. PDF generation uses jsPDF and html2canvas. Space-group symmetry data is derived from the Computational Crystallography Toolbox (cctbx).

This document was updated with the assistance of an AI.

Disclaimer: This application is provided for educational and research purposes. While it implements standard and robust algorithms, it is not a substitute for fully validated, peer-reviewed software packages (e.g., GSAS-II, FullProf, TOPAS) for analyses intended for publication.