Skip to main content

midas-dfxm

Differentiable forward + inverse for Dark-Field X-ray Microscopy (DFXM).

DFXM images a bulk grain through a magnifying objective (CRL / MLL) placed on one diffracted beam. The objective is a reciprocal-space bandpass: a sample voxel contributes intensity to its magnified detector pixel only if its local scattering vector falls inside the instrument's resolution function for the current goniometer setting. Rocking the sample (a mosaicity scan) maps local orientation; scanning 2θ / energy (a strain scan) maps local d-spacing; weak-beam settings image individual dislocations.

This package models that signal from a voxelised deformation-gradient field F(r), and (later phases) inverts a DFXM image stack back to F(r) and to per-dislocation defect types (edge/screw, Burgers vector, slip system).

Reuse-first, no re-porting. Built on the MIDAS differentiable stack: midas-stress (orientation/strain), midas-hkls (structure factors, form factors, DWF), midas-2d (continuous-q structure factor, resolution convolution), midas-defect (Stroh anisotropic-elasticity contrast solver, slip systems, GND, planar-defect rods), midas-invert (fit / UQ / experiment design), midas-distortion (detector model). Everything is torch-differentiable and device-portable (CPU / CUDA / MPS).

See implementation_plan.md for the full roadmap, physics reuse map, phase gates, and honest scope/novelty gates.

Status

Pre-alpha (v0.0.1a0). Phases 0,1,3,4,5 + a simulation-anchored roadmap implemented and tested — 64 tests pass (CPU + MPS; 3 CUDA-skipped), ~2400 LOC.

Highlights:

  • Phase 4 (defect typing): anisotropic-elasticity (Stroh) per-dislocation forward; g·b invisibility; edge/screw character; Burgers-vector recovery.
  • Phase 5 (inverse typing): identify_dislocation recovers slip system, character, core position, and the Burgers-vector sign (the gap Borgi 2025 leaves open) from multi-reflection weak-beam images.
  • Phase 3 (field inverse): full strain-tensor recovery + identifiability + UQ; honest finding — regularisation helps at low SNR, ~neutral at high SNR.
  • #1 physics coupling: recover a GND density end-to-end through the forward (Nye κ = ρb) — the DFXM↔DDD/CP interface, differentiably.
  • #2 credibility anchor: independent numpy oracle agrees bit-for-bit (~1e-16).
  • External-field ready: field_from_deformation_gradient consumes an external F(r) with zero rework.

See SIMULATION_CATALOG.md and the shipped tutorials in midas_dfxm/examples/, each runnable as a module:

python -m midas_dfxm.examples.tutorial_dislocation_typing

Figures land in dev/paper/figures/ inside a clone, ./figures otherwise; set MIDAS_FIGDIR to send them somewhere else.

Earlier milestone note

Phases 0–1 implemented and tested (30 passing, CPU + MPS):

  • Phase 0 — conventions + field. conventions.py (lab/sample/imaging frames, goniometer), field.py (DeformationField, the kinematic deform operator Q = F⁻ᵀ G0, polar decomposition F = R·U), io.py (synthetic-field generators: perfect crystal, orientation gradient, uniform strain, isotropic screw dislocation; plus a stub loader for an external collaborator field).
  • Phase 1 — geometrical-optics forward. resolution.py (anisotropic-Gaussian reciprocal-space acceptance), optics.py (magnifying inclined projection + bilinear detector splat), scan.py (mosaicity / rocking / strain scan builders, Bragg-angle helpers), forward.py (dfxm_image, dfxm_stack, mosaicity_curve).

Validated analytic limits: rocking-curve FWHM = 2√(2ln2)·σ⊥ / |axis×q|, FCC forbidden reflection is dark, uniaxial strain shifts |Q| correctly; plus gradcheck on the deform operator and end-to-end autograd to F and the instrument widths.

Next: Phase 2 (field forward on a collaborator's realistic F(r) when it lands), Phase 3 (field inverse + identifiability study), Phase 4 (per-dislocation forward via the Stroh solver + g·b defect typing), Phase 5 (inverse defect discovery).

Quickstart

import torch
from midas_dfxm import (
    make_uniform_field, with_orientation_gradient,
    GoniometerSetting, reference_q_nom, aligned_resolution,
    ObjectiveOptics, bragg_two_theta_deg, dfxm_image,
)

# A curved crystal grain (smooth lattice rotation across x).
field = make_uniform_field(shape=(64, 64, 1), spacing_um=0.5)
field = with_orientation_gradient(field, axis=(0, 0, 1), deg_per_um=0.01, along=0)

hkl, center = (1, 1, 1), GoniometerSetting()
q_nom = reference_q_nom(field, hkl, center)
res = aligned_resolution(q_nom, sigma_par=5e-3, sigma_perp=5e-3)
tt = bragg_two_theta_deg(float(torch.linalg.vector_norm(q_nom)), wavelength_A=0.172979)
optics = ObjectiveOptics(two_theta_deg=tt, magnification=10.0, detector_shape=(256, 256))

image = dfxm_image(field, hkl, center, res, optics)   # (256, 256), differentiable

Tests

# macOS: work around the duplicate-OpenMP-runtime abort (torch + MIDAS siblings).
export KMP_DUPLICATE_LIB_OK=TRUE
python -m pytest tests/ -q

Markers: unit (analytic correctness), autograd (gradcheck / autograd), device (CPU/CUDA/MPS parity), slow (heavy integration).

Metadata

Release files for midas-dfxm 0.3.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for midas-dfxm 0.3.3
File Size Uploaded
midas_dfxm-0.3.3.tar.gz 165.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for midas-dfxm 0.3.3
File Interpreter ABI Platform
midas_dfxm-0.3.3-py3-none-any.whl Python 3 none any Details

Total release size: 306.9 kB

Release files / midas_dfxm-0.3.3.tar.gz

Download URL midas_dfxm-0.3.3.tar.gz
Size 165.4 kB
Tags Source
SHA-256 checksum
How to use checksums
648c598a5de8c1d2e9b4f3ecfab7854dc9ce0d4dd552d2c772e14d6c2ac5ef73
BLAKE2b-256 checksum
How to use checksums
fec8f0d28b972c69fba85f6e3c10230602ec75b5f1309dc4319a8855fc886fd0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 14, 2026.

Transparency log

Release files / midas_dfxm-0.3.3-py3-none-any.whl

Download URL midas_dfxm-0.3.3-py3-none-any.whl
Size 141.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
df8319ee7a1b2847d5ac1bf4d26c1c26e3b9a6379b23eece38f723c6ce810074
BLAKE2b-256 checksum
How to use checksums
9b6a4f721e0a5d3d3b07cb66e442ddfe9a0528e13e8c8af0d60da9fb4d4e1e68
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 14, 2026.

Transparency log

Release history Release notifications | RSS feed

0.14.0

2 release files

0.13.0

2 release files

0.12.0

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

This release

0.3.3 This release

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release 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