nabu 2023.2.1__py3-none-any.whl → 2024.1.0rc3__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.
Files changed (183) hide show
  1. doc/conf.py +1 -1
  2. doc/doc_config.py +32 -0
  3. nabu/__init__.py +2 -1
  4. nabu/app/bootstrap_stitching.py +1 -1
  5. nabu/app/cli_configs.py +122 -2
  6. nabu/app/composite_cor.py +27 -2
  7. nabu/app/correct_rot.py +70 -0
  8. nabu/app/create_distortion_map_from_poly.py +42 -18
  9. nabu/app/diag_to_pix.py +358 -0
  10. nabu/app/diag_to_rot.py +449 -0
  11. nabu/app/generate_header.py +4 -3
  12. nabu/app/histogram.py +2 -2
  13. nabu/app/multicor.py +6 -1
  14. nabu/app/parse_reconstruction_log.py +151 -0
  15. nabu/app/prepare_weights_double.py +83 -22
  16. nabu/app/reconstruct.py +5 -1
  17. nabu/app/reconstruct_helical.py +7 -0
  18. nabu/app/reduce_dark_flat.py +6 -3
  19. nabu/app/rotate.py +4 -4
  20. nabu/app/stitching.py +16 -2
  21. nabu/app/tests/test_reduce_dark_flat.py +18 -2
  22. nabu/app/validator.py +4 -4
  23. nabu/cuda/convolution.py +8 -376
  24. nabu/cuda/fft.py +4 -0
  25. nabu/cuda/kernel.py +4 -4
  26. nabu/cuda/medfilt.py +5 -158
  27. nabu/cuda/padding.py +5 -71
  28. nabu/cuda/processing.py +23 -2
  29. nabu/cuda/src/ElementOp.cu +78 -0
  30. nabu/cuda/src/backproj.cu +28 -2
  31. nabu/cuda/src/fourier_wavelets.cu +2 -2
  32. nabu/cuda/src/normalization.cu +23 -0
  33. nabu/cuda/src/padding.cu +2 -2
  34. nabu/cuda/src/transpose.cu +16 -0
  35. nabu/cuda/utils.py +39 -0
  36. nabu/estimation/alignment.py +10 -1
  37. nabu/estimation/cor.py +808 -38
  38. nabu/estimation/cor_sino.py +7 -9
  39. nabu/estimation/tests/test_cor.py +85 -3
  40. nabu/io/reader.py +26 -18
  41. nabu/io/tests/test_cast_volume.py +3 -3
  42. nabu/io/tests/test_detector_distortion.py +3 -3
  43. nabu/io/tiffwriter_zmm.py +2 -2
  44. nabu/io/utils.py +14 -4
  45. nabu/io/writer.py +5 -3
  46. nabu/misc/fftshift.py +6 -0
  47. nabu/misc/histogram.py +5 -285
  48. nabu/misc/histogram_cuda.py +8 -104
  49. nabu/misc/kernel_base.py +3 -121
  50. nabu/misc/padding_base.py +5 -69
  51. nabu/misc/processing_base.py +3 -107
  52. nabu/misc/rotation.py +5 -62
  53. nabu/misc/rotation_cuda.py +5 -65
  54. nabu/misc/transpose.py +6 -0
  55. nabu/misc/unsharp.py +3 -78
  56. nabu/misc/unsharp_cuda.py +5 -52
  57. nabu/misc/unsharp_opencl.py +8 -85
  58. nabu/opencl/fft.py +6 -0
  59. nabu/opencl/kernel.py +21 -6
  60. nabu/opencl/padding.py +5 -72
  61. nabu/opencl/processing.py +27 -5
  62. nabu/opencl/src/backproj.cl +3 -3
  63. nabu/opencl/src/fftshift.cl +65 -12
  64. nabu/opencl/src/padding.cl +2 -2
  65. nabu/opencl/src/roll.cl +96 -0
  66. nabu/opencl/src/transpose.cl +16 -0
  67. nabu/pipeline/config_validators.py +63 -3
  68. nabu/pipeline/dataset_validator.py +2 -2
  69. nabu/pipeline/estimators.py +193 -35
  70. nabu/pipeline/fullfield/chunked.py +34 -17
  71. nabu/pipeline/fullfield/chunked_cuda.py +7 -5
  72. nabu/pipeline/fullfield/computations.py +48 -13
  73. nabu/pipeline/fullfield/nabu_config.py +13 -13
  74. nabu/pipeline/fullfield/processconfig.py +10 -5
  75. nabu/pipeline/fullfield/reconstruction.py +1 -2
  76. nabu/pipeline/helical/fbp.py +5 -0
  77. nabu/pipeline/helical/filtering.py +12 -9
  78. nabu/pipeline/helical/gridded_accumulator.py +179 -33
  79. nabu/pipeline/helical/helical_chunked_regridded.py +262 -151
  80. nabu/pipeline/helical/helical_chunked_regridded_cuda.py +4 -11
  81. nabu/pipeline/helical/helical_reconstruction.py +56 -18
  82. nabu/pipeline/helical/span_strategy.py +1 -1
  83. nabu/pipeline/helical/tests/test_accumulator.py +4 -0
  84. nabu/pipeline/params.py +23 -2
  85. nabu/pipeline/processconfig.py +3 -8
  86. nabu/pipeline/tests/test_chunk_reader.py +78 -0
  87. nabu/pipeline/tests/test_estimators.py +120 -2
  88. nabu/pipeline/utils.py +25 -0
  89. nabu/pipeline/writer.py +2 -0
  90. nabu/preproc/ccd_cuda.py +9 -7
  91. nabu/preproc/ctf.py +21 -26
  92. nabu/preproc/ctf_cuda.py +25 -25
  93. nabu/preproc/double_flatfield.py +14 -2
  94. nabu/preproc/double_flatfield_cuda.py +7 -11
  95. nabu/preproc/flatfield_cuda.py +23 -27
  96. nabu/preproc/phase.py +19 -24
  97. nabu/preproc/phase_cuda.py +21 -21
  98. nabu/preproc/shift_cuda.py +58 -28
  99. nabu/preproc/tests/test_ctf.py +5 -5
  100. nabu/preproc/tests/test_double_flatfield.py +2 -2
  101. nabu/preproc/tests/test_vshift.py +13 -2
  102. nabu/processing/__init__.py +0 -0
  103. nabu/processing/convolution_cuda.py +375 -0
  104. nabu/processing/fft_base.py +163 -0
  105. nabu/processing/fft_cuda.py +256 -0
  106. nabu/processing/fft_opencl.py +54 -0
  107. nabu/processing/fftshift.py +134 -0
  108. nabu/processing/histogram.py +286 -0
  109. nabu/processing/histogram_cuda.py +103 -0
  110. nabu/processing/kernel_base.py +126 -0
  111. nabu/processing/medfilt_cuda.py +159 -0
  112. nabu/processing/muladd.py +29 -0
  113. nabu/processing/muladd_cuda.py +68 -0
  114. nabu/processing/padding_base.py +71 -0
  115. nabu/processing/padding_cuda.py +75 -0
  116. nabu/processing/padding_opencl.py +77 -0
  117. nabu/processing/processing_base.py +123 -0
  118. nabu/processing/roll_opencl.py +64 -0
  119. nabu/processing/rotation.py +63 -0
  120. nabu/processing/rotation_cuda.py +66 -0
  121. nabu/processing/tests/__init__.py +0 -0
  122. nabu/processing/tests/test_fft.py +268 -0
  123. nabu/processing/tests/test_fftshift.py +71 -0
  124. nabu/{misc → processing}/tests/test_histogram.py +2 -4
  125. nabu/{cuda → processing}/tests/test_medfilt.py +1 -1
  126. nabu/processing/tests/test_muladd.py +54 -0
  127. nabu/{cuda → processing}/tests/test_padding.py +119 -75
  128. nabu/processing/tests/test_roll.py +63 -0
  129. nabu/{misc → processing}/tests/test_rotation.py +3 -2
  130. nabu/processing/tests/test_transpose.py +72 -0
  131. nabu/{misc → processing}/tests/test_unsharp.py +41 -8
  132. nabu/processing/transpose.py +126 -0
  133. nabu/processing/unsharp.py +79 -0
  134. nabu/processing/unsharp_cuda.py +53 -0
  135. nabu/processing/unsharp_opencl.py +75 -0
  136. nabu/reconstruction/fbp.py +34 -10
  137. nabu/reconstruction/fbp_base.py +35 -16
  138. nabu/reconstruction/fbp_opencl.py +7 -12
  139. nabu/reconstruction/filtering.py +2 -2
  140. nabu/reconstruction/filtering_cuda.py +13 -14
  141. nabu/reconstruction/filtering_opencl.py +3 -4
  142. nabu/reconstruction/projection.py +2 -0
  143. nabu/reconstruction/rings.py +158 -1
  144. nabu/reconstruction/rings_cuda.py +218 -58
  145. nabu/reconstruction/sinogram_cuda.py +16 -12
  146. nabu/reconstruction/tests/test_deringer.py +116 -14
  147. nabu/reconstruction/tests/test_fbp.py +22 -31
  148. nabu/reconstruction/tests/test_filtering.py +11 -2
  149. nabu/resources/dataset_analyzer.py +89 -26
  150. nabu/resources/nxflatfield.py +2 -2
  151. nabu/resources/tests/test_nxflatfield.py +1 -1
  152. nabu/resources/utils.py +9 -2
  153. nabu/stitching/alignment.py +184 -0
  154. nabu/stitching/config.py +241 -39
  155. nabu/stitching/definitions.py +6 -0
  156. nabu/stitching/frame_composition.py +4 -2
  157. nabu/stitching/overlap.py +99 -3
  158. nabu/stitching/sample_normalization.py +60 -0
  159. nabu/stitching/slurm_utils.py +10 -10
  160. nabu/stitching/tests/test_alignment.py +99 -0
  161. nabu/stitching/tests/test_config.py +16 -1
  162. nabu/stitching/tests/test_overlap.py +68 -2
  163. nabu/stitching/tests/test_sample_normalization.py +49 -0
  164. nabu/stitching/tests/test_slurm_utils.py +5 -5
  165. nabu/stitching/tests/test_utils.py +3 -33
  166. nabu/stitching/tests/test_z_stitching.py +391 -22
  167. nabu/stitching/utils.py +144 -202
  168. nabu/stitching/z_stitching.py +309 -126
  169. nabu/testutils.py +18 -0
  170. nabu/thirdparty/tomocupy_remove_stripe.py +586 -0
  171. nabu/utils.py +32 -6
  172. {nabu-2023.2.1.dist-info → nabu-2024.1.0rc3.dist-info}/LICENSE +1 -1
  173. {nabu-2023.2.1.dist-info → nabu-2024.1.0rc3.dist-info}/METADATA +5 -5
  174. nabu-2024.1.0rc3.dist-info/RECORD +296 -0
  175. {nabu-2023.2.1.dist-info → nabu-2024.1.0rc3.dist-info}/WHEEL +1 -1
  176. {nabu-2023.2.1.dist-info → nabu-2024.1.0rc3.dist-info}/entry_points.txt +5 -1
  177. nabu/conftest.py +0 -14
  178. nabu/opencl/fftshift.py +0 -92
  179. nabu/opencl/tests/test_fftshift.py +0 -55
  180. nabu/opencl/tests/test_padding.py +0 -84
  181. nabu-2023.2.1.dist-info/RECORD +0 -252
  182. /nabu/cuda/src/{fftshift.cu → dfi_fftshift.cu} +0 -0
  183. {nabu-2023.2.1.dist-info → nabu-2024.1.0rc3.dist-info}/top_level.txt +0 -0
