laue-torch 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.
Files changed (85) hide show
  1. laue_torch-0.1.0/LICENSE +53 -0
  2. laue_torch-0.1.0/MANIFEST.in +21 -0
  3. laue_torch-0.1.0/PKG-INFO +186 -0
  4. laue_torch-0.1.0/README.md +155 -0
  5. laue_torch-0.1.0/examples/tutorial_coded_aperture_voxel.py +300 -0
  6. laue_torch-0.1.0/examples/tutorial_per_voxel_odf.py +166 -0
  7. laue_torch-0.1.0/laue_torch/__init__.py +63 -0
  8. laue_torch-0.1.0/laue_torch/cli.py +164 -0
  9. laue_torch-0.1.0/laue_torch/coded_aperture/__init__.py +70 -0
  10. laue_torch-0.1.0/laue_torch/coded_aperture/absorption.py +59 -0
  11. laue_torch-0.1.0/laue_torch/coded_aperture/autofocus.py +302 -0
  12. laue_torch-0.1.0/laue_torch/coded_aperture/baseline_twostage.py +164 -0
  13. laue_torch-0.1.0/laue_torch/coded_aperture/io_h5.py +186 -0
  14. laue_torch-0.1.0/laue_torch/coded_aperture/landscape.py +288 -0
  15. laue_torch-0.1.0/laue_torch/coded_aperture/mask.py +421 -0
  16. laue_torch-0.1.0/laue_torch/coded_aperture/mask2d.py +423 -0
  17. laue_torch-0.1.0/laue_torch/coded_aperture/mask_spectral.py +232 -0
  18. laue_torch-0.1.0/laue_torch/distributions.py +375 -0
  19. laue_torch-0.1.0/laue_torch/forward.py +510 -0
  20. laue_torch-0.1.0/laue_torch/geometry.py +168 -0
  21. laue_torch-0.1.0/laue_torch/io.py +206 -0
  22. laue_torch-0.1.0/laue_torch/jointfit/__init__.py +79 -0
  23. laue_torch-0.1.0/laue_torch/jointfit/amplitudes.py +170 -0
  24. laue_torch-0.1.0/laue_torch/jointfit/design.py +169 -0
  25. laue_torch-0.1.0/laue_torch/jointfit/footprint.py +279 -0
  26. laue_torch-0.1.0/laue_torch/jointfit/model.py +351 -0
  27. laue_torch-0.1.0/laue_torch/jointfit/select.py +211 -0
  28. laue_torch-0.1.0/laue_torch/jointfit/synthetic.py +239 -0
  29. laue_torch-0.1.0/laue_torch/nye.py +284 -0
  30. laue_torch-0.1.0/laue_torch/odf.py +111 -0
  31. laue_torch-0.1.0/laue_torch/rasterize.py +417 -0
  32. laue_torch-0.1.0/laue_torch/realdata/__init__.py +84 -0
  33. laue_torch-0.1.0/laue_torch/realdata/coded_aperture_loader.py +90 -0
  34. laue_torch-0.1.0/laue_torch/realdata/depth_resolved.py +544 -0
  35. laue_torch-0.1.0/laue_torch/realdata/driver.py +276 -0
  36. laue_torch-0.1.0/laue_torch/realdata/geometry.py +233 -0
  37. laue_torch-0.1.0/laue_torch/realdata/io.py +154 -0
  38. laue_torch-0.1.0/laue_torch/realdata/multi_grain.py +618 -0
  39. laue_torch-0.1.0/laue_torch/realdata/multi_voxel_tv.py +245 -0
  40. laue_torch-0.1.0/laue_torch/realdata/plots.py +264 -0
  41. laue_torch-0.1.0/laue_torch/realdata/reference_grain.py +191 -0
  42. laue_torch-0.1.0/laue_torch/realdata/validate.py +392 -0
  43. laue_torch-0.1.0/laue_torch/spectrum.py +175 -0
  44. laue_torch-0.1.0/laue_torch/symmetry.py +75 -0
  45. laue_torch-0.1.0/laue_torch/synthetic.py +119 -0
  46. laue_torch-0.1.0/laue_torch/uncertainty.py +85 -0
  47. laue_torch-0.1.0/laue_torch/wire_scan.py +124 -0
  48. laue_torch-0.1.0/laue_torch.egg-info/PKG-INFO +186 -0
  49. laue_torch-0.1.0/laue_torch.egg-info/SOURCES.txt +83 -0
  50. laue_torch-0.1.0/laue_torch.egg-info/dependency_links.txt +1 -0
  51. laue_torch-0.1.0/laue_torch.egg-info/entry_points.txt +2 -0
  52. laue_torch-0.1.0/laue_torch.egg-info/requires.txt +15 -0
  53. laue_torch-0.1.0/laue_torch.egg-info/top_level.txt +1 -0
  54. laue_torch-0.1.0/pyproject.toml +71 -0
  55. laue_torch-0.1.0/setup.cfg +4 -0
  56. laue_torch-0.1.0/tests/__init__.py +0 -0
  57. laue_torch-0.1.0/tests/conftest.py +72 -0
  58. laue_torch-0.1.0/tests/test_autofocus_annealing.py +211 -0
  59. laue_torch-0.1.0/tests/test_autofocus_synthetic.py +268 -0
  60. laue_torch-0.1.0/tests/test_baseline_twostage.py +94 -0
  61. laue_torch-0.1.0/tests/test_calibration.py +244 -0
  62. laue_torch-0.1.0/tests/test_coded_aperture_devices.py +254 -0
  63. laue_torch-0.1.0/tests/test_coded_aperture_forward.py +262 -0
  64. laue_torch-0.1.0/tests/test_coded_aperture_landscape.py +189 -0
  65. laue_torch-0.1.0/tests/test_coded_aperture_loader.py +223 -0
  66. laue_torch-0.1.0/tests/test_coded_aperture_mask.py +342 -0
  67. laue_torch-0.1.0/tests/test_coded_aperture_mask2d.py +281 -0
  68. laue_torch-0.1.0/tests/test_coded_aperture_multilevel.py +179 -0
  69. laue_torch-0.1.0/tests/test_depth_resolved_posterior.py +167 -0
  70. laue_torch-0.1.0/tests/test_depth_resolved_strain.py +194 -0
  71. laue_torch-0.1.0/tests/test_depth_resolved_synthetic.py +222 -0
  72. laue_torch-0.1.0/tests/test_distributions.py +103 -0
  73. laue_torch-0.1.0/tests/test_grad.py +198 -0
  74. laue_torch-0.1.0/tests/test_jointfit_amplitudes.py +282 -0
  75. laue_torch-0.1.0/tests/test_jointfit_footprint.py +338 -0
  76. laue_torch-0.1.0/tests/test_jointfit_select.py +155 -0
  77. laue_torch-0.1.0/tests/test_jointfit_splat.py +195 -0
  78. laue_torch-0.1.0/tests/test_jointfit_streak_splat.py +192 -0
  79. laue_torch-0.1.0/tests/test_jointfit_synthetic.py +272 -0
  80. laue_torch-0.1.0/tests/test_mixture_and_nye.py +97 -0
  81. laue_torch-0.1.0/tests/test_multi_voxel_tv.py +198 -0
  82. laue_torch-0.1.0/tests/test_parity.py +176 -0
  83. laue_torch-0.1.0/tests/test_source_offset.py +132 -0
  84. laue_torch-0.1.0/tests/test_symmetry_contract.py +159 -0
  85. laue_torch-0.1.0/tests/test_wire_scan.py +57 -0
