diff --git a/imops/compat.py b/imops/compat.py index 0d0b2ee..5cfa7b8 100644 --- a/imops/compat.py +++ b/imops/compat.py @@ -9,9 +9,9 @@ from numpy import VisibleDeprecationWarning try: - from scipy.ndimage._morphology._ni_support import _normalize_sequence as normalize_sequence + from scipy.ndimage._morphology import _ni_support except ImportError: - from scipy.ndimage.morphology._ni_support import _normalize_sequence as normalize_sequence + from scipy.ndimage.morphology import _ni_support try: from scipy.spatial import QhullError @@ -19,3 +19,6 @@ from scipy.spatial.qhull import QhullError from scipy.ndimage._nd_image import euclidean_feature_transform # noqa + + +normalize_sequence = _ni_support._normalize_sequence # noqa diff --git a/imops/crop.py b/imops/crop.py index d1e1a77..dbb2c33 100644 --- a/imops/crop.py +++ b/imops/crop.py @@ -1,3 +1,5 @@ +from typing import Optional + import numpy as np from .backend import BackendLike @@ -6,7 +8,9 @@ from .utils import AxesLike, AxesParams, assert_subdtype, broadcast_axis, fill_by_indices -def crop_to_shape(x: np.ndarray, shape: AxesLike, axis: AxesLike = None, ratio: AxesParams = 0.5) -> np.ndarray: +def crop_to_shape( + x: np.ndarray, shape: AxesLike, axis: Optional[AxesLike] = None, ratio: AxesParams = 0.5 +) -> np.ndarray: """ Crop `x` to match `shape` along `axis`. @@ -57,8 +61,8 @@ def crop_to_shape(x: np.ndarray, shape: AxesLike, axis: AxesLike = None, ratio: def crop_to_box( x: np.ndarray, box: np.ndarray, - axis: AxesLike = None, - padding_values: AxesParams = None, + axis: Optional[AxesLike] = None, + padding_values: Optional[AxesParams] = None, num_threads: int = _NUMERIC_DEFAULT_NUM_THREADS, backend: BackendLike = None, ) -> np.ndarray: diff --git a/imops/interp1d.py b/imops/interp1d.py index 269cf21..861a0b6 100644 --- a/imops/interp1d.py +++ b/imops/interp1d.py @@ -1,4 +1,4 @@ -from typing import Union +from typing import Optional, Union from warnings import warn import numpy as np @@ -71,7 +71,7 @@ def __init__( kind: Union[int, str] = 'linear', axis: int = -1, copy: bool = True, - bounds_error: bool = None, + bounds_error: Optional[bool] = None, fill_value: Union[float, str] = np.nan, assume_sorted: bool = False, num_threads: int = -1, diff --git a/imops/interp2d.py b/imops/interp2d.py index 5a3df75..306801c 100644 --- a/imops/interp2d.py +++ b/imops/interp2d.py @@ -1,4 +1,5 @@ from platform import python_version +from typing import Optional import numpy as np from scipy.spatial import KDTree @@ -47,9 +48,9 @@ class Linear2DInterpolator(Linear2DInterpolatorCpp): def __init__( self, points: np.ndarray, - values: np.ndarray = None, + values: Optional[np.ndarray] = None, num_threads: int = 1, - triangles: np.ndarray = None, + triangles: Optional[np.ndarray] = None, **kwargs, ): if triangles is not None: @@ -77,7 +78,7 @@ def __init__( # FIXME: add backend dispatch self.num_threads = normalize_num_threads(num_threads, Cython(), warn_stacklevel=3) - def __call__(self, points: np.ndarray, values: np.ndarray = None, fill_value: float = 0.0) -> np.ndarray: + def __call__(self, points: np.ndarray, values: Optional[np.ndarray] = None, fill_value: float = 0.0) -> np.ndarray: """ Evaluate the interpolant diff --git a/imops/measure.py b/imops/measure.py index 056f228..1a71682 100644 --- a/imops/measure.py +++ b/imops/measure.py @@ -1,6 +1,6 @@ from collections import namedtuple from platform import python_version -from typing import List, NamedTuple, Sequence, Tuple, Union +from typing import List, NamedTuple, Optional, Sequence, Tuple, Union from warnings import warn import numpy as np @@ -32,12 +32,12 @@ # TODO: Make it work and test on immutable arrays as soon as `cc3d` package is fixed def label( label_image: np.ndarray, - background: int = None, - connectivity: int = None, + background: Optional[int] = None, + connectivity: Optional[int] = None, return_num: bool = False, return_labels: bool = False, return_sizes: bool = False, - dtype: type = None, + dtype: Optional[type] = None, ) -> Union[np.ndarray, NamedTuple]: """ Fast version of `skimage.measure.label` which optionally returns number of connected components, labels and sizes. @@ -139,8 +139,8 @@ def label( def center_of_mass( array: np.ndarray, - labels: np.ndarray = None, - index: Union[int, Sequence[int]] = None, + labels: Union[np.ndarray, None] = None, + index: Union[int, Sequence[int], None] = None, num_threads: int = -1, backend: BackendLike = None, ) -> Union[Tuple[float, ...], List[Tuple[float, ...]]]: diff --git a/imops/morphology.py b/imops/morphology.py index 39d45a1..a57243c 100644 --- a/imops/morphology.py +++ b/imops/morphology.py @@ -1,4 +1,4 @@ -from typing import Callable, Tuple, Union +from typing import Callable, Optional, Tuple, Union from warnings import warn import numpy as np @@ -32,8 +32,8 @@ def morphology_op_wrapper( ) -> Callable: def wrapped( image: np.ndarray, - footprint: np.ndarray = None, - output: np.ndarray = None, + footprint: Optional[np.ndarray] = None, + output: Optional[np.ndarray] = None, boxed: bool = False, num_threads: int = -1, backend: BackendLike = None, @@ -163,8 +163,8 @@ def wrapped( def binary_dilation( image: np.ndarray, - footprint: np.ndarray = None, - output: np.ndarray = None, + footprint: Optional[np.ndarray] = None, + output: Optional[np.ndarray] = None, boxed: bool = False, num_threads: int = -1, backend: BackendLike = None, @@ -217,8 +217,8 @@ def binary_dilation( def binary_erosion( image: np.ndarray, - footprint: np.ndarray = None, - output: np.ndarray = None, + footprint: Optional[np.ndarray] = None, + output: Optional[np.ndarray] = None, boxed: bool = False, num_threads: int = -1, backend: BackendLike = None, @@ -271,8 +271,8 @@ def binary_erosion( def binary_closing( image: np.ndarray, - footprint: np.ndarray = None, - output: np.ndarray = None, + footprint: Optional[np.ndarray] = None, + output: Optional[np.ndarray] = None, boxed: bool = False, num_threads: int = -1, backend: BackendLike = None, @@ -326,8 +326,8 @@ def binary_closing( def binary_opening( image: np.ndarray, - footprint: np.ndarray = None, - output: np.ndarray = None, + footprint: Optional[np.ndarray] = None, + output: Optional[np.ndarray] = None, boxed: bool = False, num_threads: int = -1, backend: BackendLike = None, @@ -371,7 +371,7 @@ def binary_opening( def distance_transform_edt( image: np.ndarray, - sampling: Tuple[float] = None, + sampling: Optional[Tuple[float]] = None, return_distances: bool = True, return_indices: bool = False, num_threads: int = -1, diff --git a/imops/numeric.py b/imops/numeric.py index 8cca57f..e925958 100644 --- a/imops/numeric.py +++ b/imops/numeric.py @@ -1,4 +1,4 @@ -from typing import Callable, Sequence, Union +from typing import Callable, Optional, Sequence, Union import numpy as np @@ -99,7 +99,7 @@ def _choose_cython_copy(ndim: int, is_fp16: bool, fast: bool) -> Callable: def pointwise_add( nums: np.ndarray, summand: Union[np.array, int, float], - output: np.ndarray = None, + output: Optional[np.ndarray] = None, num_threads: int = _NUMERIC_DEFAULT_NUM_THREADS, backend: BackendLike = None, ) -> np.ndarray: @@ -256,7 +256,7 @@ def fill_( def full( shape: Union[int, Sequence[int]], fill_value: Union[np.number, int, float], - dtype: Union[type, str] = None, + dtype: Union[type, str, None] = None, order: str = 'C', num_threads: int = _NUMERIC_DEFAULT_NUM_THREADS, backend: BackendLike = None, @@ -302,7 +302,7 @@ def full( def copy( nums: np.ndarray, - output: np.ndarray = None, + output: Optional[np.ndarray] = None, order: str = 'K', num_threads: int = _NUMERIC_DEFAULT_NUM_THREADS, backend: BackendLike = None, diff --git a/imops/pad.py b/imops/pad.py index b277dce..5aa0e64 100644 --- a/imops/pad.py +++ b/imops/pad.py @@ -1,4 +1,4 @@ -from typing import Callable, Sequence, Union +from typing import Callable, Optional, Sequence, Union import numpy as np @@ -10,7 +10,7 @@ def pad( x: np.ndarray, padding: Union[AxesLike, Sequence[Sequence[int]]], - axis: AxesLike = None, + axis: Optional[AxesLike] = None, padding_values: Union[AxesParams, Callable] = 0, num_threads: int = _NUMERIC_DEFAULT_NUM_THREADS, backend: BackendLike = None, @@ -76,7 +76,7 @@ def pad( def pad_to_shape( x: np.ndarray, shape: AxesLike, - axis: AxesLike = None, + axis: Optional[AxesLike] = None, padding_values: Union[AxesParams, Callable] = 0, ratio: AxesParams = 0.5, num_threads: int = _NUMERIC_DEFAULT_NUM_THREADS, @@ -135,7 +135,7 @@ def pad_to_shape( def pad_to_divisible( x: np.ndarray, divisor: AxesLike, - axis: AxesLike = None, + axis: Optional[AxesLike] = None, padding_values: Union[AxesParams, Callable] = 0, ratio: AxesParams = 0.5, remainder: AxesLike = 0, diff --git a/imops/radon.py b/imops/radon.py index a3d122b..5c068f5 100644 --- a/imops/radon.py +++ b/imops/radon.py @@ -1,4 +1,4 @@ -from typing import Sequence, Tuple, Union +from typing import Optional, Sequence, Tuple, Union import numpy as np from scipy.fftpack import fft, ifft @@ -15,7 +15,7 @@ def radon( image: np.ndarray, - axes: Tuple[int, int] = None, + axes: Optional[Tuple[int, int]] = None, theta: Union[int, Sequence[float]] = 180, return_fill: bool = False, num_threads: int = -1, @@ -104,8 +104,8 @@ def radon( def inverse_radon( sinogram: np.ndarray, - axes: Tuple[int, int] = None, - theta: Union[int, Sequence[float]] = None, + axes: Optional[Tuple[int, int]] = None, + theta: Union[int, Sequence[float], None] = None, fill_value: float = 0, a: float = 0, b: float = 1, diff --git a/imops/utils.py b/imops/utils.py index d1c58f9..4b1bd97 100644 --- a/imops/utils.py +++ b/imops/utils.py @@ -169,7 +169,9 @@ def wrapper( return wrapper -def build_slices(start: Sequence[int], stop: Sequence[int] = None, step: Sequence[int] = None) -> Tuple[slice, ...]: +def build_slices( + start: Sequence[int], stop: Optional[Sequence[int]] = None, step: Optional[Sequence[int]] = None +) -> Tuple[slice, ...]: """ Returns a tuple of slices built from `start` and `stop` with `step`. diff --git a/imops/zoom.py b/imops/zoom.py index a3ceb9f..b5a0bde 100644 --- a/imops/zoom.py +++ b/imops/zoom.py @@ -1,5 +1,5 @@ from platform import python_version -from typing import Callable, Sequence, Union +from typing import Callable, Optional, Sequence, Union from warnings import warn import numpy as np @@ -72,7 +72,7 @@ def _choose_numba_zoom(ndim: int, order: int) -> Callable: def zoom( x: np.ndarray, scale_factor: AxesParams, - axis: AxesLike = None, + axis: Optional[AxesLike] = None, order: int = 1, fill_value: Union[float, Callable] = 0, num_threads: int = -1, @@ -129,7 +129,7 @@ def zoom( def zoom_to_shape( x: np.ndarray, shape: AxesLike, - axis: AxesLike = None, + axis: Optional[AxesLike] = None, order: int = 1, fill_value: Union[float, Callable] = 0, num_threads: int = -1, @@ -191,7 +191,7 @@ def zoom_to_shape( def _zoom( image: np.ndarray, zoom: Sequence[float], - output: np.ndarray = None, + output: Optional[np.ndarray] = None, order: int = 1, mode: str = 'constant', cval: float = 0.0,