@@ -1,108 +1,4 @@
1
- import numpy as np
1
+ from nabu.processing.processing_base import ProcessingBase
2
+ from ..utils import deprecated_class
2
3
 
3
-
4
- class ProcessingBase:
5
- _array_class = None
6
-
7
- def __init__(self):
8
- self._allocated = {}
9
-
10
- def init_arrays_to_none(self, arrays_names):
11
- """
12
- Initialize arrays to None. After calling this method, the current instance will
13
- have self.array_name = None, and self._old_array_name = None.
14
-
15
- Parameters
16
- ----------
17
- arrays_names: list of str
18
- List of arrays names.
19
- """
20
- for array_name in arrays_names:
21
- setattr(self, array_name, None)
22
- setattr(self, "_old_" + array_name, None)
23
- self._allocated[array_name] = False
24
-
25
- def recover_arrays_references(self, arrays_names):
26
- """
27
- Performs self._array_name = self._old_array_name,
28
- for each array_name in arrays_names.
29
-
30
- Parameters
31
- ----------
32
- arrays_names: list of str
33
- List of array names
34
- """
35
- for array_name in arrays_names:
36
- old_arr = getattr(self, "_old_" + array_name, None)
37
- if old_arr is not None:
38
- setattr(self, array_name, old_arr)
39
-
40
- def _allocate_array_mem(self, shape, dtype):
41
- raise ValueError("Base class")
42
-
43
- def allocate_array(self, array_name, shape, dtype=np.float32):
44
- """
45
- Allocate a GPU array on the current context/stream/device,
46
- and set 'self.array_name' to this array.
47
-
48
- Parameters
49
- ----------
50
- array_name: str
51
- Name of the array (for book-keeping)
52
- shape: tuple of int
53
- Array shape
54
- dtype: numpy.dtype, optional
55
- Data type. Default is float32.
56
- """
57
- if not self._allocated.get(array_name, False):
58
- new_device_arr = self._allocate_array_mem(shape, dtype)
59
- setattr(self, array_name, new_device_arr)
60
- self._allocated[array_name] = True
61
- return getattr(self, array_name)
62
-
63
- def set_array(self, array_name, array_ref, dtype=np.float32):
64
- """
65
- Set the content of a device array.
66
-
67
- Parameters
68
- ----------
69
- array_name: str
70
- Array name. This method will look for self.array_name.
71
- array_ref: array (numpy or GPU array)
72
- Array containing the data to copy to 'array_name'.
73
- dtype: numpy.dtype, optional
74
- Data type. Default is float32.
75
- """
76
- if isinstance(array_ref, self._array_class):
77
- current_arr = getattr(self, array_name, None)
78
- setattr(self, "_old_" + array_name, current_arr)
79
- setattr(self, array_name, array_ref)
80
- elif isinstance(array_ref, np.ndarray):
81
- self.allocate_array(array_name, array_ref.shape, dtype=dtype)
82
- getattr(self, array_name).set(array_ref)
83
- else:
84
- raise ValueError("Expected numpy array or pycuda array")
85
- return getattr(self, array_name)
86
-
87
- def get_array(self, array_name):
88
- return getattr(self, array_name, None)
89
-
90
- # COMPAT.
91
- _init_arrays_to_none = init_arrays_to_none
92
- _recover_arrays_references = recover_arrays_references
93
- _allocate_array = allocate_array
94
- _set_array = set_array
95
-
96
- def check_array(self, arr, expected_shape, expected_dtype="f", check_contiguous=True):
97
- """
98
- Check whether a given array is suitable for being processed (shape, dtype, contiguous)
99
- """
100
- if arr.shape != expected_shape:
101
- raise ValueError("Expected shape %s but got %s" % (str(expected_shape), str(arr.shape)))
102
- if arr.dtype != np.dtype(expected_dtype):
103
- raise ValueError("Expected data type %s but got %s" % (str(expected_dtype), str(arr.dtype)))
104
- if check_contiguous:
105
- if isinstance(arr, np.ndarray) and not (arr.flags["C_CONTIGUOUS"]):
106
- raise ValueError("Expected C-contiguous array")
107
- if isinstance(arr, self._array_class) and not arr.flags.c_contiguous:
108
- raise ValueError("Expected C-contiguous array")
4
+ ProcessingBase = deprecated_class("ProcessingBase has been moved to nabu.processing", do_print=True)(ProcessingBase)
nabu/misc/rotation.py CHANGED
@@ -1,63 +1,6 @@
1
- try:
2
- from skimage.transform import rotate
1
+ from ..processing.rotation import *
2
+ from ..utils import deprecation_warning
3
3
 
