Skip to main content

Geometrical-optics forward model for dark-field X-ray microscopy

Project description

DFXM optics schematic — monochromator, slits + condenser, sample on goniometer, CRL objective, detector

DFXM Geometrical-Optics Forward Model

A physics-based forward model that simulates Dark-Field X-ray Microscopy images of crystals with dislocations — published in the Journal of Applied Crystallography (2024).

What this is

Dark-Field X-ray Microscopy (DFXM) is a synchrotron technique for imaging crystal defects with sub-micron resolution deep inside bulk materials. This package implements the geometrical-optics (GO) forward model described in Borgi et al., J. Appl. Cryst. 57, 358 (2024). Given a dislocation configuration and a beamline geometry, it computes the expected detector image in two stages:

  1. Reciprocal space — Monte Carlo ray tracing samples the instrument's angular and energy acceptance through monochromator, slits, condenser, CRL objective, and detector to build a voxelized resolution kernel Resq_i(q_rock', q_roll, q_2θ).
  2. Direct space — the deformation field around each dislocation (Hirth & Lothe, mixed edge/screw via the slip-system angle α) is rotated into the imaging frame and convolved with the kernel to produce the detector image.

The default configuration targets the ID06 beamline at ESRF: Al 111 reflection at 17 keV, 88-lenslet Be CRL, ID06 goniometer geometry.

What it produces

A typical weak-beam DFXM image with five random edge dislocations in single-crystal aluminium, generated by the pipeline:

Weak-beam DFXM forward model showing 5 random edge dislocations in a single crystal of aluminium

Each dislocation has its own Burgers vector, line direction, and slip-plane normal; the local contrast reflects how the lattice distortion field around each defect couples into the instrument's acceptance.

How it works — reciprocal space

