midas-dfxm 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- midas_dfxm-0.1.0/LICENSE +53 -0
- midas_dfxm-0.1.0/PKG-INFO +137 -0
- midas_dfxm-0.1.0/README.md +108 -0
- midas_dfxm-0.1.0/midas_dfxm/__init__.py +281 -0
- midas_dfxm-0.1.0/midas_dfxm/aberration.py +163 -0
- midas_dfxm-0.1.0/midas_dfxm/beamline.py +118 -0
- midas_dfxm-0.1.0/midas_dfxm/coded_aperture.py +216 -0
- midas_dfxm-0.1.0/midas_dfxm/coherence.py +181 -0
- midas_dfxm-0.1.0/midas_dfxm/conventions.py +125 -0
- midas_dfxm-0.1.0/midas_dfxm/cpfem.py +109 -0
- midas_dfxm-0.1.0/midas_dfxm/detect.py +221 -0
- midas_dfxm-0.1.0/midas_dfxm/detector.py +91 -0
- midas_dfxm-0.1.0/midas_dfxm/dislocation.py +345 -0
- midas_dfxm-0.1.0/midas_dfxm/field.py +153 -0
- midas_dfxm-0.1.0/midas_dfxm/field_inverse.py +373 -0
- midas_dfxm-0.1.0/midas_dfxm/finite_beam.py +64 -0
- midas_dfxm-0.1.0/midas_dfxm/forward.py +157 -0
- midas_dfxm-0.1.0/midas_dfxm/generators.py +166 -0
- midas_dfxm-0.1.0/midas_dfxm/inverse.py +193 -0
- midas_dfxm-0.1.0/midas_dfxm/io.py +177 -0
- midas_dfxm-0.1.0/midas_dfxm/joint_inverse.py +164 -0
- midas_dfxm-0.1.0/midas_dfxm/mosaicity_fit.py +175 -0
- midas_dfxm-0.1.0/midas_dfxm/optics.py +121 -0
- midas_dfxm-0.1.0/midas_dfxm/physics.py +182 -0
- midas_dfxm-0.1.0/midas_dfxm/pink_beam.py +139 -0
- midas_dfxm-0.1.0/midas_dfxm/plasticity.py +174 -0
- midas_dfxm-0.1.0/midas_dfxm/resolution.py +150 -0
- midas_dfxm-0.1.0/midas_dfxm/scan.py +92 -0
- midas_dfxm-0.1.0/midas_dfxm/typing.py +177 -0
- midas_dfxm-0.1.0/midas_dfxm/validate.py +96 -0
- midas_dfxm-0.1.0/midas_dfxm.egg-info/PKG-INFO +137 -0
- midas_dfxm-0.1.0/midas_dfxm.egg-info/SOURCES.txt +55 -0
- midas_dfxm-0.1.0/midas_dfxm.egg-info/dependency_links.txt +1 -0
- midas_dfxm-0.1.0/midas_dfxm.egg-info/requires.txt +15 -0
- midas_dfxm-0.1.0/midas_dfxm.egg-info/top_level.txt +1 -0
- midas_dfxm-0.1.0/pyproject.toml +49 -0
- midas_dfxm-0.1.0/setup.cfg +4 -0
- midas_dfxm-0.1.0/tests/test_aberration.py +98 -0
- midas_dfxm-0.1.0/tests/test_beamline.py +58 -0
- midas_dfxm-0.1.0/tests/test_burgers_circuit.py +76 -0
- midas_dfxm-0.1.0/tests/test_coded_aperture.py +102 -0
- midas_dfxm-0.1.0/tests/test_coherence.py +193 -0
- midas_dfxm-0.1.0/tests/test_cpfem.py +81 -0
- midas_dfxm-0.1.0/tests/test_detect.py +82 -0
- midas_dfxm-0.1.0/tests/test_detector.py +62 -0
- midas_dfxm-0.1.0/tests/test_dislocation.py +192 -0
- midas_dfxm-0.1.0/tests/test_field.py +192 -0
- midas_dfxm-0.1.0/tests/test_field_inverse.py +259 -0
- midas_dfxm-0.1.0/tests/test_finite_beam.py +68 -0
- midas_dfxm-0.1.0/tests/test_forward.py +204 -0
- midas_dfxm-0.1.0/tests/test_generators.py +91 -0
- midas_dfxm-0.1.0/tests/test_inverse.py +135 -0
- midas_dfxm-0.1.0/tests/test_joint_inverse.py +108 -0
- midas_dfxm-0.1.0/tests/test_mosaicity_fit.py +87 -0
- midas_dfxm-0.1.0/tests/test_pink_beam.py +85 -0
- midas_dfxm-0.1.0/tests/test_plasticity.py +83 -0
- midas_dfxm-0.1.0/tests/test_validate_physics.py +131 -0
midas_dfxm-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
Copyright (c) 2012, UChicago Argonne, LLC
|
|
2
|
+
|
|
3
|
+
All Rights Reserved
|
|
4
|
+
|
|
5
|
+
MIDAS Microstructural Imaging using Diffraction Analysis Software
|
|
6
|
+
|
|
7
|
+
Materials Physics and Engineering
|
|
8
|
+
Computational X-ray Science
|
|
9
|
+
Advanced Photon Source
|
|
10
|
+
Argonne National Laboratory
|
|
11
|
+
|
|
12
|
+
Contributing Authors:
|
|
13
|
+
Hemant Sharma (hsharma@anl.gov)
|
|
14
|
+
|
|
15
|
+
OPEN SOURCE LICENSE
|
|
16
|
+
|
|
17
|
+
Redistribution and use in source and binary forms, with or without
|
|
18
|
+
modification, are permitted provided that the following conditions are met:
|
|
19
|
+
|
|
20
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
21
|
+
this list of conditions and the following disclaimer. Software changes,
|
|
22
|
+
modifications, or derivative works, should be noted with comments and
|
|
23
|
+
the author and organization's name.
|
|
24
|
+
|
|
25
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
26
|
+
this list of conditions and the following disclaimer in the documentation
|
|
27
|
+
and/or other materials provided with the distribution.
|
|
28
|
+
|
|
29
|
+
3. Neither the names of UChicago Argonne, LLC or the Department of Energy
|
|
30
|
+
nor the names of its contributors may be used to endorse or promote
|
|
31
|
+
products derived from this software without specific prior written
|
|
32
|
+
permission.
|
|
33
|
+
|
|
34
|
+
4. The software and the end-user documentation included with the
|
|
35
|
+
redistribution, if any, must include the following acknowledgment:
|
|
36
|
+
|
|
37
|
+
"This product includes software produced by UChicago Argonne, LLC
|
|
38
|
+
under Contract No. DE-AC02-06CH11357 with the Department of Energy."
|
|
39
|
+
|
|
40
|
+
****************************************************************************
|
|
41
|
+
|
|
42
|
+
DISCLAIMER
|
|
43
|
+
|
|
44
|
+
THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT WARRANTY OF ANY KIND.
|
|
45
|
+
|
|
46
|
+
Neither the United States GOVERNMENT, nor the United States Department
|
|
47
|
+
of Energy, NOR UChicago Argonne, LLC, nor any of their employees, makes
|
|
48
|
+
any warranty, express or implied, or assumes any legal liability or
|
|
49
|
+
responsibility for the accuracy, completeness, or usefulness of any
|
|
50
|
+
information, data, apparatus, product, or process disclosed, or
|
|
51
|
+
represents that its use would not infringe privately owned rights.
|
|
52
|
+
|
|
53
|
+
****************************************************************************
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: midas-dfxm
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Differentiable forward + inverse for Dark-Field X-ray Microscopy (DFXM): deformation-gradient field imaging through a magnifying objective, and per-dislocation defect-type discrimination, on top of midas-stress / midas-hkls / midas-defect.
|
|
5
|
+
Author-email: Hemant Sharma <hsharma@anl.gov>
|
|
6
|
+
License-Expression: BSD-3-Clause
|
|
7
|
+
Classifier: Development Status :: 1 - Planning
|
|
8
|
+
Classifier: Intended Audience :: Science/Research
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
12
|
+
Requires-Python: >=3.9
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Requires-Dist: numpy>=1.20
|
|
16
|
+
Requires-Dist: torch>=2.0
|
|
17
|
+
Requires-Dist: midas-stress
|
|
18
|
+
Requires-Dist: midas-hkls>=0.5
|
|
19
|
+
Requires-Dist: midas-2d>=0.1
|
|
20
|
+
Requires-Dist: midas-defect
|
|
21
|
+
Requires-Dist: midas-invert>=0.1
|
|
22
|
+
Requires-Dist: midas-distortion
|
|
23
|
+
Provides-Extra: viz
|
|
24
|
+
Requires-Dist: matplotlib>=3.5; extra == "viz"
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
27
|
+
Requires-Dist: matplotlib>=3.5; extra == "dev"
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
# midas-dfxm
|
|
31
|
+
|
|
32
|
+
Differentiable **forward + inverse** for **Dark-Field X-ray Microscopy (DFXM)**.
|
|
33
|
+
|
|
34
|
+
DFXM images a bulk grain through a magnifying objective (CRL / MLL) placed on one
|
|
35
|
+
diffracted beam. The objective is a **reciprocal-space bandpass**: a sample voxel
|
|
36
|
+
contributes intensity to its magnified detector pixel only if its *local*
|
|
37
|
+
scattering vector falls inside the instrument's resolution function for the
|
|
38
|
+
current goniometer setting. Rocking the sample (a *mosaicity scan*) maps local
|
|
39
|
+
**orientation**; scanning 2θ / energy (a *strain scan*) maps local **d-spacing**;
|
|
40
|
+
weak-beam settings image **individual dislocations**.
|
|
41
|
+
|
|
42
|
+
This package models that signal from a voxelised **deformation-gradient field**
|
|
43
|
+
`F(r)`, and (later phases) inverts a DFXM image stack back to `F(r)` and to
|
|
44
|
+
**per-dislocation defect types** (edge/screw, Burgers vector, slip system).
|
|
45
|
+
|
|
46
|
+
**Reuse-first, no re-porting.** Built on the MIDAS differentiable stack:
|
|
47
|
+
`midas-stress` (orientation/strain), `midas-hkls` (structure factors, form
|
|
48
|
+
factors, DWF), `midas-2d` (continuous-q structure factor, resolution
|
|
49
|
+
convolution), `midas-defect` (Stroh anisotropic-elasticity contrast solver, slip
|
|
50
|
+
systems, GND, planar-defect rods), `midas-invert` (fit / UQ / experiment design),
|
|
51
|
+
`midas-distortion` (detector model). Everything is torch-differentiable and
|
|
52
|
+
device-portable (CPU / CUDA / MPS).
|
|
53
|
+
|
|
54
|
+
See [`implementation_plan.md`](implementation_plan.md) for the full roadmap,
|
|
55
|
+
physics reuse map, phase gates, and honest scope/novelty gates.
|
|
56
|
+
|
|
57
|
+
## Status
|
|
58
|
+
|
|
59
|
+
**Pre-alpha (v0.0.1a0).** Phases 0,1,3,4,5 + a simulation-anchored roadmap
|
|
60
|
+
implemented and tested — **64 tests pass (CPU + MPS; 3 CUDA-skipped), ~2400 LOC.**
|
|
61
|
+
|
|
62
|
+
Highlights:
|
|
63
|
+
- **Phase 4 (defect typing):** anisotropic-elasticity (Stroh) per-dislocation forward;
|
|
64
|
+
`g·b` invisibility; edge/screw character; **Burgers-vector recovery**.
|
|
65
|
+
- **Phase 5 (inverse typing):** `identify_dislocation` recovers slip system, character,
|
|
66
|
+
core position, and the **Burgers-vector sign** (the gap Borgi 2025 leaves open) from
|
|
67
|
+
multi-reflection weak-beam images.
|
|
68
|
+
- **Phase 3 (field inverse):** full strain-tensor recovery + identifiability + UQ;
|
|
69
|
+
honest finding — regularisation helps at low SNR, ~neutral at high SNR.
|
|
70
|
+
- **#1 physics coupling:** recover a **GND density** end-to-end through the forward
|
|
71
|
+
(Nye `κ = ρb`) — the DFXM↔DDD/CP interface, differentiably.
|
|
72
|
+
- **#2 credibility anchor:** independent numpy oracle agrees **bit-for-bit** (~1e-16).
|
|
73
|
+
- **Borbély-ready:** `field_from_deformation_gradient` consumes an external `F(r)` with
|
|
74
|
+
zero rework.
|
|
75
|
+
|
|
76
|
+
See [`SIMULATION_CATALOG.md`](SIMULATION_CATALOG.md) and `examples/` (figures land in
|
|
77
|
+
`dev/paper/figures/`).
|
|
78
|
+
|
|
79
|
+
<details><summary>Earlier milestone note</summary>
|
|
80
|
+
|
|
81
|
+
Phases 0–1 implemented and tested (30 passing, CPU + MPS):
|
|
82
|
+
|
|
83
|
+
- **Phase 0 — conventions + field.** `conventions.py` (lab/sample/imaging frames,
|
|
84
|
+
goniometer), `field.py` (`DeformationField`, the kinematic deform operator
|
|
85
|
+
`Q = F⁻ᵀ G0`, polar decomposition `F = R·U`), `io.py` (synthetic-field
|
|
86
|
+
generators: perfect crystal, orientation gradient, uniform strain, isotropic
|
|
87
|
+
screw dislocation; plus a stub loader for Borbély's field).
|
|
88
|
+
- **Phase 1 — geometrical-optics forward.** `resolution.py` (anisotropic-Gaussian
|
|
89
|
+
reciprocal-space acceptance), `optics.py` (magnifying inclined projection +
|
|
90
|
+
bilinear detector splat), `scan.py` (mosaicity / rocking / strain scan builders,
|
|
91
|
+
Bragg-angle helpers), `forward.py` (`dfxm_image`, `dfxm_stack`, `mosaicity_curve`).
|
|
92
|
+
|
|
93
|
+
Validated analytic limits: rocking-curve FWHM = `2√(2ln2)·σ⊥ / |axis×q|`, FCC
|
|
94
|
+
forbidden reflection is dark, uniaxial strain shifts `|Q|` correctly; plus
|
|
95
|
+
gradcheck on the deform operator and end-to-end autograd to `F` and the instrument
|
|
96
|
+
widths.
|
|
97
|
+
|
|
98
|
+
**Next:** Phase 2 (field forward on Borbély's realistic `F(r)` when it lands),
|
|
99
|
+
Phase 3 (field inverse + identifiability study), **Phase 4 (per-dislocation
|
|
100
|
+
forward via the Stroh solver + `g·b` defect typing)**, Phase 5 (inverse defect
|
|
101
|
+
discovery).
|
|
102
|
+
|
|
103
|
+
</details>
|
|
104
|
+
|
|
105
|
+
## Quickstart
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
import torch
|
|
109
|
+
from midas_dfxm import (
|
|
110
|
+
make_uniform_field, with_orientation_gradient,
|
|
111
|
+
GoniometerSetting, reference_q_nom, aligned_resolution,
|
|
112
|
+
ObjectiveOptics, bragg_two_theta_deg, dfxm_image,
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
# A curved crystal grain (smooth lattice rotation across x).
|
|
116
|
+
field = make_uniform_field(shape=(64, 64, 1), spacing_um=0.5)
|
|
117
|
+
field = with_orientation_gradient(field, axis=(0, 0, 1), deg_per_um=0.01, along=0)
|
|
118
|
+
|
|
119
|
+
hkl, center = (1, 1, 1), GoniometerSetting()
|
|
120
|
+
q_nom = reference_q_nom(field, hkl, center)
|
|
121
|
+
res = aligned_resolution(q_nom, sigma_par=5e-3, sigma_perp=5e-3)
|
|
122
|
+
tt = bragg_two_theta_deg(float(torch.linalg.vector_norm(q_nom)), wavelength_A=0.172979)
|
|
123
|
+
optics = ObjectiveOptics(two_theta_deg=tt, magnification=10.0, detector_shape=(256, 256))
|
|
124
|
+
|
|
125
|
+
image = dfxm_image(field, hkl, center, res, optics) # (256, 256), differentiable
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Tests
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# macOS: work around the duplicate-OpenMP-runtime abort (torch + MIDAS siblings).
|
|
132
|
+
export KMP_DUPLICATE_LIB_OK=TRUE
|
|
133
|
+
python -m pytest tests/ -q
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Markers: `unit` (analytic correctness), `autograd` (gradcheck / autograd),
|
|
137
|
+
`device` (CPU/CUDA/MPS parity), `slow` (heavy integration).
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# midas-dfxm
|
|
2
|
+
|
|
3
|
+
Differentiable **forward + inverse** for **Dark-Field X-ray Microscopy (DFXM)**.
|
|
4
|
+
|
|
5
|
+
DFXM images a bulk grain through a magnifying objective (CRL / MLL) placed on one
|
|
6
|
+
diffracted beam. The objective is a **reciprocal-space bandpass**: a sample voxel
|
|
7
|
+
contributes intensity to its magnified detector pixel only if its *local*
|
|
8
|
+
scattering vector falls inside the instrument's resolution function for the
|
|
9
|
+
current goniometer setting. Rocking the sample (a *mosaicity scan*) maps local
|
|
10
|
+
**orientation**; scanning 2θ / energy (a *strain scan*) maps local **d-spacing**;
|
|
11
|
+
weak-beam settings image **individual dislocations**.
|
|
12
|
+
|
|
13
|
+
This package models that signal from a voxelised **deformation-gradient field**
|
|
14
|
+
`F(r)`, and (later phases) inverts a DFXM image stack back to `F(r)` and to
|
|
15
|
+
**per-dislocation defect types** (edge/screw, Burgers vector, slip system).
|
|
16
|
+
|
|
17
|
+
**Reuse-first, no re-porting.** Built on the MIDAS differentiable stack:
|
|
18
|
+
`midas-stress` (orientation/strain), `midas-hkls` (structure factors, form
|
|
19
|
+
factors, DWF), `midas-2d` (continuous-q structure factor, resolution
|
|
20
|
+
convolution), `midas-defect` (Stroh anisotropic-elasticity contrast solver, slip
|
|
21
|
+
systems, GND, planar-defect rods), `midas-invert` (fit / UQ / experiment design),
|
|
22
|
+
`midas-distortion` (detector model). Everything is torch-differentiable and
|
|
23
|
+
device-portable (CPU / CUDA / MPS).
|
|
24
|
+
|
|
25
|
+
See [`implementation_plan.md`](implementation_plan.md) for the full roadmap,
|
|
26
|
+
physics reuse map, phase gates, and honest scope/novelty gates.
|
|
27
|
+
|
|
28
|
+
## Status
|
|
29
|
+
|
|
30
|
+
**Pre-alpha (v0.0.1a0).** Phases 0,1,3,4,5 + a simulation-anchored roadmap
|
|
31
|
+
implemented and tested — **64 tests pass (CPU + MPS; 3 CUDA-skipped), ~2400 LOC.**
|
|
32
|
+
|
|
33
|
+
Highlights:
|
|
34
|
+
- **Phase 4 (defect typing):** anisotropic-elasticity (Stroh) per-dislocation forward;
|
|
35
|
+
`g·b` invisibility; edge/screw character; **Burgers-vector recovery**.
|
|
36
|
+
- **Phase 5 (inverse typing):** `identify_dislocation` recovers slip system, character,
|
|
37
|
+
core position, and the **Burgers-vector sign** (the gap Borgi 2025 leaves open) from
|
|
38
|
+
multi-reflection weak-beam images.
|
|
39
|
+
- **Phase 3 (field inverse):** full strain-tensor recovery + identifiability + UQ;
|
|
40
|
+
honest finding — regularisation helps at low SNR, ~neutral at high SNR.
|
|
41
|
+
- **#1 physics coupling:** recover a **GND density** end-to-end through the forward
|
|
42
|
+
(Nye `κ = ρb`) — the DFXM↔DDD/CP interface, differentiably.
|
|
43
|
+
- **#2 credibility anchor:** independent numpy oracle agrees **bit-for-bit** (~1e-16).
|
|
44
|
+
- **Borbély-ready:** `field_from_deformation_gradient` consumes an external `F(r)` with
|
|
45
|
+
zero rework.
|
|
46
|
+
|
|
47
|
+
See [`SIMULATION_CATALOG.md`](SIMULATION_CATALOG.md) and `examples/` (figures land in
|
|
48
|
+
`dev/paper/figures/`).
|
|
49
|
+
|
|
50
|
+
<details><summary>Earlier milestone note</summary>
|
|
51
|
+
|
|
52
|
+
Phases 0–1 implemented and tested (30 passing, CPU + MPS):
|
|
53
|
+
|
|
54
|
+
- **Phase 0 — conventions + field.** `conventions.py` (lab/sample/imaging frames,
|
|
55
|
+
goniometer), `field.py` (`DeformationField`, the kinematic deform operator
|
|
56
|
+
`Q = F⁻ᵀ G0`, polar decomposition `F = R·U`), `io.py` (synthetic-field
|
|
57
|
+
generators: perfect crystal, orientation gradient, uniform strain, isotropic
|
|
58
|
+
screw dislocation; plus a stub loader for Borbély's field).
|
|
59
|
+
- **Phase 1 — geometrical-optics forward.** `resolution.py` (anisotropic-Gaussian
|
|
60
|
+
reciprocal-space acceptance), `optics.py` (magnifying inclined projection +
|
|
61
|
+
bilinear detector splat), `scan.py` (mosaicity / rocking / strain scan builders,
|
|
62
|
+
Bragg-angle helpers), `forward.py` (`dfxm_image`, `dfxm_stack`, `mosaicity_curve`).
|
|
63
|
+
|
|
64
|
+
Validated analytic limits: rocking-curve FWHM = `2√(2ln2)·σ⊥ / |axis×q|`, FCC
|
|
65
|
+
forbidden reflection is dark, uniaxial strain shifts `|Q|` correctly; plus
|
|
66
|
+
gradcheck on the deform operator and end-to-end autograd to `F` and the instrument
|
|
67
|
+
widths.
|
|
68
|
+
|
|
69
|
+
**Next:** Phase 2 (field forward on Borbély's realistic `F(r)` when it lands),
|
|
70
|
+
Phase 3 (field inverse + identifiability study), **Phase 4 (per-dislocation
|
|
71
|
+
forward via the Stroh solver + `g·b` defect typing)**, Phase 5 (inverse defect
|
|
72
|
+
discovery).
|
|
73
|
+
|
|
74
|
+
</details>
|
|
75
|
+
|
|
76
|
+
## Quickstart
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
import torch
|
|
80
|
+
from midas_dfxm import (
|
|
81
|
+
make_uniform_field, with_orientation_gradient,
|
|
82
|
+
GoniometerSetting, reference_q_nom, aligned_resolution,
|
|
83
|
+
ObjectiveOptics, bragg_two_theta_deg, dfxm_image,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
# A curved crystal grain (smooth lattice rotation across x).
|
|
87
|
+
field = make_uniform_field(shape=(64, 64, 1), spacing_um=0.5)
|
|
88
|
+
field = with_orientation_gradient(field, axis=(0, 0, 1), deg_per_um=0.01, along=0)
|
|
89
|
+
|
|
90
|
+
hkl, center = (1, 1, 1), GoniometerSetting()
|
|
91
|
+
q_nom = reference_q_nom(field, hkl, center)
|
|
92
|
+
res = aligned_resolution(q_nom, sigma_par=5e-3, sigma_perp=5e-3)
|
|
93
|
+
tt = bragg_two_theta_deg(float(torch.linalg.vector_norm(q_nom)), wavelength_A=0.172979)
|
|
94
|
+
optics = ObjectiveOptics(two_theta_deg=tt, magnification=10.0, detector_shape=(256, 256))
|
|
95
|
+
|
|
96
|
+
image = dfxm_image(field, hkl, center, res, optics) # (256, 256), differentiable
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Tests
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# macOS: work around the duplicate-OpenMP-runtime abort (torch + MIDAS siblings).
|
|
103
|
+
export KMP_DUPLICATE_LIB_OK=TRUE
|
|
104
|
+
python -m pytest tests/ -q
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Markers: `unit` (analytic correctness), `autograd` (gradcheck / autograd),
|
|
108
|
+
`device` (CPU/CUDA/MPS parity), `slow` (heavy integration).
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
"""midas-dfxm -- differentiable forward + inverse for Dark-Field X-ray Microscopy.
|
|
2
|
+
|
|
3
|
+
Phase 0 (conventions + deformation field):
|
|
4
|
+
from midas_dfxm import (
|
|
5
|
+
GoniometerSetting, rotation_matrix, rot_x, rot_y, rot_z,
|
|
6
|
+
DeformationField, deform_reflection, polar_decomposition,
|
|
7
|
+
make_uniform_field, with_orientation_gradient, with_screw_dislocation,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
Builds on midas-stress (orientation/strain), midas-hkls (structure factors),
|
|
11
|
+
midas-2d (continuous-q F, resolution), midas-defect (Stroh contrast solver, GND),
|
|
12
|
+
midas-invert (fit/UQ). See implementation_plan.md.
|
|
13
|
+
"""
|
|
14
|
+
from .conventions import (
|
|
15
|
+
GoniometerSetting,
|
|
16
|
+
rot_x,
|
|
17
|
+
rot_y,
|
|
18
|
+
rot_z,
|
|
19
|
+
rotation_matrix,
|
|
20
|
+
)
|
|
21
|
+
from .field import (
|
|
22
|
+
DeformationField,
|
|
23
|
+
deform_reflection,
|
|
24
|
+
polar_decomposition,
|
|
25
|
+
reciprocal_basis,
|
|
26
|
+
small_strain_from_F,
|
|
27
|
+
)
|
|
28
|
+
from .io import (
|
|
29
|
+
fcc_reference_crystal,
|
|
30
|
+
load_borbely_field,
|
|
31
|
+
make_uniform_field,
|
|
32
|
+
with_orientation_gradient,
|
|
33
|
+
with_screw_dislocation,
|
|
34
|
+
with_uniform_strain,
|
|
35
|
+
)
|
|
36
|
+
from .resolution import ResolutionFunction, aligned_resolution, poulsen_resolution_widths
|
|
37
|
+
from .detector import apply_psf, detector_model, quantize_16bit
|
|
38
|
+
from .optics import ObjectiveOptics, diffracted_beam_direction
|
|
39
|
+
from .scan import (
|
|
40
|
+
bragg_two_theta_deg,
|
|
41
|
+
mosaicity_scan,
|
|
42
|
+
reference_q_nom,
|
|
43
|
+
rocking_scan,
|
|
44
|
+
scan_angles,
|
|
45
|
+
)
|
|
46
|
+
from .forward import (
|
|
47
|
+
dfxm_image,
|
|
48
|
+
dfxm_stack,
|
|
49
|
+
mosaicity_curve,
|
|
50
|
+
structure_factor_intensity,
|
|
51
|
+
voxel_intensity,
|
|
52
|
+
)
|
|
53
|
+
from .dislocation import (
|
|
54
|
+
StrohDislocation,
|
|
55
|
+
cubic_stiffness,
|
|
56
|
+
dislocation_deformation_field,
|
|
57
|
+
dislocation_dipole,
|
|
58
|
+
edge_dislocation_wall,
|
|
59
|
+
stroh_dislocation,
|
|
60
|
+
)
|
|
61
|
+
from .typing import (
|
|
62
|
+
classify_character,
|
|
63
|
+
dfxm_contrast,
|
|
64
|
+
dilatation_ratio,
|
|
65
|
+
g_dot_b,
|
|
66
|
+
recover_burgers,
|
|
67
|
+
reflection_signal,
|
|
68
|
+
visibility_series,
|
|
69
|
+
)
|
|
70
|
+
from .inverse import (
|
|
71
|
+
normal_strain,
|
|
72
|
+
recover_strain_direct,
|
|
73
|
+
recover_strain_regularised,
|
|
74
|
+
strain_covariance,
|
|
75
|
+
strain_design_matrix,
|
|
76
|
+
strain_identifiability,
|
|
77
|
+
)
|
|
78
|
+
from .detect import (
|
|
79
|
+
DislocationLabel,
|
|
80
|
+
identify_dislocation,
|
|
81
|
+
match_residual,
|
|
82
|
+
weak_beam_stack,
|
|
83
|
+
)
|
|
84
|
+
from .validate import cross_check_voxel_intensity, voxel_intensity_numpy
|
|
85
|
+
from .physics import fit_gnd_density, fit_wall_spacing, gnd_curvature_field
|
|
86
|
+
from .generators import (
|
|
87
|
+
dislocation_pileup,
|
|
88
|
+
ensemble_density_per_um2,
|
|
89
|
+
field_from_deformation_gradient,
|
|
90
|
+
field_from_strain,
|
|
91
|
+
random_dislocation_ensemble,
|
|
92
|
+
)
|
|
93
|
+
from .plasticity import (
|
|
94
|
+
gnd_identifiability,
|
|
95
|
+
multislip_gnd_field,
|
|
96
|
+
nye_from_densities,
|
|
97
|
+
recover_gnd_densities,
|
|
98
|
+
slip_dislocation_types,
|
|
99
|
+
)
|
|
100
|
+
from .mosaicity_fit import fit_orientation_mosaicity, moment_orientation
|
|
101
|
+
from .joint_inverse import fit_dislocation_field, fit_dislocation_ensemble, signal_peaks
|
|
102
|
+
from .finite_beam import beam_integrated_observable
|
|
103
|
+
from .beamline import (Illumination, beamline_resolution, crl_abcd, crl_focal_length, crl_image, crl_na, delta_beryllium)
|
|
104
|
+
from .coherence import (
|
|
105
|
+
coherent_image,
|
|
106
|
+
dislocation_exit_wave,
|
|
107
|
+
coherent_psf,
|
|
108
|
+
dislocation_phase,
|
|
109
|
+
exit_amplitude,
|
|
110
|
+
incoherent_image,
|
|
111
|
+
partially_coherent_image,
|
|
112
|
+
)
|
|
113
|
+
from .aberration import (
|
|
114
|
+
ABERRATIONS,
|
|
115
|
+
aberrated_psf,
|
|
116
|
+
coeffs_to_tensor,
|
|
117
|
+
convolve_psf,
|
|
118
|
+
fit_aberration,
|
|
119
|
+
wiener_deconvolve,
|
|
120
|
+
zernike_terms,
|
|
121
|
+
)
|
|
122
|
+
from .field_inverse import (
|
|
123
|
+
angular_condition_number,
|
|
124
|
+
angular_sensitivity_matrix,
|
|
125
|
+
decompose_deformation,
|
|
126
|
+
deformation_covariance,
|
|
127
|
+
deformation_design_matrix,
|
|
128
|
+
deformation_identifiability,
|
|
129
|
+
deformation_observable,
|
|
130
|
+
fisher_information,
|
|
131
|
+
crlb_trace,
|
|
132
|
+
select_reflections_greedy,
|
|
133
|
+
recover_deformation_direct,
|
|
134
|
+
recover_deformation_regularised,
|
|
135
|
+
reference_Q,
|
|
136
|
+
)
|
|
137
|
+
from .coded_aperture import (
|
|
138
|
+
coded_forward,
|
|
139
|
+
coded_identifiability,
|
|
140
|
+
coding_matrix,
|
|
141
|
+
de_bruijn,
|
|
142
|
+
decode_nnls,
|
|
143
|
+
decode_regularized,
|
|
144
|
+
depth_axis,
|
|
145
|
+
)
|
|
146
|
+
from .pink_beam import (
|
|
147
|
+
EPS_MONO,
|
|
148
|
+
EPS_PINK,
|
|
149
|
+
axial_reciprocal_width,
|
|
150
|
+
intensity_gain,
|
|
151
|
+
pink_beam_res_cov,
|
|
152
|
+
pink_beam_resolution,
|
|
153
|
+
strain_resolution_ratio,
|
|
154
|
+
)
|
|
155
|
+
from .cpfem import (
|
|
156
|
+
cpfem_true_strain,
|
|
157
|
+
load_cpfem_field,
|
|
158
|
+
save_cpfem_field,
|
|
159
|
+
validate_dfxm_on_cpfem,
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
__all__ = [
|
|
163
|
+
"GoniometerSetting",
|
|
164
|
+
"rotation_matrix",
|
|
165
|
+
"rot_x",
|
|
166
|
+
"rot_y",
|
|
167
|
+
"rot_z",
|
|
168
|
+
"DeformationField",
|
|
169
|
+
"deform_reflection",
|
|
170
|
+
"polar_decomposition",
|
|
171
|
+
"reciprocal_basis",
|
|
172
|
+
"small_strain_from_F",
|
|
173
|
+
"fcc_reference_crystal",
|
|
174
|
+
"make_uniform_field",
|
|
175
|
+
"with_orientation_gradient",
|
|
176
|
+
"with_uniform_strain",
|
|
177
|
+
"with_screw_dislocation",
|
|
178
|
+
"load_borbely_field",
|
|
179
|
+
"ResolutionFunction",
|
|
180
|
+
"aligned_resolution",
|
|
181
|
+
"poulsen_resolution_widths",
|
|
182
|
+
"detector_model",
|
|
183
|
+
"apply_psf",
|
|
184
|
+
"quantize_16bit",
|
|
185
|
+
"ObjectiveOptics",
|
|
186
|
+
"diffracted_beam_direction",
|
|
187
|
+
"bragg_two_theta_deg",
|
|
188
|
+
"reference_q_nom",
|
|
189
|
+
"mosaicity_scan",
|
|
190
|
+
"rocking_scan",
|
|
191
|
+
"scan_angles",
|
|
192
|
+
"dfxm_image",
|
|
193
|
+
"dfxm_stack",
|
|
194
|
+
"mosaicity_curve",
|
|
195
|
+
"voxel_intensity",
|
|
196
|
+
"structure_factor_intensity",
|
|
197
|
+
"StrohDislocation",
|
|
198
|
+
"stroh_dislocation",
|
|
199
|
+
"cubic_stiffness",
|
|
200
|
+
"dislocation_deformation_field",
|
|
201
|
+
"edge_dislocation_wall",
|
|
202
|
+
"dislocation_dipole",
|
|
203
|
+
"g_dot_b",
|
|
204
|
+
"reflection_signal",
|
|
205
|
+
"dfxm_contrast",
|
|
206
|
+
"dilatation_ratio",
|
|
207
|
+
"classify_character",
|
|
208
|
+
"visibility_series",
|
|
209
|
+
"recover_burgers",
|
|
210
|
+
"normal_strain",
|
|
211
|
+
"strain_design_matrix",
|
|
212
|
+
"strain_identifiability",
|
|
213
|
+
"recover_strain_direct",
|
|
214
|
+
"recover_strain_regularised",
|
|
215
|
+
"strain_covariance",
|
|
216
|
+
"identify_dislocation",
|
|
217
|
+
"DislocationLabel",
|
|
218
|
+
"weak_beam_stack",
|
|
219
|
+
"match_residual",
|
|
220
|
+
"cross_check_voxel_intensity",
|
|
221
|
+
"voxel_intensity_numpy",
|
|
222
|
+
"gnd_curvature_field",
|
|
223
|
+
"fit_gnd_density",
|
|
224
|
+
"fit_wall_spacing",
|
|
225
|
+
"field_from_deformation_gradient",
|
|
226
|
+
"field_from_strain",
|
|
227
|
+
"dislocation_pileup",
|
|
228
|
+
"random_dislocation_ensemble",
|
|
229
|
+
"ensemble_density_per_um2",
|
|
230
|
+
"slip_dislocation_types",
|
|
231
|
+
"nye_from_densities",
|
|
232
|
+
"gnd_identifiability",
|
|
233
|
+
"recover_gnd_densities",
|
|
234
|
+
"multislip_gnd_field",
|
|
235
|
+
"load_cpfem_field",
|
|
236
|
+
"save_cpfem_field",
|
|
237
|
+
"cpfem_true_strain",
|
|
238
|
+
"validate_dfxm_on_cpfem",
|
|
239
|
+
"fit_orientation_mosaicity",
|
|
240
|
+
"moment_orientation",
|
|
241
|
+
"reference_Q",
|
|
242
|
+
"deformation_design_matrix",
|
|
243
|
+
"deformation_identifiability",
|
|
244
|
+
"deformation_observable",
|
|
245
|
+
"recover_deformation_direct",
|
|
246
|
+
"recover_deformation_regularised",
|
|
247
|
+
"deformation_covariance",
|
|
248
|
+
"fisher_information",
|
|
249
|
+
"crlb_trace",
|
|
250
|
+
"select_reflections_greedy",
|
|
251
|
+
"angular_sensitivity_matrix",
|
|
252
|
+
"angular_condition_number",
|
|
253
|
+
"decompose_deformation",
|
|
254
|
+
"fit_dislocation_field",
|
|
255
|
+
"fit_dislocation_ensemble",
|
|
256
|
+
"signal_peaks",
|
|
257
|
+
"beam_integrated_observable",
|
|
258
|
+
"Illumination",
|
|
259
|
+
"beamline_resolution",
|
|
260
|
+
"crl_abcd",
|
|
261
|
+
"crl_focal_length",
|
|
262
|
+
"crl_image",
|
|
263
|
+
"crl_na",
|
|
264
|
+
"delta_beryllium",
|
|
265
|
+
"de_bruijn",
|
|
266
|
+
"coding_matrix",
|
|
267
|
+
"coded_forward",
|
|
268
|
+
"coded_identifiability",
|
|
269
|
+
"decode_nnls",
|
|
270
|
+
"decode_regularized",
|
|
271
|
+
"depth_axis",
|
|
272
|
+
"EPS_MONO",
|
|
273
|
+
"EPS_PINK",
|
|
274
|
+
"axial_reciprocal_width",
|
|
275
|
+
"intensity_gain",
|
|
276
|
+
"pink_beam_resolution",
|
|
277
|
+
"pink_beam_res_cov",
|
|
278
|
+
"strain_resolution_ratio",
|
|
279
|
+
]
|
|
280
|
+
|
|
281
|
+
__version__ = "0.1.0"
|