4
- __have__skimage__ = True
5
- except ImportError:
6
- __have__skimage__ = False
7
-
8
-
9
- class Rotation:
10
- supported_modes = {
11
- "constant": "constant",
12
- "zeros": "constant",
13
- "edge": "edge",
14
- "edges": "edge",
15
- "symmetric": "symmetric",
16
- "sym": "symmetric",
17
- "reflect": "reflect",
18
- "wrap": "wrap",
19
- "periodic": "wrap",
20
- }
21
-
22
- def __init__(self, shape, angle, center=None, mode="edge", reshape=False, **sk_kwargs):
23
- """
24
- Initiate a Rotation object.
25
-
26
- Parameters
27
- ----------
28
- shape: tuple of int
29
- Shape of the images to process
30
- angle: float
31
- Rotation angle in DEGREES
32
- center: tuple of float, optional
33
- Coordinates of the center of rotation, in the format (X, Y) (mind the non-python
34
- convention !).
35
- Default is ((Nx - 1)/2.0, (Ny - 1)/2.0)
36
- mode: str, optional
37
- Padding mode. Default is "edge".
38
- reshape: bool, optional
39
-
40
-
41
- Other Parameters
42
- -----------------
43
- All the other parameters are passed directly to scikit image 'rotate' function:
44
- order, cval, clip, preserve_range.
45
- """
46
- self.shape = shape
47
- self.angle = angle
48
- self.center = center
49
- self.mode = mode
50
- self.reshape = reshape
51
- self.sk_kwargs = sk_kwargs
52
-
53
- def rotate(self, img, output=None):
54
- if not __have__skimage__:
55
- raise ValueError("scikit-image is needed for using rotate()")
56
- res = rotate(img, self.angle, resize=self.reshape, center=self.center, mode=self.mode, **self.sk_kwargs)
57
- if output is not None:
58
- output[:] = res[:]
59
- return output
60
- else:
61
- return res
62
-
63
- __call__ = rotate
4
+ deprecation_warning(
5
+ "nabu.misc.rotation has been moved to nabu.processing.rotation", do_print=True, func_name="rotation"
6
+ )
@@ -1,66 +1,6 @@
1
- import numpy as np
2
- from .rotation import Rotation
3
- from ..utils import get_cuda_srcfile, updiv
4
- from ..cuda.utils import __has_pycuda__, copy_array
5
- from ..cuda.processing import CudaProcessing
1
+ from ..processing.rotation_cuda import *
2
+ from ..utils import deprecation_warning
6
3
 