The reciprocal-space stage draws Monte-Carlo rays from truncated-Gaussian distributions over the incident divergences (ζ_v, ζ_h) and energy bandwidth ΔE/E, filters them through the CRL numerical aperture, and bins the accepted q-vectors (q_rock', q_roll, q_2θ) into a 3D kernel. The figure below shows the raw point cloud for 50 000 rays at the default Al 111 / 17 keV setting:

3D scatter plot of the reciprocal-space acceptance kernel with 2D projections onto each back-wall

The central black cloud is the angular/energy acceptance in the imaging coordinate system; the colored projections show its 2D shadows on each back-wall. Optional [beamstop] modes (square aperture in the BFP, knife edge, or absorbing tungsten wire) can be enabled to study weak-beam contrast enhancement.

How it works — direct space → detector

After the kernel is built, the forward stage rocks the sample through the Bragg condition over a (ϕ, χ) grid and renders the expected detector image at each angle. Taking the per-pixel center of mass of each pixel's rocking curve gives the local lattice tilt — one center-of-mass (COM) map per rocking axis, COM_ϕ and COM_χ (the two together make up the mosaicity). The geometrical-optics model predicts the same field directly, as the projection qi of the deformation onto the imaging axes, so the two should agree. The figure below makes that comparison for a low-angle wall of edge dislocations:

Four-panel comparison of DFXM center-of-mass maps against the geometric-optics qi field for a wall of five edge dislocations. Top row: the negated phi and chi center-of-mass maps. Bottom row: the qi_1 and qi_2 fields at the z=0 sample plane. Each top panel matches the panel below it.

Top row: the (negated) ϕ and χ center-of-mass (COM) maps extracted from the rocking stack. Bottom row: the geometrical-optics qi₁ / qi₂ fields at the z = 0 sample plane. Wall of five edge dislocations, Al 111 @ 17 keV, computed with the v2.1.0 closed-form (analytic) resolution backend; all panels share a fixed ±10⁻⁴ rad color scale. The −COM ≈ qi correspondence — each top panel reproducing the one beneath it — recovers the result of Borgi et al. (2024).

Stack

  • Language: Python 3.11+
  • Key libraries: NumPy, SciPy, numba, h5py, matplotlib; optional gemmi for CIF input
  • Geometry: symmetric and oblique-angle diffraction; single- and multi-reflection runs; any of the seven crystal systems via explicit cell parameters or a CIF file
  • HPC: Batch templates for LSF (DTU Sophia) and SLURM (ESRF clusters); in-node config fan-out for large image batches
  • I/O: HDF5 / BLISS-schema outputs (master + per-scan layout) readable by silx and darfix
  • Testing: pytest (900+ tests) with reference golden datasets; mypy-clean
  • License: MIT

Install

pip install dfxm-geo
# or, via conda-forge:
conda install -c conda-forge dfxm-geo

CIF crystal-structure input is optional and pulls in gemmi:

pip install "dfxm-geo[cif]"      # or: conda install -c conda-forge gemmi

or from source:

git clone https://github.com/borgi-s/Geometrical_Optics_master.git
cd Geometrical_Optics_master
python -m venv .venv && source .venv/bin/activate     # or .venv\Scripts\activate on Windows
pip install -e ".[dev]"
pytest                                                # smoke tests against reference data

Run

A literally empty .toml file is a valid input (since v2.0.0): the empty case produces a single detector image of a single canonical FCC dislocation at the origin, Al 111 reflection at 17 keV.

If you installed from PyPI/wheel (no repo clone), first create local copies of the config templates:

dfxm-init   # writes ./configs/default.toml and the rest of the template tree
# one-time bootstrap (generates reciprocal-space kernel ~50 s; reusable thereafter):
dfxm-bootstrap --config configs/default.toml

# forward simulation:
dfxm-forward    --config configs/default.toml   --output ./run_output

# dislocation identification (image-to-library matching):
dfxm-identify   --config configs/identification_single.toml --output ./id_output

# enumerate the reflections reachable for a crystal mount + beam energy:
dfxm-find-reflections --config configs/default.toml

Every block in configs/default.toml shows the value the pipeline would use if the block were omitted — edit any block to override, delete to fall back to the default. For larger parameter sweeps, see lsf/ and slurm/ for ready-to-submit batch scripts. Output is written to a BLISS-schema HDF5 file (master + per-scan layout) that silx and darfix can consume directly.

Beyond the default symmetric Al 111 geometry, a [geometry] mode = "oblique" block tilts the diffraction vector off the symmetric condition, and [[reflections]] runs several reflections of the same crystal in one pass. The crystal cell is set either with explicit parameters ([crystal] lattice, a, b, c, the cell angles) or by pointing at a structure file — [crystal] cif = "path/to/file.cif" populates the cell and space group, and systematically-absent reflections are filtered out automatically. dfxm-find-reflections lists the accessible (θ, η, ω) groups for any mount so you can pick a reflection before bootstrapping its kernel.

Cite

If this code or the model is useful in your work, please cite:

Borgi, S., Ræder, T. M., Carlsen, M. A., Detlefs, C., Winther, G., & Poulsen, H. F. (2024). Simulations of dislocation contrast in dark-field X-ray microscopy. Journal of Applied Crystallography 57, 358–368. doi:10.1107/S1600576724001183

A second paper applying the model to individual-dislocation identification:

Borgi, S., Winther, G., & Poulsen, H. F. (2025). Individual dislocation identification in dark-field X-ray microscopy. J. Appl. Cryst. 58, 813–821.

Background

Developed during PhD research at DTU Physics in collaboration with ESRF (European Synchrotron Radiation Facility). The forward model is a Python port and substantial extension of the MATLAB script first introduced by Poulsen et al., J. Appl. Cryst. 54, 1555 (2021). The microscope schematic and example output above are adapted from S. Borgi, Dislocation identification using dark-field X-ray microscopy in bulk single-crystalline materials (PhD thesis, DTU Physics, 2025), Chapter 3.

Roadmap

Latest release: v2.5.1 (2026-06) — identification throughput work (persistent worker pool, fused numba strain engine, config fan-out) reaching ≥5× on cluster nodes. Earlier milestones added oblique-angle diffraction geometry (v2.1–v2.3), the closed-form analytic resolution backend, and multi-reflection runs.

In development for v3.0.0 — general crystal-cell geometry (all seven systems) and CIF crystal-structure input with space-group extinction rules, broadening the model beyond cubic FCC toward ceramics and other lattices. Slip-system registries for FCC and BCC (24 systems, {110}⟨111⟩ + {112}⟨111⟩) have already landed (see docs/crystal-structures.md); HCP (basal/prismatic/pyramidal ⟨c+a⟩ families) follows in Stage 4.3b. Also tracked: Zenodo deposit of reference datasets, and darling/darfix interop polish (see follow-up issues).

Project details


Download files

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

Source Distribution

dfxm_geo-3.0.0.tar.gz (423.9 kB view details)

Uploaded Source

Built Distribution

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

dfxm_geo-3.0.0-py3-none-any.whl (208.1 kB view details)

Uploaded Python 3

File details

Details for the file dfxm_geo-3.0.0.tar.gz.

File metadata

  • Download URL: dfxm_geo-3.0.0.tar.gz
  • Upload date:
  • Size: 423.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dfxm_geo-3.0.0.tar.gz
Algorithm Hash digest
SHA256 8a5a3e130b5d78b39f6acf3e69540944a9515221abe866d3fb8b2a1af94ec70b
MD5 63997eeddd210a90cb54449b9e1510ba
BLAKE2b-256 2717799acfa12c9ed2ae6b78fd0dfd29de72a556b532f125e5f0486c0ca066aa

See more details on using hashes here.

Provenance

The following attestation bundles were made for dfxm_geo-3.0.0.tar.gz:

Publisher: publish.yml on borgi-s/Geometrical_Optics_master

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dfxm_geo-3.0.0-py3-none-any.whl.

File metadata

  • Download URL: dfxm_geo-3.0.0-py3-none-any.whl
  • Upload date:
  • Size: 208.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dfxm_geo-3.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9d13f1d4262f794f9bebd4075869c2fd7cbc4cbf2c547ca6912778cd3be1d164
MD5 0d308fcf6132ac2c64eecae377f72099
BLAKE2b-256 c74479e926f82db55faace007a1c49da9496626118191b684e07f83d8f976d71

See more details on using hashes here.

Provenance

The following attestation bundles were made for dfxm_geo-3.0.0-py3-none-any.whl:

Publisher: publish.yml on borgi-s/Geometrical_Optics_master

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page