midas-integrate 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_integrate-0.1.0/PKG-INFO +129 -0
- midas_integrate-0.1.0/README.md +96 -0
- midas_integrate-0.1.0/midas_integrate/__init__.py +124 -0
- midas_integrate-0.1.0/midas_integrate/_mapper_numba.py +901 -0
- midas_integrate-0.1.0/midas_integrate/bin_io.py +289 -0
- midas_integrate-0.1.0/midas_integrate/cli.py +257 -0
- midas_integrate-0.1.0/midas_integrate/detector_mapper.py +698 -0
- midas_integrate-0.1.0/midas_integrate/fused_csr.py +296 -0
- midas_integrate-0.1.0/midas_integrate/geometry.py +555 -0
- midas_integrate-0.1.0/midas_integrate/image.py +184 -0
- midas_integrate-0.1.0/midas_integrate/kernels.py +461 -0
- midas_integrate-0.1.0/midas_integrate/panel.py +215 -0
- midas_integrate-0.1.0/midas_integrate/params.py +279 -0
- midas_integrate-0.1.0/midas_integrate/peak_io.py +156 -0
- midas_integrate-0.1.0/midas_integrate/peakfit.py +421 -0
- midas_integrate-0.1.0/midas_integrate/postprocess.py +142 -0
- midas_integrate-0.1.0/midas_integrate/residual_corr.py +114 -0
- midas_integrate-0.1.0/midas_integrate/server.py +375 -0
- midas_integrate-0.1.0/midas_integrate.egg-info/PKG-INFO +129 -0
- midas_integrate-0.1.0/midas_integrate.egg-info/SOURCES.txt +33 -0
- midas_integrate-0.1.0/midas_integrate.egg-info/dependency_links.txt +1 -0
- midas_integrate-0.1.0/midas_integrate.egg-info/entry_points.txt +4 -0
- midas_integrate-0.1.0/midas_integrate.egg-info/requires.txt +13 -0
- midas_integrate-0.1.0/midas_integrate.egg-info/top_level.txt +1 -0
- midas_integrate-0.1.0/pyproject.toml +76 -0
- midas_integrate-0.1.0/setup.cfg +4 -0
- midas_integrate-0.1.0/tests/test_bin_io.py +95 -0
- midas_integrate-0.1.0/tests/test_detector_mapper.py +97 -0
- midas_integrate-0.1.0/tests/test_distortion_parity.py +126 -0
- midas_integrate-0.1.0/tests/test_fused_postprocess.py +160 -0
- midas_integrate-0.1.0/tests/test_geometry.py +132 -0
- midas_integrate-0.1.0/tests/test_kernels.py +227 -0
- midas_integrate-0.1.0/tests/test_panel_parity.py +153 -0
- midas_integrate-0.1.0/tests/test_peakfit.py +76 -0
- midas_integrate-0.1.0/tests/test_residual_corr_parity.py +137 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: midas-integrate
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Pure-Python radial integration for area X-ray detectors (MIDAS) — DetectorMapper + CSR integration + streaming server, CPU/GPU selectable
|
|
5
|
+
Author-email: Hemant Sharma <hsharma@anl.gov>
|
|
6
|
+
License-Expression: BSD-3-Clause
|
|
7
|
+
Project-URL: Homepage, https://github.com/marinerhemant/MIDAS
|
|
8
|
+
Project-URL: Documentation, https://github.com/marinerhemant/MIDAS/tree/master/manuals
|
|
9
|
+
Project-URL: Issues, https://github.com/marinerhemant/MIDAS/issues
|
|
10
|
+
Keywords: MIDAS,X-ray,diffraction,radial integration,azimuthal integration,HEDM,SAXS,WAXS,PDF,detector,PyTorch,CUDA
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
20
|
+
Requires-Python: >=3.9
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
Requires-Dist: numpy>=1.22
|
|
23
|
+
Requires-Dist: scipy>=1.9
|
|
24
|
+
Requires-Dist: torch>=2.1
|
|
25
|
+
Requires-Dist: tifffile>=2022.0
|
|
26
|
+
Requires-Dist: h5py>=3.0
|
|
27
|
+
Requires-Dist: numba>=0.59
|
|
28
|
+
Requires-Dist: joblib>=1.2
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
32
|
+
Provides-Extra: cuda
|
|
33
|
+
|
|
34
|
+
# midas-integrate
|
|
35
|
+
|
|
36
|
+
Pure-Python radial integration for area X-ray detectors. A drop-in,
|
|
37
|
+
pip-installable replacement for the MIDAS C/CUDA radial integration
|
|
38
|
+
pipeline — no compilers, no native libraries, no CMake.
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pip install midas-integrate
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## What's in the box
|
|
45
|
+
|
|
46
|
+
| C/CUDA source | Python module |
|
|
47
|
+
| -------------------------------------- | -------------------------------------- |
|
|
48
|
+
| `MapperCore.c`, `DetectorGeometry.c`, `DetectorMapper.c` | `midas_integrate.detector_mapper`, `midas_integrate.geometry` |
|
|
49
|
+
| `IntegratorFitPeaksGPUStream.cu` (GPU streaming) | `midas_integrate.kernels`, `midas_integrate.server`, `midas_integrate.pipeline` |
|
|
50
|
+
| `IntegratorZarrOMP.c` (CPU OMP, bilinear) | `midas_integrate.kernels` (`mode='bilinear'`) |
|
|
51
|
+
| `PeakFit.c` | `midas_integrate.peakfit` |
|
|
52
|
+
| `PeakFitIO.c` | `midas_integrate.peak_io` |
|
|
53
|
+
| `Map.bin` / `nMap.bin` | `midas_integrate.bin_io` |
|
|
54
|
+
|
|
55
|
+
## CPU/GPU selection
|
|
56
|
+
|
|
57
|
+
Everything that touches arrays accepts a `device` argument that is forwarded
|
|
58
|
+
to PyTorch. CPU and CUDA are first-class:
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
from midas_integrate import build_csr, integrate, profile_1d, load_map
|
|
62
|
+
|
|
63
|
+
pixmap = load_map('Map.bin', 'nMap.bin')
|
|
64
|
+
geom_cpu = build_csr(pixmap, n_r=990, n_eta=72, n_pixels_y=1475, n_pixels_z=1679, device='cpu')
|
|
65
|
+
geom_cuda = build_csr(pixmap, ..., device='cuda')
|
|
66
|
+
|
|
67
|
+
import torch
|
|
68
|
+
img = torch.from_numpy(image_2d)
|
|
69
|
+
profile = profile_1d(integrate(img, geom_cuda, mode='bilinear'), geom_cuda)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Three integration modes (full parity with C codes)
|
|
73
|
+
|
|
74
|
+
| `mode` | Equivalent C kernel | Use when |
|
|
75
|
+
|-------------|--------------------------------------------------------|----------|
|
|
76
|
+
| `'floor'` | `integrate_noMapMask` in `IntegratorFitPeaksGPUStream.cu` | streaming, max throughput |
|
|
77
|
+
| `'bilinear'`| pixel loop in `IntegratorZarrOMP.c` lines 1733–1744 | offline analysis, max accuracy |
|
|
78
|
+
| `'gradient'`| `GradientCorrection=1` branch in the GPU stream | strong tilt + small R |
|
|
79
|
+
|
|
80
|
+
## CLI
|
|
81
|
+
|
|
82
|
+
Three entry points mirror the C binaries:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# 1. Build Map.bin / nMap.bin from a parameter file (one-shot, slow):
|
|
86
|
+
midas-detector-mapper params.txt -j 8
|
|
87
|
+
|
|
88
|
+
# 2. Integrate one frame (one-shot, fast):
|
|
89
|
+
midas-integrate params.txt --image frame.tif --device cuda
|
|
90
|
+
|
|
91
|
+
# 3. Streaming socket server (matches the C wire protocol on port 60439):
|
|
92
|
+
midas-integrate-server params.txt --device cuda --num-streams 4
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Numerical parity
|
|
96
|
+
|
|
97
|
+
- DetectorMapper output (`Map.bin`/`nMap.bin`): byte-equivalent to the C
|
|
98
|
+
version (entry counts, sums of `frac` and `areaWeight` per bin agree to
|
|
99
|
+
ULP; entry order within a bin may differ).
|
|
100
|
+
- Per-frame integration: float32 ULP-level (median 1.7e-8 relative error
|
|
101
|
+
vs the C/CUDA `IntegratorFitPeaksGPUStream` binary on PILATUS3 2M with
|
|
102
|
+
CeO₂ data; max 2.1e-7 relative).
|
|
103
|
+
- Peak fitting: same model (pseudo-Voigt + global background, SNIP
|
|
104
|
+
background subtraction), different optimizer (scipy LM vs NLopt
|
|
105
|
+
Nelder-Mead). Fit parameters typically agree to ~1e-5 relative on
|
|
106
|
+
noisy real data.
|
|
107
|
+
|
|
108
|
+
## Performance (PILATUS3 2M, 1475×1679, NVIDIA H100)
|
|
109
|
+
|
|
110
|
+
| | Throughput |
|
|
111
|
+
|----------------------------------------------|------------------|
|
|
112
|
+
| C MIDAS GPU stream (per the paper) | ~1,600 fps |
|
|
113
|
+
| **midas-integrate (PyTorch CSR, FP32, CUDA)**| **~3,250 fps** |
|
|
114
|
+
| midas-integrate (PyTorch CSR, FP64, CPU) | ~675 fps |
|
|
115
|
+
| C MIDAS CPU (per the paper) | ~262 fps |
|
|
116
|
+
| pyFAI CSR-cython (per the paper) | ~7 fps |
|
|
117
|
+
|
|
118
|
+
## Requirements
|
|
119
|
+
|
|
120
|
+
- Python ≥ 3.9
|
|
121
|
+
- numpy, scipy, torch, tifffile, h5py, joblib
|
|
122
|
+
|
|
123
|
+
CUDA support is automatic if your installed `torch` has CUDA. macOS Metal (MPS)
|
|
124
|
+
works for the integration kernel; sparse-CSR support on MPS is partial as of
|
|
125
|
+
torch 2.7.
|
|
126
|
+
|
|
127
|
+
## License
|
|
128
|
+
|
|
129
|
+
BSD-3-Clause. See LICENSE.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# midas-integrate
|
|
2
|
+
|
|
3
|
+
Pure-Python radial integration for area X-ray detectors. A drop-in,
|
|
4
|
+
pip-installable replacement for the MIDAS C/CUDA radial integration
|
|
5
|
+
pipeline — no compilers, no native libraries, no CMake.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install midas-integrate
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## What's in the box
|
|
12
|
+
|
|
13
|
+
| C/CUDA source | Python module |
|
|
14
|
+
| -------------------------------------- | -------------------------------------- |
|
|
15
|
+
| `MapperCore.c`, `DetectorGeometry.c`, `DetectorMapper.c` | `midas_integrate.detector_mapper`, `midas_integrate.geometry` |
|
|
16
|
+
| `IntegratorFitPeaksGPUStream.cu` (GPU streaming) | `midas_integrate.kernels`, `midas_integrate.server`, `midas_integrate.pipeline` |
|
|
17
|
+
| `IntegratorZarrOMP.c` (CPU OMP, bilinear) | `midas_integrate.kernels` (`mode='bilinear'`) |
|
|
18
|
+
| `PeakFit.c` | `midas_integrate.peakfit` |
|
|
19
|
+
| `PeakFitIO.c` | `midas_integrate.peak_io` |
|
|
20
|
+
| `Map.bin` / `nMap.bin` | `midas_integrate.bin_io` |
|
|
21
|
+
|
|
22
|
+
## CPU/GPU selection
|
|
23
|
+
|
|
24
|
+
Everything that touches arrays accepts a `device` argument that is forwarded
|
|
25
|
+
to PyTorch. CPU and CUDA are first-class:
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
from midas_integrate import build_csr, integrate, profile_1d, load_map
|
|
29
|
+
|
|
30
|
+
pixmap = load_map('Map.bin', 'nMap.bin')
|
|
31
|
+
geom_cpu = build_csr(pixmap, n_r=990, n_eta=72, n_pixels_y=1475, n_pixels_z=1679, device='cpu')
|
|
32
|
+
geom_cuda = build_csr(pixmap, ..., device='cuda')
|
|
33
|
+
|
|
34
|
+
import torch
|
|
35
|
+
img = torch.from_numpy(image_2d)
|
|
36
|
+
profile = profile_1d(integrate(img, geom_cuda, mode='bilinear'), geom_cuda)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Three integration modes (full parity with C codes)
|
|
40
|
+
|
|
41
|
+
| `mode` | Equivalent C kernel | Use when |
|
|
42
|
+
|-------------|--------------------------------------------------------|----------|
|
|
43
|
+
| `'floor'` | `integrate_noMapMask` in `IntegratorFitPeaksGPUStream.cu` | streaming, max throughput |
|
|
44
|
+
| `'bilinear'`| pixel loop in `IntegratorZarrOMP.c` lines 1733–1744 | offline analysis, max accuracy |
|
|
45
|
+
| `'gradient'`| `GradientCorrection=1` branch in the GPU stream | strong tilt + small R |
|
|
46
|
+
|
|
47
|
+
## CLI
|
|
48
|
+
|
|
49
|
+
Three entry points mirror the C binaries:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# 1. Build Map.bin / nMap.bin from a parameter file (one-shot, slow):
|
|
53
|
+
midas-detector-mapper params.txt -j 8
|
|
54
|
+
|
|
55
|
+
# 2. Integrate one frame (one-shot, fast):
|
|
56
|
+
midas-integrate params.txt --image frame.tif --device cuda
|
|
57
|
+
|
|
58
|
+
# 3. Streaming socket server (matches the C wire protocol on port 60439):
|
|
59
|
+
midas-integrate-server params.txt --device cuda --num-streams 4
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Numerical parity
|
|
63
|
+
|
|
64
|
+
- DetectorMapper output (`Map.bin`/`nMap.bin`): byte-equivalent to the C
|
|
65
|
+
version (entry counts, sums of `frac` and `areaWeight` per bin agree to
|
|
66
|
+
ULP; entry order within a bin may differ).
|
|
67
|
+
- Per-frame integration: float32 ULP-level (median 1.7e-8 relative error
|
|
68
|
+
vs the C/CUDA `IntegratorFitPeaksGPUStream` binary on PILATUS3 2M with
|
|
69
|
+
CeO₂ data; max 2.1e-7 relative).
|
|
70
|
+
- Peak fitting: same model (pseudo-Voigt + global background, SNIP
|
|
71
|
+
background subtraction), different optimizer (scipy LM vs NLopt
|
|
72
|
+
Nelder-Mead). Fit parameters typically agree to ~1e-5 relative on
|
|
73
|
+
noisy real data.
|
|
74
|
+
|
|
75
|
+
## Performance (PILATUS3 2M, 1475×1679, NVIDIA H100)
|
|
76
|
+
|
|
77
|
+
| | Throughput |
|
|
78
|
+
|----------------------------------------------|------------------|
|
|
79
|
+
| C MIDAS GPU stream (per the paper) | ~1,600 fps |
|
|
80
|
+
| **midas-integrate (PyTorch CSR, FP32, CUDA)**| **~3,250 fps** |
|
|
81
|
+
| midas-integrate (PyTorch CSR, FP64, CPU) | ~675 fps |
|
|
82
|
+
| C MIDAS CPU (per the paper) | ~262 fps |
|
|
83
|
+
| pyFAI CSR-cython (per the paper) | ~7 fps |
|
|
84
|
+
|
|
85
|
+
## Requirements
|
|
86
|
+
|
|
87
|
+
- Python ≥ 3.9
|
|
88
|
+
- numpy, scipy, torch, tifffile, h5py, joblib
|
|
89
|
+
|
|
90
|
+
CUDA support is automatic if your installed `torch` has CUDA. macOS Metal (MPS)
|
|
91
|
+
works for the integration kernel; sparse-CSR support on MPS is partial as of
|
|
92
|
+
torch 2.7.
|
|
93
|
+
|
|
94
|
+
## License
|
|
95
|
+
|
|
96
|
+
BSD-3-Clause. See LICENSE.
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"""midas-integrate — pure-Python radial integration for area X-ray detectors.
|
|
2
|
+
|
|
3
|
+
Public API surface (re-exports from submodules so users can do
|
|
4
|
+
`from midas_integrate import build_csr` etc.).
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
__version__ = "0.1.0"
|
|
9
|
+
|
|
10
|
+
from midas_integrate.bin_io import (
|
|
11
|
+
PXLIST_DTYPE,
|
|
12
|
+
MAP_HEADER_MAGIC,
|
|
13
|
+
MAP_HEADER_SIZE,
|
|
14
|
+
MapHeader,
|
|
15
|
+
PixelMap,
|
|
16
|
+
load_map,
|
|
17
|
+
write_map,
|
|
18
|
+
write_synthetic_map,
|
|
19
|
+
)
|
|
20
|
+
from midas_integrate.params import IntegrationParams, parse_params
|
|
21
|
+
from midas_integrate.geometry import (
|
|
22
|
+
DEG2RAD,
|
|
23
|
+
RAD2DEG,
|
|
24
|
+
build_tilt_matrix,
|
|
25
|
+
pixel_to_REta,
|
|
26
|
+
REta_to_YZ,
|
|
27
|
+
build_bin_edges,
|
|
28
|
+
build_q_bin_edges_in_R,
|
|
29
|
+
polygon_area,
|
|
30
|
+
circle_seg_intersect,
|
|
31
|
+
ray_seg_intersect,
|
|
32
|
+
point_in_quad,
|
|
33
|
+
invert_REta_to_pixel,
|
|
34
|
+
)
|
|
35
|
+
from midas_integrate.detector_mapper import build_map, BuildMapResult
|
|
36
|
+
from midas_integrate.kernels import (
|
|
37
|
+
AREA_THRESHOLD,
|
|
38
|
+
CSRGeometry,
|
|
39
|
+
build_csr,
|
|
40
|
+
integrate,
|
|
41
|
+
profile_1d,
|
|
42
|
+
)
|
|
43
|
+
from midas_integrate.image import (
|
|
44
|
+
bytes_per_pixel,
|
|
45
|
+
decode_payload,
|
|
46
|
+
decode_hybrid_payload,
|
|
47
|
+
NUMPY_DTYPE_FOR_CODE,
|
|
48
|
+
DTYPE_CODE_UINT8,
|
|
49
|
+
DTYPE_CODE_UINT16,
|
|
50
|
+
DTYPE_CODE_UINT32,
|
|
51
|
+
DTYPE_CODE_INT64,
|
|
52
|
+
DTYPE_CODE_FLOAT32,
|
|
53
|
+
DTYPE_CODE_FLOAT64,
|
|
54
|
+
DTYPE_CODE_HYBRID,
|
|
55
|
+
)
|
|
56
|
+
from midas_integrate.peakfit import (
|
|
57
|
+
fit_peaks,
|
|
58
|
+
fit_peaks_autodetect,
|
|
59
|
+
pseudo_voigt,
|
|
60
|
+
snip_background,
|
|
61
|
+
PF_PARAMS_PER_PEAK,
|
|
62
|
+
)
|
|
63
|
+
from midas_integrate.fused_csr import build_fused_geometry
|
|
64
|
+
from midas_integrate.postprocess import gauss_smooth_eta, median_filter_eta
|
|
65
|
+
|
|
66
|
+
__all__ = [
|
|
67
|
+
"__version__",
|
|
68
|
+
# bin_io
|
|
69
|
+
"PXLIST_DTYPE",
|
|
70
|
+
"MAP_HEADER_MAGIC",
|
|
71
|
+
"MAP_HEADER_SIZE",
|
|
72
|
+
"MapHeader",
|
|
73
|
+
"PixelMap",
|
|
74
|
+
"load_map",
|
|
75
|
+
"write_map",
|
|
76
|
+
"write_synthetic_map",
|
|
77
|
+
# params
|
|
78
|
+
"IntegrationParams",
|
|
79
|
+
"parse_params",
|
|
80
|
+
# geometry
|
|
81
|
+
"DEG2RAD",
|
|
82
|
+
"RAD2DEG",
|
|
83
|
+
"build_tilt_matrix",
|
|
84
|
+
"pixel_to_REta",
|
|
85
|
+
"REta_to_YZ",
|
|
86
|
+
"build_bin_edges",
|
|
87
|
+
"build_q_bin_edges_in_R",
|
|
88
|
+
"polygon_area",
|
|
89
|
+
"circle_seg_intersect",
|
|
90
|
+
"ray_seg_intersect",
|
|
91
|
+
"point_in_quad",
|
|
92
|
+
"invert_REta_to_pixel",
|
|
93
|
+
# detector_mapper
|
|
94
|
+
"build_map",
|
|
95
|
+
"BuildMapResult",
|
|
96
|
+
# kernels
|
|
97
|
+
"AREA_THRESHOLD",
|
|
98
|
+
"CSRGeometry",
|
|
99
|
+
"build_csr",
|
|
100
|
+
"integrate",
|
|
101
|
+
"profile_1d",
|
|
102
|
+
# image
|
|
103
|
+
"bytes_per_pixel",
|
|
104
|
+
"decode_payload",
|
|
105
|
+
"decode_hybrid_payload",
|
|
106
|
+
"NUMPY_DTYPE_FOR_CODE",
|
|
107
|
+
"DTYPE_CODE_UINT8",
|
|
108
|
+
"DTYPE_CODE_UINT16",
|
|
109
|
+
"DTYPE_CODE_UINT32",
|
|
110
|
+
"DTYPE_CODE_INT64",
|
|
111
|
+
"DTYPE_CODE_FLOAT32",
|
|
112
|
+
"DTYPE_CODE_FLOAT64",
|
|
113
|
+
"DTYPE_CODE_HYBRID",
|
|
114
|
+
# peakfit
|
|
115
|
+
"fit_peaks",
|
|
116
|
+
"fit_peaks_autodetect",
|
|
117
|
+
"pseudo_voigt",
|
|
118
|
+
"snip_background",
|
|
119
|
+
"PF_PARAMS_PER_PEAK",
|
|
120
|
+
# alias-mitigation API (Family II + III)
|
|
121
|
+
"build_fused_geometry",
|
|
122
|
+
"gauss_smooth_eta",
|
|
123
|
+
"median_filter_eta",
|
|
124
|
+
]
|