httomolibgpu 5.4__tar.gz → 5.5.1__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 (38) hide show
  1. {httomolibgpu-5.4/httomolibgpu.egg-info → httomolibgpu-5.5.1}/PKG-INFO +8 -8
  2. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/README.rst +3 -3
  3. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/cuda_kernels/__init__.py +1 -1
  4. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/cuda_kernels/calc_metrics.cu +26 -2
  5. httomolibgpu-5.5.1/httomolibgpu/cuda_kernels/median_kernel.cu +114 -0
  6. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/cuda_kernels/raven_filter.cu +18 -2
  7. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/cuda_kernels/remove_nan_inf.cu +12 -2
  8. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/cuda_kernels/remove_stripe_fw.cu +16 -16
  9. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/misc/corr.py +37 -32
  10. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/misc/denoise.py +53 -8
  11. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/misc/morph.py +66 -23
  12. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/misc/rescale.py +29 -5
  13. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/misc/utils.py +58 -4
  14. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/prep/alignment.py +44 -4
  15. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/prep/normalize.py +37 -13
  16. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/prep/phase.py +87 -59
  17. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/prep/stripe.py +131 -75
  18. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/recon/algorithm.py +342 -66
  19. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/recon/rotation.py +76 -29
  20. {httomolibgpu-5.4 → httomolibgpu-5.5.1/httomolibgpu.egg-info}/PKG-INFO +8 -8
  21. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu.egg-info/SOURCES.txt +0 -1
  22. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu.egg-info/requires.txt +2 -2
  23. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/pyproject.toml +4 -4
  24. httomolibgpu-5.4/httomolibgpu/cuda_kernels/median_kernel.cu +0 -54
  25. httomolibgpu-5.4/httomolibgpu/memory_estimator_helpers.py +0 -24
  26. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/LICENSE +0 -0
  27. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/MANIFEST.in +0 -0
  28. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/__init__.py +0 -0
  29. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/cuda_kernels/center_360_shifts.cu +0 -0
  30. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/cuda_kernels/generate_mask.cu +0 -0
  31. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/cupywrapper.py +0 -0
  32. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/misc/__init__.py +0 -0
  33. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/prep/__init__.py +0 -0
  34. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/recon/__init__.py +0 -0
  35. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu/recon/_phase_cross_correlation.py +0 -0
  36. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu.egg-info/dependency_links.txt +0 -0
  37. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/httomolibgpu.egg-info/top_level.txt +0 -0
  38. {httomolibgpu-5.4 → httomolibgpu-5.5.1}/setup.cfg +0 -0
@@ -1,20 +1,20 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: httomolibgpu
3
- Version: 5.4
3
+ Version: 5.5.1
4
4
  Summary: Commonly used tomography data processing methods at DLS.
5
5
  Author-email: Daniil Kazantsev <daniil.kazantsev@diamond.ac.uk>, Yousef Moazzam <yousef.moazzam@diamond.ac.uk>, Naman Gera <naman.gera@diamond.ac.uk>
6
6
  License: BSD-3-Clause
7
7
  Project-URL: Repository, https://github.com/DiamondLightSource/httomolibgpu
8
8
  Classifier: Development Status :: 4 - Beta
9
9
  Classifier: License :: OSI Approved :: BSD License
10
- Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: Programming Language :: Python :: 3.12
11
11
  Classifier: Environment :: GPU :: NVIDIA CUDA
12
- Requires-Python: >=3.10
12
+ Requires-Python: >=3.12
13
13
  Description-Content-Type: text/x-rst
14
14
  License-File: LICENSE
15
- Requires-Dist: cupy==12.3.0
15
+ Requires-Dist: cupy==14.0.*
16
16
  Requires-Dist: nvtx
17
- Requires-Dist: numpy
17
+ Requires-Dist: numpy==2.4.*
18
18
  Requires-Dist: scipy
19
19
  Requires-Dist: pillow
20
20
  Requires-Dist: scikit-image
@@ -46,7 +46,7 @@ Some of the methods also have been optimised to ensure higher computational effi
46
46
  The purpose of HTTomolibGPU
47
47
  ===========================
48
48
 
49
- Although **HTTomolibGPU** can be used as a stand-alone library, it has been specifically developed to work together with the
49
+ Although **HTTomolibGPU** can be used as a stand-alone library, it has been specifically developed to work together with the
50
50
  `HTTomo <https://diamondlightsource.github.io/httomo/>`_ package as
