diffct 2.4.3__py3-none-any.whl → 2.4.4__py3-none-any.whl
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.
- diffct/__init__.py +1 -1
- diffct/analytical.py +12 -9
- diffct/analytical_execution.py +7 -3
- diffct/backends.py +505 -110
- diffct/chunking.py +3 -2
- diffct/constants.py +12 -0
- diffct/kernels/analytical_transpose.py +40 -16
- diffct/kernels/cone_beam.py +117 -63
- diffct/kernels/fan_beam.py +49 -33
- diffct/kernels/geometry_vjp.py +153 -51
- diffct/kernels/parallel_beam.py +45 -15
- diffct/kernels/spacing.py +79 -0
- diffct/kernels/surface_geometry.py +15 -4
- diffct/operators.py +67 -11
- diffct/projectors.py +13 -6
- diffct/reconstruction.py +7 -4
- diffct/surfaces.py +7 -2
- {diffct-2.4.3.dist-info → diffct-2.4.4.dist-info}/METADATA +7 -4
- diffct-2.4.4.dist-info/RECORD +34 -0
- {diffct-2.4.3.dist-info → diffct-2.4.4.dist-info}/licenses/NOTICE +2 -0
- diffct-2.4.3.dist-info/RECORD +0 -33
- {diffct-2.4.3.dist-info → diffct-2.4.4.dist-info}/WHEEL +0 -0
- {diffct-2.4.3.dist-info → diffct-2.4.4.dist-info}/licenses/LICENSE +0 -0
diffct/__init__.py
CHANGED
diffct/analytical.py
CHANGED
|
@@ -27,7 +27,7 @@ import math
|
|
|
27
27
|
|
|
28
28
|
import torch
|
|
29
29
|
|
|
30
|
-
from .constants import _DTYPE
|
|
30
|
+
from .constants import _DTYPE, _native_spacing
|
|
31
31
|
from .utils import (
|
|
32
32
|
DeviceManager,
|
|
33
33
|
TorchCUDABridge,
|
|
@@ -431,7 +431,7 @@ def _parallel_weighted_backproject_raw(sinogram, ray_dir, det_origin, det_u_vec,
|
|
|
431
431
|
_resolve_kernel('_parallel_2d_fbp_backproject_kernel')[grid, tpb, numba_stream](
|
|
432
432
|
d_sino, n_views, n_det, d_reco, Nx, Ny,
|
|
433
433
|
_DTYPE(detector_spacing), d_ray_dir, d_det_origin, d_det_u_vec,
|
|
434
|
-
cx, cy,
|
|
434
|
+
cx, cy, _native_spacing(voxel_spacing),
|
|
435
435
|
)
|
|
436
436
|
|
|
437
437
|
return reco * (1.0 / (2.0 * math.pi))
|
|
@@ -522,8 +522,9 @@ def _fan_weighted_backproject_raw(sinogram, src_pos, det_center, det_u_vec,
|
|
|
522
522
|
_resolve_kernel('_fan_2d_fbp_backproject_kernel')[grid, tpb, numba_stream](
|
|
523
523
|
d_sino, n_views, n_det, d_reco, Nx, Ny,
|
|
524
524
|
_DTYPE(detector_spacing), d_src_pos, d_det_center, d_det_u_vec,
|
|
525
|
-
cx, cy,
|
|
526
|
-
*(_DTYPE(value
|
|
525
|
+
cx, cy, _native_spacing(voxel_spacing),
|
|
526
|
+
*(_DTYPE(value if isinstance(voxel_spacing, (tuple, list)) else value / voxel_spacing)
|
|
527
|
+
for value in isocenter.tolist()),
|
|
527
528
|
)
|
|
528
529
|
|
|
529
530
|
return reco
|
|
@@ -584,8 +585,9 @@ def _cone_weighted_backproject_raw(sinogram, src_pos, det_center, det_u_vec, det
|
|
|
584
585
|
d_sino, n_views, n_u, n_v, d_reco, Nx, Ny, Nz,
|
|
585
586
|
_DTYPE(du), _DTYPE(dv),
|
|
586
587
|
d_src_pos, d_det_center, d_det_u_vec, d_det_v_vec,
|
|
587
|
-
cx, cy, cz,
|
|
588
|
-
*(_DTYPE(value
|
|
588
|
+
cx, cy, cz, _native_spacing(voxel_spacing),
|
|
589
|
+
*(_DTYPE(value if isinstance(voxel_spacing, (tuple, list)) else value / voxel_spacing)
|
|
590
|
+
for value in isocenter.tolist()),
|
|
589
591
|
)
|
|
590
592
|
|
|
591
593
|
# Convert back to (D, H, W) layout for the user.
|
|
@@ -637,7 +639,8 @@ def _analytical_transpose_raw(image, beam, geometry, parameters, isocenter, sino
|
|
|
637
639
|
scale = (sdd_n / (2.0 * math.pi * sid_n)).view(
|
|
638
640
|
(-1,) + (1,) * (len(sinogram_shape) - 1)
|
|
639
641
|
)
|
|
640
|
-
iso = tuple(_DTYPE(value
|
|
642
|
+
iso = tuple(_DTYPE(value if isinstance(parameters[-1], (tuple, list)) else value / parameters[-1])
|
|
643
|
+
for value in isocenter.tolist())
|
|
641
644
|
|
|
642
645
|
if beam == "cone":
|
|
643
646
|
D, H, W, du, dv, spacing = parameters
|
|
@@ -647,7 +650,7 @@ def _analytical_transpose_raw(image, beam, geometry, parameters, isocenter, sino
|
|
|
647
650
|
_resolve_kernel('_cone_3d_fdk_transpose_kernel')[grid, tpb, stream](
|
|
648
651
|
d_sino, *sinogram_shape, d_image, W, H, D, _DTYPE(du), _DTYPE(dv),
|
|
649
652
|
*d_geometry, _DTYPE(W * 0.5), _DTYPE(H * 0.5), _DTYPE(D * 0.5),
|
|
650
|
-
|
|
653
|
+
_native_spacing(spacing), *iso,
|
|
651
654
|
)
|
|
652
655
|
else:
|
|
653
656
|
pitch, H, W, spacing = parameters
|
|
@@ -657,7 +660,7 @@ def _analytical_transpose_raw(image, beam, geometry, parameters, isocenter, sino
|
|
|
657
660
|
else '_fan_2d_fbp_transpose_kernel')
|
|
658
661
|
kernel[grid, tpb, stream](
|
|
659
662
|
d_sino, *sinogram_shape, d_image, W, H, _DTYPE(pitch), *d_geometry,
|
|
660
|
-
_DTYPE(W * 0.5), _DTYPE(H * 0.5),
|
|
663
|
+
_DTYPE(W * 0.5), _DTYPE(H * 0.5), _native_spacing(spacing), *iso,
|
|
661
664
|
)
|
|
662
665
|
return sinogram * scale
|
|
663
666
|
|
diffct/analytical_execution.py
CHANGED
|
@@ -16,6 +16,7 @@ from .analytical import (
|
|
|
16
16
|
fan_weighted_backproject, parallel_weighted_backproject,
|
|
17
17
|
)
|
|
18
18
|
from .backends import _zero_dependency, select_backend, voxel_spacing_tuple
|
|
19
|
+
from .constants import _native_spacing
|
|
19
20
|
from .chunking import _memory_budget, _pixel_tiles
|
|
20
21
|
from .distribution import Partition, preflight
|
|
21
22
|
from .operators import _detector_spacing, _normalize_devices, _positive_int, _shape, _validate_trajectory
|
|
@@ -143,6 +144,9 @@ class AnalyticalExecution:
|
|
|
143
144
|
self.rank = 3 if beam == "cone" else 2
|
|
144
145
|
self.global_volume_shape = _shape(volume_shape, self.rank, "volume_shape")
|
|
145
146
|
self.spacing = voxel_spacing_tuple(voxel_spacing, self.rank)
|
|
147
|
+
self.voxel_spacing = self.spacing if isinstance(voxel_spacing, (tuple, list)) else self.spacing[0]
|
|
148
|
+
if self.backend == "numba" and isinstance(self.voxel_spacing, tuple):
|
|
149
|
+
_native_spacing(self.voxel_spacing)
|
|
146
150
|
self.pitch = _detector_spacing(detector_spacing, beam)
|
|
147
151
|
self.devices = _normalize_devices(devices)
|
|
148
152
|
if not isinstance(source, torch.Tensor):
|
|
@@ -336,14 +340,14 @@ class AnalyticalExecution:
|
|
|
336
340
|
device=data.device, dtype=self.dtype)
|
|
337
341
|
if self.beam == "parallel":
|
|
338
342
|
geometry = (geometry[0], geometry[1] - centre, geometry[2])
|
|
339
|
-
return parallel_weighted_backproject(data, *geometry, self.pitch[0], *shape, self.
|
|
343
|
+
return parallel_weighted_backproject(data, *geometry, self.pitch[0], *shape, self.voxel_spacing)
|
|
340
344
|
geometry = (geometry[0] - centre, geometry[1] - centre, *geometry[2:])
|
|
341
345
|
isocenter = self.isocenter.to(data.device) - centre
|
|
342
346
|
if self.beam == "fan":
|
|
343
347
|
return fan_weighted_backproject(data, *geometry, self.pitch[0], *shape,
|
|
344
|
-
self.
|
|
348
|
+
self.voxel_spacing, isocenter=isocenter)
|
|
345
349
|
return cone_weighted_backproject(data, *geometry, *shape, *self.pitch,
|
|
346
|
-
self.
|
|
350
|
+
self.voxel_spacing, isocenter=isocenter)
|
|
347
351
|
|
|
348
352
|
def _tile(self, spatial):
|
|
349
353
|
shape = tuple(part.stop - part.start for part in spatial)
|