nabu 2024.2.4__py3-none-any.whl → 2024.2.5__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.
nabu/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "2024.2.4"
1
+ __version__ = "2024.2.5"
2
2
  __nabu_modules__ = [
3
3
  "app",
4
4
  "cuda",
nabu/cuda/src/cone.cu CHANGED
@@ -26,23 +26,33 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
26
26
  */
27
27
 
28
28
 
29
- static const unsigned int g_anglesPerWeightBlock = 16;
30
- static const unsigned int g_detBlockU = 32;
31
- static const unsigned int g_detBlockV = 32;
29
+ // static const unsigned int g_anglesPerWeightBlock = 16;
30
+ // static const unsigned int g_detBlockU = 32;
31
+ // static const unsigned int g_detBlockV = 32;
32
32
 
33
33
 
34
34
  __global__ void devFDK_preweight(void* D_projData, unsigned int projPitch, unsigned int startAngle, unsigned int endAngle, float fSrcOrigin, float fDetOrigin, float fZShift, float fDetUSize, float fDetVSize, unsigned int iProjAngles, unsigned int iProjU, unsigned int iProjV)
35
35
  {
36
36
  float* projData = (float*)D_projData;
37
- int angle = startAngle + blockIdx.y * g_anglesPerWeightBlock + threadIdx.y;
37
+
38
+ const uint angle = blockDim.y * blockIdx.y + threadIdx.y + startAngle;
39
+
38
40
  if (angle >= endAngle)
39
41
  return;
40
42
 
41
- const int detectorU = (blockIdx.x%((iProjU+g_detBlockU-1)/g_detBlockU)) * g_detBlockU + threadIdx.x;
42
- const int startDetectorV = (blockIdx.x/((iProjU+g_detBlockU-1)/g_detBlockU)) * g_detBlockV;
43
- int endDetectorV = startDetectorV + g_detBlockV;
44
- if (endDetectorV > iProjV)
45
- endDetectorV = iProjV;
43
+ // Astra FDK kernel used this indexing (with the appropriate grid)
44
+ // const int detectorU = (blockIdx.x%((iProjU+g_detBlockU-1)/g_detBlockU)) * g_detBlockU + threadIdx.x;
45
+ // const int startDetectorV = (blockIdx.x/((iProjU+g_detBlockU-1)/g_detBlockU)) * g_detBlockV;
46
+ // Instead we choose a simpler scheme which does not assume pitch memory allocation
47
+
48
+ const uint detectorU = blockDim.x * blockIdx.x + threadIdx.x;
49
+ const int startDetectorV = 0;
50
+
51
+ int endDetectorV = iProjV; // startDetectorV + g_detBlockV;
52
+ // if (endDetectorV > iProjV)
53
+ // endDetectorV = iProjV;
54
+ if (detectorU >= iProjU) return;
55
+
46
56
 
47
57
  // We need the length of the central ray and the length of the ray(s) to
48
58
  // our detector pixel(s).
@@ -1,10 +1,11 @@
1
+ import logging
1
2
  from math import sqrt
2
3
  import numpy as np
3
4
 
4
5
  from ..cuda.kernel import CudaKernel
5
6
  from ..cuda.processing import CudaProcessing
6
7
  from ..reconstruction.filtering_cuda import CudaSinoFilter
7
- from ..utils import get_cuda_srcfile
8
+ from ..utils import get_cuda_srcfile, updiv
8
9
 
9
10
  try:
10
11
  import astra
@@ -14,6 +15,9 @@ except ImportError:
14
15
  __have_astra__ = False
15
16
 
16
17
 
18
+ _logger = logging.getLogger(__name__)
19
+
20
+
17
21
  class ConebeamReconstructor:
18
22
  """
19
23
  A reconstructor for cone-beam geometry using the astra toolbox.
@@ -159,7 +163,9 @@ class ConebeamReconstructor:
159
163
  def _init_fdk(self, padding_mode, filter_name):
160
164
  self.padding_mode = padding_mode
161
165
  self._use_astra_fdk = bool(self.extra_options.get("use_astra_fdk", True))
162
- self._use_astra_fdk &= padding_mode in ["zeros", "constant", None, "none"]
166
+ if self._use_astra_fdk and padding_mode not in ["zeros", "constant", None, "none"]:
167
+ self._use_astra_fdk = False
168
+ _logger.warning("padding_mode was set to %s, cannot use native astra FDK" % padding_mode)
163
169
  if self._use_astra_fdk:
164
170
  return
165
171
  self.sino_filter = CudaSinoFilter(
@@ -386,12 +392,11 @@ def fdk_preweighting(d_sinos, proj_geom, relative_z_position=0.0, cor_shift=0.0)
386
392
  signature="Piiifffffiii",
387
393
  )
388
394
 
389
- # n_angles, n_z, n_x = d_sinos.shape
390
395
  n_z, n_angles, n_x = d_sinos.shape
391
396
  det_origin = sqrt(proj_geom["DistanceOriginDetector"] ** 2 + cor_shift**2)
392
397
 
393
398
  block = (32, 16, 1)
394
- grid = (((n_x + 32 - 1) // 32) * ((n_z + 32 - 1) // 32), (n_angles + 16 - 1) // 16, 1)
399
+ grid = (updiv(n_x, block[0]), updiv(n_angles, block[1]), 1)
395
400
 
396
401
  preweight_kernel(
397
402
  d_sinos,
@@ -1,7 +1,9 @@
1
+ import logging
1
2
  import pytest
2
3
  import numpy as np
3
4
  from scipy.ndimage import gaussian_filter, shift
4
5
  from nabu.utils import subdivide_into_overlapping_segment, clip_circle
6
+ from nabu.testutils import __do_long_tests__, generate_tests_scenarios
5
7
 
6
8
  try:
7
9
  import astra
@@ -387,6 +389,77 @@ class TestCone:
387
389
  str(roi)
388
390
  )
389
391
 
392
+ def test_fdk_preweight(self, caplog):
393
+ """
394
+ Check that nabu's FDK pre-weighting give the same results as astra
395
+ """
396
+ shapes = [
397
+ {"n_z": 256, "n_x": 256, "n_a": 500},
398
+ # {"n_z": 250, "n_x": 340, "n_a": 250}, # Astra reconstruction is incorrect in this case!
399
+ ]
400
+ src_orig_dist = 1000
401
+ orig_det_dist = 50
402
+
403
+ rot_centers_from_middle = [0]
404
+ if __do_long_tests__:
405
+ rot_centers_from_middle.extend([10, -15])
406
+
407
+ params_list = generate_tests_scenarios({"shape": shapes, "rot_center": rot_centers_from_middle})
408
+
409
+ for params in params_list:
410
+ n_z = params["shape"]["n_z"]
411
+ n_x = n_y = params["shape"]["n_x"]
412
+ n_a = params["shape"]["n_a"]
413
+ rc = params["rot_center"]
414
+ volume, cone_data = generate_hollow_cube_cone_sinograms(
415
+ vol_shape=(n_z, n_y, n_x),
416
+ n_angles=n_a,
417
+ src_orig_dist=src_orig_dist,
418
+ orig_det_dist=orig_det_dist,
419
+ apply_filter=False,
420
+ rot_center_shift=rc,
421
+ )
422
+
423
+ reconstructor_args = [(n_z, n_a, n_x), src_orig_dist, orig_det_dist]
424
+ reconstructor_kwargs_base = {
425
+ "volume_shape": volume.shape,
426
+ "rot_center": (n_x - 1) / 2 + rc,
427
+ "cuda_options": {"ctx": self.ctx},
428
+ }
429
+ reconstructor_kwargs_astra = {"padding_mode": "zeros", "extra_options": {"use_astra_fdk": True}}
430
+ reconstructor_kwargs_nabu = {"padding_mode": "zeros", "extra_options": {"use_astra_fdk": False}}
431
+ reconstructor_astra = ConebeamReconstructor(
432
+ *reconstructor_args, **{**reconstructor_kwargs_base, **reconstructor_kwargs_astra}
433
+ )
434
+ assert reconstructor_astra._use_astra_fdk is True, "reconstructor_astra should use native astra FDK"
435
+ reconstructor_nabu = ConebeamReconstructor(
436
+ *reconstructor_args, **{**reconstructor_kwargs_base, **reconstructor_kwargs_nabu}
437
+ )
438
+ ref = reconstructor_astra.reconstruct(cone_data)
439
+ res = reconstructor_nabu.reconstruct(cone_data)
440
+
441
+ reconstructor_kwargs_nabu = {"padding_mode": "edges", "extra_options": {"use_astra_fdk": False}}
442
+ cb_ep = ConebeamReconstructor(
443
+ *reconstructor_args, **{**reconstructor_kwargs_base, **reconstructor_kwargs_nabu}
444
+ )
445
+ res_ep = cb_ep.reconstruct(cone_data) # noqa: F841
446
+
447
+ assert np.max(np.abs(res - ref)) < 2e-3, "Wrong FDK results for parameters: %s" % (str(params))
448
+
449
+ # Test with edges padding - only nabu can do that
450
+ reconstructor_kwargs_nabu["padding_mode"] = "edges"
451
+ reconstructor_nabu = ConebeamReconstructor(
452
+ *reconstructor_args, **{**reconstructor_kwargs_base, **reconstructor_kwargs_nabu}
453
+ )
454
+ reconstructor_nabu.reconstruct(cone_data)
455
+ # result is slightly different than "res" in the borders, which is expected
456
+ # it would be good to test it as well, but it's outside of the scope of this test
457
+
458
+ with caplog.at_level(logging.WARNING):
459
+ reconstructor_kwargs_nabu = {"padding_mode": "edges", "extra_options": {"use_astra_fdk": True}}
460
+ ConebeamReconstructor(*reconstructor_args, **{**reconstructor_kwargs_base, **reconstructor_kwargs_nabu})
461
+ assert "cannot use native astra FDK" in caplog.text
462
+
390
463
 
391
464
  def generate_hollow_cube_cone_sinograms(
392
465
  vol_shape,
@@ -406,7 +479,7 @@ def generate_hollow_cube_cone_sinograms(
406
479
  prj_height = n_z
407
480
  angles = np.linspace(0, 2 * np.pi, n_angles, True)
408
481
 
409
- proj_geom = astra.create_proj_geom("cone", 1.0, 1.0, prj_width, prj_width, angles, src_orig_dist, orig_det_dist)
482
+ proj_geom = astra.create_proj_geom("cone", 1.0, 1.0, n_z, prj_width, angles, src_orig_dist, orig_det_dist)
410
483
  if rot_center_shift is not None:
411
484
  proj_geom = astra.geom_postalignment(proj_geom, (-rot_center_shift, 0))
412
485
  magnification = 1 + orig_det_dist / src_orig_dist
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: nabu
3
- Version: 2024.2.4
3
+ Version: 2024.2.5
4
4
  Summary: Nabu - Tomography software
5
5
  Author-email: Pierre Paleo <pierre.paleo@esrf.fr>, Henri Payno <henri.payno@esrf.fr>, Alessandro Mirone <mirone@esrf.fr>, Jérôme Lesaint <jerome.lesaint@esrf.fr>
6
6
  Maintainer-email: Pierre Paleo <pierre.paleo@esrf.fr>
@@ -49,35 +49,35 @@ Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
49
49
  Requires-Python: >=3.7
50
50
  Description-Content-Type: text/markdown
51
51
  License-File: LICENSE
52
- Requires-Dist: numpy <2,>1.9.0
52
+ Requires-Dist: numpy<2,>1.9.0
53
53
  Requires-Dist: scipy
54
- Requires-Dist: h5py >=3.0
55
- Requires-Dist: silx >=0.15.0
56
- Requires-Dist: tomoscan >=2.1.0
54
+ Requires-Dist: h5py>=3.0
55
+ Requires-Dist: silx>=0.15.0
56
+ Requires-Dist: tomoscan>=2.1.0
57
57
  Requires-Dist: psutil
58
58
  Requires-Dist: pytest
59
59
  Requires-Dist: tifffile
60
60
  Requires-Dist: tqdm
61
- Provides-Extra: doc
62
- Requires-Dist: sphinx ; extra == 'doc'
63
- Requires-Dist: cloud-sptheme ; extra == 'doc'
64
- Requires-Dist: myst-parser ; extra == 'doc'
65
- Requires-Dist: nbsphinx ; extra == 'doc'
66
61
  Provides-Extra: full
67
- Requires-Dist: scikit-image ; extra == 'full'
68
- Requires-Dist: PyWavelets ; extra == 'full'
69
- Requires-Dist: glymur ; extra == 'full'
70
- Requires-Dist: pycuda !=2024.1.1 ; extra == 'full'
71
- Requires-Dist: scikit-cuda ; extra == 'full'
72
- Requires-Dist: pycudwt ; extra == 'full'
73
- Requires-Dist: sluurp >=0.3 ; extra == 'full'
74
- Requires-Dist: pyvkfft ; extra == 'full'
75
- Provides-Extra: full_nocuda
76
- Requires-Dist: scikit-image ; extra == 'full_nocuda'
77
- Requires-Dist: PyWavelets ; extra == 'full_nocuda'
78
- Requires-Dist: glymur ; extra == 'full_nocuda'
79
- Requires-Dist: sluurp >=0.3 ; extra == 'full_nocuda'
80
- Requires-Dist: pyvkfft ; extra == 'full_nocuda'
62
+ Requires-Dist: scikit-image; extra == "full"
63
+ Requires-Dist: PyWavelets; extra == "full"
64
+ Requires-Dist: glymur; extra == "full"
65
+ Requires-Dist: pycuda!=2024.1.1; extra == "full"
66
+ Requires-Dist: scikit-cuda; extra == "full"
67
+ Requires-Dist: pycudwt; extra == "full"
68
+ Requires-Dist: sluurp>=0.3; extra == "full"
69
+ Requires-Dist: pyvkfft; extra == "full"
70
+ Provides-Extra: full-nocuda
71
+ Requires-Dist: scikit-image; extra == "full-nocuda"
72
+ Requires-Dist: PyWavelets; extra == "full-nocuda"
73
+ Requires-Dist: glymur; extra == "full-nocuda"
74
+ Requires-Dist: sluurp>=0.3; extra == "full-nocuda"
75
+ Requires-Dist: pyvkfft; extra == "full-nocuda"
76
+ Provides-Extra: doc
77
+ Requires-Dist: sphinx; extra == "doc"
78
+ Requires-Dist: cloud_sptheme; extra == "doc"
79
+ Requires-Dist: myst-parser; extra == "doc"
80
+ Requires-Dist: nbsphinx; extra == "doc"
81
81
 
82
82
  # Nabu
83
83
 
@@ -1,7 +1,7 @@
1
1
  doc/conf.py,sha256=3xtCarCHrXPr50GbeRDuH-o3Jzojw7mpr7vpGfZPLAE,3787
2
2
  doc/create_conf_doc.py,sha256=IVOdP70KvbW9WS_UQu3Iyd0YfS60E2fJ5IDtQ_s4cDw,1143
3
3
  doc/get_mathjax.py,sha256=VIvKRCdDuF2VoY8JD3mSey9XX13AZMmwTJBHdt1tUs4,1012
4
- nabu/__init__.py,sha256=c6RQ-mRwrAgEkoyeON7u8FYClLvqty1oogHOSMgxIRw,270
4
+ nabu/__init__.py,sha256=BhsllrJ2adOlOshSRwCN9w9DtOegccwzs8GPbrfvAUA,270
5
5
  nabu/tests.py,sha256=cew9OY2uTyncHI_HM32W8CP6B1GTGKaOW65XtMEqs7o,1417
6
6
  nabu/testutils.py,sha256=VkSL9tbY0XEH49Z5OjDFFhzkSxrCv4UIuvSVFgegSUY,7632
7
7
  nabu/utils.py,sha256=V1B_sD54XGNKn5pORa2yNCATyswOzybey3sv8BuIYWY,26355
@@ -44,7 +44,7 @@ nabu/cuda/src/ElementOp.cu,sha256=PhebQQgeF0V7MDNzeYiRXIeNq3tE2PsBx00XhanBmvg,71
44
44
  nabu/cuda/src/backproj.cu,sha256=Zq9w8TP9zSYCHH_91dfrTVLOSEmY0y4hzm7J2qdCdJ8,6257
45
45
  nabu/cuda/src/backproj_polar.cu,sha256=sZbtw3KMfN69XyubJQSSLC87d5IPOyzbPBoRSNC1Cek,1851
46
46
  nabu/cuda/src/boundary.h,sha256=eQhfKZm-o0kj88BvkUwzqfqxYfRde4Tuj8AhQvRK16Y,2898
47
- nabu/cuda/src/cone.cu,sha256=Q-mKNBnx0pXzpOUGKi0Kq4POp7VqaQrLCDgqTf1pdkk,3071
47
+ nabu/cuda/src/cone.cu,sha256=IuuVpHPnGekQmLq7_FyJ3pN4Ntjs7k5yeUiPKty7H9w,3399
48
48
  nabu/cuda/src/convolution.cu,sha256=O6r8qPpQjpaqnNivMRX0LK3dEACKk9xyNYO9u_JysU0,7353
49
49
  nabu/cuda/src/dfi_fftshift.cu,sha256=ElgNXy8H14mff2hmyjxCq7CnFK_DSY2Z564QGytRO1o,2220
50
50
  nabu/cuda/src/flatfield.cu,sha256=ZVVmEd-jcsK03VWv42uugYw6LeUnDEVY8qo_G07doHs,2058
@@ -220,7 +220,7 @@ nabu/processing/tests/test_rotation.py,sha256=vedRXV9RePJywBKoyBkGANP1dhZCjphbYO
220
220
  nabu/processing/tests/test_transpose.py,sha256=hTG17wTaB5Wv6twbW3ZFhBv6BYfqJY7DTQPoO0-KdkM,2760
221
221
  nabu/processing/tests/test_unsharp.py,sha256=R3ovbwDDp3ccy2A8t6CcUVELXRWkED5EnQdN2FQOfQM,4391
222
222
  nabu/reconstruction/__init__.py,sha256=EmKVvx_-FJvzJngG4ielIC7FhMCpI1Waaflg_lF44tk,163
223
- nabu/reconstruction/cone.py,sha256=WObFcHvv7NkaZhUoC_xTlvl95f38AjsAJkePSOzngVk,18870
223
+ nabu/reconstruction/cone.py,sha256=RZj1JoxqskShvglgxUnsbYw7qbm6Rralt7hJ96eU-8c,19015
224
224
  nabu/reconstruction/fbp.py,sha256=uwEniGdEOn1atc9mTAHEDeF1y-ZqneifCKVr-ieHZss,5015
225
225
  nabu/reconstruction/fbp_base.py,sha256=DwZCilPXgGMRPV8_XfkWiaXUzWFM8rNBa8IyMdy5nno,17092
226
226
  nabu/reconstruction/fbp_opencl.py,sha256=coEGLq65PCuvWnhAbIyLPHACkWjMB0XOceMp9ZIDWtc,3274
@@ -238,7 +238,7 @@ nabu/reconstruction/sinogram.py,sha256=KTSGP_JJABf4Yr9l628HPbyWsBnpbnyGKyPEq3ZrP
238
238
  nabu/reconstruction/sinogram_cuda.py,sha256=DmTWdI9JhINjBpBuPiEt5mSqFmqu2FitIV94g3hSTAI,10659
239
239
  nabu/reconstruction/sinogram_opencl.py,sha256=vxJa5BeOd2NVdUayXYfQGAfO1AEbJfTGotuijT8qgCs,1486
240
240
  nabu/reconstruction/tests/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
241
- nabu/reconstruction/tests/test_cone.py,sha256=2BsR1kHlnlronghckifGmcrtROWF43lilYo8TMDUTjo,17846
241
+ nabu/reconstruction/tests/test_cone.py,sha256=Vb31LX_KXYU8FPlco9heFRHIftk0-RI5_LSbhX9OMIA,21453
242
242
  nabu/reconstruction/tests/test_deringer.py,sha256=XE97waf6TKFm-Kxe9PGQ-Vs_Pldn-OzvOolhuy7a5k4,8340
243
243
  nabu/reconstruction/tests/test_fbp.py,sha256=jj2eSRB56-xs4SM_pK3Q9EupKQWFTzbtraXPD165rcU,15291
244
244
  nabu/reconstruction/tests/test_filtering.py,sha256=I5H1KSfd4iXTJWSqeMPR5Q7v5rFTXO6Vp2jYU4ugl58,5247
@@ -310,9 +310,9 @@ nabu/thirdparty/pore3d_deringer_munch.py,sha256=o4bisnFc-wMjuohWBT8wgWmfNehPQGtC
310
310
  nabu/thirdparty/tomocupy_remove_stripe.py,sha256=Khe4zFf0kRzu65Yxnvq58gt1ljOztqJGdMDhVAiM7lM,24363
311
311
  nabu/thirdparty/tomopy_phase.py,sha256=hK4oPpkogLOhv23XzzEXQY2u3r8fJvASY_bINVs6ERE,8634
312
312
  nabu/thirdparty/tomwer_load_flats_darks.py,sha256=ZNoVAinUb_wGYbfvs_4BVnWsjsQmNxSvCh1bWhR2WWg,5611
313
- nabu-2024.2.4.dist-info/LICENSE,sha256=1eAIPSnEsnSFNUODnLtNtQTs76exG3ZxJ1DJR6zoUBA,1066
314
- nabu-2024.2.4.dist-info/METADATA,sha256=8aKl-Zw_YMikzn33XIqdUzSbSqI4x3bUwhxL_wZi8Dc,5538
315
- nabu-2024.2.4.dist-info/WHEEL,sha256=5sUXSg9e4bi7lTLOHcm6QEYwO5TIF1TNbTSVFVjcJcc,92
316
- nabu-2024.2.4.dist-info/entry_points.txt,sha256=cJKGkBeykVL7uK3E4R0RLRqMXifTL2qdO573syPAvJc,1288
317
- nabu-2024.2.4.dist-info/top_level.txt,sha256=fsm_N3eXLRZk2QXF9OSKPNDPFXOz8FAQjHh5avT3dok,9
318
- nabu-2024.2.4.dist-info/RECORD,,
313
+ nabu-2024.2.5.dist-info/LICENSE,sha256=1eAIPSnEsnSFNUODnLtNtQTs76exG3ZxJ1DJR6zoUBA,1066
314
+ nabu-2024.2.5.dist-info/METADATA,sha256=dagapyWNaPkQX79F5M8U6pRfmPJqczjoupUC41I5yfw,5514
315
+ nabu-2024.2.5.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
316
+ nabu-2024.2.5.dist-info/entry_points.txt,sha256=cJKGkBeykVL7uK3E4R0RLRqMXifTL2qdO573syPAvJc,1288
317
+ nabu-2024.2.5.dist-info/top_level.txt,sha256=fsm_N3eXLRZk2QXF9OSKPNDPFXOz8FAQjHh5avT3dok,9
318
+ nabu-2024.2.5.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.41.1)
2
+ Generator: setuptools (75.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5