7
- if __has_pycuda__:
8
- from ..cuda.kernel import CudaKernel
9
- import pycuda.driver as cuda
10
-
11
-
12
- class CudaRotation(Rotation):
13
- def __init__(self, shape, angle, center=None, mode="edge", reshape=False, cuda_options=None, **sk_kwargs):
14
- if center is None:
15
- center = ((shape[1] - 1) / 2.0, (shape[0] - 1) / 2.0)
16
- super().__init__(shape, angle, center=center, mode=mode, reshape=reshape, **sk_kwargs)
17
- self._init_cuda_rotation(cuda_options)
18
-
19
- def _init_cuda_rotation(self, cuda_options):
20
- cuda_options = cuda_options or {}
21
- self.cuda_processing = CudaProcessing(**cuda_options)
22
- self._allocate_arrays()
23
- self._init_rotation_kernel()
24
-
25
- def _allocate_arrays(self):
26
- self._d_image_cua = cuda.np_to_array(np.zeros(self.shape, "f"), "C")
27
- self.cuda_processing.init_arrays_to_none(["d_output"])
28
-
29
- def _init_rotation_kernel(self):
30
- self.cuda_rotation_kernel = CudaKernel("rotate", get_cuda_srcfile("rotation.cu"))
31
- self.texref_image = self.cuda_rotation_kernel.module.get_texref("tex_image")
32
- self.texref_image.set_filter_mode(cuda.filter_mode.LINEAR) # bilinear
33
- self.texref_image.set_address_mode(0, cuda.address_mode.CLAMP) # TODO tune
34
- self.texref_image.set_address_mode(1, cuda.address_mode.CLAMP) # TODO tune
35
- self.cuda_rotation_kernel.prepare("Piiffff", [self.texref_image])
36
- self.texref_image.set_array(self._d_image_cua)
37
- self._cos_theta = np.cos(np.deg2rad(self.angle))
38
- self._sin_theta = np.sin(np.deg2rad(self.angle))
39
- self._Nx = np.int32(self.shape[1])
40
- self._Ny = np.int32(self.shape[0])
41
- self._center_x = np.float32(self.center[0])
42
- self._center_y = np.float32(self.center[1])
43
- self._block = (32, 32, 1) # tune ?
44
- self._grid = (updiv(self.shape[1], self._block[1]), updiv(self.shape[0], self._block[0]), 1)
45
-
46
- def rotate(self, img, output=None, do_checks=True):
47
- copy_array(self._d_image_cua, img, check=do_checks)
48
- if output is not None:
49
- d_out = output
50
- else:
51
- self.cuda_processing.allocate_array("d_output", self.shape, np.float32)
52
- d_out = self.cuda_processing.d_output
53
- self.cuda_rotation_kernel(
54
- d_out,
55
- self._Nx,
56
- self._Ny,
57
- self._cos_theta,
58
- self._sin_theta,
59
- self._center_x,
60
- self._center_y,
61
- grid=self._grid,
62
- block=self._block,
63
- )
64
- return d_out
65
-
66
- __call__ = rotate
4
+ deprecation_warning(
5
+ "nabu.misc.rotation_cuda has been moved to nabu.processing.rotation_cuda", do_print=True, func_name="rotation_cuda"
6
+ )
nabu/misc/transpose.py ADDED
@@ -0,0 +1,6 @@
1
+ from ..processing.transpose import *
2
+ from ..utils import deprecation_warning
3
+
4
+ deprecation_warning(
5
+ "nabu.misc.transpose has been moved to nabu.processing.transpose", do_print=True, func_name="transpose"
6
+ )
nabu/misc/unsharp.py CHANGED
@@ -1,79 +1,4 @@
1
- import numpy as np
2
- from scipy.ndimage import convolve1d
3
- from silx.image.utils import gaussian_kernel
1
+ from ..processing.unsharp import *
2
+ from ..utils import deprecation_warning
4
3
 
