httomolibgpu 5.5.1__tar.gz → 5.7__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 (36) hide show
  1. {httomolibgpu-5.5.1/httomolibgpu.egg-info → httomolibgpu-5.7}/PKG-INFO +1 -1
  2. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/misc/denoise.py +3 -1
  3. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/misc/morph.py +52 -21
  4. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/misc/rescale.py +0 -1
  5. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/prep/normalize.py +71 -11
  6. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/recon/algorithm.py +135 -4
  7. {httomolibgpu-5.5.1 → httomolibgpu-5.7/httomolibgpu.egg-info}/PKG-INFO +1 -1
  8. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/LICENSE +0 -0
  9. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/MANIFEST.in +0 -0
  10. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/README.rst +0 -0
  11. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/__init__.py +0 -0
  12. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/cuda_kernels/__init__.py +0 -0
  13. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/cuda_kernels/calc_metrics.cu +0 -0
  14. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/cuda_kernels/center_360_shifts.cu +0 -0
  15. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/cuda_kernels/generate_mask.cu +0 -0
  16. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/cuda_kernels/median_kernel.cu +0 -0
  17. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/cuda_kernels/raven_filter.cu +0 -0
  18. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/cuda_kernels/remove_nan_inf.cu +0 -0
  19. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/cuda_kernels/remove_stripe_fw.cu +0 -0
  20. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/cupywrapper.py +0 -0
  21. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/misc/__init__.py +0 -0
  22. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/misc/corr.py +0 -0
  23. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/misc/utils.py +0 -0
  24. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/prep/__init__.py +0 -0
  25. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/prep/alignment.py +0 -0
  26. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/prep/phase.py +0 -0
  27. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/prep/stripe.py +0 -0
  28. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/recon/__init__.py +0 -0
  29. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/recon/_phase_cross_correlation.py +0 -0
  30. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu/recon/rotation.py +0 -0
  31. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu.egg-info/SOURCES.txt +0 -0
  32. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu.egg-info/dependency_links.txt +0 -0
  33. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu.egg-info/requires.txt +0 -0
  34. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/httomolibgpu.egg-info/top_level.txt +0 -0
  35. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/pyproject.toml +0 -0
  36. {httomolibgpu-5.5.1 → httomolibgpu-5.7}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: httomolibgpu