51
51
  its backend for data processing. HTTomo is a user interface (UI) written in Python for fast big tomographic data processing using
52
52
  MPI protocols or as well serially.
@@ -71,7 +71,7 @@ Conda environment
71
71
 
72
72
  $ conda create --name httomolibgpu # create a fresh conda environment
73
73
  $ conda activate httomolibgpu # activate the environment
74
- $ conda install conda-forge::cupy==12.3.0
74
+ $ conda install conda-forge::cupy==14.0.*
75
75
  $ pip install httomolibgpu
76
76
 
77
77
  Setup the development environment:
@@ -80,6 +80,6 @@ Setup the development environment:
80
80
  .. code-block:: console
81
81
 
82
82
  $ git clone git@github.com:DiamondLightSource/httomolibgpu.git # clone the repo
83
- $ conda env create --name httomolibgpu -c conda-forge cupy==12.3.0 # install dependencies
83
+ $ conda env create --name httomolibgpu -c conda-forge cupy==14.0.* # install dependencies
84
84
  $ conda activate httomolibgpu # activate the environment
85
85
  $ pip install -e ./httomolibgpu[dev] # editable/development mode
@@ -9,7 +9,7 @@ Some of the methods also have been optimised to ensure higher computational effi
9
9
  The purpose of HTTomolibGPU
10
10
  ===========================
11
11
 
12
- Although **HTTomolibGPU** can be used as a stand-alone library, it has been specifically developed to work together with the
12
+ Although **HTTomolibGPU** can be used as a stand-alone library, it has been specifically developed to work together with the
13
13
  `HTTomo <https://diamondlightsource.github.io/httomo/>`_ package as
14
14
  its backend for data processing. HTTomo is a user interface (UI) written in Python for fast big tomographic data processing using
15
15
  MPI protocols or as well serially.
@@ -34,7 +34,7 @@ Conda environment
34
34
 
35
35
  $ conda create --name httomolibgpu # create a fresh conda environment
36
36
  $ conda activate httomolibgpu # activate the environment
37
- $ conda install conda-forge::cupy==12.3.0
37
+ $ conda install conda-forge::cupy==14.0.*
38
38
  $ pip install httomolibgpu
39
39
 
40
40
  Setup the development environment:
@@ -43,6 +43,6 @@ Setup the development environment:
43
43
  .. code-block:: console
44
44
 
45
45
  $ git clone git@github.com:DiamondLightSource/httomolibgpu.git # clone the repo
46
- $ conda env create --name httomolibgpu -c conda-forge cupy==12.3.0 # install dependencies
46
+ $ conda env create --name httomolibgpu -c conda-forge cupy==14.0.* # install dependencies
47
47
  $ conda activate httomolibgpu # activate the environment
48
48
  $ pip install -e ./httomolibgpu[dev] # editable/development mode