5
-
6
- class UnsharpMask:
7
- """
8
- A helper class for unsharp masking.
9
- """
10
-
11
- avail_methods = ["gaussian", "log", "imagej"]
12
-
13
- def __init__(self, shape, sigma, coeff, mode="reflect", method="gaussian"):
14
- """
15
- Initialize a Unsharp mask.
16
- `UnsharpedImage = (1 + coeff)*Image - coeff * ConvolutedImage`
17
-
18
- If method == "log":
19
- `UnsharpedImage = Image + coeff*ConvolutedImage`
20
-
21
- Parameters
22
- -----------
23
- shape: tuple
24
- Shape of the image.
25
- sigma: float
26
- Standard deviation of the Gaussian kernel
27
- coeff: float
28
- Coefficient in the linear combination of unsharp mask
29
- mode: str, optional
30
- Convolution mode. Default is "reflect"
31
- method: str, optional
32
- Method of unsharp mask. Can be "gaussian" (default) or "log" (Laplacian of Gaussian),
33
- or "imagej".
34
-
35
-
36
- Notes
37
- -----
38
- The computation is the following depending on the method:
39
-
40
- - For method="gaussian": output = (1 + coeff) * image - coeff * image_blurred
41
- - For method="log": output = image + coeff * image_blurred
42
- - For method="imagej": output = (image - coeff*image_blurred)/(1-coeff)
43
- """
44
- self.shape = shape
45
- self.ndim = len(self.shape)
46
- self.sigma = sigma
47
- self.coeff = coeff
48
- self._set_method(method)
49
- self.mode = mode
50
- self._compute_gaussian_kernel()
51
-
52
- def _set_method(self, method):
53
- if method not in self.avail_methods:
54
- raise ValueError("Unknown unsharp method '%s'. Available are %s" % (method, str(self.avail_methods)))
55
- self.method = method
56
-
57
- def _compute_gaussian_kernel(self):
58
- self._gaussian_kernel = np.ascontiguousarray(gaussian_kernel(self.sigma), dtype=np.float32)
59
-
60
- def _blur2d(self, image):
61
- res1 = convolve1d(image, self._gaussian_kernel, axis=1, mode=self.mode)
62
- res = convolve1d(res1, self._gaussian_kernel, axis=0, mode=self.mode)
63
- return res
64
-
65
- def unsharp(self, image, output=None):
66
- """
67
- Reference unsharp mask implementation.
68
- """
69
- image_b = self._blur2d(image)
70
- if self.method == "gaussian":
71
- res = (1 + self.coeff) * image - self.coeff * image_b
72
- elif self.method == "log":
73
- res = image + self.coeff * image_b
74
- else: # "imagej":
75
- res = (image - self.coeff * image_b) / (1 - self.coeff)
76
- if output is not None:
77
- output[:] = res[:]
78
- return output
79
- return res
4
+ deprecation_warning("nabu.misc.unsharp has been moved to nabu.processing.unsharp", do_print=True, func_name="unsharp")
nabu/misc/unsharp_cuda.py CHANGED
@@ -1,53 +1,6 @@
1
- from ..cuda.utils import __has_pycuda__
2
- from ..cuda.convolution import Convolution
3
- from ..cuda.processing import CudaProcessing
4
- from .unsharp import UnsharpMask
1
+ from ..processing.unsharp_cuda import *
2
+ from ..utils import deprecation_warning
5
3
 