3
- Version: 5.5.1
3
+ Version: 5.7
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
@@ -175,7 +175,9 @@ def total_variation_PD(
175
175
  __check_variable_type(iterations, [int], "iterations", [], methods_name)
176
176
  __check_variable_type(isotropic, [bool], "isotropic", [], methods_name)
177
177
  __check_variable_type(nonnegativity, [bool], "nonnegativity", [], methods_name)
178
- __check_variable_type(lipschitz_const, [float, int], "lipschitz_const", [], methods_name)
178
+ __check_variable_type(
179
+ lipschitz_const, [float, int], "lipschitz_const", [], methods_name
180
+ )
179
181
  __check_variable_type(gpu_id, [int], "gpu_id", [], methods_name)
180
182
  __check_variable_type(half_precision, [bool], "half_precision", [], methods_name)
181
183
  ###################################
@@ -80,45 +80,76 @@ def sino_360_to_180(
80
80
  )
81
81
  __check_variable_type(overlap, [int, float], "overlap", [], methods_name)
82
82
  __check_variable_type(side, [str], "side", ["left", "right"], methods_name)
83
- __check_if_positive_nonzero(
84
- overlap, "overlap", positive=True, nonzero=True, methods_name=methods_name
85
- )
86
83
  ###################################
87
84
  #
88
85
  dx, dy, dz = data.shape
89
86
 
90
87
  overlap = int(np.round(overlap))
91
- if overlap >= dz - 1:
92
- raise ValueError("Overlap must be less than size of the horizontal detector")
93
88
  if overlap % 2 != 0:
94
89
  overlap += 1
95
-
90
+ overlap_pos = abs(overlap)
91
+ if overlap_pos >= dz - 1:
92
+ raise ValueError("Overlap must be less than size of the horizontal detector")
96
93
  n = dx // 2
97
94
  out = cp.empty((n, dy, 2 * dz - overlap), dtype=data.dtype)
98
95
 
99
96
  if side == "left":
100
- weights = cp.linspace(0, 1.0, overlap, dtype=cp.float32)
101
- out[:, :, -dz + overlap :] = data[:n, :, overlap:]
102
- out[:, :, : dz - overlap] = data[n : 2 * n, :, overlap:][:, :, ::-1]
103
- out[:, :, dz - overlap : dz] = (
104
- weights * data[:n, :, :overlap]
105
- + (weights * data[n : 2 * n, :, :overlap])[:, :, ::-1]
106
- )
97
+ if overlap == 0:
98
+ out[:, :, -dz:] = data[:n, :, :]
99
+ out[:, :, :dz] = data[n : 2 * n, :, :][:, :, ::-1]
100
+ return out
101
+ elif overlap < 0:
102
+ out[:, :, -dz:] = data[:n, :, :]
103
+ out[:, :, : (dz + overlap_pos)] = cp.pad(
104
+ data[n : 2 * n, :, :][:, :, ::-1],
105
+ pad_width=(
106
+ (0, 0),
107
+ (0, 0),
108
+ (0, overlap_pos),
109
+ ),
110
+ mode="edge",
111
+ )
112
+ return out
113
+ else:
114
+ weights = cp.linspace(0, 1.0, overlap, dtype=cp.float32)
115
+ out[:, :, -dz + overlap :] = data[:n, :, overlap:]
116
+ out[:, :, : dz - overlap] = data[n : 2 * n, :, overlap:][:, :, ::-1]
117
+ out[:, :, dz - overlap : dz] = (
118
+ weights * data[:n, :, :overlap]
119
+ + (weights * data[n : 2 * n, :, :overlap])[:, :, ::-1]
120
+ )
107
121
  if side == "right":
108
- weights = cp.linspace(1.0, 0, overlap, dtype=cp.float32)
109
- out[:, :, : dz - overlap] = data[:n, :, :-overlap]
110
- out[:, :, -dz + overlap :] = data[n : 2 * n, :, :-overlap][:, :, ::-1]
111
- out[:, :, dz - overlap : dz] = (
112
- weights * data[:n, :, -overlap:]
113
- + (weights * data[n : 2 * n, :, -overlap:])[:, :, ::-1]
114
- )
122
+ if overlap == 0:
123
+ out[:, :, :dz] = data[:n, :, :]
124
+ out[:, :, dz::] = data[n : 2 * n, :, :][:, :, ::-1]
125
+ return out
126
+ elif overlap < 0:
127
+ out[:, :, : (dz + overlap_pos)] = cp.pad(
128
+ data[:n, :, :],
129
+ pad_width=(
130
+ (0, 0),
131
+ (0, 0),
132
+ (0, overlap_pos),
133
+ ),
134
+ mode="edge",
135
+ )
136
+ out[:, :, (dz + overlap_pos) : :] = data[n : 2 * n, :, :][:, :, ::-1]
137
+ return out
138
+ else:
139
+ weights = cp.linspace(1.0, 0, overlap, dtype=cp.float32)
140
+ out[:, :, : dz - overlap] = data[:n, :, :-overlap]
141
+ out[:, :, -dz + overlap :] = data[n : 2 * n, :, :-overlap][:, :, ::-1]
142
+ out[:, :, dz - overlap : dz] = (
143
+ weights * data[:n, :, -overlap:]
144
+ + (weights * data[n : 2 * n, :, -overlap:])[:, :, ::-1]
145
+ )
115
146
 
116
147
  return cp.pad(
117
148
  out,
118
149
  pad_width=(
119
150
  (0, 0),
120
151
  (0, 0),
121
- (overlap // 2, overlap // 2),
152
+ (overlap_pos // 2, overlap_pos // 2),
122
153
  ),
123
154
  mode="edge",
124
155
  )
@@ -33,7 +33,6 @@ __all__ = [
33
33
 
34
34
  from httomolibgpu.misc.utils import (
35
35
  __check_variable_type,
36
- __check_if_data_3D_array,
37
36
  __check_if_data_correct_type,
38
37
  )
39
38
 
@@ -21,6 +21,7 @@
21
21
  """Modules for raw projection data normalization"""
22
22
 
23
23
  from httomolibgpu import cupywrapper
24
+ import numpy as np
24
25
 
25
26
  cp = cupywrapper.cp
26
27
  cupy_run = cupywrapper.cupy_run
@@ -32,8 +33,8 @@ if cupy_run:
32
33
  else:
33
34
  mean = Mock()
34
35
 
35
- from typing import Union
36
- from numpy import float32
36
+ from typing import Union, Optional
37
+ from numpy import float32, int64
37
38
  from httomolibgpu.misc.utils import (
38
39
  __check_variable_type,
39
40
  __check_if_data_3D_array,
@@ -49,7 +50,8 @@ def dark_flat_field_correction(
49
50
  darks: cp.ndarray,
50
51
  flats_multiplier: Union[float, int] = 1.0,
51
52
  darks_multiplier: Union[float, int] = 1.0,
52
- cutoff: Union[float, int] = 10.0,
53
+ upper_bound: Optional[Union[float, int]] = None,
54
+ lower_bound: Optional[Union[float, int]] = None,
53
55
  ) -> cp.ndarray:
54
56
  """
55
57
  Perform dark/flat field correction of raw projection data.
@@ -66,8 +68,10 @@ def dark_flat_field_correction(
66
68
  A multiplier to apply to flats, can work as an intensity compensation constant.
67
69
  darks_multiplier: float,int
68
70
  A multiplier to apply to darks, can work as an intensity compensation constant.
69
- cutoff : float,int
70
- Permitted maximum value for the normalised data.
71
+ upper_bound : Optional[float, int]
72
+ All values above the upper bound are set to the provided value. Default None.
73
+ lower_bound : Optional[float, int]
74
+ All values bellow the lower bound are set to the provided value. Default None.
71
75
 
72
76
  Returns
73
77
  -------
@@ -92,10 +96,21 @@ def dark_flat_field_correction(
92
96
  __check_variable_type(
93
97
  darks_multiplier, [int, float], "darks_multiplier", [], methods_name
94
98
  )
95
- __check_variable_type(cutoff, [int, float], "cutoff", [], methods_name)
96
- ###################################
99
+ __check_variable_type(
100
+ upper_bound, [int, float, type(None)], "upper_bound", [], methods_name
101
+ )
102
+ __check_variable_type(
103
+ lower_bound, [int, float, type(None)], "lower_bound", [], methods_name
104
+ )
97
105
 
98
106
  _check_valid_input_flats_darks(flats, darks)
107
+ ###################################
108
+
109
+ data_elements_num = int(np.prod(data.shape))
110
+ if upper_bound is None:
111
+ upper_bound = 1e12
112
+ if lower_bound is None:
113
+ lower_bound = -1e12
99
114
 
100
115
  dark0 = cp.empty(darks.shape[1:], dtype=float32)
101
116
  flat0 = cp.empty(flats.shape[1:], dtype=float32)
@@ -114,12 +129,12 @@ def dark_flat_field_correction(
114
129
  }
115
130
  float v = (float(data) - float(darks))/denom;
116
131
  """
117
- kernel += "if (v > cutoff) v = cutoff;\n"
118
- kernel += "if (v < -cutoff) v = cutoff;\n"
132
+ kernel += "if (v > upper_bound) v = upper_bound;\n"
133
+ kernel += "if (v <= lower_bound) v = lower_bound;\n"
119
134
  kernel += "out = v;\n"
120
135
 
121
136
  normalisation_kernel = cp.ElementwiseKernel(
122
- "T data, U flats, U darks, raw float32 cutoff",
137
+ "T data, U flats, U darks, raw float32 upper_bound, raw float32 lower_bound",
123
138
  "float32 out",
124
139
  kernel,
125
140
  kernel_name,
@@ -128,7 +143,52 @@ def dark_flat_field_correction(
128
143
  no_return=True,
129
144
  )
130
145
 
131
- normalisation_kernel(data, flat0, dark0, float32(cutoff), out)
146
+ count_greater_kernel = cp.ReductionKernel(
147
+ in_params="T data, raw float32 upper_bound",
148
+ out_params="int32 out",
149
+ map_expr="data >= upper_bound ? 1 : 0", # map each element → 1 or 0
150
+ reduce_expr="a + b", # sum them
151
+ post_map_expr="out = a", # final result
152
+ identity="0",
153
+ name="count_greater",
154
+ )
155
+
156
+ count_smaller_kernel = cp.ReductionKernel(
157
+ in_params="T data, raw float32 lower_bound",
158
+ out_params="int32 out",
159
+ map_expr="data <= lower_bound ? 1 : 0", # map each element → 1 or 0
160
+ reduce_expr="a + b", # sum them
161
+ post_map_expr="out = a", # final result
162
+ identity="0",
163
+ name="count_smaller",
164
+ )
165
+
166
+ normalisation_kernel(data, flat0, dark0, upper_bound, lower_bound, out)
167
+
168
+ # Count the amount of clipping and raise warnings if required
169
+ clipped_percentage_warning = (
170
+ 50.0 # warning if more clipped values than given percentage
171
+ )
172
+
173
+ clipped_total_up = int(count_greater_kernel(out, float32(upper_bound)))
174
+ clipped_up_percent = clipped_total_up / data_elements_num * 100
175
+
176
+ if clipped_up_percent >= clipped_percentage_warning:
177
+ print(
178
+ "Warning! The output data of 'dark_flat_field_correction' method contains \033[31m{}\033[0m percent of 'upper_bound' clipped data.".format(
179
+ int(clipped_up_percent)
180
+ )
181
+ )
182
+
183
+ clipped_total_lower = int(count_smaller_kernel(out, float32(lower_bound)))
184
+ clipped_down_percent = clipped_total_lower / data_elements_num * 100
185
+
186
+ if clipped_down_percent >= clipped_percentage_warning:
187
+ print(
188
+ "Warning! The output data of 'dark_flat_field_correction' method contains \033[31m{}\033[0m percent of 'lower_bound' clipped data.".format(
189
+ int(clipped_down_percent)
190
+ )
191
+ )
132
192
 
133
193
  return out
134
194
 
@@ -56,6 +56,7 @@ __all__ = [
56
56
  "CGLS3d_tomobar",
57
57
  "FISTA3d_tomobar",
58
58
  "ADMM3d_tomobar",
59
+ "OSEM3d_tomobar",
59
60
  ]
60
61
 
61
62
  input_data_axis_labels = ["angles", "detY", "detX"] # set the labels of the input data
@@ -126,7 +127,18 @@ def FBP2d_astra(
126
127
  filter_type,
127
128
  [str],
128
129
  "filter_type",
129
- ["none", "ram-lak", "shepp-logan", "tukey", "gaussian", "blackman", "kaiser"],
130
+ [
131
+ "none",
132
+ "ram-lak",
133
+ "cosine",
134
+ "shepp-logan",
135
+ "tukey",
136
+ "gaussian",
137
+ "blackman",
138
+ "kaiser",
139
+ "lanczos",
140
+ "hann",
141
+ ],
130
142
  methods_name,
131
143
  )
132
144
  __check_variable_type(
@@ -552,7 +564,7 @@ def FISTA3d_tomobar(
552
564
  subsets_number: int
553
565
  The number of the ordered subsets to accelerate convergence. Keep the value bellow 10 to avoid divergence.
554
566
  data_fidelity: str
555
- Data fidelity given as 'LS' (Least Squares), 'PWLS' (Penalised Weightes LS).
567
+ Data fidelity given as 'LS' (Least Squares)
556
568
  regularisation_type: str
557
569
  A method to use for regularisation. Currently PD_TV and ROF_TV are available.
558
570
  regularisation_parameter: float
@@ -644,7 +656,7 @@ def ADMM3d_tomobar(
644
656
  initialisation: Literal["FBP", "CGLS", "SIRT", None] = "FBP",
645
657
  ADMM_rho_const: float = 1.0,
646
658
  ADMM_relax_par: float = 1.7,
647
- regularisation_type: str = "PD_TV",
659
+ regularisation_type: Literal["ROF_TV", "PD_TV"] = "PD_TV",
648
660
  regularisation_parameter: float = 0.0025,
649
661
  regularisation_iterations: int = 40,
650
662
  regularisation_half_precision: bool = True,
@@ -679,7 +691,7 @@ def ADMM3d_tomobar(
679
691
  subsets_number: int
680
692
  The number of the ordered subsets to accelerate convergence. The recommended range is between 12 to 24.
681
693
  data_fidelity: str
682
- Data fidelity given as 'LS' (Least Squares), 'PWLS' (Penalised Weightes LS).
694
+ Data fidelity given as 'LS' (Least Squares)
683
695
  initialisation: str, optional
684
696
  Initialise ADMM with the reconstructed image to reduce the number of iterations and accelerate. Choose between 'CGLS' or 'SIRT' when data
685
697
  is noisy and/or undersampled. Choose 'FBP' when the data is of better quality (default) or None.
@@ -835,6 +847,125 @@ def ADMM3d_tomobar(
835
847
  return cp.require(cp.swapaxes(reconstruction, 0, 1), requirements="C")
836
848
 
837
849
 
850
+ ## %%%%%%%%%%%%%%%%%%%%%%% OSEM reconstruction %%%%%%%%%%%%%%%%%%%%%%%%%%%% ##
851
+ def OSEM3d_tomobar(
852
+ data: cp.ndarray,
853
+ angles: np.ndarray,
854
+ center: Optional[float] = None,
855
+ detector_pad: Union[bool, int] = False,
856
+ recon_size: Optional[int] = None,
857
+ recon_mask_radius: Optional[float] = 0.95,
858
+ iterations: int = 20,
859
+ subsets_number: int = 12,
860
+ regularisation_type: Literal["ROF_TV", "PD_TV"] = "PD_TV",
861
+ regularisation_parameter: float = 1.0,
862
+ regularisation_iterations: int = 30,
863
+ regularisation_half_precision: bool = True,
864
+ nonnegativity: bool = True,
865
+ gpu_id: int = 0,
866
+ ) -> cp.ndarray:
867
+ """
868
+ Ordered-Subsets Expectation-Maximisation method is the accelerated Maximum Likelihood Expectation-Maximisation (MLEM) algorithm.
869
+ Can be coupled with various types of regularisation or denoising operations :cite:`kazantsev2019ccpi` (currently accepts ROF_TV and PD_TV regularisations only).
870
+ Should be applied to reconstruct emission-type measurements, e.g., XRF tomography measurements.
871
+
872
+ Parameters
873
+ ----------
874
+ data : cp.ndarray
875
+ Projection data as a CuPy array.
876
+ angles : np.ndarray
877
+ An array of angles given in radians.
878
+ center : float, optional
879
+ The center of rotation (CoR).
880
+ detector_pad : bool, int
881
+ Detector width padding with edge values to remove circle/arc type artifacts in the reconstruction. Set to True to perform
882
+ an automated padding or specify a certain value as an integer.
883
+ recon_size : int, optional
884
+ The squared size of the reconstructed slice. By default (None), the reconstructed size will be the dimension of the horizontal detector.
885
+ recon_mask_radius: float, optional
886
+ The radius of the circular mask that applies to the reconstructed slice in order to crop
887
+ out some undesirable artifacts. The values outside the given diameter will be set to zero.
888
+ To implement the cropping one can use the range [0.7-1.0] or set to None (2.0) when no cropping is needed.
889
+ iterations : int
890
+ The number of OSEM algorithm iterations. For OS method 20 interations is normally sufficient, while for MLEM one should run 300-500 iterations.
891
+ subsets_number: int
892
+ The number of the ordered subsets to accelerate convergence. One can set 'subsets_number' to 1 to achieve MLEM, but the number of 'iterations' should be also increased.
893
+ data_fidelity: str
894
+ Data fidelity given as 'LS' (Least Squares)
895
+ regularisation_type: str
896
+ A method to use for regularisation. Currently PD_TV and ROF_TV are available.
897
+ regularisation_parameter: float
898
+ The main regularisation parameter to control the amount of smoothing/noise removal. Larger values lead to stronger smoothing.
899
+ regularisation_iterations: int
900
+ The number of iterations for regularisers (aka INNER iterations).
901
+ regularisation_half_precision: bool
902
+ Perform faster regularisation computation in half-precision with a very minimal sacrifice in quality.
903
+ nonnegativity : bool
904
+ Impose nonnegativity constraint on the reconstructed image.
905
+ gpu_id : int
906
+ A GPU device index to perform operation on.
907
+
908
+ Returns
909
+ -------
910
+ cp.ndarray
911
+ The OSEM reconstructed volume as a CuPy array.
912
+ """
913
+ ### Data and parameters checks ###
914
+ methods_name = "OSEM3d_tomobar"
915
+ __common_data_parameters_check(
916
+ data,
917
+ angles,
918
+ methods_name,
919
+ center,
920
+ detector_pad,
921
+ recon_size,
922
+ recon_mask_radius,
923
+ gpu_id,
924
+ )
925
+ __common_iterative_basic_parameters_check(methods_name, iterations, nonnegativity)
926
+ __common_iterative_parameters_check(
927
+ methods_name,
928
+ subsets_number,
929
+ regularisation_type,
930
+ regularisation_parameter,
931
+ regularisation_iterations,
932
+ regularisation_half_precision,
933
+ )
934
+ ###################################
935
+
936
+ RecToolsCP = _instantiate_iterative_recon_class(
937
+ data,
938
+ angles,
939
+ center,
940
+ detector_pad,
941
+ recon_size,
942
+ subsets_number,
943
+ gpu_id,
944
+ )
945
+
946
+ _data_ = {
947
+ "projection_data": data,
948
+ "data_axes_labels_order": input_data_axis_labels,
949
+ }
950
+
951
+ _algorithm_ = {
952
+ "iterations": iterations,
953
+ "nonnegativity": nonnegativity,
954
+ "recon_mask_radius": recon_mask_radius,
955
+ }
956
+
957
+ _regularisation_ = {
958
+ "method": regularisation_type, # Selected regularisation method
959
+ "regul_param": regularisation_parameter, # Regularisation parameter
960
+ "iterations": regularisation_iterations, # The number of regularisation iterations
961
+ "half_precision": regularisation_half_precision, # enabling half-precision calculation
962
+ }
963
+
964
+ reconstruction = RecToolsCP.OSEM(_data_, _algorithm_, _regularisation_)
965
+ cp._default_memory_pool.free_all_blocks()
966
+ return cp.require(cp.swapaxes(reconstruction, 0, 1), requirements="C")
967
+
968
+
838
969
  ## %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ##
839
970
  def _instantiate_direct_recon_class(
840
971
  data: cp.ndarray | Tuple[int, int, int],
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: httomolibgpu
3
- Version: 5.5.1
3
+ Version: 5.7
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
File without changes
File without changes
File without changes
File without changes
File without changes