diff --git a/.github/workflows/httomolibgpu_pypi_publish.yml b/.github/workflows/httomolibgpu_pypi_publish.yml new file mode 100644 index 00000000..ce5f8d81 --- /dev/null +++ b/.github/workflows/httomolibgpu_pypi_publish.yml @@ -0,0 +1,31 @@ +name: Upload Python Package to PyPI when Release is Created + +on: + release: + types: [created] + +jobs: + pypi-publish: + name: Publish release to PyPI + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/httomolibgpu + permissions: + id-token: write + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.10" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install setuptools wheel + pip install --upgrade build + - name: Build package + run: | + python -m build + - name: Publish package distributions to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/conda/environment.yml b/conda/environment.yml index e5d9c904..f6f408f6 100644 --- a/conda/environment.yml +++ b/conda/environment.yml @@ -4,7 +4,7 @@ channels: - httomo dependencies: - conda-forge::cupy=12.3.0 - - conda-forge::numpy<=1.25 + - conda-forge::numpy - conda-forge::nvtx - conda-forge::scipy - conda-forge::python diff --git a/httomolibgpu/cupywrapper.py b/httomolibgpu/cupywrapper.py index c01c28f5..48d25e02 100644 --- a/httomolibgpu/cupywrapper.py +++ b/httomolibgpu/cupywrapper.py @@ -1,8 +1,6 @@ -cupy_run = False try: import cupy as cp import nvtx - import cupyx try: cp.cuda.Device(0).compute_capability @@ -17,5 +15,6 @@ from unittest.mock import Mock import numpy as cp + cupy_run = False + nvtx = Mock() - cupyx = Mock() diff --git a/httomolibgpu/misc/corr.py b/httomolibgpu/misc/corr.py index 91775610..b2c58845 100644 --- a/httomolibgpu/misc/corr.py +++ b/httomolibgpu/misc/corr.py @@ -28,10 +28,16 @@ from httomolibgpu import cupywrapper cp = cupywrapper.cp -nvtx = cupywrapper.nvtx +cupy_run = cupywrapper.cupy_run from numpy import float32 -from httomolibgpu.cuda_kernels import load_cuda_module +from unittest.mock import Mock + +if cupy_run: + from httomolibgpu.cuda_kernels import load_cuda_module +else: + load_cuda_module = Mock() + __all__ = [ "median_filter", @@ -67,19 +73,6 @@ def median_filter( ValueError If the input array is not three dimensional. """ - if cupywrapper.cupy_run: - return __median_filter(data, kernel_size, dif) - else: - print("median_filter won't be executed because CuPy is not installed") - return data - - -@nvtx.annotate() -def __median_filter( - data: cp.ndarray, - kernel_size: int = 3, - dif: float = 0.0, -) -> cp.ndarray: input_type = data.dtype if input_type not in ["float32", "uint16"]: @@ -148,8 +141,4 @@ def remove_outlier( if dif <= 0.0: raise ValueError("Threshold value (dif) must be positive and nonzero.") - if cupywrapper.cupy_run: - return __median_filter(data, kernel_size, dif) - else: - print("remove_outlier won't be executed because CuPy is not installed") - return data + return median_filter(data, kernel_size, dif) diff --git a/httomolibgpu/misc/morph.py b/httomolibgpu/misc/morph.py index 081bf4f0..422290f9 100644 --- a/httomolibgpu/misc/morph.py +++ b/httomolibgpu/misc/morph.py @@ -24,10 +24,14 @@ from httomolibgpu import cupywrapper cp = cupywrapper.cp -nvtx = cupywrapper.nvtx -cupyx = cupywrapper.cupyx +cupy_run = cupywrapper.cupy_run -from cupyx.scipy.interpolate import interpn +from unittest.mock import Mock + +if cupy_run: + from cupyx.scipy.interpolate import interpn +else: + interpn = Mock() from typing import Literal @@ -59,17 +63,6 @@ def sino_360_to_180( cp.ndarray Output 3D data. """ - if cupywrapper.cupy_run: - return __sino_360_to_180(data, overlap, rotation) - else: - print("sino_360_to_180 won't be executed because CuPy is not installed") - return data - - -@nvtx.annotate() -def __sino_360_to_180( - data: cp.ndarray, overlap: int = 0, rotation: Literal["left", "right"] = "left" -) -> cp.ndarray: if data.ndim != 3: raise ValueError("only 3D data is supported") @@ -80,8 +73,8 @@ def __sino_360_to_180( raise ValueError("overlap must be less than data.shape[2]") if overlap < 0: raise ValueError("only positive overlaps are allowed.") - - if rotation not in ['left', 'right']: + + if rotation not in ["left", "right"]: raise ValueError('rotation parameter must be either "left" or "right"') n = dx // 2 @@ -128,18 +121,6 @@ def data_resampler( Returns: cp.ndarray: Up/Down-scaled 3D cupy array """ - if cupywrapper.cupy_run: - return __data_resampler(data, newshape, axis, interpolation) - else: - print("data_resampler won't be executed because CuPy is not installed") - return data - - -@nvtx.annotate() -def __data_resampler( - data: cp.ndarray, newshape: list, axis: int = 1, interpolation: str = "linear" -) -> cp.ndarray: - if data.ndim != 3: raise ValueError("only 3D data is supported") diff --git a/httomolibgpu/misc/rescale.py b/httomolibgpu/misc/rescale.py index 4a38913f..5c4af6f4 100644 --- a/httomolibgpu/misc/rescale.py +++ b/httomolibgpu/misc/rescale.py @@ -24,7 +24,6 @@ cp = cupywrapper.cp -nvtx = cupywrapper.nvtx from typing import Literal, Optional, Tuple, Union __all__ = [ @@ -70,53 +69,6 @@ def rescale_to_int( The original data, clipped to the range specified with the perc_range_min and perc_range_max, and scaled to the full range of the output integer type """ - if cupywrapper.cupy_run: - return __rescale_to_int(data, perc_range_min, perc_range_max, bits, glob_stats) - else: - print("rescale_to_int won't be executed because CuPy is not installed") - return data - - -@nvtx.annotate() -def __rescale_to_int( - data: cp.ndarray, - perc_range_min: float = 0.0, - perc_range_max: float = 100.0, - bits: Literal[8, 16, 32] = 8, - glob_stats: Optional[Tuple[float, float, float, int]] = None, -): - """ - Rescales the data and converts it fit into the range of an unsigned integer type - with the given number of bits. - - Parameters - ---------- - data : cp.ndarray - Required input data array, on GPU - perc_range_min: float, optional - The lower cutoff point in the input data, in percent of the data range (defaults to 0). - The lower bound is computed as min + perc_range_min/100*(max-min) - perc_range_max: float, optional - The upper cutoff point in the input data, in percent of the data range (defaults to 100). - The upper bound is computed as min + perc_range_max/100*(max-min) - bits: Literal[8, 16, 32], optional - The number of bits in the output integer range (defaults to 8). - Allowed values are: - - 8 -> uint8 - - 16 -> uint16 - - 32 -> uint32 - glob_stats: tuple, optional - Global statistics of the full dataset (beyond the data passed into this call). - It's a tuple with (min, max, sum, num_items). If not given, the min/max is - computed from the given data. - - Returns - ------- - cp.ndarray - The original data, clipped to the range specified with the perc_range_min and - perc_range_max, and scaled to the full range of the output integer type - """ - if bits == 8: output_dtype: Union[type[np.uint8], type[np.uint16], type[np.uint32]] = np.uint8 elif bits == 16: diff --git a/httomolibgpu/prep/alignment.py b/httomolibgpu/prep/alignment.py index 30a725c3..85be8cd4 100644 --- a/httomolibgpu/prep/alignment.py +++ b/httomolibgpu/prep/alignment.py @@ -24,10 +24,14 @@ from httomolibgpu import cupywrapper cp = cupywrapper.cp -nvtx = cupywrapper.nvtx -cupyx = cupywrapper.cupyx +cupy_run = cupywrapper.cupy_run -from cupyx.scipy.ndimage import map_coordinates +from unittest.mock import Mock + +if cupy_run: + from cupyx.scipy.ndimage import map_coordinates +else: + map_coordinates = Mock() from typing import Dict, List @@ -77,55 +81,6 @@ def distortion_correction_proj_discorpy( cp.ndarray 3D array. Distortion-corrected array. """ - if cupywrapper.cupy_run: - return __distortion_correction_proj_discorpy( - data, metadata_path, preview, order, mode - ) - else: - print( - "distortion_correction_proj_discorpy won't be executed because CuPy is not installed" - ) - return data - - -@nvtx.annotate() -def __distortion_correction_proj_discorpy( - data: cp.ndarray, - metadata_path: str, - preview: Dict[str, List[int]], - order: int = 1, - mode: str = "reflect", -): - """Unwarp a stack of images using a backward model. - - Parameters - ---------- - data : cp.ndarray - 3D array. - - metadata_path : str - The path to the file containing the distortion coefficients for the - data. - - preview : Dict[str, List[int]] - A dict containing three key-value pairs: - - a list containing the `start` value of each dimension - - a list containing the `stop` value of each dimension - - a list containing the `step` value of each dimension - - order : int, optional. - The order of the spline interpolation. - - mode : {'reflect', 'grid-mirror', 'constant', 'grid-constant', 'nearest', - 'mirror', 'grid-wrap', 'wrap'}, optional - To determine how to handle image boundaries. - - Returns - ------- - cp.ndarray - 3D array. Distortion-corrected image(s). - """ - # Check if it's a stack of 2D images, or only a single 2D image if len(data.shape) == 2: data = cp.expand_dims(data, axis=0) diff --git a/httomolibgpu/prep/normalize.py b/httomolibgpu/prep/normalize.py index 449f0962..08b9dde8 100644 --- a/httomolibgpu/prep/normalize.py +++ b/httomolibgpu/prep/normalize.py @@ -24,9 +24,14 @@ from httomolibgpu import cupywrapper cp = cupywrapper.cp -nvtx = cupywrapper.nvtx +cupy_run = cupywrapper.cupy_run -from cupy import mean +from unittest.mock import Mock + +if cupy_run: + from cupy import mean +else: + mean = Mock() from numpy import float32 from typing import Tuple @@ -69,26 +74,6 @@ def normalize( cp.ndarray Normalised 3D tomographic data as a CuPy array. """ - if cupywrapper.cupy_run: - return __normalize( - data, flats, darks, cutoff, minus_log, nonnegativity, remove_nans - ) - else: - print("normalize won't be executed because CuPy is not installed") - return data - - -@nvtx.annotate() -def __normalize( - data: cp.ndarray, - flats: cp.ndarray, - darks: cp.ndarray, - cutoff: float = 10.0, - minus_log: bool = True, - nonnegativity: bool = False, - remove_nans: bool = True, -) -> cp.ndarray: - _check_valid_input(data, flats, darks) dark0 = cp.empty(darks.shape[1:], dtype=float32) diff --git a/httomolibgpu/prep/phase.py b/httomolibgpu/prep/phase.py index 2696687e..a191bda5 100644 --- a/httomolibgpu/prep/phase.py +++ b/httomolibgpu/prep/phase.py @@ -24,10 +24,18 @@ from httomolibgpu import cupywrapper cp = cupywrapper.cp -nvtx = cupywrapper.nvtx +cupy_run = cupywrapper.cupy_run -from httomolibgpu.cuda_kernels import load_cuda_module -from cupyx.scipy.fft import fft2, ifft2, fftshift +from unittest.mock import Mock + +if cupy_run: + from httomolibgpu.cuda_kernels import load_cuda_module + from cupyx.scipy.fft import fft2, ifft2, fftshift +else: + load_cuda_module = Mock() + fft2 = Mock() + ifft2 = Mock() + fftshift = Mock() from numpy import float32 from typing import Union @@ -90,36 +98,6 @@ def paganin_filter_savu( cp.ndarray The stack of filtered projections. """ - if cupywrapper.cupy_run: - return __paganin_filter_savu( - data, - ratio, - energy, - distance, - resolution, - pad_y, - pad_x, - pad_method, - increment, - ) - else: - print("__paganin_filter_savu won't be executed because CuPy is not installed") - return data - - -@nvtx.annotate() -def __paganin_filter_savu( - data: cp.ndarray, - ratio: float = 250.0, - energy: float = 53.0, - distance: float = 1.0, - resolution: float = 1.28, - pad_y: int = 100, - pad_x: int = 100, - pad_method: str = "edge", - increment: float = 0.0, -) -> cp.ndarray: - # Check the input data is valid if data.ndim != 3: raise ValueError( @@ -313,22 +291,6 @@ def paganin_filter_tomopy( cp.ndarray The 3D array of Paganin phase-filtered projection images. """ - if cupywrapper.cupy_run: - return __paganin_filter_tomopy(tomo, pixel_size, dist, energy, alpha) - else: - print("paganin_filter_tomopy won't be executed because CuPy is not installed") - return tomo - - -@nvtx.annotate() -def __paganin_filter_tomopy( - tomo: cp.ndarray, - pixel_size: float = 1e-4, - dist: float = 50.0, - energy: float = 53.0, - alpha: float = 1e-3, -) -> cp.ndarray: - # Check the input data is valid if tomo.ndim != 3: raise ValueError( diff --git a/httomolibgpu/prep/stripe.py b/httomolibgpu/prep/stripe.py index fe6afae6..22a838e6 100644 --- a/httomolibgpu/prep/stripe.py +++ b/httomolibgpu/prep/stripe.py @@ -24,9 +24,16 @@ from httomolibgpu import cupywrapper cp = cupywrapper.cp -nvtx = cupywrapper.nvtx +cupy_run = cupywrapper.cupy_run -from cupyx.scipy.ndimage import median_filter, binary_dilation, uniform_filter1d +from unittest.mock import Mock + +if cupy_run: + from cupyx.scipy.ndimage import median_filter, binary_dilation, uniform_filter1d +else: + median_filter = Mock() + binary_dilation = Mock() + uniform_filter1d = Mock() from typing import Union @@ -66,21 +73,6 @@ def remove_stripe_based_sorting( Corrected 3D tomographic data as a CuPy or NumPy array. """ - if cupywrapper.cupy_run: - return __remove_stripe_based_sorting(data, size, dim) - else: - print( - "remove_stripe_based_sorting won't be executed because CuPy is not installed" - ) - return data - - -@nvtx.annotate() -def __remove_stripe_based_sorting( - data: Union[cp.ndarray, np.ndarray], - size: int = 11, - dim: int = 1, -) -> Union[cp.ndarray, np.ndarray]: if size is None: if data.shape[2] > 2000: size = 21 @@ -93,7 +85,6 @@ def __remove_stripe_based_sorting( return data -@nvtx.annotate() def _rs_sort(sinogram, size, dim): """ Remove stripes using the sorting technique. @@ -136,18 +127,6 @@ def remove_stripe_ti( ndarray 3D array of de-striped projections. """ - if cupywrapper.cupy_run: - return __remove_stripe_ti(data, beta) - else: - print("remove_stripe_ti won't be executed because CuPy is not installed") - return data - - -@nvtx.annotate() -def __remove_stripe_ti( - data: Union[cp.ndarray, np.ndarray], - beta: float = 0.1, -) -> Union[cp.ndarray, np.ndarray]: # TODO: detector dimensions must be even otherwise error gamma = beta * ((1 - beta) / (1 + beta)) ** cp.abs( cp.fft.fftfreq(data.shape[-1]) * data.shape[-1] @@ -215,21 +194,6 @@ def remove_all_stripe( Corrected 3D tomographic data as a CuPy or NumPy array. """ - if cupywrapper.cupy_run: - return __remove_all_stripe(data, snr, la_size, sm_size, dim) - else: - print("remove_all_stripe won't be executed because CuPy is not installed") - return data - - -@nvtx.annotate() -def __remove_all_stripe( - data: cp.ndarray, - snr: float = 3.0, - la_size: int = 61, - sm_size: int = 21, - dim: int = 1, -) -> cp.ndarray: matindex = _create_matindex(data.shape[2], data.shape[0]) for m in range(data.shape[1]): sino = data[:, m, :] @@ -240,7 +204,6 @@ def __remove_all_stripe( return data -@nvtx.annotate() def _rs_sort2(sinogram, size, matindex, dim): """ Remove stripes using the sorting technique. @@ -269,7 +232,6 @@ def _rs_sort2(sinogram, size, matindex, dim): return cp.transpose(sino_corrected) -@nvtx.annotate() def _mpolyfit(x, y): n = len(x) x_mean = cp.mean(x) @@ -283,7 +245,6 @@ def _mpolyfit(x, y): return slope, intercept -@nvtx.annotate() def _detect_stripe(listdata, snr): """ Algorithm 4 in :cite:`Vo:18`. Used to locate stripes. @@ -314,7 +275,6 @@ def _detect_stripe(listdata, snr): return listmask -@nvtx.annotate() def _rs_large(sinogram, snr, size, matindex, drop_ratio=0.1, norm=True): """ Remove large stripes. @@ -362,7 +322,6 @@ def _rs_large(sinogram, snr, size, matindex, drop_ratio=0.1, norm=True): return sinogram -@nvtx.annotate() def _rs_dead(sinogram, snr, size, matindex, norm=True): """ Remove unresponsive and fluctuating stripes. @@ -401,7 +360,6 @@ def _rs_dead(sinogram, snr, size, matindex, norm=True): return sinogram -@nvtx.annotate() def _create_matindex(nrow, ncol): """ Create a 2D array of indexes used for the sorting technique. diff --git a/httomolibgpu/recon/algorithm.py b/httomolibgpu/recon/algorithm.py index 2da0c091..b254eee6 100644 --- a/httomolibgpu/recon/algorithm.py +++ b/httomolibgpu/recon/algorithm.py @@ -24,10 +24,16 @@ from httomolibgpu import cupywrapper cp = cupywrapper.cp -nvtx = cupywrapper.nvtx +cupy_run = cupywrapper.cupy_run -from tomobar.methodsDIR_CuPy import RecToolsDIRCuPy -from tomobar.methodsIR_CuPy import RecToolsIRCuPy +from unittest.mock import Mock + +if cupy_run: + from tomobar.methodsDIR_CuPy import RecToolsDIRCuPy + from tomobar.methodsIR_CuPy import RecToolsIRCuPy +else: + RecToolsDIRCuPy = Mock() + RecToolsIRCuPy = Mock() from numpy import float32, complex64 from typing import Optional, Type @@ -83,31 +89,6 @@ def FBP( cp.ndarray The FBP reconstructed volume as a CuPy array. """ - if cupywrapper.cupy_run: - return __FBP( - data, - angles, - center, - filter_freq_cutoff, - recon_size, - recon_mask_radius, - gpu_id, - ) - else: - print("FBP won't be executed because CuPy is not installed") - return data - - -@nvtx.annotate() -def __FBP( - data: cp.ndarray, - angles: np.ndarray, - center: Optional[float] = None, - filter_freq_cutoff: Optional[float] = 1.1, - recon_size: Optional[int] = None, - recon_mask_radius: Optional[float] = None, - gpu_id: int = 0, -) -> cp.ndarray: RecToolsCP = _instantiate_direct_recon_class( data, angles, center, recon_size, gpu_id ) @@ -156,26 +137,6 @@ def LPRec( cp.ndarray The Log-polar Fourier reconstructed volume as a CuPy array. """ - if cupywrapper.cupy_run: - return __LPRec( - data, - angles, - center, - recon_size, - recon_mask_radius, - ) - else: - print("LPRec won't be executed because CuPy is not installed") - return data - - -def __LPRec( - data: cp.ndarray, - angles: np.ndarray, - center: Optional[float] = None, - recon_size: Optional[int] = None, - recon_mask_radius: Optional[float] = None, -) -> cp.ndarray: RecToolsCP = _instantiate_direct_recon_class(data, angles, center, recon_size, 0) reconstruction = RecToolsCP.FOURIER_INV( @@ -225,31 +186,6 @@ def SIRT( cp.ndarray The SIRT reconstructed volume as a CuPy array. """ - if cupywrapper.cupy_run: - return __SIRT( - data, - angles, - center, - recon_size, - iterations, - nonnegativity, - gpu_id, - ) - else: - print("SIRT won't be executed because CuPy is not installed") - return data - - -@nvtx.annotate() -def __SIRT( - data: cp.ndarray, - angles: np.ndarray, - center: Optional[float] = None, - recon_size: Optional[int] = None, - iterations: Optional[int] = 300, - nonnegativity: Optional[bool] = True, - gpu_id: int = 0, -) -> cp.ndarray: RecToolsCP = _instantiate_iterative_recon_class( data, angles, center, recon_size, gpu_id, datafidelity="LS" ) @@ -305,31 +241,6 @@ def CGLS( cp.ndarray The CGLS reconstructed volume as a CuPy array. """ - if cupywrapper.cupy_run: - return __CGLS( - data, - angles, - center, - recon_size, - iterations, - nonnegativity, - gpu_id, - ) - else: - print("CGLS won't be executed because CuPy is not installed") - return data - - -@nvtx.annotate() -def __CGLS( - data: cp.ndarray, - angles: np.ndarray, - center: Optional[float] = None, - recon_size: Optional[int] = None, - iterations: Optional[int] = 20, - nonnegativity: Optional[bool] = True, - gpu_id: int = 0, -) -> cp.ndarray: RecToolsCP = _instantiate_iterative_recon_class( data, angles, center, recon_size, gpu_id, datafidelity="LS" ) diff --git a/httomolibgpu/recon/rotation.py b/httomolibgpu/recon/rotation.py index b720c875..a88414ec 100644 --- a/httomolibgpu/recon/rotation.py +++ b/httomolibgpu/recon/rotation.py @@ -24,13 +24,23 @@ from httomolibgpu import cupywrapper cp = cupywrapper.cp -nvtx = cupywrapper.nvtx - -from httomolibgpu.cuda_kernels import load_cuda_module -from cupyx.scipy.ndimage import shift, gaussian_filter -from skimage.registration import phase_cross_correlation -from cupyx.scipy.fftpack import get_fft_plan -from cupyx.scipy.fft import rfft2 +cupy_run = cupywrapper.cupy_run + +from unittest.mock import Mock + +if cupy_run: + from httomolibgpu.cuda_kernels import load_cuda_module + from cupyx.scipy.ndimage import shift, gaussian_filter + from skimage.registration import phase_cross_correlation + from cupyx.scipy.fftpack import get_fft_plan + from cupyx.scipy.fft import rfft2 +else: + load_cuda_module = Mock() + shift = Mock() + gaussian_filter = Mock() + phase_cross_correlation = Mock() + get_fft_plan = Mock() + rfft2 = Mock() import math from typing import List, Literal, Optional, Tuple, Union @@ -83,26 +93,6 @@ def find_center_vo( float Rotation axis location. """ - if cupywrapper.cupy_run: - return __find_center_vo(data, ind, smin, smax, srad, step, ratio, drop) - else: - print("find_center_vo won't be executed because CuPy is not installed") - return 0.0 - - -# %%%%%%%%%%%%%%%%%%%%%%%%%find_center_vo%%%%%%%%%%%%%%%%%%%%%%%%%%%% -@nvtx.annotate() -def __find_center_vo( - data: cp.ndarray, - ind: Optional[int] = None, - smin: int = -50, - smax: int = 50, - srad: float = 6.0, - step: float = 0.25, - ratio: float = 0.5, - drop: int = 20, -) -> float: - if data.ndim == 2: data = cp.expand_dims(data, 1) ind = 0 @@ -118,10 +108,8 @@ def __find_center_vo( else: _sino = data[:, ind, :] - with nvtx.annotate("gaussian_filter_1", color="green"): - _sino_cs = gaussian_filter(_sino, (3, 1), mode="reflect") - with nvtx.annotate("gaussian_filter_2", color="green"): - _sino_fs = gaussian_filter(_sino, (2, 2), mode="reflect") + _sino_cs = gaussian_filter(_sino, (3, 1), mode="reflect") + _sino_fs = gaussian_filter(_sino, (2, 2), mode="reflect") if _sino.shape[0] * _sino.shape[1] > 4e6: # data is large, so downsample it before performing search for @@ -136,7 +124,6 @@ def __find_center_vo( return cp.asnumpy(fine_cen) -@nvtx.annotate() def _search_coarse(sino, smin, smax, ratio, drop): (nrow, ncol) = sino.shape flip_sino = cp.ascontiguousarray(cp.fliplr(sino)) @@ -166,7 +153,6 @@ def _search_coarse(sino, smin, smax, ratio, drop): return cor -@nvtx.annotate() def _search_fine(sino, srad, step, init_cen, ratio, drop): (nrow, ncol) = sino.shape @@ -187,9 +173,7 @@ def _search_fine(sino, srad, step, init_cen, ratio, drop): return cor -@nvtx.annotate() def _create_mask(nrow, ncol, radius, drop): - du = 1.0 / ncol dv = (nrow - 1.0) / (nrow * 2.0 * np.pi) cen_row = int(math.ceil(nrow / 2.0) - 1) @@ -259,7 +243,6 @@ def _calculate_chunks( return stop_idx -@nvtx.annotate() def _calculate_metric(list_shift, sino1, sino2, sino3, mask, out): # this tries to simplify - if shift_col is integer, no need to spline interpolate assert list_shift.dtype == cp.float32, "shifts must be single precision floats" @@ -347,7 +330,6 @@ def _calculate_metric(list_shift, sino1, sino2, sino3, mask, out): ) -@nvtx.annotate() def _downsample(sino, level, axis): assert sino.dtype == cp.float32, "single precision floating point input required" assert sino.flags["C_CONTIGUOUS"], "list_shift must be C-contiguous" @@ -424,24 +406,6 @@ def find_center_360( Position of the window in the first image giving the best correlation metric. """ - - if cupywrapper.cupy_run: - return __find_center_360(data, ind, win_width, side, denoise, norm, use_overlap) - else: - print("find_center_360 won't be executed because CuPy is not installed") - return (0, 0, 0, 0) - - -@nvtx.annotate() -def __find_center_360( - data: cp.ndarray, - ind: Optional[int] = None, - win_width: int = 10, - side: Optional[Literal[0, 1]] = None, - denoise: bool = True, - norm: bool = False, - use_overlap: bool = False, -) -> Tuple[float, float, Optional[Literal[0, 1]], float]: if data.ndim != 3: raise ValueError("A 3D array must be provided") @@ -571,7 +535,6 @@ def _find_overlap( return overlap, side, overlap_position -@nvtx.annotate() def _search_overlap( mat1, mat2, win_width, side, denoise=True, norm=False, use_overlap=False ): @@ -611,9 +574,8 @@ def _search_overlap( if denoise is True: # note: the filtering makes the output contiguous - with nvtx.annotate("denoise_filter", color="green"): - mat1 = gaussian_filter(mat1, (2, 2), mode="reflect") - mat2 = gaussian_filter(mat2, (2, 2), mode="reflect") + mat1 = gaussian_filter(mat1, (2, 2), mode="reflect") + mat2 = gaussian_filter(mat2, (2, 2), mode="reflect") else: mat1 = cp.ascontiguousarray(mat1, dtype=cp.float32) mat2 = cp.ascontiguousarray(mat2, dtype=cp.float32) @@ -637,7 +599,6 @@ def _search_overlap( return list_metric, offset -@nvtx.annotate() def _calc_metrics(mat1, mat2, win_width, side, use_overlap, norm): assert mat1.dtype == cp.float32, "only float32 supported" assert mat2.dtype == cp.float32, "only float32 supported" @@ -681,7 +642,6 @@ def _calc_metrics(mat1, mat2, win_width, side, use_overlap, norm): return list_metric -@nvtx.annotate() def _calculate_curvature(list_metric): """ Calculate the curvature of a fitted curve going through the minimum @@ -745,21 +705,6 @@ def find_center_pc( Returns: float: Rotation axis location. """ - if cupywrapper.cupy_run: - return __find_center_pc(proj1, proj2, tol, rotc_guess) - else: - print("find_center_pc won't be executed because CuPy is not installed") - return 0 - - -@nvtx.annotate() -def __find_center_pc( - proj1: cp.ndarray, - proj2: cp.ndarray, - tol: float = 0.5, - rotc_guess: Union[float, Optional[str]] = None, -) -> float: - imgshift = 0.0 if rotc_guess is None else rotc_guess - (proj1.shape[1] - 1.0) / 2.0 proj1 = shift(proj1, [0, -imgshift], mode="constant", cval=0) diff --git a/pyproject.toml b/pyproject.toml index 6904dc26..6e4cf21a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ authors = [ ] classifiers = [ "Development Status :: 4 - Beta", - "License :: OSI Approved :: BSD 3-clause", + "License :: OSI Approved :: BSD License", "Programming Language :: Python :: 3.10", "Environment :: GPU :: NVIDIA CUDA" ]