Skip to main content

rietx

CI PyPI

API-first Rietveld refinement of powder X-ray diffraction data: a typed, JSON-round-trippable Python library with staged refinement plans, an analytic Jacobian, and a fit report built for programs — including LLM agents — to act on. MIT licensed.

It is for people who refine powder data from code — a script, a beamline pipeline, an autonomous lab, an agent loop — and for interactive users who want the same machinery with a local GUI over it.

Install

pip install rietx            # Python >= 3.11; numpy/scipy core
pip install "rietx[viz]"     # + matplotlib and plotly rendering

One fit, end to end

Condensed from examples/nac_11bm.py (APS 11-BM synchrotron data, NAC with a CaF₂ impurity). The walkthroughs have one authority and it is the scripts in examples/: the manual includes them verbatim and the test suite executes them.

import rietx as rx

data = rx.read_pattern("11BM_NAC.fxye")              # esd column read from file
structure = rx.Structure.from_cif("cod_1000236.cif")
instrument = rx.Instrument.debye_scherrer(wavelength=0.4139090)

ref = rx.Refinement(structure, instrument)

# structure-free Le Bail first: cell + profile + background
lebail = ref.fit(data, mode="lebail", two_theta_limits=(2, 24))

# then Rietveld under the staged turn-on order of McCusker et al. (1999)
result = ref.fit(data, plan="mccusker_default", two_theta_limits=(2, 24))

report = rx.build_report(result)                     # numbers, not pixels
result.plot(path="fit.png")                          # obs/calc/diff/ticks

Output of the full script (trimmed at the ):

Le Bail:  status=converged  Rwp=0.1457  GoF=5.52  a=10.251214 A
Rietveld: status=converged  Rwp=0.0932  GoF=3.53
          a = 10.251216 +/- 0.000046 A (COD reference 10.257(1); high-accuracy powder ~10.2497-10.2506)
          [warning] BOUND_HIT: phases.1.atoms.0.biso refined to its bound

FitReport: Rwp=0.0932 GoF=3.53; 52 regions, top 15 shown (74% of χ²); 54 unmatched observed peak(s); …
  region  14.22- 14.54 deg  localRwp=0.154  chi2share=13.6%  max|d/sig|=49.5
  …

Refinement history (every stage is a restorable checkpoint):
t5544a638  13 nodes  data=11BM_NAC.fxye
 n0000  root                   —
└─  n0001  stage:bkg              Rwp 3.1725
   …
                                 └─ *n0012  stage:biso             Rwp 0.0932

What it does

Each clause links to its manual chapter or worked example.

  • Rietveld, Le Bail and Pawley modes, multi-phase, with staged plans following the IUCr guidelines, correlation/bound/background guards, and crystal-system and site-symmetry constraints wired automatically.
  • A forward model with documented physics: TCHZ and true-Voigt profiles, FCJ axial asymmetry, Kα doublets on the NIST SRD 128 scale, anomalous dispersion on by default, capillary and flat-plate absorption, preferred orientation, extinction, surface roughness, anisotropic ADPs and Stephens anisotropic strain. Every physics function cites its reference in the docstring.
  • Bounded least squares (scipy TRF, or an LM driver carrying linear-inequality constraints) with an analytic Jacobian and Bérar-Lelann-inflated esds — how the numbers are estimated.
  • Pattern readers for .xy/.xye, GSAS raw, pdCIF, .chi, Rigaku .ras/.rasx, Bruker .uxd/.brml/.raw, PANalytical .xrdml — dispatched on content, with structured diagnostics for every repair a reader makes; exporters for reflection tables, refinement CIF and QPA tables.
  • A three-layer FitReport: model-free diagnostics, misfit attributed to physical causes, and typed suggested actions — every layer gated to abstain rather than guess.
  • A branchable refinement history: every stage auto-commits a restorable node; checkout, branch, merge, cherry-pick, replay. Multi-histogram joint fits, and warm-started sequential series for in-situ and parametric runs — with a forward-vs-backward path-dependence check, because a chained trajectory is path-dependent by construction.
  • Unit-cell indexing: peak picking with esds, three consensus-gated search engines, whole-profile Le Bail validation, extinction-symbol ranking — and an API that cannot express a confident wrong singleton.
  • Agent surfaces: rietx.agent.refine_json (one JSON call, schema generated from the live registries), capabilities(), streaming events, and cooperative cancellation.
  • A local refinement GUI, rietx gui (import → edit → refine → inspect → branch → export; a Svelte build served by a stdlib server, nothing leaves the machine). The GUI ships as a beta: its panels are still moving, it is deliberately undocumented at 1.0, and the API — not the GUI — carries the stability promise.

