httomolibgpu 5.6__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.6/httomolibgpu.egg-info → httomolibgpu-5.7}/PKG-INFO +1 -1
  2. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/misc/denoise.py +3 -1
  3. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/misc/morph.py +52 -21
  4. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/recon/algorithm.py +135 -4
  5. {httomolibgpu-5.6 → httomolibgpu-5.7/httomolibgpu.egg-info}/PKG-INFO +1 -1
  6. {httomolibgpu-5.6 → httomolibgpu-5.7}/LICENSE +0 -0
  7. {httomolibgpu-5.6 → httomolibgpu-5.7}/MANIFEST.in +0 -0
  8. {httomolibgpu-5.6 → httomolibgpu-5.7}/README.rst +0 -0
  9. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/__init__.py +0 -0
  10. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/cuda_kernels/__init__.py +0 -0
  11. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/cuda_kernels/calc_metrics.cu +0 -0
  12. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/cuda_kernels/center_360_shifts.cu +0 -0
  13. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/cuda_kernels/generate_mask.cu +0 -0
  14. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/cuda_kernels/median_kernel.cu +0 -0
  15. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/cuda_kernels/raven_filter.cu +0 -0
  16. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/cuda_kernels/remove_nan_inf.cu +0 -0
  17. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/cuda_kernels/remove_stripe_fw.cu +0 -0
  18. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/cupywrapper.py +0 -0
  19. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/misc/__init__.py +0 -0
  20. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/misc/corr.py +0 -0
  21. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/misc/rescale.py +0 -0
  22. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/misc/utils.py +0 -0
  23. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/prep/__init__.py +0 -0
  24. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/prep/alignment.py +0 -0
  25. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/prep/normalize.py +0 -0
  26. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/prep/phase.py +0 -0
  27. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/prep/stripe.py +0 -0
  28. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/recon/__init__.py +0 -0
  29. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/recon/_phase_cross_correlation.py +0 -0
  30. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu/recon/rotation.py +0 -0
  31. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu.egg-info/SOURCES.txt +0 -0
  32. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu.egg-info/dependency_links.txt +0 -0
  33. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu.egg-info/requires.txt +0 -0
  34. {httomolibgpu-5.6 → httomolibgpu-5.7}/httomolibgpu.egg-info/top_level.txt +0 -0
  35. {httomolibgpu-5.6 → httomolibgpu-5.7}/pyproject.toml +0 -0
  36. {httomolibgpu-5.6 → httomolibgpu-5.7}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: httomolibgpu
3
- Version: 5.6
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
  )
@@ -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.6
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