@@ -0,0 +1,53 @@
1
+ Copyright (c) 2024, UChicago Argonne, LLC
2
+
3
+ All Rights Reserved
4
+
5
+ LaueMatching: rapid and robust indexing of Laue diffraction patterns
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,21 @@
1
+ # setuptools' default sdist picks up package modules but NOT conftest.py,
2
+ # tests/__init__.py or examples/ -- without this file the shipped test suite
3
+ # is unrunnable (no fixtures) and the tutorials are absent.
4
+ include LICENSE
5
+ include README.md
6
+ include pyproject.toml
7
+
8
+ recursive-include tests *.py
9
+ recursive-include examples *.py
10
+
11
+ # Belt-and-braces against the unpublished research tree. It lives OUTSIDE this
12
+ # directory (repo-root research/, git-excluded) and pyproject uses an explicit
13
+ # packages= list, so these should be unreachable -- but a sdist that silently
14
+ # grows a report/ directory is a disclosure, not a bug report.
15
+ prune report
16
+ prune experiments
17
+ prune research
18
+
19
+ global-exclude __pycache__
20
+ global-exclude *.py[cod]
21
+ global-exclude .DS_Store
@@ -0,0 +1,186 @@
1
+ Metadata-Version: 2.4
2
+ Name: laue-torch
3
+ Version: 0.1.0
4
+ Summary: Differentiable PyTorch forward model for white-beam Laue microdiffraction, with per-voxel orientation- and strain-distribution (ODF/SDF) recovery, coded-aperture depth resolution, and joint multi-grain fitting.
5
+ Author-email: Hemant Sharma <hsharma@anl.gov>
6
+ License-Expression: BSD-3-Clause
7
+ Project-URL: Homepage, https://github.com/AdvancedPhotonSource/LaueMatching
8
+ Project-URL: Repository, https://github.com/AdvancedPhotonSource/LaueMatching
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Topic :: Scientific/Engineering :: Physics
14
+ Requires-Python: >=3.9
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Requires-Dist: numpy>=1.20
18
+ Requires-Dist: torch>=2.0
19
+ Requires-Dist: h5py>=3.0
20
+ Requires-Dist: Pillow>=9.0
21
+ Requires-Dist: scipy>=1.7
22
+ Requires-Dist: midas-stress>=0.11.0
23
+ Requires-Dist: midas-hkls>=0.9.0
24
+ Requires-Dist: midas-invert>=0.1.1
25
+ Provides-Extra: viz
26
+ Requires-Dist: matplotlib>=3.5; extra == "viz"
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest>=7.0; extra == "dev"
29
+ Requires-Dist: matplotlib>=3.5; extra == "dev"
30
+ Dynamic: license-file
31
+
32
+ # `laue_torch`
33
+
34
+ A fully differentiable PyTorch forward model for white-beam Laue
35
+ micro-diffraction, plus a per-voxel orientation- and strain-distribution
36
+ function (ODF / SDF) recovery pipeline that runs on top of any
37
+ conventional Laue indexer.
38
+
39
+ The package is built as a drop-in **refinement** stage downstream of the
40
+ existing [LaueMatching](https://github.com/AdvancedPhotonSource/LaueMatching)
41
+ pipeline: LaueMatching's coarse-grid indexer (or any equivalent) gives
42
+ an approximate mean orientation per voxel; `laue_torch` refines the
43
+ *distribution* parameters around that mean from peak shape, with
44
+ analytic gradients through every step of the forward map.
45
+
46
+ ## Highlights
47
+
48
+ - **Differentiable forward**: parity-tested against the reference
49
+ NumPy/C simulator (94/94 spot match on the canonical test case);
50
+ passes a strict `torch.autograd.gradcheck` on the geometry path for
51
+ every parameter group (orientation, strain, lattice, detector pose).
52
+ - **Distribution-level recovery**: tangent-Gaussian on SO(3) for
53
+ unimodal mosaic; mixture for twins / sub-grain modes; multivariate
54
+ Gaussian on Voigt-6 strain.
55
+ - **Tensor GND density**: Nye's dislocation density tensor follows
56
+ analytically from the recovered per-voxel ODF gradient; FCC slip-
57
+ system projection helper included.
58
+ - **Posterior uncertainty**: Laplace approximation at convergence
59
+ gives per-parameter marginal credible intervals.
60
+ - **Hessian eigenanalysis**: explicit identification of the physical
61
+ degeneracies of polychromatic Laue (hydrostatic-strain null, lattice
62
+ scale null, $P_z\!\leftrightarrow\!$lattice trade-off, etc.).
63
+ - **Real-data adapter**: reads LaueMatching post-processed H5 output
64
+ and runs the per-voxel ODF refinement with one function call.
65
+
66
+ ## Quick start
67
+
68
+ ```python
69
+ import torch
70
+ from laue_torch import LaueForwardModel, generate_hkls, parse_params
71
+
72
+ p = parse_params("simulation/params_sim.txt")
73
+ hkls = generate_hkls(p.sg_num, p.lattice, p.E_hi)
74
+ t = p.to_tensors()
75
+
76
+ model = LaueForwardModel(
77
+ hkls=hkls, n_pix=t["n_pix"], px_size=t["px_size"],
78
+ psf_sigma=t["psf_sigma"],
79
+ rotation="quat", strain_mode="voigt",
80
+ )
81
+
82
+ U = torch.tensor([[1.0, 0.0, 0.0, 0.0]], dtype=torch.float64) # (G, 4) quaternion
83
+ img = model(U, t["lattice"], t["P"], t["R"]) # (Nx, Ny)
84
+ ```
85
+
86
+ ## Per-voxel ODF refinement on real data
87
+
88
+ ```python
89
+ from laue_torch import parse_params
90
+ from laue_torch.realdata import LaueScanLoader, VoxelODFRefiner, plot_sigma_map
91
+
92
+ params = parse_params("simulation/params_sim.txt")
93
+ refiner = VoxelODFRefiner(params, sigma_init_deg=1.0,
94
+ M_render=128, n_steps=500)
95
+
96
+ results = []
97
+ for voxel in LaueScanLoader("/path/to/scan/"):
98
+ results.append(refiner.refine(voxel))
99
+
100
+ plot_sigma_map(results, grid_shape=(20, 20),
101
+ out_path="sigma_map.png", show_posterior=True)
102
+ ```
103
+
104
+ Each `result` is a `VoxelODFResult` carrying:
105
+
106
+ - `U_mean`: refined mean orientation (3×3)
107
+ - `sigma_U_deg`: recovered isotropic mosaic spread
108
+ - `posterior_sigma_U_deg`: 1-σ Laplace posterior on `sigma_U_deg`
109
+ - `final_loss`, `n_steps`, `dt_s`, ...
110
+
111
+ For multi-voxel scans, the `plots` module supplies `plot_sigma_map`,
112
+ `plot_orientation_map`, `plot_gnd_map` (which computes Nye's tensor on
113
+ the recovered orientation field by central differences).
114
+
115
+ ## Tutorial
116
+
117
+ The single-script tutorial `examples/tutorial_per_voxel_odf.py` walks
118
+ through the full synthetic pipeline end-to-end (forward → render →
119
+ Adam → Nye tensor → Laplace posterior) in $\sim$3 min on CPU.
120
+
121
+ ## Synthetic experiments
122
+
123
+ The numerical experiments that characterised this package (mosaic-spread
124
+ recovery, twin-variant identification, intragranular gradients and the Nye
125
+ tensor, Laplace-posterior calibration, basin-of-convergence and Hessian
126
+ eigenanalysis studies) are research scripts and are **not** distributed with the
127
+ package.
128
+
129
+ What ships instead is the part that transfers: the two runnable tutorials in
130
+ `examples/`, and the test suite, which exercises every one of those code paths
131
+ against synthetic ground truth.
132
+
133
+ ## Tests
134
+
135
+ ```bash
136
+ cd packages/laue_torch
137
+ pip install -e '.[dev]'
138
+ KMP_DUPLICATE_LIB_OK=TRUE pytest
139
+ ```
140
+
141
+ 219 tests cover parity against the NumPy/C reference, gradient flow /
142
+ `gradcheck` on every parameter group, calibration recovery, distribution
143
+ moments, mixture / Nye correctness, coded-aperture and joint-fit paths, and a
144
+ contract test pinning the `midas-stress` misorientation convention.
145
+
146
+ The four parity tests need a LaueMatching **checkout** (they read
147
+ `simulation/params_sim.txt` and the reference simulator). Run from an installed
148
+ wheel instead and they skip cleanly rather than failing.
149
+
150
+ ## Documentation
151
+
152
+ - [`docs/torch-forward-model.md`](../../docs/torch-forward-model.md) — math + API
153
+ reference: the forward map, every differentiable parameter group, and the
154
+ parameterisation choices.
155
+ - `examples/` — two runnable tutorials: per-voxel ODF recovery, and the
156
+ coded-aperture voxel workflow.
157
+ - The test suite is the other reference. `tests/test_parity.py` pins the forward
158
+ model against the repository's NumPy/C simulator, and
159
+ `tests/test_grad.py` gradchecks every parameter group.
160
+
161
+ ## Dependencies
162
+
163
+ Runtime (installed automatically):
164
+
165
+ - `torch >= 2.0`, `numpy >= 1.20`, `scipy >= 1.7`, `h5py >= 3.0`, `Pillow >= 9.0`
166
+ - `midas-stress >= 0.11.0` — symmetry-reduced misorientation. Note it returns
167
+ **radians**; `laue_torch.symmetry` converts to degrees in one place.
168
+ - `midas-hkls >= 0.9.0` — lattice, space group, hkl generation, absorption
169
+ - `midas-invert >= 0.1.1` — Laplace uncertainty, fit / loss primitives
170
+
171
+ Optional: `matplotlib >= 3.5` (`pip install 'laue-torch[viz]'`) for the plotting
172
+ helpers in `laue_torch.realdata.plots`.
173
+
174
+ ## Citation
175
+
176
+ If you use this package, please cite the LaueMatching pipeline that produces the
177
+ indexer seed orientations:
178
+
179
+ > H. Sharma, D. Sheyfer, R. Harder, J.Z. Tischler.
180
+ > *LaueMatching: an approach for rapid and robust indexing of Laue
181
+ > diffraction patterns.*
182
+ > J. Appl. Cryst. **59**, 552–563 (2026).
183
+
184
+ ## License
185
+
186
+ BSD-3-Clause (UChicago Argonne, LLC) — see [`LICENSE`](LICENSE).
@@ -0,0 +1,155 @@
1
+ # `laue_torch`
2
+
3
+ A fully differentiable PyTorch forward model for white-beam Laue
4
+ micro-diffraction, plus a per-voxel orientation- and strain-distribution
5
+ function (ODF / SDF) recovery pipeline that runs on top of any
6
+ conventional Laue indexer.
7
+
8
+ The package is built as a drop-in **refinement** stage downstream of the
9
+ existing [LaueMatching](https://github.com/AdvancedPhotonSource/LaueMatching)
10
+ pipeline: LaueMatching's coarse-grid indexer (or any equivalent) gives
11
+ an approximate mean orientation per voxel; `laue_torch` refines the
12
+ *distribution* parameters around that mean from peak shape, with
13
+ analytic gradients through every step of the forward map.
14
+
15
+ ## Highlights
16
+
17
+ - **Differentiable forward**: parity-tested against the reference
18
+ NumPy/C simulator (94/94 spot match on the canonical test case);
19
+ passes a strict `torch.autograd.gradcheck` on the geometry path for
20
+ every parameter group (orientation, strain, lattice, detector pose).
21
+ - **Distribution-level recovery**: tangent-Gaussian on SO(3) for
22
+ unimodal mosaic; mixture for twins / sub-grain modes; multivariate
23
+ Gaussian on Voigt-6 strain.
24
+ - **Tensor GND density**: Nye's dislocation density tensor follows
25
+ analytically from the recovered per-voxel ODF gradient; FCC slip-
26
+ system projection helper included.
27
+ - **Posterior uncertainty**: Laplace approximation at convergence
28
+ gives per-parameter marginal credible intervals.
29
+ - **Hessian eigenanalysis**: explicit identification of the physical
30
+ degeneracies of polychromatic Laue (hydrostatic-strain null, lattice
31
+ scale null, $P_z\!\leftrightarrow\!$lattice trade-off, etc.).
32
+ - **Real-data adapter**: reads LaueMatching post-processed H5 output
33
+ and runs the per-voxel ODF refinement with one function call.
34
+
35
+ ## Quick start
36
+
37
+ ```python
38
+ import torch
39
+ from laue_torch import LaueForwardModel, generate_hkls, parse_params
40
+
41
+ p = parse_params("simulation/params_sim.txt")
42
+ hkls = generate_hkls(p.sg_num, p.lattice, p.E_hi)
43
+ t = p.to_tensors()
44
+
45
+ model = LaueForwardModel(
46
+ hkls=hkls, n_pix=t["n_pix"], px_size=t["px_size"],
47
+ psf_sigma=t["psf_sigma"],
48
+ rotation="quat", strain_mode="voigt",
49
+ )
50
+
51
+ U = torch.tensor([[1.0, 0.0, 0.0, 0.0]], dtype=torch.float64) # (G, 4) quaternion
52
+ img = model(U, t["lattice"], t["P"], t["R"]) # (Nx, Ny)
53
+ ```
54
+
55
+ ## Per-voxel ODF refinement on real data
56
+
57
+ ```python
58
+ from laue_torch import parse_params
59
+ from laue_torch.realdata import LaueScanLoader, VoxelODFRefiner, plot_sigma_map
60
+
61
+ params = parse_params("simulation/params_sim.txt")
62
+ refiner = VoxelODFRefiner(params, sigma_init_deg=1.0,
63
+ M_render=128, n_steps=500)
64
+
65
+ results = []
66
+ for voxel in LaueScanLoader("/path/to/scan/"):
67
+ results.append(refiner.refine(voxel))
68
+
69
+ plot_sigma_map(results, grid_shape=(20, 20),
70
+ out_path="sigma_map.png", show_posterior=True)
71
+ ```
72
+
73
+ Each `result` is a `VoxelODFResult` carrying:
74
+
75
+ - `U_mean`: refined mean orientation (3×3)
76
+ - `sigma_U_deg`: recovered isotropic mosaic spread
77
+ - `posterior_sigma_U_deg`: 1-σ Laplace posterior on `sigma_U_deg`
78
+ - `final_loss`, `n_steps`, `dt_s`, ...
79
+
80
+ For multi-voxel scans, the `plots` module supplies `plot_sigma_map`,
81
+ `plot_orientation_map`, `plot_gnd_map` (which computes Nye's tensor on
82
+ the recovered orientation field by central differences).
83
+
84
+ ## Tutorial
85
+
86
+ The single-script tutorial `examples/tutorial_per_voxel_odf.py` walks
87
+ through the full synthetic pipeline end-to-end (forward → render →
88
+ Adam → Nye tensor → Laplace posterior) in $\sim$3 min on CPU.
89
+
90
+ ## Synthetic experiments
91
+
92
+ The numerical experiments that characterised this package (mosaic-spread
93
+ recovery, twin-variant identification, intragranular gradients and the Nye
94
+ tensor, Laplace-posterior calibration, basin-of-convergence and Hessian
95
+ eigenanalysis studies) are research scripts and are **not** distributed with the
96
+ package.
97
+
98
+ What ships instead is the part that transfers: the two runnable tutorials in
99
+ `examples/`, and the test suite, which exercises every one of those code paths
100
+ against synthetic ground truth.
101
+
102
+ ## Tests
103
+
104
+ ```bash
105
+ cd packages/laue_torch
106
+ pip install -e '.[dev]'
107
+ KMP_DUPLICATE_LIB_OK=TRUE pytest
108
+ ```
109
+
110
+ 219 tests cover parity against the NumPy/C reference, gradient flow /
111
+ `gradcheck` on every parameter group, calibration recovery, distribution
112
+ moments, mixture / Nye correctness, coded-aperture and joint-fit paths, and a
113
+ contract test pinning the `midas-stress` misorientation convention.
114
+
115
+ The four parity tests need a LaueMatching **checkout** (they read
116
+ `simulation/params_sim.txt` and the reference simulator). Run from an installed
117
+ wheel instead and they skip cleanly rather than failing.
118
+
119
+ ## Documentation
120
+
121
+ - [`docs/torch-forward-model.md`](../../docs/torch-forward-model.md) — math + API
122
+ reference: the forward map, every differentiable parameter group, and the
123
+ parameterisation choices.
124
+ - `examples/` — two runnable tutorials: per-voxel ODF recovery, and the
125
+ coded-aperture voxel workflow.
126
+ - The test suite is the other reference. `tests/test_parity.py` pins the forward
127
+ model against the repository's NumPy/C simulator, and
128
+ `tests/test_grad.py` gradchecks every parameter group.
129
+
130
+ ## Dependencies
131
+
132
+ Runtime (installed automatically):
133
+
134
+ - `torch >= 2.0`, `numpy >= 1.20`, `scipy >= 1.7`, `h5py >= 3.0`, `Pillow >= 9.0`
135
+ - `midas-stress >= 0.11.0` — symmetry-reduced misorientation. Note it returns
136
+ **radians**; `laue_torch.symmetry` converts to degrees in one place.
137
+ - `midas-hkls >= 0.9.0` — lattice, space group, hkl generation, absorption
138
+ - `midas-invert >= 0.1.1` — Laplace uncertainty, fit / loss primitives
139
+
140
+ Optional: `matplotlib >= 3.5` (`pip install 'laue-torch[viz]'`) for the plotting
141
+ helpers in `laue_torch.realdata.plots`.
142
+
143
+ ## Citation
144
+
145
+ If you use this package, please cite the LaueMatching pipeline that produces the
146
+ indexer seed orientations:
147
+
148
+ > H. Sharma, D. Sheyfer, R. Harder, J.Z. Tischler.
149
+ > *LaueMatching: an approach for rapid and robust indexing of Laue
150
+ > diffraction patterns.*
151
+ > J. Appl. Cryst. **59**, 552–563 (2026).
152
+
153
+ ## License
154
+
155
+ BSD-3-Clause (UChicago Argonne, LLC) — see [`LICENSE`](LICENSE).