@@ -25,5 +25,5 @@ def load_cuda_module(
25
25
  code += f.read()
26
26
 
27
27
  return cp.RawModule(
28
- options=("-std=c++11", *options), code=code, name_expressions=name_expressions
28
+ options=("-std=c++17", *options), code=code, name_expressions=name_expressions
29
29
  )
@@ -321,7 +321,7 @@ __device__ void _calc_metrics_overlap(const float *mat1, int mat1_nx,
321
321
  * the compiler (rather than at runtime), which reduces the register count.
322
322
  */
323
323
  template <bool norm, bool use_overlap>
324
- __global__ void calc_metrics_kernel(const float *mat1, int mat1_nx,
324
+ __device__ __forceinline__ void calc_metrics_kernel_impl(const float *mat1, int mat1_nx,
325
325
  const float *mat2, int mat2_nx,
326
326
  int win_width, int rows, int side,
327
327
  float *list_metric)
@@ -331,4 +331,28 @@ __global__ void calc_metrics_kernel(const float *mat1, int mat1_nx,
331
331
  } else {
332
332
  _calc_metrics_no_overlap<norm>(mat1, mat1_nx, mat2, mat2_nx, win_width, rows, side, list_metric);
333
333
  }
334
- }
334
+ }
335
+
336
+ extern "C" __global__ void calc_metrics_kernel(const float *mat1, int mat1_nx, const float *mat2, int mat2_nx,
337
+ int win_width, int rows, int side, float *list_metric)
338
+ {
339
+ calc_metrics_kernel_impl<false, false>(mat1, mat1_nx, mat2, mat2_nx, win_width, rows, side, list_metric);
340
+ }
341
+
342
+ extern "C" __global__ void calc_metrics_kernel_norm(const float *mat1, int mat1_nx, const float *mat2, int mat2_nx,
343
+ int win_width, int rows, int side, float *list_metric)
344
+ {
345
+ calc_metrics_kernel_impl<true, false>(mat1, mat1_nx, mat2, mat2_nx, win_width, rows, side, list_metric);
346
+ }
347
+
348
+ extern "C" __global__ void calc_metrics_kernel_use_overlap(const float *mat1, int mat1_nx, const float *mat2, int mat2_nx,
349
+ int win_width, int rows, int side, float *list_metric)
350
+ {
351
+ calc_metrics_kernel_impl<false, true>(mat1, mat1_nx, mat2, mat2_nx, win_width, rows, side, list_metric);
352
+ }
353
+
354
+ extern "C" __global__ void calc_metrics_kernel_norm_use_overlap(const float *mat1, int mat1_nx, const float *mat2, int mat2_nx,
355
+ int win_width, int rows, int side, float *list_metric)
356
+ {
357
+ calc_metrics_kernel_impl<true, true>(mat1, mat1_nx, mat2, mat2_nx, win_width, rows, side, list_metric);
358
+ }
@@ -0,0 +1,114 @@
1
+ template <typename Type, int diameter>
2
+ __device__ __forceinline__ void median_general_kernel3d_impl(const Type *in, Type *out, float dif,
3
+ int Z, int M, int N) {
4
+ constexpr int radius = diameter / 2;
5
+ constexpr int d3 = diameter * diameter * diameter;
6
+ constexpr int midpoint = d3 / 2;
7
+
8
+ Type ValVec[d3];
9
+ const long i = blockDim.x * blockIdx.x + threadIdx.x;
10
+ const long j = blockDim.y * blockIdx.y + threadIdx.y;
11
+ const long k = blockDim.z * blockIdx.z + threadIdx.z;
12
+
13
+ if (i >= N || j >= M || k >= Z)
14
+ return;
15
+
16
+ long long index = static_cast<long long>(i) + N * static_cast<long long>(j) + N * M * static_cast<long long>(k);
17
+
18
+ int counter = 0;
19
+ for (int i_m = -radius; i_m <= radius; i_m++) {
20
+ long long i1 = i + i_m; // using long long to avoid integer overflows
21
+ if ((i1 < 0) || (i1 >= N))
22
+ i1 = i;
23
+ for (int j_m = -radius; j_m <= radius; j_m++) {
24
+ long long j1 = j + j_m;
25
+ if ((j1 < 0) || (j1 >= M))
26
+ j1 = j;
27
+ for (int k_m = -radius; k_m <= radius; k_m++) {
28
+ long long k1 = k + k_m;
29
+ if ((k1 < 0) || (k1 >= Z))
30
+ k1 = k;
31
+ ValVec[counter] = in[i1 + N * j1 + N * M * k1];
32
+ counter++;
33
+ }
34
+ }
35
+ }
36
+
37
+ /* do bubble sort here */
38
+ for (int x = 0; x < d3 - 1; x++) {
39
+ for (int y = 0; y < d3 - x - 1; y++) {
40
+ if (ValVec[y] > ValVec[y + 1]) {
41
+ Type temp = ValVec[y];
42
+ ValVec[y] = ValVec[y + 1];
43
+ ValVec[y + 1] = temp;
44
+ }
45
+ }
46
+ }
47
+
48
+ if (dif > 0.0f) {
49
+ /* perform dezingering */
50
+ out[index] =
51
+ fabsf(in[index] - ValVec[midpoint]) >= dif ? ValVec[midpoint] : in[index];
52
+ }
53
+ else out[index] = ValVec[midpoint]; /* median filtering */
54
+ }
55
+
56
+ extern "C" __global__ void median_general_kernel3d_float_3(const float *in, float *out, float dif, int Z, int M, int N)
57
+ {
58
+ median_general_kernel3d_impl<float, 3>(in, out, dif, Z, M, N);
59
+ }
60
+
61
+ extern "C" __global__ void median_general_kernel3d_float_5(const float *in, float *out, float dif, int Z, int M, int N)
62
+ {
63
+ median_general_kernel3d_impl<float, 5>(in, out, dif, Z, M, N);
64
+ }
65
+
66
+ extern "C" __global__ void median_general_kernel3d_float_7(const float *in, float *out, float dif, int Z, int M, int N)
67
+ {
68
+ median_general_kernel3d_impl<float, 7>(in, out, dif, Z, M, N);
69
+ }
70
+
71
+ extern "C" __global__ void median_general_kernel3d_float_9(const float *in, float *out, float dif, int Z, int M, int N)
72
+ {
73
+ median_general_kernel3d_impl<float, 9>(in, out, dif, Z, M, N);
74
+ }
75
+
76
+ extern "C" __global__ void median_general_kernel3d_float_11(const float *in, float *out, float dif, int Z, int M, int N)
77
+ {
78
+ median_general_kernel3d_impl<float, 11>(in, out, dif, Z, M, N);
79
+ }
80
+
81
+ extern "C" __global__ void median_general_kernel3d_float_13(const float *in, float *out, float dif, int Z, int M, int N)
82
+ {
83
+ median_general_kernel3d_impl<float, 13>(in, out, dif, Z, M, N);
84
+ }
85
+
86
+ extern "C" __global__ void median_general_kernel3d_unsigned_short_3(const unsigned short *in, unsigned short *out, float dif, int Z, int M, int N)
87
+ {
88
+ median_general_kernel3d_impl<unsigned short, 3>(in, out, dif, Z, M, N);
89
+ }
90
+
91
+ extern "C" __global__ void median_general_kernel3d_unsigned_short_5(const unsigned short *in, unsigned short *out, float dif, int Z, int M, int N)
92
+ {
93
+ median_general_kernel3d_impl<unsigned short, 5>(in, out, dif, Z, M, N);
94
+ }
95
+
96
+ extern "C" __global__ void median_general_kernel3d_unsigned_short_7(const unsigned short *in, unsigned short *out, float dif, int Z, int M, int N)
97
+ {
98
+ median_general_kernel3d_impl<unsigned short, 7>(in, out, dif, Z, M, N);
99
+ }
100
+
101
+ extern "C" __global__ void median_general_kernel3d_unsigned_short_9(const unsigned short *in, unsigned short *out, float dif, int Z, int M, int N)
102
+ {
103
+ median_general_kernel3d_impl<unsigned short, 9>(in, out, dif, Z, M, N);
104
+ }
105
+
106
+ extern "C" __global__ void median_general_kernel3d_unsigned_short_11(const unsigned short *in, unsigned short *out, float dif, int Z, int M, int N)
107
+ {
108
+ median_general_kernel3d_impl<unsigned short, 11>(in, out, dif, Z, M, N);
109
+ }
110
+
111
+ extern "C" __global__ void median_general_kernel3d_unsigned_short_13(const unsigned short *in, unsigned short *out, float dif, int Z, int M, int N)
112
+ {
113
+ median_general_kernel3d_impl<unsigned short, 13>(in, out, dif, Z, M, N);
114
+ }
@@ -1,8 +1,8 @@
1
1
  #include <cupy/complex.cuh>
2
2
 
3
3
  template <typename Type>
4
- __global__ void
5
- raven_filter(
4
+ __device__ __forceinline__ void
5
+ raven_filter_impl(
6
6
  complex<Type> *input,
7
7
  complex<Type> *output,
8
8
  int width, int images, int height,
@@ -47,3 +47,19 @@ raven_filter(
47
47
 
48
48
  output[outIndex] = value;
49
49
  }
50
+
51
+ extern "C" __global__ void raven_filter_float(complex<float> *input,
52
+ complex<float> *output,
53
+ int width, int images, int height,
54
+ int u0, int n, int v0)
55
+ {
56
+ raven_filter_impl<float>(input, output, width, images, height, u0, n, v0);
57
+ }
58
+
59
+ extern "C" __global__ void raven_filter_double(complex<double> *input,
60
+ complex<double> *output,
61
+ int width, int images, int height,
62
+ int u0, int n, int v0)
63
+ {
64
+ raven_filter_impl<double>(input, output, width, images, height, u0, n, v0);
65
+ }
@@ -1,5 +1,5 @@
1
1
  template <typename Type>
2
- __global__ void remove_nan_inf(Type *data, int Z, int M, int N, int *result) {
2
+ __device__ __forceinline__ void remove_nan_inf_impl(Type *data, int Z, int M, int N, int *result) {
3
3
  const long i = blockDim.x * blockIdx.x + threadIdx.x;
4
4
  const long j = blockDim.y * blockIdx.y + threadIdx.y;
5
5
  const long k = blockDim.z * blockIdx.z + threadIdx.z;
@@ -16,4 +16,14 @@ __global__ void remove_nan_inf(Type *data, int Z, int M, int N, int *result) {
16
16
  data[index] = zero;
17
17
  }
18
18
 
19
- }
19
+ }
20
+
21
+ extern "C" __global__ void remove_nan_inf_float(float *data, int Z, int M, int N, int *result)
22
+ {
23
+ remove_nan_inf_impl<float>(data, Z, M, N, result);
24
+ }
25
+
26
+ extern "C" __global__ void remove_nan_inf_unsigned_short(unsigned short *data, int Z, int M, int N, int *result)
27
+ {
28
+ remove_nan_inf_impl<unsigned short>(data, Z, M, N, result);
29
+ }
@@ -1,5 +1,4 @@
1
- template<int WSize>
2
- __global__ void grouped_convolution_x(
1
+ extern "C" __global__ void grouped_convolution_x(
3
2
  int dim_x,
4
3
  int dim_y,
5
4
  int dim_z,
@@ -10,7 +9,8 @@ __global__ void grouped_convolution_x(
10
9
  float* out,
11
10
  int out_stride_z,
12
11
  int out_stride_group,
13
- const float* w
12
+ const float* w,
13
+ int wk
14
14
  )
15
15
  {
16
16
  const int g_thd_x = blockDim.x * blockIdx.x + threadIdx.x;
@@ -25,9 +25,9 @@ __global__ void grouped_convolution_x(
25
25
  for (int i = 0; i < out_groups; ++i)
26
26
  {
27
27
  float acc = 0.F;
28
- for (int j = 0; j < WSize; ++j)
28
+ for (int j = 0; j < wk; ++j)
29
29
  {
30
- const int w_idx = i * WSize + j;
30
+ const int w_idx = i * wk + j;
31
31
  const int in_idx = (g_thd_x * in_stride_x + j) + g_thd_y * in_stride_y + g_thd_z * in_stride_z;
32
32
  acc += w[w_idx] * in[in_idx];
33
33
  }
@@ -36,8 +36,7 @@ __global__ void grouped_convolution_x(
36
36
  }
37
37
  }
38
38
 
39
- template<int WSize>
40
- __global__ void grouped_convolution_y(
39
+ extern "C" __global__ void grouped_convolution_y(
41
40
  int dim_x,
42
41
  int dim_y,
43
42
  int dim_z,
@@ -49,7 +48,8 @@ __global__ void grouped_convolution_y(
49
48
  float* out,
50
49
  int out_stride_z,
51
50
  int out_stride_group,
52
- const float* w
51
+ const float* w,
52
+ int hk
53
53
  )
54
54
  {
55
55
  const int g_thd_x = blockDim.x * blockIdx.x + threadIdx.x;
@@ -68,9 +68,9 @@ __global__ void grouped_convolution_y(
68
68
  for (int i = 0; i < out_groups; ++i)
69
69
  {
70
70
  float acc = 0.F;
71
- for (int j = 0; j < WSize; ++j)
71
+ for (int j = 0; j < hk; ++j)
72
72
  {
73
- const int w_idx = (out_groups * group + i) * WSize + j;
73
+ const int w_idx = (out_groups * group + i) * hk + j;
74
74
  const int in_idx = g_thd_x * in_stride_x + (item_stride_y * g_thd_y + j) * in_stride_y + group * in_stride_group + g_thd_z * in_stride_z;
75
75
  acc += w[w_idx] * in[in_idx];
76
76
  }
@@ -80,8 +80,7 @@ __global__ void grouped_convolution_y(
80
80
  }
81
81
  }
82
82
 
83
- template<int WSize>
84
- __global__ void transposed_convolution_x(
83
+ extern "C" __global__ void transposed_convolution_x(
85
84
  int dim_x,
86
85
  int dim_y,
87
86
  int dim_z,
@@ -90,6 +89,7 @@ __global__ void transposed_convolution_x(
90
89
  int in_stride_y,
91
90
  int in_stride_z,
92
91
  const float* w,
92
+ int wk,
93
93
  float* out
94
94
  )
95
95
  {
@@ -103,7 +103,7 @@ __global__ void transposed_convolution_x(
103
103
 
104
104
  constexpr int item_out_stride = 2;
105
105
  float acc = 0.F;
106
- for (int i = 0; i < WSize; ++i)
106
+ for (int i = 0; i < wk; ++i)
107
107
  {
108
108
  const int in_x = (g_thd_x - i) / item_out_stride;
109
109
  const int in_x_mod = (g_thd_x - i) % item_out_stride;
@@ -117,8 +117,7 @@ __global__ void transposed_convolution_x(
117
117
  out[out_idx] = acc;
118
118
  }
119
119
 
120
- template<int WSize>
121
- __global__ void transposed_convolution_y(
120
+ extern "C" __global__ void transposed_convolution_y(
122
121
  int dim_x,
123
122
  int dim_y,
124
123
  int dim_z,
@@ -127,6 +126,7 @@ __global__ void transposed_convolution_y(
127
126
  int in_stride_y,
128
127
  int in_stride_z,
129
128
  const float* w,
129
+ int hk,
130
130
  float* out
131
131
  )
132
132
  {
@@ -140,7 +140,7 @@ __global__ void transposed_convolution_y(
140
140
 
141
141
  constexpr int item_out_stride = 2;
142
142
  float acc = 0.F;
143
- for (int i = 0; i < WSize; ++i)
143
+ for (int i = 0; i < hk; ++i)
144
144
  {
145
145
  const int in_y = (g_thd_y - i) / item_out_stride;
146
146
  const int in_y_mod = (g_thd_y - i) % item_out_stride;
@@ -20,21 +20,25 @@
20
20
  # ---------------------------------------------------------------------------
21
21
  """Module for data correction. For more detailed information see :ref:`data_correction_module`."""
22
22
 
23
- import numpy as np
24
- from typing import Union
25
-
26
23
  from httomolibgpu import cupywrapper
27
24
 
28
25
  cp = cupywrapper.cp
29
26
  cupy_run = cupywrapper.cupy_run
30
27
 
31
- from numpy import float32
32
28
  from unittest.mock import Mock
33
29
 
34
30
  if cupy_run:
35
31
  from httomolibgpu.cuda_kernels import load_cuda_module
36
32
  else:
37
33
  load_cuda_module = Mock()
34
+ from typing import Union
35
+
36
+ from httomolibgpu.misc.utils import (
37
+ __check_variable_type,
38
+ __check_if_data_3D_array,
39
+ __check_if_data_correct_type,
40
+ __check_if_positive_nonzero,
41
+ )
38
42
 
39
43
  __all__ = [
40
44
  "median_filter",
@@ -45,7 +49,7 @@ __all__ = [
45
49
  def median_filter(
46
50
  data: cp.ndarray,
47
51
  kernel_size: int = 3,
48
- dif: float = 0.0,
52
+ dif: Union[float, int] = 0.0,
49
53
  ) -> cp.ndarray:
50
54
  """
51
55
  Applies 3D median filter to a 3D CuPy array. For more detailed information, see :ref:`method_median_filter`.
@@ -54,9 +58,9 @@ def median_filter(
54
58
  ----------
55
59
  data : cp.ndarray
56
60
  Input CuPy 3D array either float32 or uint16 data type.
57
- kernel_size : int, optional
58
- The size of the filter's kernel (a diameter).
59
- dif : float, optional
61
+ kernel_size : int
62
+ The size of the filter's kernel (a "diameter").
63
+ dif : float, int
60
64
  Expected difference value between outlier value and the
61
65
  median value of the array, leave equal to 0 for classical median.
62
66
 
@@ -70,25 +74,25 @@ def median_filter(
70
74
  ValueError
71
75
  If the input array is not three dimensional.
72
76
  """
73
- input_type = data.dtype
74
- if input_type not in ["float32", "uint16"]:
75
- raise ValueError("The input data should be either float32 or uint16 data type")
76
-
77
- if data.ndim == 3:
78
- if 0 in data.shape:
79
- raise ValueError("The length of one of dimensions is equal to zero")
80
- else:
81
- raise ValueError("The input array must be a 3D array")
82
-
83
- if kernel_size not in [3, 5, 7, 9, 11, 13]:
84
- raise ValueError("Please select a correct kernel size: 3, 5, 7, 9, 11, 13")
77
+ ### Data and parameters checks ###
78
+ methods_name = "median_filter/remove_outlier"
79
+ __check_if_data_3D_array(data, methods_name)
80
+ __check_if_data_correct_type(
81
+ data, accepted_type=["float32", "uint16"], methods_name=methods_name
82
+ )
83
+ __check_variable_type(
84
+ kernel_size, [int], "kernel_size", [3, 5, 7, 9, 11, 13], methods_name
85
+ )
86
+ __check_variable_type(dif, [int, float], "dif", [], methods_name)
87
+ ###################################
85
88
 
86
89
  dz, dy, dx = data.shape
90
+ input_type = data.dtype
87
91
  output = cp.copy(data, order="C")
88
92
 
89
93
  # 3d median or dezinger
90
- kernel_args = "median_general_kernel3d<{0}, {1}>".format(
91
- "float" if input_type == "float32" else "unsigned short", kernel_size
94
+ kernel_name = "median_general_kernel3d_{0}_{1}".format(
95
+ "float" if input_type == "float32" else "unsigned_short", kernel_size
92
96
  )
93
97
  block_x = 128
94
98
  # setting grid/block parameters
@@ -99,8 +103,8 @@ def median_filter(
99
103
  grid_dims = (grid_x, grid_y, grid_z)
100
104
  params = (data, output, cp.float32(dif), dz, dy, dx)
101
105
 
102
- median_module = load_cuda_module("median_kernel", name_expressions=[kernel_args])
103
- median_filt = median_module.get_function(kernel_args)
106
+ median_module = load_cuda_module("median_kernel")
107
+ median_filt = median_module.get_function(kernel_name)
104
108
 
105
109
  median_filt(grid_dims, block_dims, params)
106
110
 
@@ -108,7 +112,7 @@ def median_filter(
108
112
 
109
113
 
110
114
  def remove_outlier(
111
- data: cp.ndarray, kernel_size: int = 3, dif: float = 1000
115
+ data: cp.ndarray, kernel_size: int = 3, dif: Union[float, int] = 1000
112
116
  ) -> cp.ndarray:
113
117
  """Selectively applies 3D median filter to a 3D CuPy array to remove outliers. Also called a dezinger.
114
118
  For more detailed information, see :ref:`method_outlier_removal`.
@@ -117,9 +121,9 @@ def remove_outlier(
117
121
  ----------
118
122
  data : cp.ndarray
119
123
  Input CuPy 3D array either float32 or uint16 data type.
120
- kernel_size : int, optional
121
- The size of the filter's kernel (a diameter).
122
- dif : float, optional
124
+ kernel_size : int
125
+ The size of the filter's kernel (a "diameter").
126
+ dif : float, int
123
127
  Expected difference value between the outlier value (central voxel) and the
124
128
  median value of the neighbourhood. Lower values lead to median filtering.
125
129
 
@@ -133,8 +137,9 @@ def remove_outlier(
133
137
  ValueError
134
138
  Threshold value (dif) must be positive and nonzero.
135
139
  """
136
-
137
- if dif <= 0.0:
138
- raise ValueError("Threshold value (dif) must be positive and nonzero.")
139
-
140
+ ### Data and parameters checks ###
141
+ __check_if_positive_nonzero(
142
+ dif, "dif", positive=True, nonzero=True, methods_name="remove_outlier"
143
+ )
144
+ ###################################
140
145
  return median_filter(data, kernel_size, dif)
@@ -20,8 +20,6 @@
20
20
  # ---------------------------------------------------------------------------
21
21
  """Module for data denoising. For more detailed information see :ref:`data_denoising_module`."""
22
22
 
23
- import numpy as np
24
-
25
23
  from httomolibgpu import cupywrapper
26
24
 
27
25
  cp = cupywrapper.cp
@@ -35,6 +33,13 @@ else:
35
33
  ROF_TV = Mock()
36
34
  PD_TV = Mock()
37
35
 
36
+ from typing import Union
37
+
38
+ from httomolibgpu.misc.utils import (
39
+ __check_variable_type,
40
+ __check_if_data_3D_array,
41
+ __check_if_data_correct_type,
42
+ )
38
43
 
39
44
  __all__ = [
40
45
  "total_variation_ROF",
@@ -44,7 +49,7 @@ __all__ = [
44
49
 
45
50
  def total_variation_ROF(
46
51
  data: cp.ndarray,
47
- regularisation_parameter: float = 1e-05,
52
+ regularisation_parameter: Union[float, int] = 1e-05,
48
53
  iterations: int = 3000,
49
54
  time_marching_parameter: float = 0.001,
50
55
  gpu_id: int = 0,
@@ -55,7 +60,6 @@ def total_variation_ROF(
55
60
  This is a gradient-based algorithm for a smoothed TV term which requires a small time marching parameter and a significant number of iterations.
56
61
  See more in :ref:`method_total_variation_ROF`.
57
62
 
58
-
59
63
  Parameters
60
64
  ----------
61
65
  data : cp.ndarray
@@ -81,6 +85,26 @@ def total_variation_ROF(
81
85
  ValueError
82
86
  If the input array is not float32 data type.
83
87
  """
88
+ ### Data and parameters checks ###
89
+ methods_name = "total_variation_ROF"
90
+ __check_if_data_3D_array(data, methods_name)
91
+ __check_if_data_correct_type(
92
+ data, accepted_type=["float32"], methods_name=methods_name
93
+ )
94
+ __check_variable_type(
95
+ regularisation_parameter,
96
+ [float, int],
97
+ "regularisation_parameter",
98
+ [],
99
+ methods_name,
100
+ )
101
+ __check_variable_type(iterations, [int], "iterations", [], methods_name)
102
+ __check_variable_type(
103
+ time_marching_parameter, [float], "time_marching_parameter", [], methods_name
104
+ )
105
+ __check_variable_type(gpu_id, [int], "gpu_id", [], methods_name)
106
+ __check_variable_type(half_precision, [bool], "half_precision", [], methods_name)
107
+ ###################################
84
108
 
85
109
  return ROF_TV_cupy(
86
110
  data,
@@ -94,11 +118,11 @@ def total_variation_ROF(
94
118
 
95
119
  def total_variation_PD(
96
120
  data: cp.ndarray,
97
- regularisation_parameter: float = 1e-05,
121
+ regularisation_parameter: Union[float, int] = 1e-05,
98
122
  iterations: int = 1000,
99
123
  isotropic: bool = True,
100
124
  nonnegativity: bool = False,
101
- lipschitz_const: float = 8.0,
125
+ lipschitz_const: Union[float, int] = 8.0,
102
126
  gpu_id: int = 0,
103
127
  half_precision: bool = False,
104
128
  ) -> cp.ndarray:
@@ -109,7 +133,7 @@ def total_variation_PD(
109
133
  ----------
110
134
  data : cp.ndarray
111
135
  Input CuPy 3D array of float32 data type.
112
- regularisation_parameter : float
136
+ regularisation_parameter : float, int
113
137
  Regularisation parameter to control the level of smoothing. Defaults to 1e-05.
114
138
  iterations : int
115
139
  The number of iterations. Defaults to 1000.
@@ -117,7 +141,7 @@ def total_variation_PD(
117
141
  Choose between isotropic or anisotropic TV norm. Defaults to isotropic.
118
142
  nonnegativity : bool
119
143
  Enable non-negativity in iterations. Defaults to False.
120
- lipschitz_const : float
144
+ lipschitz_const : float,int
121
145
  Lipschitz constant to control convergence. Defaults to 8.
122
146
  gpu_id : int
123
147
  GPU device index to perform processing on. Defaults to 0.
@@ -135,6 +159,27 @@ def total_variation_PD(
135
159
  If the input array is not float32 data type.
136
160
  """
137
161
 
162
+ ### Data and parameters checks ###
163
+ methods_name = "total_variation_PD"
164
+ __check_if_data_3D_array(data, methods_name)
165
+ __check_if_data_correct_type(
166
+ data, accepted_type=["float32"], methods_name=methods_name
167
+ )
168
+ __check_variable_type(
169
+ regularisation_parameter,
170
+ [float, int],
171
+ "regularisation_parameter",
172
+ [],
173
+ methods_name,
174
+ )
175
+ __check_variable_type(iterations, [int], "iterations", [], methods_name)
176
+ __check_variable_type(isotropic, [bool], "isotropic", [], methods_name)
177
+ __check_variable_type(nonnegativity, [bool], "nonnegativity", [], methods_name)
178
+ __check_variable_type(lipschitz_const, [float, int], "lipschitz_const", [], methods_name)
179
+ __check_variable_type(gpu_id, [int], "gpu_id", [], methods_name)
180
+ __check_variable_type(half_precision, [bool], "half_precision", [], methods_name)
181
+ ###################################
182
+
138
183
  methodTV = 0
139
184
  if not isotropic:
140
185
  methodTV = 1