6
- if __has_pycuda__:
7
- from pycuda.elementwise import ElementwiseKernel
8
-
9
-
10
- class CudaUnsharpMask(UnsharpMask):
11
- def __init__(self, shape, sigma, coeff, mode="reflect", method="gaussian", cuda_options=None):
12
- """
13
- Unsharp Mask, cuda backend.
14
- """
15
- super().__init__(shape, sigma, coeff, mode=mode, method=method)
16
- self.cuda_processing = CudaProcessing(**(cuda_options or {}))
17
- self._init_convolution()
18
- self._init_mad_kernel()
19
- self.cuda_processing.init_arrays_to_none(["_d_out"])
20
-
21
- def _init_convolution(self):
22
- self.convolution = Convolution(
23
- self.shape,
24
- self._gaussian_kernel,
25
- mode=self.mode,
26
- extra_options={ # Use the lowest amount of memory
27
- "allocate_input_array": False,
28
- "allocate_output_array": False,
29
- "allocate_tmp_array": True,
30
- },
31
- )
32
-
33
- def _init_mad_kernel(self):
34
- # garray.GPUArray.mul_add is out of place...
35
- self.mad_kernel = ElementwiseKernel(
36
- "float* array, float fac, float* other, float otherfac",
37
- "array[i] = fac * array[i] + otherfac * other[i]",
38
- name="mul_add",
39
- )
40
-
41
- def unsharp(self, image, output=None):
42
- if output is None:
43
- output = self.cuda_processing.allocate_array("_d_out", self.shape, "f")
44
- self.convolution(image, output=output)
45
- if self.method == "gaussian":
46
- self.mad_kernel(output, -self.coeff, image, 1.0 + self.coeff)
47
- elif self.method == "log":
48
- # output = output * coeff + image where output was image_blurred
49
- self.mad_kernel(output, self.coeff, image, 1.0)
50
- else: # "imagej":
51
- # output = (image - coeff*image_blurred)/(1-coeff) where output was image_blurred
52
- self.mad_kernel(output, -self.coeff / (1 - self.coeff), image, 1.0 / (1 - self.coeff))
53
- return output
4
+ deprecation_warning(
5
+ "nabu.misc.unsharp_cuda has been moved to nabu.processing.unsharp_cuda", do_print=True, func_name="unsharp_cuda"
6
+ )
@@ -1,85 +1,8 @@
1
- try:
2
- from silx.opencl.processing import OpenclProcessing
3
- from silx.opencl.convolution import Convolution as CLConvolution
4
- import pyopencl.array as parray
5
- from pyopencl.elementwise import ElementwiseKernel
6
-
7
- __have_opencl__ = True
8
- except ImportError:
9
- __have_opencl__ = False
10
- from .unsharp import UnsharpMask
11
-
12
-
13
- class OpenclUnsharpMask(UnsharpMask, OpenclProcessing):
14
- def __init__(
15
- self,
16
- shape,
17
- sigma,
18
- coeff,
19
- mode="reflect",
20
- method="gaussian",
21
- ctx=None,
22
- devicetype="all",
23
- platformid=None,
24
- deviceid=None,
25
- block_size=None,
26
- memory=None,
27
- profile=False,
28
- ):
29
- """
30
- NB: For now, this class is designed to use the lowest amount of GPU memory
31
- as possible. Therefore, the input and output image/volumes are assumed
32
- to be already on device.
33
- """
34
- if not (__have_opencl__):
35
- raise ImportError("Need silx and pyopencl")
36
- OpenclProcessing.__init__(
37
- self,
38
- ctx=ctx,
39
- devicetype=devicetype,
40
- platformid=platformid,
41
- deviceid=deviceid,
42
- block_size=block_size,
43
- memory=memory,
44
- profile=profile,
45
- )
46
- UnsharpMask.__init__(self, shape, sigma, coeff, mode=mode, method=method)
47
- self._init_convolution()
48
- self._init_mad_kernel()
49
-
50
- def _init_convolution(self):
51
- self.convolution = CLConvolution(
52
- self.shape,
53
- self._gaussian_kernel,
54
- mode=self.mode,
55
- ctx=self.ctx,
56
- profile=self.profile,
57
- extra_options={ # Use the lowest amount of memory
58
- "allocate_input_array": False,
59
- "allocate_output_array": False,
60
- "allocate_tmp_array": True,
61
- "dont_use_textures": True,
62
- },
63
- )
64
-
65
- def _init_mad_kernel(self):
66
- # parray.Array.mul_add is out of place...
67
- self.mad_kernel = ElementwiseKernel(
68
- self.ctx,
69
- "float* array, float fac, float* other, float otherfac",
70
- "array[i] = fac * array[i] + otherfac * other[i]",
71
- name="mul_add",
72
- )
73
-
74
- def unsharp(self, image, output):
75
- # For now image and output are assumed to be already allocated on device
76
- assert isinstance(image, parray.Array)
77
- assert isinstance(output, parray.Array)
78
- self.convolution(image, output=output)
79
- if self.method == "gaussian":
80
- self.mad_kernel(output, -self.coeff, image, 1.0 + self.coeff)
81
- elif self.method == "log":
82
- self.mad_kernel(output, self.coeff, image, 1.0)
83
- else: # "imagej":
84
- self.mad_kernel(output, -self.coeff / (1 - self.coeff), image, 1.0 / (1 - self.coeff))
85
- return output
1
+ from ..processing.unsharp_opencl import *
2
+ from ..utils import deprecation_warning
3
+
4
+ deprecation_warning(
5
+ "nabu.misc.unsharp_opencl has been moved to nabu.processing.unsharp_opencl",
6
+ do_print=True,
7
+ func_name="unsharp_opencl",
8
+ )
nabu/opencl/fft.py ADDED
@@ -0,0 +1,6 @@
1
+ from ..processing.fft_opencl import *
2
+ from ..utils import deprecation_warning
3
+
4
+ deprecation_warning(
5
+ "nabu.opencl.fft has been moved to nabu.processing.fft_opencl", do_print=True, func_name="fft_opencl"
6
+ )
nabu/opencl/kernel.py CHANGED
@@ -1,7 +1,7 @@
1
1
  import pyopencl.array as parray
