httomolibgpu 2.5.1__tar.gz → 2.6__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 (35) hide show
  1. {httomolibgpu-2.5.1/httomolibgpu.egg-info → httomolibgpu-2.6}/PKG-INFO +1 -1
  2. httomolibgpu-2.6/httomolibgpu/cuda_kernels/remove_nan_inf.cu +19 -0
  3. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu/misc/corr.py +6 -4
  4. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu/misc/denoise.py +7 -3
  5. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu/misc/morph.py +6 -0
  6. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu/misc/rescale.py +5 -4
  7. httomolibgpu-2.6/httomolibgpu/misc/supp_func.py +191 -0
  8. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu/prep/alignment.py +6 -0
  9. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu/prep/normalize.py +8 -2
  10. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu/prep/phase.py +6 -0
  11. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu/prep/stripe.py +16 -2
  12. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu/recon/algorithm.py +21 -0
  13. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu/recon/rotation.py +27 -2
  14. {httomolibgpu-2.5.1 → httomolibgpu-2.6/httomolibgpu.egg-info}/PKG-INFO +1 -1
  15. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu.egg-info/SOURCES.txt +2 -0
  16. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/LICENSE +0 -0
  17. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/MANIFEST.in +0 -0
  18. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/README.rst +0 -0
  19. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu/__init__.py +0 -0
  20. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu/cuda_kernels/__init__.py +0 -0
  21. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu/cuda_kernels/calc_metrics.cu +0 -0
  22. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu/cuda_kernels/center_360_shifts.cu +0 -0
  23. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu/cuda_kernels/generate_mask.cu +0 -0
  24. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu/cuda_kernels/median_kernel.cu +0 -0
  25. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu/cuda_kernels/paganin_filter_gen.cu +0 -0
  26. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu/cuda_kernels/raven_filter.cu +0 -0
  27. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu/cupywrapper.py +0 -0
  28. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu/misc/__init__.py +0 -0
  29. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu/prep/__init__.py +0 -0
  30. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu/recon/__init__.py +0 -0
  31. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu.egg-info/dependency_links.txt +0 -0
  32. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu.egg-info/requires.txt +0 -0
  33. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/httomolibgpu.egg-info/top_level.txt +0 -0
  34. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/pyproject.toml +0 -0
  35. {httomolibgpu-2.5.1 → httomolibgpu-2.6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: httomolibgpu
3
- Version: 2.5.1
3
+ Version: 2.6
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
@@ -0,0 +1,19 @@
1
+ template <typename Type>
2
+ __global__ void remove_nan_inf(Type *data, int Z, int M, int N, int *result) {
3
+ const long i = blockDim.x * blockIdx.x + threadIdx.x;
4
+ const long j = blockDim.y * blockIdx.y + threadIdx.y;
5
+ const long k = blockDim.z * blockIdx.z + threadIdx.z;
6
+
7
+ if (i >= N || j >= M || k >= Z)
8
+ return;
9
+
10
+ long long index = static_cast<long long>(i) + N * static_cast<long long>(j) + N * M * static_cast<long long>(k);
11
+
12
+ float val = float(data[index]); /*needs a cast to float for isnan isinf functions to work*/
13
+ Type zero = 0;
14
+ if (isnan(val) || isinf(val)) {
15
+ result[0] = 1;
16
+ data[index] = zero;
17
+ }
18
+
19
+ }
@@ -18,9 +18,7 @@
18
18
  # Created By : Tomography Team at DLS <scientificsoftware@diamond.ac.uk>
19
19
  # Created Date: 21/October/2022
20
20
  # ---------------------------------------------------------------------------
21
- """ Module for data correction. For more detailed information see :ref:`data_correction_module`.
22
-
23
- """
21
+ """Module for data correction. For more detailed information see :ref:`data_correction_module`."""
24
22
 
25
23
  import numpy as np
26
24
  from typing import Union
@@ -38,6 +36,7 @@ if cupy_run:
38
36
  else:
39
37
  load_cuda_module = Mock()
40
38
 
39
+ from httomolibgpu.misc.supp_func import data_checker
41
40
 
42
41
  __all__ = [
43
42
  "median_filter",
@@ -74,7 +73,6 @@ def median_filter(
74
73
  If the input array is not three dimensional.
75
74
  """
76
75
  input_type = data.dtype
77
-
78
76
  if input_type not in ["float32", "uint16"]:
79
77
  raise ValueError("The input data should be either float32 or uint16 data type")
80
78
 
@@ -84,6 +82,10 @@ def median_filter(
84
82
  else:
85
83
  raise ValueError("The input array must be a 3D array")
86
84
 
85
+ data = data_checker(
86
+ data, verbosity=True, method_name="median_filter_or_remove_outlier"
87
+ )
88
+
87
89
  if kernel_size not in [3, 5, 7, 9, 11, 13]:
88
90
  raise ValueError("Please select a correct kernel size: 3, 5, 7, 9, 11, 13")
89
91
 
@@ -18,8 +18,7 @@
18
18
  # Created By : Tomography Team at DLS <scientificsoftware@diamond.ac.uk>
19
19
  # Created Date: 18/December/2024
20
20
  # ---------------------------------------------------------------------------
21
- """ Module for data denoising. For more detailed information see :ref:`data_denoising_module`.
22
- """
21
+ """Module for data denoising. For more detailed information see :ref:`data_denoising_module`."""
23
22
 
24
23
  import numpy as np
25
24
  from typing import Union, Optional
@@ -29,9 +28,10 @@ from httomolibgpu import cupywrapper
29
28
  cp = cupywrapper.cp
30
29
  cupy_run = cupywrapper.cupy_run
31
30
 
32
- from numpy import float32
33
31
  from unittest.mock import Mock
34
32
 
33
+ from httomolibgpu.misc.supp_func import data_checker
34
+
35
35
  if cupy_run:
36
36
  from ccpi.filters.regularisersCuPy import ROF_TV, PD_TV
37
37
  else:
@@ -82,6 +82,8 @@ def total_variation_ROF(
82
82
  If the input array is not float32 data type.
83
83
  """
84
84
 
85
+ data = data_checker(data, verbosity=True, method_name="total_variation_ROF")
86
+
85
87
  return ROF_TV(
86
88
  data, regularisation_parameter, iterations, time_marching_parameter, gpu_id
87
89
  )
@@ -127,6 +129,8 @@ def total_variation_PD(
127
129
  If the input array is not float32 data type.
128
130
  """
129
131
 
132
+ data_checker(data, verbosity=True, method_name="total_variation_PD")
133
+
130
134
  methodTV = 0
131
135
  if not isotropic:
132
136
  methodTV = 1
@@ -35,6 +35,8 @@ else:
35
35
 
36
36
  from typing import Literal
37
37
 
38
+ from httomolibgpu.misc.supp_func import data_checker
39
+
38
40
  __all__ = [
39
41
  "sino_360_to_180",
40
42
  "data_resampler",
@@ -66,6 +68,8 @@ def sino_360_to_180(
66
68
  if data.ndim != 3:
67
69
  raise ValueError("only 3D data is supported")
68
70
 
71
+ data = data_checker(data, verbosity=True, method_name="sino_360_to_180")
72
+
69
73
  dx, dy, dz = data.shape
70
74
 
71
75
  overlap = int(np.round(overlap))
@@ -136,6 +140,8 @@ def data_resampler(
136
140
  data = cp.expand_dims(data, 1)
137
141
  axis = 1
138
142
 
143
+ data = data_checker(data, verbosity=True, method_name="data_resampler")
144
+
139
145
  N, M, Z = cp.shape(data)
140
146
 
141
147
  if axis == 0:
@@ -18,9 +18,7 @@
18
18
  # Created By : Tomography Team at DLS <scientificsoftware@diamond.ac.uk>
19
19
  # Created Date: 1 March 2024
20
20
  # ---------------------------------------------------------------------------
21
- """ Module for data rescaling. For more detailed information see :ref:`data_rescale_module`.
22
-
23
- """
21
+ """Module for data rescaling. For more detailed information see :ref:`data_rescale_module`."""
24
22
 
25
23
  import numpy as np
26
24
  from httomolibgpu import cupywrapper
@@ -30,6 +28,8 @@ cupy_run = cupywrapper.cupy_run
30
28
 
31
29
  from typing import Literal, Optional, Tuple, Union
32
30
 
31
+ from httomolibgpu.misc.supp_func import data_checker
32
+
33
33
  __all__ = [
34
34
  "rescale_to_int",
35
35
  ]
@@ -80,6 +80,8 @@ def rescale_to_int(
80
80
  else:
81
81
  output_dtype = np.uint32
82
82
 
83
+ data = data_checker(data, verbosity=True, method_name="rescale_to_int")
84
+
83
85
  if cupy_run:
84
86
  xp = cp.get_array_module(data)
85
87
  else:
@@ -109,7 +111,6 @@ def rescale_to_int(
109
111
  if xp.__name__ == "numpy":
110
112
  if input_max == pow(2, 32):
111
113
  input_max -= 1
112
- data[np.logical_not(np.isfinite(data))] = 0
113
114
  res = np.copy(data.astype(float))
114
115
  res[data.astype(float) < input_min] = int(input_min)
115
116
  res[data.astype(float) > input_max] = int(input_max)
@@ -0,0 +1,191 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # ---------------------------------------------------------------------------
4
+ # Copyright 2022 Diamond Light Source Ltd.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ # ---------------------------------------------------------------------------
18
+ # Created By : Tomography Team at DLS <scientificsoftware@diamond.ac.uk>
19
+ # Created Date: 02/June/2025
20
+ # ---------------------------------------------------------------------------
21
+ """This is a collection of supplementary functions (utils) to perform various data checks"""
22
+
23
+ from httomolibgpu import cupywrapper
24
+ from typing import Optional
25
+
26
+ cp = cupywrapper.cp
27
+ cupy_run = cupywrapper.cupy_run
28
+
29
+ import numpy as np
30
+
31
+ from unittest.mock import Mock
32
+
33
+ if cupy_run:
34
+ from httomolibgpu.cuda_kernels import load_cuda_module
35
+ else:
36
+ load_cuda_module = Mock()
37
+
38
+
39
+ def _naninfs_check(
40
+ data: cp.ndarray,
41
+ verbosity: bool = True,
42
+ method_name: Optional[str] = None,
43
+ ) -> cp.ndarray:
44
+ """
45
+ This function finds NaN's, +-Inf's in the input data and then prints the warnings and correct the data if correction is enabled.
46
+
47
+ Parameters
48
+ ----------
49
+ data : cp.ndarray
50
+ Input CuPy or Numpy array either float32 or uint16 data type.
51
+ verbosity : bool
52
+ If enabled, then the printing of the warning happens when data contains infs or nans
53
+ method_name : str, optional.
54
+ Method's name for which input data is tested.
55
+
56
+ Returns
57
+ -------
58
+ ndarray
59
+ Uncorrected or corrected (nans and infs converted to zeros) input array.
60
+ """
61
+ present_nans_infs_b = False
62
+
63
+ if cupy_run:
64
+ xp = cp.get_array_module(data)
65
+ else:
66
+ import numpy as xp
67
+
68
+ if xp.__name__ == "cupy":
69
+ input_type = data.dtype
70
+ if len(data.shape) == 2:
71
+ dy, dx = data.shape
72
+ dz = 1
73
+ else:
74
+ dz, dy, dx = data.shape
75
+
76
+ present_nans_infs = cp.zeros(shape=(1)).astype(cp.uint8)
77
+
78
+ block_x = 128
79
+ # setting grid/block parameters
80
+ block_dims = (block_x, 1, 1)
81
+ grid_x = (dx + block_x - 1) // block_x
82
+ grid_y = dy
83
+ grid_z = dz
84
+ grid_dims = (grid_x, grid_y, grid_z)
85
+ params = (data, dz, dy, dx, present_nans_infs)
86
+
87
+ kernel_args = "remove_nan_inf<{0}>".format(
88
+ "float" if input_type == "float32" else "unsigned short"
89
+ )
90
+
91
+ module = load_cuda_module("remove_nan_inf", name_expressions=[kernel_args])
92
+ remove_nan_inf_kernel = module.get_function(kernel_args)
93
+ remove_nan_inf_kernel(grid_dims, block_dims, params)
94
+
95
+ if present_nans_infs[0].get() == 1:
96
+ present_nans_infs_b = True
97
+ else:
98
+ if not np.all(np.isfinite(data)):
99
+ present_nans_infs_b = True
100
+ np.nan_to_num(data, copy=False, nan=0.0, posinf=0.0, neginf=0.0)
101
+
102
+ if present_nans_infs_b:
103
+ if verbosity:
104
+ print(
105
+ f"Warning!!! Input data to method: {method_name} contains Inf's or/and NaN's. This will be corrected but it is recommended to check the validity of input to the method."
106
+ )
107
+
108
+ return data
109
+
110
+
111
+ def _zeros_check(
112
+ data: cp.ndarray,
113
+ verbosity: bool = True,
114
+ percentage_threshold: float = 50,
115
+ method_name: Optional[str] = None,
116
+ ) -> bool:
117
+ """
118
+ This function finds all zeros present in the data. If the amount of zeros is larger than percentage_threshold it prints the warning.
119
+
120
+ Parameters
121
+ ----------
122
+ data : cp.ndarray
123
+ Input CuPy or Numpy array.
124
+ verbosity : bool
125
+ If enabled, then the printing of the warning happens when data contains infs or nans.
126
+ percentage_threshold: float:
127
+ If the number of zeros in input data is more than the percentage of all data points, then print the data warning
128
+ method_name : str, optional.
129
+ Method's name for which input data is tested.
130
+
131
+ Returns
132
+ -------
133
+ bool
134
+ True if the data contains too many zeros
135
+ """
136
+ if cupy_run:
137
+ xp = cp.get_array_module(data)
138
+ else:
139
+ import numpy as xp
140
+
141
+ nonzero_elements_total = 1
142
+ for tot_elements_mult in data.shape:
143
+ nonzero_elements_total *= tot_elements_mult
144
+
145
+ warning_zeros = False
146
+ zero_elements_total = nonzero_elements_total - int(xp.count_nonzero(data))
147
+
148
+ if (zero_elements_total / nonzero_elements_total) * 100 >= percentage_threshold:
149
+ warning_zeros = True
150
+ if verbosity:
151
+ print(
152
+ f"Warning!!! Input data to method: {method_name} contains more than {percentage_threshold} percent of zeros."
153
+ )
154
+
155
+ return warning_zeros
156
+
157
+
158
+ def data_checker(
159
+ data: cp.ndarray,
160
+ verbosity: bool = True,
161
+ method_name: Optional[str] = None,
162
+ ) -> bool:
163
+ """
164
+ Function that performs the variety of checks on input data, in some cases also correct the data and prints warnings.
165
+ Currently it checks for: the presence of infs and nans in data; the number of zero elements.
166
+
167
+ Parameters
168
+ ----------
169
+ data : xp.ndarray
170
+ Input CuPy or Numpy array either float32 or uint16 data type.
171
+ verbosity : bool
172
+ If enabled, then the printing of the warning happens when data contains infs or nans.
173
+ method_name : str, optional.
174
+ Method's name for which input data is tested.
175
+
176
+ Returns
177
+ -------
178
+ cp.ndarray
179
+ Returns corrected or not data array.
180
+ """
181
+
182
+ data = _naninfs_check(data, verbosity=verbosity, method_name=method_name)
183
+
184
+ _zeros_check(
185
+ data,
186
+ verbosity=verbosity,
187
+ percentage_threshold=50,
188
+ method_name=method_name,
189
+ )
190
+
191
+ return data
@@ -35,6 +35,8 @@ else:
35
35
 
36
36
  from typing import Dict, List, Tuple
37
37
 
38
+ from httomolibgpu.misc.supp_func import data_checker
39
+
38
40
  __all__ = [
39
41
  "distortion_correction_proj_discorpy",
40
42
  ]
@@ -86,6 +88,10 @@ def distortion_correction_proj_discorpy(
86
88
  if len(data.shape) == 2:
87
89
  data = cp.expand_dims(data, axis=0)
88
90
 
91
+ data = data_checker(
92
+ data, verbosity=True, method_name="distortion_correction_proj_discorpy"
93
+ )
94
+
89
95
  # Get info from metadata txt file
90
96
  xcenter, ycenter, list_fact = _load_metadata_txt(metadata_path)
91
97
 
@@ -36,6 +36,8 @@ else:
36
36
  from numpy import float32
37
37
  from typing import Tuple
38
38
 
39
+ from httomolibgpu.misc.supp_func import data_checker
40
+
39
41
  __all__ = ["normalize"]
40
42
 
41
43
 
@@ -80,7 +82,7 @@ def normalize(
80
82
  cp.ndarray
81
83
  Normalised 3D tomographic data as a CuPy array.
82
84
  """
83
- _check_valid_input(data, flats, darks)
85
+ _check_valid_input_normalise(data, flats, darks)
84
86
 
85
87
  dark0 = cp.empty(darks.shape[1:], dtype=float32)
86
88
  flat0 = cp.empty(flats.shape[1:], dtype=float32)
@@ -128,7 +130,7 @@ def normalize(
128
130
  return out
129
131
 
130
132
 
131
- def _check_valid_input(data, flats, darks) -> None:
133
+ def _check_valid_input_normalise(data, flats, darks) -> None:
132
134
  """Helper function to check the validity of inputs to normalisation functions"""
133
135
  if data.ndim != 3:
134
136
  raise ValueError("Input data must be a 3D stack of projections")
@@ -143,3 +145,7 @@ def _check_valid_input(data, flats, darks) -> None:
143
145
  flats = flats[cp.newaxis, :, :]
144
146
  if darks.ndim == 2:
145
147
  darks = darks[cp.newaxis, :, :]
148
+
149
+ data_checker(data, verbosity=True, method_name="normalize_data")
150
+ data_checker(flats, verbosity=True, method_name="normalize_flats")
151
+ data_checker(darks, verbosity=True, method_name="normalize_darks")
@@ -41,6 +41,8 @@ from numpy import float32
41
41
  from typing import Tuple
42
42
  import math
43
43
 
44
+ from httomolibgpu.misc.supp_func import data_checker
45
+
44
46
  __all__ = [
45
47
  "paganin_filter_savu",
46
48
  "paganin_filter_tomopy",
@@ -105,6 +107,8 @@ def paganin_filter_savu(
105
107
  " please provide a stack of 2D projections."
106
108
  )
107
109
 
110
+ data = data_checker(data, verbosity=True, method_name="paganin_filter_savu")
111
+
108
112
  # Setup various values for the filter
109
113
  _, height, width = data.shape
110
114
  micron = 1e-6
@@ -297,6 +301,8 @@ def paganin_filter_tomopy(
297
301
  " please provide a stack of 2D projections."
298
302
  )
299
303
 
304
+ tomo = data_checker(tomo, verbosity=True, method_name="paganin_filter_tomopy")
305
+
300
306
  dz_orig, dy_orig, dx_orig = tomo.shape
301
307
 
302
308
  # Perform padding to the power of 2 as FFT is O(n*log(n)) complexity
@@ -43,6 +43,8 @@ else:
43
43
 
44
44
  from typing import Union
45
45
 
46
+ from httomolibgpu.misc.supp_func import data_checker
47
+
46
48
  __all__ = [
47
49
  "remove_stripe_based_sorting",
48
50
  "remove_stripe_ti",
@@ -80,6 +82,9 @@ def remove_stripe_based_sorting(
80
82
  Corrected 3D tomographic data as a CuPy or NumPy array.
81
83
 
82
84
  """
85
+
86
+ data = data_checker(data, verbosity=True, method_name="remove_stripe_based_sorting")
87
+
83
88
  if size is None:
84
89
  if data.shape[2] > 2000:
85
90
  size = 21
@@ -134,7 +139,13 @@ def remove_stripe_ti(
134
139
  ndarray
135
140
  3D array of de-striped projections.
136
141
  """
137
- # TODO: detector dimensions must be even otherwise error
142
+ data = data_checker(data, verbosity=True, method_name="remove_stripe_ti")
143
+
144
+ _, _, dx_orig = data.shape
145
+ if (dx_orig % 2) != 0:
146
+ # the horizontal detector size is odd, data needs to be padded/cropped, for now raising the error
147
+ raise ValueError("The horizontal detector size must be even")
148
+
138
149
  gamma = beta * ((1 - beta) / (1 + beta)) ** cp.abs(
139
150
  cp.fft.fftfreq(data.shape[-1]) * data.shape[-1]
140
151
  )
@@ -201,6 +212,8 @@ def remove_all_stripe(
201
212
  Corrected 3D tomographic data as a CuPy or NumPy array.
202
213
 
203
214
  """
215
+ data = data_checker(data, verbosity=True, method_name="remove_all_stripe")
216
+
204
217
  matindex = _create_matindex(data.shape[2], data.shape[0])
205
218
  for m in range(data.shape[1]):
206
219
  sino = data[:, m, :]
@@ -372,10 +385,11 @@ def raven_filter(
372
385
  ValueError
373
386
  If the input array is not three dimensional.
374
387
  """
375
-
376
388
  if data.dtype != cp.float32:
377
389
  raise ValueError("The input data should be float32 data type")
378
390
 
391
+ data = data_checker(data, verbosity=True, method_name="raven_filter")
392
+
379
393
  # Padding of the sinogram
380
394
  data = cp.pad(data, ((pad_y, pad_y), (0, 0), (pad_x, pad_x)), mode=pad_method)
381
395
 
@@ -40,6 +40,8 @@ else:
40
40
  from numpy import float32, complex64
41
41
  from typing import Optional, Type
42
42
 
43
+ from httomolibgpu.misc.supp_func import data_checker
44
+
43
45
 
44
46
  __all__ = [
45
47
  "FBP2d_astra",
@@ -103,6 +105,8 @@ def FBP2d_astra(
103
105
  np.ndarray
104
106
  The FBP reconstructed volume as a numpy array.
105
107
  """
108
+ data = data_checker(data, verbosity=True, method_name="FBP2d_astra")
109
+
106
110
  data_shape = np.shape(data)
107
111
  if recon_size is None:
108
112
  recon_size = data_shape[2]
@@ -175,6 +179,8 @@ def FBP3d_tomobar(
175
179
  cp.ndarray
176
180
  FBP reconstructed volume as a CuPy array.
177
181
  """
182
+ data = data_checker(data, verbosity=True, method_name="FBP3d_tomobar")
183
+
178
184
  RecToolsCP = _instantiate_direct_recon_class(
179
185
  data, angles, center, recon_size, gpu_id
180
186
  )
@@ -194,6 +200,8 @@ def LPRec3d_tomobar(
194
200
  data: cp.ndarray,
195
201
  angles: np.ndarray,
196
202
  center: Optional[float] = None,
203
+ filter_type: str = "shepp",
204
+ filter_freq_cutoff: float = 1.0,
197
205
  recon_size: Optional[int] = None,
198
206
  recon_mask_radius: Optional[float] = 0.95,
199
207
  neglog: bool = False,
@@ -211,6 +219,10 @@ def LPRec3d_tomobar(
211
219
  An array of angles given in radians.
212
220
  center : float, optional
213
221
  The center of rotation (CoR).
222
+ filter_type : str
223
+ Filter type, the accepted strings are: none, ramp, shepp, cosine, cosine2, hamming, hann, parzen.
224
+ filter_freq_cutoff : float
225
+ Cutoff frequency parameter for a filter. The higher values increase the resolution but also amplify the noise.
214
226
  recon_size : int, optional
215
227
  The [recon_size, recon_size] shape of the reconstructed slice in pixels.
216
228
  By default (None), the reconstructed size will be the dimension of the horizontal detector.
@@ -227,12 +239,17 @@ def LPRec3d_tomobar(
227
239
  cp.ndarray
228
240
  The Log-polar Fourier reconstructed volume as a CuPy array.
229
241
  """
242
+
243
+ data = data_checker(data, verbosity=True, method_name="LPRec3d_tomobar")
244
+
230
245
  RecToolsCP = _instantiate_direct_recon_class(data, angles, center, recon_size, 0)
231
246
 
232
247
  reconstruction = RecToolsCP.FOURIER_INV(
233
248
  _take_neg_log(data) if neglog else data,
234
249
  recon_mask_radius=recon_mask_radius,
235
250
  data_axes_labels_order=input_data_axis_labels,
251
+ filter_type=filter_type,
252
+ cutoff_freq=filter_freq_cutoff,
236
253
  )
237
254
  cp._default_memory_pool.free_all_blocks()
238
255
  return cp.require(cp.swapaxes(reconstruction, 0, 1), requirements="C")
@@ -281,6 +298,8 @@ def SIRT3d_tomobar(
281
298
  cp.ndarray
282
299
  The SIRT reconstructed volume as a CuPy array.
283
300
  """
301
+ data = data_checker(data, verbosity=True, method_name="SIRT3d_tomobar")
302
+
284
303
  RecToolsCP = _instantiate_iterative_recon_class(
285
304
  data,
286
305
  angles,
@@ -346,6 +365,8 @@ def CGLS3d_tomobar(
346
365
  cp.ndarray
347
366
  The CGLS reconstructed volume as a CuPy array.
348
367
  """
368
+ data = data_checker(data, verbosity=True, method_name="CGLS3d_tomobar")
369
+
349
370
  RecToolsCP = _instantiate_iterative_recon_class(
350
371
  data, angles, center, recon_size, gpu_id, datafidelity="LS"
351
372
  )
@@ -21,6 +21,7 @@
21
21
  """Modules for finding the axis of rotation for 180 and 360 degrees scans"""
22
22
 
23
23
  import numpy as np
24
+ from numpy.polynomial import Polynomial
24
25
  from httomolibgpu import cupywrapper
25
26
 
26
27
  cp = cupywrapper.cp
@@ -48,6 +49,8 @@ else:
48
49
  import math
49
50
  from typing import List, Literal, Optional, Tuple, Union
50
51
 
52
+ from httomolibgpu.misc.supp_func import data_checker
53
+
51
54
  __all__ = [
52
55
  "find_center_vo",
53
56
  "find_center_360",
@@ -107,6 +110,8 @@ def find_center_vo(
107
110
  data = cp.expand_dims(data, 1)
108
111
  ind = 0
109
112
 
113
+ data = data_checker(data, verbosity=True, method_name="find_center_vo")
114
+
110
115
  angles_tot, detY_size, detX_size = data.shape
111
116
 
112
117
  if ind is None:
@@ -455,6 +460,8 @@ def find_center_360(
455
460
  if data.ndim != 3:
456
461
  raise ValueError("A 3D array must be provided")
457
462
 
463
+ data = data_checker(data, verbosity=True, method_name="find_center_360")
464
+
458
465
  # this method works with a 360-degree sinogram.
459
466
  if ind is None:
460
467
  _sino = data[:, 0, :]
@@ -712,9 +719,23 @@ def _calculate_curvature(list_metric):
712
719
 
713
720
  # work mostly on CPU here - we have very small arrays here
714
721
  list1 = cp.asnumpy(list_metric[min_pos - radi : min_pos + radi + 1])
715
- afact1 = np.polyfit(np.arange(0, 2 * radi + 1), list1, 2)[0]
722
+ if not all(map(np.isfinite, list1)):
723
+ raise ValueError(
724
+ "The list of metrics (list1) contains nan's or infs. Check your input data"
725
+ )
726
+
727
+ series1 = Polynomial.fit(np.arange(0, 2 * radi + 1), list1, deg=2)
728
+ afact1 = series1.convert().coef[-1]
729
+
716
730
  list2 = cp.asnumpy(list_metric[min_pos - 1 : min_pos + 2])
717
- (afact2, bfact2, _) = np.polyfit(np.arange(min_pos - 1, min_pos + 2), list2, 2)
731
+ if not all(map(np.isfinite, list2)):
732
+ raise ValueError(
733
+ "The list of metrics (list2) contains nan's or infs. Check your input data"
734
+ )
735
+
736
+ series2 = Polynomial.fit(np.arange(min_pos - 1, min_pos + 2), list2, deg=2)
737
+ afact2 = series2.convert().coef[-1]
738
+ bfact2 = series2.convert().coef[-1 - 1]
718
739
 
719
740
  curvature = np.abs(afact1)
720
741
  if afact2 != 0.0:
@@ -759,6 +780,10 @@ def find_center_pc(
759
780
  np.float32
760
781
  Rotation axis location.
761
782
  """
783
+
784
+ proj1 = data_checker(proj1, verbosity=True, method_name="find_center_pc")
785
+ proj2 = data_checker(proj2, verbosity=True, method_name="find_center_pc")
786
+
762
787
  imgshift = 0.0 if rotc_guess is None else rotc_guess - (proj1.shape[1] - 1.0) / 2.0
763
788
 
764
789
  proj1 = shift(proj1, [0, -imgshift], mode="constant", cval=0)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: httomolibgpu
3
- Version: 2.5.1
3
+ Version: 2.6
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
@@ -16,11 +16,13 @@ httomolibgpu/cuda_kernels/generate_mask.cu
16
16
  httomolibgpu/cuda_kernels/median_kernel.cu
17
17
  httomolibgpu/cuda_kernels/paganin_filter_gen.cu
18
18
  httomolibgpu/cuda_kernels/raven_filter.cu
19
+ httomolibgpu/cuda_kernels/remove_nan_inf.cu
19
20
  httomolibgpu/misc/__init__.py
20
21
  httomolibgpu/misc/corr.py
21
22
  httomolibgpu/misc/denoise.py
22
23
  httomolibgpu/misc/morph.py
23
24
  httomolibgpu/misc/rescale.py
25
+ httomolibgpu/misc/supp_func.py
24
26
  httomolibgpu/prep/__init__.py
25
27
  httomolibgpu/prep/alignment.py
26
28
  httomolibgpu/prep/normalize.py
File without changes
File without changes
File without changes
File without changes
File without changes