@@ -74,6 +74,8 @@ def paganin_filter(
7474 Beam energy in keV.
7575 ratio_delta_beta : float
7676 The ratio of delta/beta, where delta is the phase shift and real part of the complex material refractive index and beta is the absorption.
77+ calc_peak_gpu_mem: bool
78+ Parameter to support memory estimation in HTTomo. Irrelevant to the method itself and can be ignored by user.
7779
7880 Returns
7981 -------
@@ -125,24 +127,33 @@ def paganin_filter(
125127 indy = _reciprocal_coord (pixel_size , dx )
126128
127129 if mem_stack :
128- mem_stack .malloc (indx .size * indx .dtype .itemsize ) # cp.asarray(indx)
129- mem_stack .malloc (indx .size * indx .dtype .itemsize ) # cp.square
130- mem_stack .free (indx .size * indx .dtype .itemsize ) # cp.asarray(indx)
130+ mem_stack .malloc (indx .size * indx .dtype .itemsize ) # cp.asarray(indx)
131+ mem_stack .malloc (indx .size * indx .dtype .itemsize ) # cp.square
132+ mem_stack .free (indx .size * indx .dtype .itemsize ) # cp.asarray(indx)
131133 mem_stack .malloc (indy .size * indy .dtype .itemsize ) # cp.asarray(indy)
132- mem_stack .malloc (indy .size * indy .dtype .itemsize ) # cp.square
134+ mem_stack .malloc (indy .size * indy .dtype .itemsize ) # cp.square
133135 mem_stack .free (indy .size * indy .dtype .itemsize ) # cp.asarray(indy)
134136
135- mem_stack .malloc (indx .size * indy .size * indx .dtype .itemsize ) # cp.add.outer
136- mem_stack .free (indx .size * indx .dtype .itemsize ) # cp.square
137- mem_stack .free (indy .size * indy .dtype .itemsize ) # cp.square
138- mem_stack .malloc (indx .size * indy .size * indx .dtype .itemsize ) # phase_filter
139- mem_stack .free (indx .size * indy .size * indx .dtype .itemsize ) # cp.add.outer
140- mem_stack .free (indx .size * indy .size * indx .dtype .itemsize ) # phase_filter
137+ mem_stack .malloc (indx .size * indy .size * indx .dtype .itemsize ) # cp.add.outer
138+ mem_stack .free (indx .size * indx .dtype .itemsize ) # cp.square
139+ mem_stack .free (indy .size * indy .dtype .itemsize ) # cp.square
140+ mem_stack .malloc (indx .size * indy .size * indx .dtype .itemsize ) # phase_filter
141+ mem_stack .free (indx .size * indy .size * indx .dtype .itemsize ) # cp.add.outer
142+ mem_stack .free (indx .size * indy .size * indx .dtype .itemsize ) # phase_filter
141143
142144 else :
143145 # Build Lorentzian-type filter
144146 phase_filter = fftshift (
145- 1.0 / (1.0 + alpha * (cp .add .outer (cp .square (cp .asarray (indx )), cp .square (cp .asarray (indy )))))
147+ 1.0
148+ / (
149+ 1.0
150+ + alpha
151+ * (
152+ cp .add .outer (
153+ cp .square (cp .asarray (indx )), cp .square (cp .asarray (indy ))
154+ )
155+ )
156+ )
146157 )
147158
148159 phase_filter = phase_filter / phase_filter .max () # normalisation
@@ -152,15 +163,17 @@ def paganin_filter(
152163 del phase_filter
153164
154165 # Apply filter and take inverse FFT
155- ifft_input = fft_tomo if not mem_stack else cp .empty (padded_tomo , dtype = cp .complex64 )
166+ ifft_input = (
167+ fft_tomo if not mem_stack else cp .empty (padded_tomo , dtype = cp .complex64 )
168+ )
156169 ifft_plan = get_fft_plan (ifft_input , axes = (- 2 , - 1 ))
157170 if mem_stack :
158171 mem_stack .malloc (ifft_plan .work_area .mem .size )
159172 mem_stack .free (ifft_plan .work_area .mem .size )
160173 else :
161174 with ifft_plan :
162175 ifft_filtered_tomo = ifft2 (fft_tomo , axes = (- 2 , - 1 ), overwrite_x = True ).real
163- del fft_tomo
176+ del fft_tomo
164177 del ifft_plan
165178 del ifft_input
166179
@@ -172,9 +185,13 @@ def paganin_filter(
172185 )
173186
174187 if mem_stack :
175- mem_stack .malloc (np .prod (tomo ) * np .float32 ().itemsize ) # astype(cp.float32)
176- mem_stack .free (np .prod (padded_tomo ) * np .complex64 ().itemsize ) # ifft_filtered_tomo
177- mem_stack .malloc (np .prod (tomo ) * np .float32 ().itemsize ) # return _log_kernel(tomo)
188+ mem_stack .malloc (np .prod (tomo ) * np .float32 ().itemsize ) # astype(cp.float32)
189+ mem_stack .free (
190+ np .prod (padded_tomo ) * np .complex64 ().itemsize
191+ ) # ifft_filtered_tomo
192+ mem_stack .malloc (
193+ np .prod (tomo ) * np .float32 ().itemsize
194+ ) # return _log_kernel(tomo)
178195 return mem_stack .highwater
179196
180197 # crop the padded filtered data:
@@ -232,8 +249,7 @@ def _calculate_pad_size(datashape: tuple) -> list:
232249
233250
234251def _pad_projections_to_second_power (
235- tomo : cp .ndarray ,
236- mem_stack : Optional [_DeviceMemStack ]
252+ tomo : cp .ndarray , mem_stack : Optional [_DeviceMemStack ]
237253) -> Tuple [cp .ndarray , Tuple [int , int ]]:
238254 """
239255 Performs padding of each projection to the next power of 2.
@@ -255,7 +271,9 @@ def _pad_projections_to_second_power(
255271 pad_list = _calculate_pad_size (full_shape_tomo )
256272
257273 if mem_stack :
258- padded_tomo = [sh + pad [0 ] + pad [1 ] for sh , pad in zip (full_shape_tomo , pad_list )]
274+ padded_tomo = [
275+ sh + pad [0 ] + pad [1 ] for sh , pad in zip (full_shape_tomo , pad_list )
276+ ]
259277 mem_stack .malloc (np .prod (padded_tomo ) * np .float32 ().itemsize )
260278 else :
261279 padded_tomo = cp .pad (tomo , tuple (pad_list ), "edge" )
@@ -317,11 +335,20 @@ def paganin_filter_savu_legacy(
317335 Beam energy in keV.
318336 ratio_delta_beta : float
319337 The ratio of delta/beta, where delta is the phase shift and real part of the complex material refractive index and beta is the absorption.
338+ calc_peak_gpu_mem: bool
339+ Parameter to support memory estimation in HTTomo. Irrelevant to the method itself and can be ignored by user.
320340
321341 Returns
322342 -------
323343 cp.ndarray
324344 The 3D array of Paganin phase-filtered projection images.
325345 """
326346
327- return paganin_filter (tomo , pixel_size , distance , energy , ratio_delta_beta / 4 , calc_peak_gpu_mem = calc_peak_gpu_mem )
347+ return paganin_filter (
348+ tomo ,
349+ pixel_size ,
350+ distance ,
351+ energy ,
352+ ratio_delta_beta / 4 ,
353+ calc_peak_gpu_mem = calc_peak_gpu_mem ,
354+ )
0 commit comments