2
2
  from pyopencl import Program, CommandQueue, kernel_work_group_info
3
- from ..utils import updiv, deprecation_warning
4
- from ..misc.kernel_base import KernelBase
3
+ from ..utils import deprecation_warning
4
+ from ..processing.kernel_base import KernelBase
5
5
 
6
6
 
7
7
  class OpenCLKernel(KernelBase):
@@ -14,6 +14,8 @@ class OpenCLKernel(KernelBase):
14
14
  Name of the OpenCL kernel.
15
15
  ctx: pyopencl.Context
16
16
  OpenCL context to use.
17
+ queue: pyopencl.CommandQueue
18
+ OpenCL queue to use. If provided, will use this queue's context instead of 'ctx'
17
19
  filename: str, optional
18
20
  Path to the file name containing kernels definitions
19
21
  src: str, optional
@@ -28,13 +30,19 @@ class OpenCLKernel(KernelBase):
28
30
  self,
29
31
  kernel_name,
30
32
  ctx,
33
+ queue=None,
31
34
  filename=None,
32
35
  src=None,
33
36
  automation_params=None,
34
37
  **build_kwargs,
35
38
  ):
36
39
  super().__init__(kernel_name, filename=filename, src=src, automation_params=automation_params)
37
- self.ctx = ctx
40
+ if queue is not None:
41
+ self.ctx = queue.context
42
+ self.queue = queue
43
+ else:
44
+ self.ctx = ctx
45
+ self.queue = None
38
46
  self.compile_kernel_source(kernel_name, build_kwargs)