What it does not do

  • Constant-wavelength X-ray only, in three geometries (capillary, Bragg-Brentano, flat-plate transmission). Fundamental-parameters profiles, neutron and time-of-flight data, and spherical-harmonics texture are deferred, not planned — see the manual's scope statement.
  • Indexing returns cells and ranked extinction symbols, not solved structures.
  • A sequential series is session-scoped at 1.0: its trajectories are returned, not persisted. The GUI's HTTP routes and its text document are provisional. The full list is in the compatibility promise.

Validation

Nine real-data acceptance suites run in CI, each tolerance chosen to match what its reference actually is — a certified value, another code's converged result, a published participant spread, or a pre-registered prediction. Highlights: NIST SRM 660c LaB₆ lands +28 ppm from NIST's recomputed cell for that dataset; the GSAS-II fluorapatite tutorial agrees with GSAS's own fit within 116 ppm on identical channels; the IUCr QPA round robin comes back with worst-case 1.4 wt% error once anomalous dispersion is applied — a parameter-free correction whose effect was written down before the refits. docs/VALIDATION.md is the full matrix, generated from the test suite so it cannot drift from what is actually asserted; the SRM 660c gap to the certificate's ±8×10⁻⁶ Å band is documented there rather than tuned away.

Documentation

  • The manual — Part 1 is the task-ordered guide to the library (install → one fit → what the fit did → the numbers → the report → what is on disk → driving it from a program → the compatibility promise); Part 2 is the theory: numbered equations transcribed from the physics docstrings, with the convention warnings that decide whether a number transfers between Rietveld codes.
  • AGENT_PROTOCOL.md — the operating protocol for automated callers: turn-on order, degeneracies, what each diagnostic code forbids you from reporting. Also shipped inside the wheel as rietx/data/AGENT_PROTOCOL.md, so it resolves with no network.
  • Release notes for 1.0.0 and the compatibility promise: the data contracts (schemas, the agent envelope, the project format, the event stream) are frozen at 1.0; the Python call surface freezes as the manual documents it, and undocumented public items are provisional until their chapter lands.

Development

git clone https://github.com/yue-here/rietx && cd rietx
uv venv --python 3.12 && uv pip install -e ".[dev]"
.venv/bin/python -m pytest -n auto --dist loadgroup -m "not slow"   # ~1-3 min
.venv/bin/python -m pytest -n auto --dist loadgroup                 # + real-data acceptance, ~15-30 min
.venv/bin/python -m ruff check src tests examples

--dist loadgroup is not optional — it keeps shared expensive fixtures on one worker. Wall clock is quoted as a range on purpose: machine state moves it further than most changes do. See CONTRIBUTING.md for the test ladder and style, and AGENTS.md if your contributor is an agent.

License and credits

MIT. Algorithms are independent implementations from the published literature — every physics function cites author, year and journal; the source and licence map is ATTRIBUTION.md, and test-data provenance is tests/data/README.md. GPL codebases (BGMN, Profex, xrayutilities) were studied conceptually only; no code was ported. CIF and symmetry handling is gemmi. To cite the package, use CITATION.cff.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rietx-1.0.0.tar.gz (4.5 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rietx-1.0.0-py3-none-any.whl (2.2 MB view details)

Uploaded Python 3

File details

Details for the file rietx-1.0.0.tar.gz.

File metadata

  • Download URL: rietx-1.0.0.tar.gz
  • Upload date:
  • Size: 4.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.11

File hashes

Hashes for rietx-1.0.0.tar.gz
Algorithm Hash digest
SHA256 1b771eefe34be24e1fd678f7d9e6e2c4b0106b7b3124290d3de8aa4fca4c0a6f
MD5 38a4e000f7dbbd22f47ea81a94882364
BLAKE2b-256 7bd44a8228423ab987c4e727ea9c3ffad9d4ff3ced406e0b708dfd6e97299e74

See more details on using hashes here.

File details

Details for the file rietx-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: rietx-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 2.2 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.11

File hashes

Hashes for rietx-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dff1f8a6ac2253a12c54f510ec762ae83dadb532da2820ff6b91a0b686c28d2d
MD5 994ee0de3d96e2eee1bdb9c93746bb63
BLAKE2b-256 7fcfff609f4e89960ff606b03ef3293509222e25476391703458adad52734fb3

See more details on using hashes here.

Release history Release notifications | RSS feed

1.4.0

2 files

1.3.0

2 files

1.2.0

2 files

1.1.0

2 files

1.0.1

2 files

This release

1.0.0 This release

2 files

0.0.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page