39
47
  self.get_kernel()
40
48
 
@@ -105,9 +113,16 @@ class OpenCLKernel(KernelBase):
105
113
  args[i] = arg.data
106
114
  return tuple(args)
107
115
 
108
- def call(self, queue, *args, **kwargs):
109
- if not isinstance(queue, CommandQueue):
110
- raise ValueError("First argument must be a pyopencl queue")
116
+ def call(self, *args, **kwargs):
117
+ if not isinstance(args[0], CommandQueue):
118
+ queue = self.queue
119
+ if queue is None:
120
+ raise ValueError(
121
+ "First argument must be a pyopencl queue - otherwise provide OpenCLKernel(..., queue=queue)"
122
+ )
123
+ else:
124
+ queue = args[0]
125
+ args = args[1:]
111
126
  global_size, local_size, args, kwargs = self._prepare_call(*args, **kwargs)
112
127
 
113
128
  kwargs.pop("global_size", None)
nabu/opencl/padding.py CHANGED
@@ -1,73 +1,6 @@
1
- import numpy as np
2
- from ..utils import get_opencl_srcfile, updiv, check_supported
3
- from .kernel import OpenCLKernel
4
- from .processing import OpenCLProcessing
5
- from .memcpy import OpenCLMemcpy2D
6
- import pyopencl.array as parray
7
- from ..misc.padding_base import PaddingBase
1
+ from ..processing.padding_opencl import *
2
+ from ..utils import deprecation_warning
8
3
 
9
-
10
- class OpenCLPadding(PaddingBase):
11
- """
12
- A class for performing padding on GPU using Cuda
13
- """
14
-
15
- # TODO docstring from base class
16
- def __init__(self, shape, pad_width, mode="constant", opencl_options=None, **kwargs):
17
- super().__init__(shape, pad_width, mode=mode, **kwargs)
18
- self.opencl_processing = OpenCLProcessing(**(opencl_options or {}))
19
- self.queue = self.opencl_processing.queue
20
- self._init_opencl_coordinate_transform()
21
-
22
- def _init_opencl_coordinate_transform(self):
23
- if self.mode == "constant":
24
- self.d_padded_array_constant = parray.to_device(self.queue, self.padded_array_constant)
25
- self.memcpy2D = OpenCLMemcpy2D(ctx=self.opencl_processing.ctx, queue=self.queue)
26
- return
27
- self._coords_transform_kernel = OpenCLKernel(
28
- "coordinate_transform",
29
- self.opencl_processing.ctx,
30
- filename=get_opencl_srcfile("padding.cl"),
31
- )
32
- self._coords_transform_global_size = self.padded_shape[::-1]
33
- self.d_coords_rows = parray.to_device(self.queue, self.coords_rows)
34
- self.d_coords_cols = parray.to_device(self.queue, self.coords_cols)
35
-
36
- def _pad_constant(self, image, output):
37
- pad_y, pad_x = self.pad_width
38
- # the following line is not implemented in pyopencl
39
- # self.d_padded_array_constant[pad_y[0] : pad_y[0] + self.shape[0], pad_x[0] : pad_x[0] + self.shape[1]] = image[:]
40
- # cl.enqueue_copy is too cumbersome to use for Buffer <-> Buffer.
41
- # Use a dedicated kernel instead.
42
- # This is not optimal (two copies) - TODO write a constant padding kernel
43
- self.memcpy2D(self.d_padded_array_constant, image, image.shape[::-1], dst_offset_xy=(pad_x[0], pad_y[0]))
44
- output[:] = self.d_padded_array_constant[:]
45
- return output
46
-
47
- def pad(self, image, output=None):
48
- """
49
- Pad an array.
50
-
51
- Parameters
52
- ----------
53
- image: pycuda.gpuarray.GPUArray
54
- Image to pad
55
- output: pycuda.gpuarray.GPUArray, optional
56
- Output image. If provided, must be in the expected shape.
57
- """
58
- if output is None:
59
- output = self.opencl_processing.allocate_array("d_output", self.padded_shape)
60
- if self.mode == "constant":
61
- return self._pad_constant(image, output)
62
- self._coords_transform_kernel(
63
- self.queue,
64
- image,
65
- output,
66
- self.d_coords_cols,
67
- self.d_coords_rows,
68
- np.int32(self.shape[1]),
69
- np.int32(self.padded_shape[1]),
70
- np.int32(self.padded_shape[0]),
71
- global_size=self._coords_transform_global_size,
72
- )
73
- return output
4
+ deprecation_warning(
5
+ "nabu.opencl.padding has been moved to nabu.processing.padding_opencl", do_print=True, func_name="padding_opencl"
6
+ )