From 5727cf767ea6b8a2936c989a2e6ff3853b526721 Mon Sep 17 00:00:00 2001 From: Alex <95913221+Pwhsky@users.noreply.github.com> Date: Fri, 7 Mar 2025 11:31:22 +0100 Subject: [PATCH 01/17] Now using __future__ type hints --- deeptrack/image.py | 161 +++++++++++++++++++++++---------------------- 1 file changed, 84 insertions(+), 77 deletions(-) diff --git a/deeptrack/image.py b/deeptrack/image.py index 753581f60..be120cf32 100644 --- a/deeptrack/image.py +++ b/deeptrack/image.py @@ -6,8 +6,8 @@ class is central to DeepTrack2, acting as a container for numerical data (such as images, tensors, and scalars) while maintaining the properties generated by features during pipeline processing. -Key Features ------------- +Main Concepts +------------- - **Enhanced Array-Like Interface** The `Image` class provides an interface similar to NumPy arrays, enabling @@ -30,13 +30,15 @@ class is central to DeepTrack2, acting as a container for numerical data Includes helper functions (`coerce`, `strip`, etc.) for managing and manipulating `Image` objects efficiently within pipelines. -Module Structure ----------------- -Classes: +Key Classes +----------- -- `Image`: Core class for managing array-like data and their properties. +- `Image`: + Core class for managing array-like data and their properties. -Utility Functions: + +Methods +------- - `strip(element)` @@ -80,8 +82,8 @@ class is central to DeepTrack2, acting as a container for numerical data >>> img = Image(np.array([[1, 2], [3, 4]])) >>> print(img + 1) -Image([[2, 3], - [4, 5]]) +... Image([[2, 3], +... [4, 5]]) Property tracking: @@ -95,19 +97,18 @@ class is central to DeepTrack2, acting as a container for numerical data import operator as ops from typing import Any, Callable, Dict, Iterable, List, Tuple, Union +from __future__ import annotations import numpy as np -from .backend._config import cupy -from .properties import Property -from .types import NumberLike # NumberLike = Union[np.ndarray, int, float, - # bool, complex, cupy.ndarray, - # torch.Tensor] +from deeeptrack.backend._config import cupy +from deeptrack.properties import Property +from deeptrack.types import NumberLike def _binary_method( - op : Callable[[NumberLike, NumberLike], NumberLike], -) -> Callable[['Image', Union['Image', NumberLike]], 'Image']: + op: Callable[[NumberLike, NumberLike], NumberLike], +) -> Callable[[Image, Union[Image, NumberLike]], Image]: """Implement a binary operator for the Image class. This function generates a binary method (e.g., `__add__`, `__sub__`) for @@ -134,7 +135,7 @@ def _binary_method( Returns ------- - Callable[['Image', Union['Image', NumberLike]], 'Image'] + Callable[[Image, Union[Image, NumberLike]], Image] A method that can be assigned to a binary operator (e.g., `__add__`) of the `Image` class. @@ -165,9 +166,9 @@ def _binary_method( """ def func( - self : 'Image', - other : Union['Image', NumberLike], - ) -> 'Image': + self: Image, + other: Union[Image, NumberLike], + ) -> Image: # Coerce inputs to compatible types. self, other = coerce([self, other]) @@ -192,7 +193,7 @@ def func( def _reflected_binary_method( op: Callable[[NumberLike, NumberLike], NumberLike], -) -> Callable[[Union['Image', NumberLike], 'Image'], 'Image']: +) -> Callable[[Union[Image, NumberLike], Image], Image]: """Implement a reflected binary operator for the Image class. This function generates a reflected binary method (e.g., `__radd__`, @@ -220,7 +221,7 @@ def _reflected_binary_method( Returns ------- - Callable[['Image', Union['Image', NumberLike]], 'Image'] + Callable[[Image, Union[Image, NumberLike]], Image] A method that can be assigned to a reflected binary operator (e.g., `__radd__`) of the `Image` class. @@ -251,9 +252,9 @@ def _reflected_binary_method( """ def func( - self: 'Image', - other: Union['Image', NumberLike], - ) -> 'Image': + self: Image, + other: Union[Image, NumberLike], + ) -> Image: # Coerce inputs to compatible types. self, other = coerce([self, other]) @@ -278,7 +279,7 @@ def func( def _inplace_binary_method( op: Callable[[NumberLike, NumberLike], NumberLike] -) -> Callable[['Image', Union['Image', NumberLike]], 'Image']: +) -> Callable[[Image, Union[Image, NumberLike]], Image]: """Implement an in-place binary operator for the Image class. This function generates an in-place binary method (e.g., `__iadd__`, @@ -302,7 +303,7 @@ def _inplace_binary_method( Returns ------- - Callable[['Image', Union['Image', NumberLike]], None] + Callable[[Image, Union[Image, NumberLike]], None] A method that can be assigned to an in-place binary operator (e.g., `__iadd__`) of the `Image` class. @@ -333,9 +334,9 @@ def _inplace_binary_method( """ def func( - self: 'Image', - other: Union['Image', NumberLike], - ) -> 'Image': + self: Image, + other: Union[Image, NumberLike], + ) -> Image: # Coerce inputs to compatible types. self, other = coerce([self, other]) @@ -358,9 +359,9 @@ def func( def _numeric_methods( op: Callable[[NumberLike, NumberLike], NumberLike], ) -> Tuple[ - Callable[['Image', Union['Image', NumberLike]], 'Image'], - Callable[[Union['Image', NumberLike], 'Image'], 'Image'], - Callable[['Image', Union['Image', NumberLike]], 'Image'] + Callable[[Image, Union[Image, NumberLike]], Image], + Callable[[Union[Image, NumberLike], Image], Image], + Callable[[Image, Union[Image, NumberLike]], Image] ]: """Generate forward, reflected, and in-place binary methods. @@ -381,9 +382,9 @@ def _numeric_methods( Returns ------- Tuple[ - Callable[['Image', Union['Image', NumberLike]], 'Image'], - Callable[[Union['Image', NumberLike], 'Image'], 'Image'], - Callable[['Image', Union['Image', NumberLike]], 'Image'] + Callable[[Image, Union[Image, NumberLike]], Image], + Callable[[Union[Image, NumberLike], Image], Image], + Callable[[Image, Union[Image, NumberLike]], Image] ] A tuple containing three callables: (1) The forward binary method (`_binary_method`). @@ -431,7 +432,7 @@ def _numeric_methods( def _unary_method( op: Callable[[NumberLike], NumberLike], -) -> Callable[['Image'], 'Image']: +) -> Callable[[Image], Image]: """Implement a unary special method for the Image class. This function generates a unary method (e.g., `__neg__`, `__abs__`) for @@ -447,7 +448,7 @@ def _unary_method( Returns ------- - Callable[['Image'], 'Image'] + Callable[[Image], Image] A method that can be assigned to a unary operator (e.g., `__neg__`) of the `Image` class. @@ -471,8 +472,8 @@ def _unary_method( """ def func( - self: 'Image', - ) -> 'Image': + self: Image, + ) -> Image: # Apply the unary operator to the Image instance. return Image( @@ -527,21 +528,21 @@ class Image: ------- **Property Management** - `append(property_dict: dict) -> 'Image'` + `append(property_dict: dict) -> Image` Add a dictionary of properties to the `Image`. `get_property(key: str, get_one: bool = True, default: Any = None) -> Union[Any, List[Any]]` Retrieve a property by key. If `get_one` is `True`, returns the first match; otherwise, returns a list of matches. - `merge_properties_from(other: Union['Image', List['Image'], np.ndarray]) -> 'Image'` + `merge_properties_from(other: Union[Image, List[Image], np.ndarray]) -> Image` Merge properties from another `Image`, list of `Image`s, or a NumPy array. **Conversion Utilities** - `to_cupy() -> 'Image'` + `to_cupy() -> Image` Convert the `Image` to a CuPy array if the underlying value is a NumPy array. - `to_numpy() -> 'Image'` + `to_numpy() -> Image` Convert the `Image` to a numpy array if the underlying value is a CuPy array. `__array__(*args: Tuple[Any, ...], **kwargs: Dict[str, Any]) -> np.ndarray` @@ -549,7 +550,7 @@ class Image: **NumPy Compatibility - `__array_ufunc__(ufunc: Callable, method: str, *inputs: Tuple[Any], **kwargs: Dict[str, Any]) -> Union['Image', Tuple['Image', ...], None]` + `__array_ufunc__(ufunc: Callable, method: str, *inputs: Tuple[Any], **kwargs: Dict[str, Any]) -> Union[Image, Tuple[Image, ...], None]` Enable compatibility with numpy's universal functions (ufuncs). Examples include `np.add`, `np.multiply`, and `np.sin`. @@ -569,7 +570,7 @@ class Image: - Bitwise: `np.bitwise_and`, `np.bitwise_or`, `np.bitwise_xor`, etc. - `__array_function__(func: Callable[..., Any], types: Tuple[type, ...], args: Tuple[Any, ...], kwargs: Dict[str, Any]) -> Union['Image', Tuple['Image', ...], Any]` + `__array_function__(func: Callable[..., Any], types: Tuple[type, ...], args: Tuple[Any, ...], kwargs: Dict[str, Any]) -> Union[Image, Tuple[Image, ...], Any]` Enable compatibility with numpy's general functions, such as `np.mean`, `np.dot`, and `np.concatenate`. @@ -584,7 +585,7 @@ class Image: **Indexing and Assignment** - `__getitem__(idx: Any) -> Union['Image', Any]` + `__getitem__(idx: Any) -> Union[Image, Any]` Access array elements using standard indexing or slicing. If the result is scalar, returns it; otherwise, returns an `Image`. `__setitem__(key: Any, value: Any) -> None` @@ -646,8 +647,8 @@ class Image: properties : List[Dict[str, Property]] def __init__( - self : 'Image', - value: Union[np.ndarray, list, int, float, bool, 'Image'], + self : Image, + value: Union[np.ndarray, list, int, float, bool, Image], copy: bool = True, ): """Initialize an Image object. @@ -695,9 +696,9 @@ def __init__( self.properties = [] def append( - self : 'Image', + self : Image, property_dict: Dict[str, Property], - ) -> 'Image': + ) -> Image: """Append a dictionary to the properties list. This method adds a dictionary of property values to the `properties` @@ -754,7 +755,7 @@ def append( return self def get_property( - self : 'Image', + self : Image, key: str, get_one: bool = True, default: Any = None, @@ -830,9 +831,9 @@ def get_property( ] or default def merge_properties_from( - self : 'Image', - other: Union[np.ndarray, 'Image', Iterable], - ) -> 'Image': + self : Image, + other: Union[np.ndarray, Image, Iterable], + ) -> Image: """Merge properties with those from another Image. Appends properties from another images without duplicating properties. @@ -943,8 +944,8 @@ def merge_properties_from( return self def _view( - self : 'Image', - value: Union[np.ndarray, list, int, float, bool, 'Image'], + self : Image, + value: Union[np.ndarray, list, int, float, bool, Image], ) -> np.ndarray: """Convert the value to NumPy array for storage in the Image object. @@ -986,12 +987,12 @@ def _view( return value def __array_ufunc__( - self: 'Image', + self: Image, ufunc: np.ufunc, method: str, *inputs: Tuple[Any, ...], **kwargs: Dict[str, Any], - ) -> Union['Image', Tuple['Image', ...], None]: + ) -> Union[Image, Tuple[Image, ...], None]: """Enable Image objects to use NumPy ufuncs. This method integrates the Image class with NumPy's universal functions @@ -1068,6 +1069,7 @@ def __array_ufunc__( results = getattr(ufunc, method)(*args, **kwargs) if type(results) is tuple: + # If the ufunc returns a tuple, return a tuple of Image objects. outputs = [] for result in results: @@ -1077,21 +1079,23 @@ def __array_ufunc__( return tuple(outputs) elif method == "at": #TODO: check whether not implemented on purpose? + # Does not have an output. return None else: + # If the ufunc returns a single value, return an Image object. result = Image(results, copy=False) result.merge_properties_from(inputs) return result def __array_function__( - self: 'Image', + self: Image, func: Callable[..., Any], types: Tuple[type, ...], args: Tuple[Any, ...], kwargs: Dict[str, Any], - ) -> Union['Image', Tuple['Image', ...], Any]: + ) -> Union[Image, Tuple[Image, ...], Any]: """Handle NumPy functions for Image objects. This method integrates Image objects with NumPy functions, allowing @@ -1185,7 +1189,7 @@ def __array_function__( return result def __array__( - self: 'Image', + self: Image, *args: Tuple[Any, ...], **kwargs: Dict[str, Any], ) -> np.ndarray: @@ -1232,8 +1236,8 @@ def __array__( return np.array(self.to_numpy()._value, *args) def to_cupy( - self: 'Image', - ) -> 'Image': + self: Image, + ) -> Image: """Convert the image's underlying value to a CuPy array. This method converts the `_value` of the `Image` object to a CuPy array @@ -1281,8 +1285,8 @@ def to_cupy( return self def to_numpy( - self: 'Image', - ) -> 'Image': + self: Image, + ) -> Image: """Convert the image's underlying value to a NumPy array. This method converts the `_value` of the `Image` object to a NumPy @@ -1333,7 +1337,7 @@ def to_numpy( return self def __getattr__( - self: 'Image', + self: Image, key: str, ) -> Any: """Access attributes of the underlying value. @@ -1362,9 +1366,9 @@ def __getattr__( return getattr(self._value, key) def __getitem__( - self: 'Image', + self: Image, idx: Union[int, slice, Tuple[Union[int, slice], ...], Any], - ) -> Union['Image', int, float, bool, complex, np.ndarray]: + ) -> Union[Image, int, float, bool, complex, np.ndarray]: """Access and return an item or a slice from the Image. This method allows indexing into the wrapped `_value` of the Image, @@ -1412,7 +1416,7 @@ def __getitem__( return out def __setitem__( - self: 'Image', + self: Image, key: Union[int, slice, Tuple[Union[int, slice], ...], List[int]], value: Union[int, slice, Tuple[Union[int, slice], ...], List[int]], ) -> None: @@ -1480,7 +1484,7 @@ def __setitem__( self.merge_properties_from([key, value]) def __int__( - self: 'Image', + self: Image, )-> int: """Convert the Image's value to an integer. @@ -1494,7 +1498,7 @@ def __int__( return int(self._value) def __float__( - self: 'Image', + self: Image, ) -> float: """Convert the Image's value to a float. @@ -1508,7 +1512,7 @@ def __float__( return float(self._value) def __bool__( - self: 'Image', + self: Image, ) -> bool: """Check if the Image's value is truthy. @@ -1522,7 +1526,7 @@ def __bool__( return bool(self._value) def __round__( - self: 'Image', + self: Image, ndigits: int = 0, ) -> float: """Round the Image's value to a specified number of digits. @@ -1542,7 +1546,7 @@ def __round__( return round(self._value, ndigits) def __len__( - self: 'Image', + self: Image, ) -> int: """Return the length of the Image's value. @@ -1556,7 +1560,7 @@ def __len__( return len(self._value) def __repr__( - self: 'Image', + self: Image, ) -> str: """Return the string representation of the Image. @@ -1582,12 +1586,14 @@ def __repr__( __sub__, __rsub__, __isub__ = _numeric_methods(ops.sub) __mul__, __rmul__, __imul__ = _numeric_methods(ops.mul) __matmul__, __rmatmul__, __imatmul__ = _numeric_methods(ops.matmul) + # Python 3 does not use __div__, __rdiv__, or __idiv__ __truediv__, __rtruediv__, __itruediv__ = _numeric_methods(ops.truediv) __floordiv__, __rfloordiv__, __ifloordiv__ = _numeric_methods(ops.floordiv) __mod__, __rmod__, __imod__ = _numeric_methods(ops.mod) __divmod__ = _binary_method(divmod) __rdivmod__ = _reflected_binary_method(divmod) + # __idivmod__ does not exist #TODO: handle the optional third argument for __pow__? __pow__, __rpow__, __ipow__ = _numeric_methods(ops.pow) @@ -1777,6 +1783,7 @@ def pad_image_to_fft( def _closest( dim: int, ) -> int: + # Returns the smallest value frin _FASTEST_SIZES larger than dim. for size in _FASTEST_SIZES: if size >= dim: @@ -1848,7 +1855,7 @@ def maybe_cupy( """ - from . import config + from deeptrack.backend import _config if config.gpu_enabled: return cupy.array(array) From 35a1a806fc29821d9f5f1085852e56d4d9730f43 Mon Sep 17 00:00:00 2001 From: Alex <95913221+Pwhsky@users.noreply.github.com> Date: Fri, 7 Mar 2025 11:34:52 +0100 Subject: [PATCH 02/17] fix: config -> _config --- deeptrack/image.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deeptrack/image.py b/deeptrack/image.py index be120cf32..ca6db7dac 100644 --- a/deeptrack/image.py +++ b/deeptrack/image.py @@ -1857,7 +1857,7 @@ def maybe_cupy( from deeptrack.backend import _config - if config.gpu_enabled: + if _config.gpu_enabled: return cupy.array(array) return array From 56711f3b17dee79855e9988057cba7fa5b979ea8 Mon Sep 17 00:00:00 2001 From: Alex <95913221+Pwhsky@users.noreply.github.com> Date: Fri, 7 Mar 2025 11:37:58 +0100 Subject: [PATCH 03/17] moved __future__ import to start --- deeptrack/image.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deeptrack/image.py b/deeptrack/image.py index ca6db7dac..8adff4741 100644 --- a/deeptrack/image.py +++ b/deeptrack/image.py @@ -95,9 +95,9 @@ class is central to DeepTrack2, acting as a container for numerical data """ +from __future__ import annotations import operator as ops from typing import Any, Callable, Dict, Iterable, List, Tuple, Union -from __future__ import annotations import numpy as np From fe5d67ce4d62f9a8e4cf8993d39267a9551381e3 Mon Sep 17 00:00:00 2001 From: Alex <95913221+Pwhsky@users.noreply.github.com> Date: Fri, 7 Mar 2025 11:47:30 +0100 Subject: [PATCH 04/17] _config import --- deeptrack/image.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/deeptrack/image.py b/deeptrack/image.py index 8adff4741..80d046197 100644 --- a/deeptrack/image.py +++ b/deeptrack/image.py @@ -101,7 +101,7 @@ class is central to DeepTrack2, acting as a container for numerical data import numpy as np -from deeeptrack.backend._config import cupy +from deeptrack.backend import _config from deeptrack.properties import Property from deeptrack.types import NumberLike @@ -1855,9 +1855,7 @@ def maybe_cupy( """ - from deeptrack.backend import _config - if _config.gpu_enabled: - return cupy.array(array) + return _config.cupy.array(array) return array From b7a9685226d3bd8cb81ee4fd1e8435900c1702a2 Mon Sep 17 00:00:00 2001 From: Alex <95913221+Pwhsky@users.noreply.github.com> Date: Fri, 7 Mar 2025 11:49:36 +0100 Subject: [PATCH 05/17] cupy import --- deeptrack/image.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deeptrack/image.py b/deeptrack/image.py index 80d046197..7fc56529b 100644 --- a/deeptrack/image.py +++ b/deeptrack/image.py @@ -101,7 +101,7 @@ class is central to DeepTrack2, acting as a container for numerical data import numpy as np -from deeptrack.backend import _config +from deeptrack.backend._config import cupy, gpu_enabled from deeptrack.properties import Property from deeptrack.types import NumberLike @@ -1855,7 +1855,7 @@ def maybe_cupy( """ - if _config.gpu_enabled: - return _config.cupy.array(array) + if gpu_enabled: + return cupy.array(array) return array From cf6a39cd18bb8b1ff8da14a863ac0831c3e6da0b Mon Sep 17 00:00:00 2001 From: Alex <95913221+Pwhsky@users.noreply.github.com> Date: Fri, 7 Mar 2025 11:50:49 +0100 Subject: [PATCH 06/17] removed ' cupy array' type hint --- deeptrack/image.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/deeptrack/image.py b/deeptrack/image.py index 7fc56529b..37b00a544 100644 --- a/deeptrack/image.py +++ b/deeptrack/image.py @@ -69,7 +69,7 @@ class is central to DeepTrack2, acting as a container for numerical data maybe_cupy( array: Union[np.ndarray, List, Tuple], - ) -> Union['cupy.ndarray', np.ndarray] + ) -> Union[cupy.ndarray, np.ndarray] Convert an array to a CuPy array if GPU is available and enabled. @@ -634,7 +634,7 @@ class Image: >>> gpu_img = img.to_cupy() >>> print(type(gpu_img._value)) - + >>> converted_back = gpu_img.to_numpy() >>> print(type(converted_back._value)) @@ -1707,7 +1707,7 @@ def coerce( >>> img3 = Image(cupy.array([7, 8, 9])) >>> result = coerce([img1, img3]) >>> print([type(img._value) for img in result]) - [, ] + [, ] """ @@ -1809,7 +1809,7 @@ def _closest( def maybe_cupy( array: Union[np.ndarray, List, Tuple], -) -> Union['cupy.ndarray', np.ndarray]: +) -> Union[cupy.ndarray, np.ndarray]: """Convert an array to a CuPy array if GPU is available and enabled. This function checks if GPU computation is enabled in the configuration. @@ -1844,7 +1844,7 @@ def maybe_cupy( >>> array = np.array([1, 2, 3]) >>> gpu_array = maybe_cupy(array) >>> type(gpu_array) - + If GPU is not enabled: From 4f504a1b162d76a6fca4a1a6957b2bb4536ccd93 Mon Sep 17 00:00:00 2001 From: Alex <95913221+Pwhsky@users.noreply.github.com> Date: Fri, 7 Mar 2025 12:16:10 +0100 Subject: [PATCH 07/17] import config --- deeptrack/image.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deeptrack/image.py b/deeptrack/image.py index 37b00a544..b0c0af84a 100644 --- a/deeptrack/image.py +++ b/deeptrack/image.py @@ -101,7 +101,7 @@ class is central to DeepTrack2, acting as a container for numerical data import numpy as np -from deeptrack.backend._config import cupy, gpu_enabled +from deeptrack.backend._config import cupy from deeptrack.properties import Property from deeptrack.types import NumberLike @@ -1854,8 +1854,8 @@ def maybe_cupy( """ - - if gpu_enabled: + from deeptrack.backend import config + if config.gpu_enabled: return cupy.array(array) return array From 050ba906eb2efa7364cc9ba5c813c0175a818ad8 Mon Sep 17 00:00:00 2001 From: Alex <95913221+Pwhsky@users.noreply.github.com> Date: Fri, 7 Mar 2025 17:33:35 +0100 Subject: [PATCH 08/17] spacing between : --- deeptrack/image.py | 90 +++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/deeptrack/image.py b/deeptrack/image.py index b0c0af84a..27135912a 100644 --- a/deeptrack/image.py +++ b/deeptrack/image.py @@ -129,7 +129,7 @@ def _binary_method( Parameters ---------- - op : Callable[[NumberLike, NumberLike], NumberLike] + op: Callable[[NumberLike, NumberLike], NumberLike] The operator function (e.g., `operator.add`, `operator.sub`) that defines the binary operation. @@ -215,7 +215,7 @@ def _reflected_binary_method( Parameters ---------- - op : Callable[[NumberLike, NumberLike], NumberLike] + op: Callable[[NumberLike, NumberLike], NumberLike] The operator function (e.g., `operator.add`, `operator.sub`) that defines the reflected binary operation. @@ -297,7 +297,7 @@ def _inplace_binary_method( Parameters ---------- - op : Callable[[NumberLike, NumberLike], NumberLike] + op: Callable[[NumberLike, NumberLike], NumberLike] The operator function (e.g., `operator.iadd`, `operator.imul`) that defines the in-place binary operation. @@ -375,7 +375,7 @@ def _numeric_methods( Parameters ---------- - op : Callable[[NumberLike, NumberLike], NumberLike] + op: Callable[[NumberLike, NumberLike], NumberLike] A callable representing the numeric operator (e.g., `operator.add`, `operator.mul`) to implement the methods for. @@ -442,7 +442,7 @@ def _unary_method( Parameters ---------- - op : Callable[[NumberLike], NumberLike] + op: Callable[[NumberLike], NumberLike] A callable representing the unary operation (e.g., `operator.neg`, `operator.abs`). @@ -508,19 +508,19 @@ class Image: Attributes ---------- - _value : np.ndarray + _value: np.ndarray The underlying data stored in the Image object as NumPy. - properties : List[Dict[str, Property]] + properties: List[Dict[str, Property]] A list of property dictionaries associated with the Image. Parameters ---------- - value : np.ndarray or list or int or float or bool or Image + value: np.ndarray or list or int or float or bool or Image The array-like object to be converted to a NumPy array and stored in the Image object. If it is an Image, the value and properties of the image are copied or referenced depening on the value of the `copy` parameter. - copy : bool, optional + copy: bool, optional If `True`, the `value` is copied to ensure independence (default). If `False`, a reference to the original value is maintained. @@ -643,11 +643,11 @@ class Image: """ # Attributes. - _value : np.ndarray - properties : List[Dict[str, Property]] + _value: np.ndarray + properties: List[Dict[str, Property]] def __init__( - self : Image, + self: Image, value: Union[np.ndarray, list, int, float, bool, Image], copy: bool = True, ): @@ -659,20 +659,20 @@ def __init__( Parameters ---------- - value : np.ndarray or list or int or float or bool or Image + value: np.ndarray or list or int or float or bool or Image The array-like object to be converted to a NumPy array and stored in the Image object. If it is an Image, the value and properties of the image are copied or referenced depening on the value of the `copy` parameter. - copy : bool, optional + copy: bool, optional If `True`, the `value` is copied to ensure independence (default). If `False`, a reference to the original value is maintained. Attributes ---------- - _value : np.ndarray + _value: np.ndarray The underlying data stored in the Image object as NumPy. - properties : List[Dict[str, Property]] + properties: List[Dict[str, Property]] A list of property dictionaries associated with the Image. """ @@ -696,7 +696,7 @@ def __init__( self.properties = [] def append( - self : Image, + self: Image, property_dict: Dict[str, Property], ) -> Image: """Append a dictionary to the properties list. @@ -710,7 +710,7 @@ def append( Parameters ---------- - property_dict : Dict[str, Property] + property_dict: Dict[str, Property] A dictionary to append to the property list. Returns @@ -755,7 +755,7 @@ def append( return self def get_property( - self : Image, + self: Image, key: str, get_one: bool = True, default: Any = None, @@ -770,12 +770,12 @@ def get_property( Parameters ---------- - key : str + key: str The name of the property. get_one: bool, optional Whether to return only the first instance of the property (default behavior for `True`) or all instances of the property (`False`). - default : Any, optional + default: Any, optional The value to be returned as default, which is by default `None`. Returns @@ -831,7 +831,7 @@ def get_property( ] or default def merge_properties_from( - self : Image, + self: Image, other: Union[np.ndarray, Image, Iterable], ) -> Image: """Merge properties with those from another Image. @@ -847,7 +847,7 @@ def merge_properties_from( Parameters ---------- - other : Image or np.ndarray or Iterable + other: Image or np.ndarray or Iterable The data to retrieve properties from. It can be an Image, a NumPy array (which has no properties), or an iterable object. @@ -944,7 +944,7 @@ def merge_properties_from( return self def _view( - self : Image, + self: Image, value: Union[np.ndarray, list, int, float, bool, Image], ) -> np.ndarray: """Convert the value to NumPy array for storage in the Image object. @@ -963,7 +963,7 @@ def _view( Parameters ---------- - value : np.ndarray or list or int or float or bool or Image + value: np.ndarray or list or int or float or bool or Image The input value to be transformed to a NumPy array. Returns @@ -1001,13 +1001,13 @@ def __array_ufunc__( Parameters ---------- - ufunc : np.ufunc + ufunc: np.ufunc The NumPy ufunc being called. - method : str + method: str The method of the ufunc being called (e.g., "__call__", "reduce"). - *inputs : Tuple[Any, ...] + *inputs: Tuple[Any, ...] Positional arguments passed to the ufunc. - **kwargs : Dict[str, Any] + **kwargs: Dict[str, Any] Keyword arguments passed to the ufunc. Returns @@ -1104,13 +1104,13 @@ def __array_function__( Parameters ---------- - func : Callable + func: Callable The NumPy function being called (e.g., `np.mean`, `np.dot`). - types : Tuple[type, ...] + types: Tuple[type, ...] The types of the arguments involved in the function. - args : Tuple[Any, ...] + args: Tuple[Any, ...] The positional arguments for the function. - kwargs : Dict[str, Any] + kwargs: Dict[str, Any] The keyword arguments for the function. Returns @@ -1205,9 +1205,9 @@ def __array__( Parameters ---------- - *args : Tuple[Any, ...] + *args: Tuple[Any, ...] Positional arguments passed to `numpy.array`. - **kwargs : Dict[str, Any] + **kwargs: Dict[str, Any] Keyword arguments passed to `numpy.array`. Returns @@ -1348,7 +1348,7 @@ def __getattr__( Parameters ---------- - key : str + key: str The name of the attribute to access. Returns @@ -1378,7 +1378,7 @@ def __getitem__( Parameters ---------- - idx : int or slice or Tuple[int or slice, ...] or Any + idx: int or slice or Tuple[int or slice, ...] or Any The index or indices used to access elements of the Image. Returns @@ -1428,12 +1428,12 @@ def __setitem__( Parameters ---------- - key : int or slice or Tuple[int or slice, ...] or List[int] + key: int or slice or Tuple[int or slice, ...] or List[int] The index or slice to update. It can be a single integer to update a specific position, a slice to update a range of positions, a tuple of integers or slices for multi-dimensional indexing, or a list of integers for advanced indexing. - value : Image or numpy.ndarray or int or float or bool or complex + value: Image or numpy.ndarray or int or float or bool or complex The value to assign to the specified index or slice. If `value` is an `Image`, its `_value` attribute is extracted before assignment. Other types are assigned directly after being stripped if @@ -1533,7 +1533,7 @@ def __round__( Parameters ---------- - ndigits : int, optional + ndigits: int, optional The number of decimal places to round to (default is 0). Returns @@ -1622,7 +1622,7 @@ def strip( Parameters ---------- - element : Image or List or Tuple or Any + element: Image or List or Tuple or Any The input to process. Returns @@ -1675,7 +1675,7 @@ def coerce( Parameters ---------- - images : List[Union[Image, np.ndarray]] + images: List[Union[Image, np.ndarray]] A list of images to be coerced. Each image can be an `Image` instance or a NumPy array. @@ -1743,10 +1743,10 @@ def pad_image_to_fft( Parameters ---------- - image : Image or np.ndarray + image: Image or np.ndarray The input image to pad. It should be an instance of the `Image` class or any array-like structure compatible with FFT operations. - axes : Iterable[int], optional + axes: Iterable[int], optional The axes along which to apply padding. Defaults to `(0, 1)`. Returns @@ -1821,7 +1821,7 @@ def maybe_cupy( Parameters ---------- - array : np.ndarray or List or Tuple + array: np.ndarray or List or Tuple The input array to be potentially converted to a CuPy array. Returns From 5edfceeba18c10514af5f91a89f2f67cab5bb90b Mon Sep 17 00:00:00 2001 From: Alex <95913221+Pwhsky@users.noreply.github.com> Date: Mon, 10 Mar 2025 11:36:48 +0100 Subject: [PATCH 09/17] formatting docstring --- deeptrack/image.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/deeptrack/image.py b/deeptrack/image.py index 27135912a..9e7983dbd 100644 --- a/deeptrack/image.py +++ b/deeptrack/image.py @@ -1,4 +1,4 @@ -"""Image class and relative functions. +"""Containers for array-like structures. This module defines the `Image` class and related utility functions for managing array-like structures and their associated properties. The `Image` @@ -32,14 +32,14 @@ class is central to DeepTrack2, acting as a container for numerical data Key Classes ----------- +- `Image`: Core class for managing array-like data and their properties. -- `Image`: - Core class for managing array-like data and their properties. - + Encapsulates array-like data structures (e.g., NumPy arrays, lists, + Torch tensors) while providing a unified interface for array operations and + property management. Methods ------- - - `strip(element)` strip( From 703869bb85865eae106e5af2f3b68a757f4c9c70 Mon Sep 17 00:00:00 2001 From: Alex <95913221+Pwhsky@users.noreply.github.com> Date: Wed, 12 Mar 2025 11:07:53 +0100 Subject: [PATCH 10/17] style in example --- deeptrack/image.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deeptrack/image.py b/deeptrack/image.py index 9e7983dbd..12f815c2c 100644 --- a/deeptrack/image.py +++ b/deeptrack/image.py @@ -82,8 +82,8 @@ class is central to DeepTrack2, acting as a container for numerical data >>> img = Image(np.array([[1, 2], [3, 4]])) >>> print(img + 1) -... Image([[2, 3], -... [4, 5]]) +Image([[2, 3], +[4, 5]]) Property tracking: From 3b5a49873f2b616ed53fd2cfd0ac18db954e264a Mon Sep 17 00:00:00 2001 From: Alex <95913221+Pwhsky@users.noreply.github.com> Date: Wed, 12 Mar 2025 16:12:25 +0100 Subject: [PATCH 11/17] main concepts -> key features --- deeptrack/image.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deeptrack/image.py b/deeptrack/image.py index 12f815c2c..89c65d57d 100644 --- a/deeptrack/image.py +++ b/deeptrack/image.py @@ -6,8 +6,8 @@ class is central to DeepTrack2, acting as a container for numerical data (such as images, tensors, and scalars) while maintaining the properties generated by features during pipeline processing. -Main Concepts -------------- +Key Features +------------ - **Enhanced Array-Like Interface** The `Image` class provides an interface similar to NumPy arrays, enabling From 79d36d0dc02c19073c0459ea317b39f1f027cd42 Mon Sep 17 00:00:00 2001 From: Alex <95913221+Pwhsky@users.noreply.github.com> Date: Thu, 13 Mar 2025 13:38:47 +0100 Subject: [PATCH 12/17] Docs, union removed, generic types used --- deeptrack/image.py | 142 ++++++++++++++++++++++----------------------- 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/deeptrack/image.py b/deeptrack/image.py index 89c65d57d..dbb9b1d5e 100644 --- a/deeptrack/image.py +++ b/deeptrack/image.py @@ -43,7 +43,7 @@ class is central to DeepTrack2, acting as a container for numerical data - `strip(element)` strip( - element: Union[Image, List, Tuple, Any], + element: Image | List | Tuple | Any, ) -> Any Recursively extract the underlying value from an Image object. @@ -51,17 +51,17 @@ class is central to DeepTrack2, acting as a container for numerical data - `coerce(images)` coerce( - images: List[Union[Image, np.ndarray]], - ) -> List[Image] + images: list[Image | np.ndarray], + ) -> list[Image] Coerce a list of images to a consistent type. - `pad_image_to_fft(image, axes)` pad_image_to_fft( - image: Union[Image, np.ndarray], + image: Image | np.ndarray, axes: Iterable[int] = (0, 1), - ) -> Union[Image, np.ndarray] + ) -> Image | np.ndarray Pads an image to optimize Fast Fourier Transform (FFT) performance. @@ -69,7 +69,7 @@ class is central to DeepTrack2, acting as a container for numerical data maybe_cupy( array: Union[np.ndarray, List, Tuple], - ) -> Union[cupy.ndarray, np.ndarray] + ) -> cupy.ndarray | np.ndarray Convert an array to a CuPy array if GPU is available and enabled. @@ -97,7 +97,7 @@ class is central to DeepTrack2, acting as a container for numerical data from __future__ import annotations import operator as ops -from typing import Any, Callable, Dict, Iterable, List, Tuple, Union +from typing import Any, Callable #Dict, Iterable, Tuple, Union import numpy as np @@ -139,8 +139,8 @@ def _binary_method( A method that can be assigned to a binary operator (e.g., `__add__`) of the `Image` class. - Example - ------- + Examples + -------- >>> import operator >>> import numpy as np >>> from deeptrack.image import _binary_method, Image @@ -167,7 +167,7 @@ def _binary_method( def func( self: Image, - other: Union[Image, NumberLike], + other: Image | NumberLike, ) -> Image: # Coerce inputs to compatible types. @@ -193,7 +193,7 @@ def func( def _reflected_binary_method( op: Callable[[NumberLike, NumberLike], NumberLike], -) -> Callable[[Union[Image, NumberLike], Image], Image]: +) -> Callable[[Image | NumberLike, Image], Image]: """Implement a reflected binary operator for the Image class. This function generates a reflected binary method (e.g., `__radd__`, @@ -225,8 +225,8 @@ def _reflected_binary_method( A method that can be assigned to a reflected binary operator (e.g., `__radd__`) of the `Image` class. - Example - ------- + Examples + -------- >>> import operator >>> import numpy as np >>> from deeptrack.image import _reflected_binary_method, Image @@ -253,7 +253,7 @@ def _reflected_binary_method( def func( self: Image, - other: Union[Image, NumberLike], + other: Image | NumberLike, ) -> Image: # Coerce inputs to compatible types. @@ -279,7 +279,7 @@ def func( def _inplace_binary_method( op: Callable[[NumberLike, NumberLike], NumberLike] -) -> Callable[[Image, Union[Image, NumberLike]], Image]: +) -> Callable[[Image, Image | NumberLike], Image]: """Implement an in-place binary operator for the Image class. This function generates an in-place binary method (e.g., `__iadd__`, @@ -307,8 +307,8 @@ def _inplace_binary_method( A method that can be assigned to an in-place binary operator (e.g., `__iadd__`) of the `Image` class. - Example - ------- + Examples + -------- >>> import operator >>> import numpy as np >>> from deeptrack.image import _inplace_binary_method, Image @@ -335,7 +335,7 @@ def _inplace_binary_method( def func( self: Image, - other: Union[Image, NumberLike], + other: Image | NumberLike, ) -> Image: # Coerce inputs to compatible types. @@ -359,9 +359,9 @@ def func( def _numeric_methods( op: Callable[[NumberLike, NumberLike], NumberLike], ) -> Tuple[ - Callable[[Image, Union[Image, NumberLike]], Image], - Callable[[Union[Image, NumberLike], Image], Image], - Callable[[Image, Union[Image, NumberLike]], Image] + Callable[[Image, Image | NumberLike], Image], + Callable[[Image | NumberLike, Image], Image], + Callable[[Image, Image | NumberLike], Image] ]: """Generate forward, reflected, and in-place binary methods. @@ -391,8 +391,8 @@ def _numeric_methods( (2) The reflected binary method (`_reflected_binary_method`). (3) The in-place binary method (`_inplace_binary_method`). - Example - ------- + Examples + -------- >>> import operator >>> from deeptrack.image import _numeric_methods, Image @@ -452,8 +452,8 @@ def _unary_method( A method that can be assigned to a unary operator (e.g., `__neg__`) of the `Image` class. - Example - ------- + Examples + -------- >>> import operator >>> import numpy as np >>> from deeptrack.image import _unary_method, Image @@ -530,10 +530,10 @@ class Image: `append(property_dict: dict) -> Image` Add a dictionary of properties to the `Image`. - `get_property(key: str, get_one: bool = True, default: Any = None) -> Union[Any, List[Any]]` + `get_property(key: str, get_one: bool = True, default: Any = None) -> Any | List[Any]` Retrieve a property by key. If `get_one` is `True`, returns the first match; otherwise, returns a list of matches. - `merge_properties_from(other: Union[Image, List[Image], np.ndarray]) -> Image` + `merge_properties_from(other: Image | List[Image] | np.ndarray) -> Image` Merge properties from another `Image`, list of `Image`s, or a NumPy array. @@ -550,7 +550,7 @@ class Image: **NumPy Compatibility - `__array_ufunc__(ufunc: Callable, method: str, *inputs: Tuple[Any], **kwargs: Dict[str, Any]) -> Union[Image, Tuple[Image, ...], None]` + `__array_ufunc__(ufunc: Callable, method: str, *inputs: Tuple[Any], **kwargs: Dict[str, Any]) -> Image | Tuple[Image, ...] | None` Enable compatibility with numpy's universal functions (ufuncs). Examples include `np.add`, `np.multiply`, and `np.sin`. @@ -570,7 +570,7 @@ class Image: - Bitwise: `np.bitwise_and`, `np.bitwise_or`, `np.bitwise_xor`, etc. - `__array_function__(func: Callable[..., Any], types: Tuple[type, ...], args: Tuple[Any, ...], kwargs: Dict[str, Any]) -> Union[Image, Tuple[Image, ...], Any]` + `__array_function__(func: Callable[..., Any], types: tuple[type, ...], args: tuple[Any, ...], kwargs: dict[str, Any]) -> Image | tuple[Image, ...] | Any` Enable compatibility with numpy's general functions, such as `np.mean`, `np.dot`, and `np.concatenate`. @@ -585,7 +585,7 @@ class Image: **Indexing and Assignment** - `__getitem__(idx: Any) -> Union[Image, Any]` + `__getitem__(idx: Any) -> Image | Any` Access array elements using standard indexing or slicing. If the result is scalar, returns it; otherwise, returns an `Image`. `__setitem__(key: Any, value: Any) -> None` @@ -648,7 +648,7 @@ class Image: def __init__( self: Image, - value: Union[np.ndarray, list, int, float, bool, Image], + value: np.ndarray | list | int | float | bool | Image], copy: bool = True, ): """Initialize an Image object. @@ -697,7 +697,7 @@ def __init__( def append( self: Image, - property_dict: Dict[str, Property], + property_dict: dict[str, Property], ) -> Image: """Append a dictionary to the properties list. @@ -718,8 +718,8 @@ def append( Image Returns itself. - Example - ------- + Examples + -------- >>> import numpy as np >>> from deeptrack import Feature, Image @@ -759,7 +759,7 @@ def get_property( key: str, get_one: bool = True, default: Any = None, - ) -> Union[Any, List[Any]]: + ) -> Any | list[Any]: """Retrieve the value of a property of the Image. If the feature has the property defined by `key`, the method returns @@ -785,8 +785,8 @@ def get_property( as a list (if `get_one` is `True`). If the property is not found, it returns `default`. - Example - ------- + Examples + -------- >>> import numpy as np >>> from deeptrack import Feature, Image @@ -832,7 +832,7 @@ def get_property( def merge_properties_from( self: Image, - other: Union[np.ndarray, Image, Iterable], + other: np.ndarray | Image | Iterable, ) -> Image: """Merge properties with those from another Image. @@ -856,8 +856,8 @@ def merge_properties_from( Image Returns itself. - Example - ------- + Examples + -------- >>> import numpy as np >>> from deeptrack import Feature, Image @@ -945,7 +945,7 @@ def merge_properties_from( def _view( self: Image, - value: Union[np.ndarray, list, int, float, bool, Image], + value: np.ndarray | list | int | float | bool | Image, ) -> np.ndarray: """Convert the value to NumPy array for storage in the Image object. @@ -990,9 +990,9 @@ def __array_ufunc__( self: Image, ufunc: np.ufunc, method: str, - *inputs: Tuple[Any, ...], - **kwargs: Dict[str, Any], - ) -> Union[Image, Tuple[Image, ...], None]: + *inputs: tuple[Any, ...], + **kwargs: dict[str, Any], + ) -> Image | tuple[Image, ...] | None: """Enable Image objects to use NumPy ufuncs. This method integrates the Image class with NumPy's universal functions @@ -1092,10 +1092,10 @@ def __array_ufunc__( def __array_function__( self: Image, func: Callable[..., Any], - types: Tuple[type, ...], - args: Tuple[Any, ...], - kwargs: Dict[str, Any], - ) -> Union[Image, Tuple[Image, ...], Any]: + types: tuple[type, ...], + args: tuple[Any, ...], + kwargs: dict[str, Any], + ) -> Image | tuple[Image, ...] | Any: """Handle NumPy functions for Image objects. This method integrates Image objects with NumPy functions, allowing @@ -1190,8 +1190,8 @@ def __array_function__( def __array__( self: Image, - *args: Tuple[Any, ...], - **kwargs: Dict[str, Any], + *args: tuple[Any, ...], + **kwargs: dict[str, Any], ) -> np.ndarray: """Convert the Image object to a NumPy array. @@ -1367,8 +1367,8 @@ def __getattr__( def __getitem__( self: Image, - idx: Union[int, slice, Tuple[Union[int, slice], ...], Any], - ) -> Union[Image, int, float, bool, complex, np.ndarray]: + idx: int | slice | tuple[int | slice, ...], Any, + ) -> Image | int | float | bool | complex | np.ndarray: """Access and return an item or a slice from the Image. This method allows indexing into the wrapped `_value` of the Image, @@ -1387,8 +1387,8 @@ def __getitem__( The accessed value, either as an Image (for array-like results) or as a scalar for single-element results. - Example - ------- + Examples + -------- >>> from deeptrack.image import Image >>> img = Image(np.array([[1, 2], [3, 4]])) @@ -1417,8 +1417,8 @@ def __getitem__( def __setitem__( self: Image, - key: Union[int, slice, Tuple[Union[int, slice], ...], List[int]], - value: Union[int, slice, Tuple[Union[int, slice], ...], List[int]], + key: int | slice | tuple[int | slice, ...] | list[int], + value: int | slice | tuple[int | slice, ...] | list[int], ) -> None: """Assign a value to a specific index or slice of the image. @@ -1443,8 +1443,8 @@ def __setitem__( ------- None - Example - ------- + Examples + -------- Assign a scalar to a specific index: >>> import numpy as np @@ -1611,7 +1611,7 @@ def __repr__( def strip( - element: Union[Image, List, Tuple, Any], + element: Image | list | tuple | Any, ) -> Any: """Recursively extract the underlying value from an Image object. @@ -1665,8 +1665,8 @@ def strip( def coerce( - images: List[Union[Image, np.ndarray]], -) -> List[Image]: + images: list[Image | np.ndarray], +) -> list[Image]: """Coerce a list of images to a consistent type. This function ensures that all images in the input list are instances of @@ -1685,8 +1685,8 @@ def coerce( A list of `Image` instances where all elements are coerced to the same type (CuPy if CuPy arrays are present in any image). - Example - ------- + Examples + -------- >>> import numpy as np >>> from deeptrack.image import coerce, Image @@ -1732,9 +1732,9 @@ def coerce( def pad_image_to_fft( - image: Union[Image, np.ndarray], + image: Image | np.ndarray, axes: Iterable[int] = (0, 1), -) -> Union[Image, np.ndarray]: +) -> Image | np.ndarray: """Pads an image to optimize Fast Fourier Transform (FFT) performance. This function pads an image by adding zeros to the end of specified axes @@ -1759,8 +1759,8 @@ def pad_image_to_fft( ValueError If no suitable size is found in `_FASTEST_SIZES` for any axis length. - Example - ------- + Examples + -------- >>> import numpy as np >>> from deeptrack.image import Image, pad_image_to_fft @@ -1808,8 +1808,8 @@ def _closest( def maybe_cupy( - array: Union[np.ndarray, List, Tuple], -) -> Union[cupy.ndarray, np.ndarray]: + array: np.ndarray | list | tuple, +) -> cupy.ndarray | np.ndarray: """Convert an array to a CuPy array if GPU is available and enabled. This function checks if GPU computation is enabled in the configuration. @@ -1834,8 +1834,8 @@ def maybe_cupy( ImportError If GPU is enabled but the `cupy` library is not installed. - Example - ------- + Examples + -------- >>> import numpy as np >>> from deeptrack.image import maybe_cupy From d87d051358d1a97a13c9ab7743a02ba14da79133 Mon Sep 17 00:00:00 2001 From: Alex <95913221+Pwhsky@users.noreply.github.com> Date: Thu, 13 Mar 2025 13:41:51 +0100 Subject: [PATCH 13/17] fix unclosed bracket --- deeptrack/image.py | 58 +++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/deeptrack/image.py b/deeptrack/image.py index dbb9b1d5e..e23104b94 100644 --- a/deeptrack/image.py +++ b/deeptrack/image.py @@ -43,7 +43,7 @@ class is central to DeepTrack2, acting as a container for numerical data - `strip(element)` strip( - element: Image | List | Tuple | Any, + element: Image | list | tuple | Any, ) -> Any Recursively extract the underlying value from an Image object. @@ -68,7 +68,7 @@ class is central to DeepTrack2, acting as a container for numerical data - `maybe_cupy(array)` maybe_cupy( - array: Union[np.ndarray, List, Tuple], + array: Union[np.ndarray, list, tuple], ) -> cupy.ndarray | np.ndarray Convert an array to a CuPy array if GPU is available and enabled. @@ -358,7 +358,7 @@ def func( def _numeric_methods( op: Callable[[NumberLike, NumberLike], NumberLike], -) -> Tuple[ +) -> tuple[ Callable[[Image, Image | NumberLike], Image], Callable[[Image | NumberLike, Image], Image], Callable[[Image, Image | NumberLike], Image] @@ -381,7 +381,7 @@ def _numeric_methods( Returns ------- - Tuple[ + tuple[ Callable[[Image, Union[Image, NumberLike]], Image], Callable[[Union[Image, NumberLike], Image], Image], Callable[[Image, Union[Image, NumberLike]], Image] @@ -510,7 +510,7 @@ class Image: ---------- _value: np.ndarray The underlying data stored in the Image object as NumPy. - properties: List[Dict[str, Property]] + properties: list[dict[str, Property]] A list of property dictionaries associated with the Image. Parameters @@ -530,10 +530,10 @@ class Image: `append(property_dict: dict) -> Image` Add a dictionary of properties to the `Image`. - `get_property(key: str, get_one: bool = True, default: Any = None) -> Any | List[Any]` + `get_property(key: str, get_one: bool = True, default: Any = None) -> Any | list[Any]` Retrieve a property by key. If `get_one` is `True`, returns the first match; otherwise, returns a list of matches. - `merge_properties_from(other: Image | List[Image] | np.ndarray) -> Image` + `merge_properties_from(other: Image | list[Image] | np.ndarray) -> Image` Merge properties from another `Image`, list of `Image`s, or a NumPy array. @@ -545,12 +545,12 @@ class Image: `to_numpy() -> Image` Convert the `Image` to a numpy array if the underlying value is a CuPy array. - `__array__(*args: Tuple[Any, ...], **kwargs: Dict[str, Any]) -> np.ndarray` + `__array__(*args: tuple[Any, ...], **kwargs: dict[str, Any]) -> np.ndarray` Convert the `Image` to a numpy array. Used implicitly by numpy functions. **NumPy Compatibility - `__array_ufunc__(ufunc: Callable, method: str, *inputs: Tuple[Any], **kwargs: Dict[str, Any]) -> Image | Tuple[Image, ...] | None` + `__array_ufunc__(ufunc: Callable, method: str, *inputs: tuple[Any], **kwargs: dict[str, Any]) -> Image | tuple[Image, ...] | None` Enable compatibility with numpy's universal functions (ufuncs). Examples include `np.add`, `np.multiply`, and `np.sin`. @@ -644,11 +644,11 @@ class Image: # Attributes. _value: np.ndarray - properties: List[Dict[str, Property]] + properties: list[dict[str, Property]] def __init__( self: Image, - value: np.ndarray | list | int | float | bool | Image], + value: np.ndarray | list | int | float | bool | Image, copy: bool = True, ): """Initialize an Image object. @@ -672,7 +672,7 @@ def __init__( ---------- _value: np.ndarray The underlying data stored in the Image object as NumPy. - properties: List[Dict[str, Property]] + properties: list[dict[str, Property]] A list of property dictionaries associated with the Image. """ @@ -710,7 +710,7 @@ def append( Parameters ---------- - property_dict: Dict[str, Property] + property_dict: dict[str, Property] A dictionary to append to the property list. Returns @@ -780,7 +780,7 @@ def get_property( Returns ------- - Any or List[Any] + Any or list[Any] The value of the property (if `get_one` is `True`) or all instances as a list (if `get_one` is `True`). If the property is not found, it returns `default`. @@ -1005,14 +1005,14 @@ def __array_ufunc__( The NumPy ufunc being called. method: str The method of the ufunc being called (e.g., "__call__", "reduce"). - *inputs: Tuple[Any, ...] + *inputs: tuple[Any, ...] Positional arguments passed to the ufunc. - **kwargs: Dict[str, Any] + **kwargs: dict[str, Any] Keyword arguments passed to the ufunc. Returns ------- - Image or Tuple[Image, ...] or None] + Image or tuple[Image, ...] or None] The result of the ufunc applied to the Image object(s). If the ufunc returns a tuple, each element is wrapped in an Image. For the `at` method, returns `None`. @@ -1106,16 +1106,16 @@ def __array_function__( ---------- func: Callable The NumPy function being called (e.g., `np.mean`, `np.dot`). - types: Tuple[type, ...] + types: tuple[type, ...] The types of the arguments involved in the function. - args: Tuple[Any, ...] + args: tuple[Any, ...] The positional arguments for the function. - kwargs: Dict[str, Any] + kwargs: dict[str, Any] The keyword arguments for the function. Returns ------- - Union[Image, Tuple[Image, ...], Any] + Union[Image, tuple[Image, ...], Any] The result of the NumPy function. If the function returns a single value, it may be wrapped as an Image object. If it returns a tuple, each element is wrapped as an Image. Constants remain unwrapped. @@ -1205,9 +1205,9 @@ def __array__( Parameters ---------- - *args: Tuple[Any, ...] + *args: tuple[Any, ...] Positional arguments passed to `numpy.array`. - **kwargs: Dict[str, Any] + **kwargs: dict[str, Any] Keyword arguments passed to `numpy.array`. Returns @@ -1378,7 +1378,7 @@ def __getitem__( Parameters ---------- - idx: int or slice or Tuple[int or slice, ...] or Any + idx: int or slice or tuple[int or slice, ...] or Any The index or indices used to access elements of the Image. Returns @@ -1428,7 +1428,7 @@ def __setitem__( Parameters ---------- - key: int or slice or Tuple[int or slice, ...] or List[int] + key: int or slice or tuple[int or slice, ...] or list[int] The index or slice to update. It can be a single integer to update a specific position, a slice to update a range of positions, a tuple of integers or slices for multi-dimensional indexing, or a @@ -1622,7 +1622,7 @@ def strip( Parameters ---------- - element: Image or List or Tuple or Any + element: Image or list or tuple or Any The input to process. Returns @@ -1675,13 +1675,13 @@ def coerce( Parameters ---------- - images: List[Union[Image, np.ndarray]] + images: list[Union[Image, np.ndarray]] A list of images to be coerced. Each image can be an `Image` instance or a NumPy array. Returns ------- - List[Image] + list[Image] A list of `Image` instances where all elements are coerced to the same type (CuPy if CuPy arrays are present in any image). @@ -1821,7 +1821,7 @@ def maybe_cupy( Parameters ---------- - array: np.ndarray or List or Tuple + array: np.ndarray or list or tuple The input array to be potentially converted to a CuPy array. Returns From 58b3a3fdb2bc7d48387dfc767bf285611b95b696 Mon Sep 17 00:00:00 2001 From: Alex <95913221+Pwhsky@users.noreply.github.com> Date: Thu, 13 Mar 2025 13:45:29 +0100 Subject: [PATCH 14/17] removed Union in docs --- deeptrack/image.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/deeptrack/image.py b/deeptrack/image.py index e23104b94..6f2d5214e 100644 --- a/deeptrack/image.py +++ b/deeptrack/image.py @@ -68,7 +68,7 @@ class is central to DeepTrack2, acting as a container for numerical data - `maybe_cupy(array)` maybe_cupy( - array: Union[np.ndarray, list, tuple], + array: np.ndarray | list | tuple, ) -> cupy.ndarray | np.ndarray Convert an array to a CuPy array if GPU is available and enabled. @@ -108,7 +108,7 @@ class is central to DeepTrack2, acting as a container for numerical data def _binary_method( op: Callable[[NumberLike, NumberLike], NumberLike], -) -> Callable[[Image, Union[Image, NumberLike]], Image]: +) -> Callable[[Image, Image | NumberLike], Image]: """Implement a binary operator for the Image class. This function generates a binary method (e.g., `__add__`, `__sub__`) for @@ -135,7 +135,7 @@ def _binary_method( Returns ------- - Callable[[Image, Union[Image, NumberLike]], Image] + Callable[[Image, Image | NumberLike], Image] A method that can be assigned to a binary operator (e.g., `__add__`) of the `Image` class. @@ -221,7 +221,7 @@ def _reflected_binary_method( Returns ------- - Callable[[Image, Union[Image, NumberLike]], Image] + Callable[[Image, Image | NumberLike], Image] A method that can be assigned to a reflected binary operator (e.g., `__radd__`) of the `Image` class. @@ -303,7 +303,7 @@ def _inplace_binary_method( Returns ------- - Callable[[Image, Union[Image, NumberLike]], None] + Callable[[Image, Image | NumberLike], None] A method that can be assigned to an in-place binary operator (e.g., `__iadd__`) of the `Image` class. @@ -382,9 +382,9 @@ def _numeric_methods( Returns ------- tuple[ - Callable[[Image, Union[Image, NumberLike]], Image], - Callable[[Union[Image, NumberLike], Image], Image], - Callable[[Image, Union[Image, NumberLike]], Image] + Callable[[Image, Image | NumberLike], Image], + Callable[[Image | NumberLike, Image], Image], + Callable[[Image, Image | NumberLike], Image] ] A tuple containing three callables: (1) The forward binary method (`_binary_method`). @@ -1115,7 +1115,7 @@ def __array_function__( Returns ------- - Union[Image, tuple[Image, ...], Any] + Image | tuple[Image, ...] | Any The result of the NumPy function. If the function returns a single value, it may be wrapped as an Image object. If it returns a tuple, each element is wrapped as an Image. Constants remain unwrapped. @@ -1675,7 +1675,7 @@ def coerce( Parameters ---------- - images: list[Union[Image, np.ndarray]] + images: list[Image | np.ndarray] A list of images to be coerced. Each image can be an `Image` instance or a NumPy array. @@ -1858,4 +1858,4 @@ def maybe_cupy( if config.gpu_enabled: return cupy.array(array) - return array + return array \ No newline at end of file From 9469231a313f4c7b99709a228c54adfb3f40367e Mon Sep 17 00:00:00 2001 From: Alex <95913221+Pwhsky@users.noreply.github.com> Date: Thu, 13 Mar 2025 13:47:03 +0100 Subject: [PATCH 15/17] import iterable --- deeptrack/image.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deeptrack/image.py b/deeptrack/image.py index 6f2d5214e..3328eaa37 100644 --- a/deeptrack/image.py +++ b/deeptrack/image.py @@ -97,7 +97,7 @@ class is central to DeepTrack2, acting as a container for numerical data from __future__ import annotations import operator as ops -from typing import Any, Callable #Dict, Iterable, Tuple, Union +from typing import Any, Callable, Iterable import numpy as np From 227b904c038d88bd05edd47b188da93b8e34c19e Mon Sep 17 00:00:00 2001 From: Alex <95913221+Pwhsky@users.noreply.github.com> Date: Thu, 13 Mar 2025 13:51:22 +0100 Subject: [PATCH 16/17] typo fix --- deeptrack/image.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deeptrack/image.py b/deeptrack/image.py index 3328eaa37..bf1b011f3 100644 --- a/deeptrack/image.py +++ b/deeptrack/image.py @@ -1367,7 +1367,7 @@ def __getattr__( def __getitem__( self: Image, - idx: int | slice | tuple[int | slice, ...], Any, + idx: int | slice | tuple[int | slice, ...] | Any, ) -> Image | int | float | bool | complex | np.ndarray: """Access and return an item or a slice from the Image. From fe80f3882f43d4210cd0988298e24d84eb1ec8e3 Mon Sep 17 00:00:00 2001 From: Alex <95913221+Pwhsky@users.noreply.github.com> Date: Thu, 13 Mar 2025 16:20:59 +0100 Subject: [PATCH 17/17] Type hints in docs --- deeptrack/image.py | 161 ++++++++++++++++++++++++++------------------- 1 file changed, 93 insertions(+), 68 deletions(-) diff --git a/deeptrack/image.py b/deeptrack/image.py index bf1b011f3..52dd501a3 100644 --- a/deeptrack/image.py +++ b/deeptrack/image.py @@ -43,7 +43,7 @@ class is central to DeepTrack2, acting as a container for numerical data - `strip(element)` strip( - element: Image | list | tuple | Any, + element: Image | np.ndarray | list | tuple | Any, ) -> Any Recursively extract the underlying value from an Image object. @@ -166,8 +166,8 @@ def _binary_method( """ def func( - self: Image, - other: Image | NumberLike, + self: Image | np.ndarray, + other: Image | np.ndarray | NumberLike, ) -> Image: # Coerce inputs to compatible types. @@ -252,8 +252,8 @@ def _reflected_binary_method( """ def func( - self: Image, - other: Image | NumberLike, + self: Image | np.ndarray, + other: Image | np.ndarray | NumberLike, ) -> Image: # Coerce inputs to compatible types. @@ -334,8 +334,8 @@ def _inplace_binary_method( """ def func( - self: Image, - other: Image | NumberLike, + self: Image | np.ndarray, + other: Image | np.ndarray | NumberLike, ) -> Image: # Coerce inputs to compatible types. @@ -472,7 +472,7 @@ def _unary_method( """ def func( - self: Image, + self: Image | np.ndarray, ) -> Image: # Apply the unary operator to the Image instance. @@ -515,7 +515,7 @@ class Image: Parameters ---------- - value: np.ndarray or list or int or float or bool or Image + value: np.ndarray | list | int | float | bool | Image The array-like object to be converted to a NumPy array and stored in the Image object. If it is an Image, the value and properties of the image are copied or referenced depening on the value of the `copy` @@ -528,12 +528,22 @@ class Image: ------- **Property Management** - `append(property_dict: dict) -> Image` + `append( + property_dict: dict + ) -> Image` Add a dictionary of properties to the `Image`. - `get_property(key: str, get_one: bool = True, default: Any = None) -> Any | list[Any]` + + `get_property( + key: str, + get_one: bool = True, + default: Any = None + ) -> Any | list[Any]` Retrieve a property by key. If `get_one` is `True`, returns the first match; otherwise, returns a list of matches. - `merge_properties_from(other: Image | list[Image] | np.ndarray) -> Image` + + `merge_properties_from( + other: Image | list[Image] | np.ndarray | list[np.ndarray] + ) -> Image` Merge properties from another `Image`, list of `Image`s, or a NumPy array. @@ -550,27 +560,37 @@ class Image: **NumPy Compatibility - `__array_ufunc__(ufunc: Callable, method: str, *inputs: tuple[Any], **kwargs: dict[str, Any]) -> Image | tuple[Image, ...] | None` + `__array_ufunc__( + ufunc: Callable, + method: str, + *inputs: tuple[Any], + **kwargs: dict[str, Any] + ) -> Image | tuple[Image, ...] | None` Enable compatibility with numpy's universal functions (ufuncs). Examples include `np.add`, `np.multiply`, and `np.sin`. - The following NumPy universal functions (ufuncs) are supported: - - - Arithmetic: - `np.add`, `np.subtract`, `np.multiply`, `np.divide`, `np.power`, - `np.mod`, etc. - - Trigonometric: - `np.sin`, `np.cos`, `np.tan`, `np.arcsin`, `np.arccos`, - `np.arctan`, etc. - - Exponential and logarithmic: - `np.exp`, `np.log`, `np.log10`, etc. - - Comparison: - `np.equal`, `np.not_equal`, `np.less`, `np.less_equal`, - `np.greater`, `np.greater_equal`, etc. - - Bitwise: - `np.bitwise_and`, `np.bitwise_or`, `np.bitwise_xor`, etc. - - `__array_function__(func: Callable[..., Any], types: tuple[type, ...], args: tuple[Any, ...], kwargs: dict[str, Any]) -> Image | tuple[Image, ...] | Any` + The following NumPy universal functions (ufuncs) are supported: + + - Arithmetic: + `np.add`, `np.subtract`, `np.multiply`, `np.divide`, `np.power`, + `np.mod`, etc. + - Trigonometric: + `np.sin`, `np.cos`, `np.tan`, `np.arcsin`, `np.arccos`, + `np.arctan`, etc. + - Exponential and logarithmic: + `np.exp`, `np.log`, `np.log10`, etc. + - Comparison: + `np.equal`, `np.not_equal`, `np.less`, `np.less_equal`, + `np.greater`, `np.greater_equal`, etc. + - Bitwise: + `np.bitwise_and`, `np.bitwise_or`, `np.bitwise_xor`, etc. + + `__array_function__( + func: Callable[..., Any], + types: tuple[type, ...], + args: tuple[Any, ...], + kwargs: dict[str, Any] + ) -> Image | tuple[Image, ...] | Any` Enable compatibility with numpy's general functions, such as `np.mean`, `np.dot`, and `np.concatenate`. @@ -585,10 +605,15 @@ class Image: **Indexing and Assignment** - `__getitem__(idx: Any) -> Image | Any` + `__getitem__( + idx: Any + ) -> Image | Any` Access array elements using standard indexing or slicing. If the result is scalar, returns it; otherwise, returns an `Image`. - `__setitem__(key: Any, value: Any) -> None` + `__setitem__( + key: Any, + value: Any + ) -> None` Assign values to specific array elements. Updates the properties of the `Image` accordingly. @@ -647,8 +672,8 @@ class Image: properties: list[dict[str, Property]] def __init__( - self: Image, - value: np.ndarray | list | int | float | bool | Image, + self: Image | np.ndarray, + value: Image | np.ndarray | list | int | float | bool, copy: bool = True, ): """Initialize an Image object. @@ -659,7 +684,7 @@ def __init__( Parameters ---------- - value: np.ndarray or list or int or float or bool or Image + value: np.ndarray | list | int | float | bool | Image The array-like object to be converted to a NumPy array and stored in the Image object. If it is an Image, the value and properties of the image are copied or referenced depening on the value of the @@ -696,7 +721,7 @@ def __init__( self.properties = [] def append( - self: Image, + self: Image | np.ndarray, property_dict: dict[str, Property], ) -> Image: """Append a dictionary to the properties list. @@ -755,7 +780,7 @@ def append( return self def get_property( - self: Image, + self: Image | np.ndarray, key: str, get_one: bool = True, default: Any = None, @@ -780,7 +805,7 @@ def get_property( Returns ------- - Any or list[Any] + Any | list[Any] The value of the property (if `get_one` is `True`) or all instances as a list (if `get_one` is `True`). If the property is not found, it returns `default`. @@ -831,7 +856,7 @@ def get_property( ] or default def merge_properties_from( - self: Image, + self: Image | np.ndarray, other: np.ndarray | Image | Iterable, ) -> Image: """Merge properties with those from another Image. @@ -847,7 +872,7 @@ def merge_properties_from( Parameters ---------- - other: Image or np.ndarray or Iterable + other: Image | np.ndarray | Iterable The data to retrieve properties from. It can be an Image, a NumPy array (which has no properties), or an iterable object. @@ -944,8 +969,8 @@ def merge_properties_from( return self def _view( - self: Image, - value: np.ndarray | list | int | float | bool | Image, + self: Image | np.ndarray, + value: Image | np.ndarray | list | int | float | bool, ) -> np.ndarray: """Convert the value to NumPy array for storage in the Image object. @@ -963,7 +988,7 @@ def _view( Parameters ---------- - value: np.ndarray or list or int or float or bool or Image + value: np.ndarray | list | int | float | bool | Image The input value to be transformed to a NumPy array. Returns @@ -987,7 +1012,7 @@ def _view( return value def __array_ufunc__( - self: Image, + self: Image | np.ndarray, ufunc: np.ufunc, method: str, *inputs: tuple[Any, ...], @@ -1012,7 +1037,7 @@ def __array_ufunc__( Returns ------- - Image or tuple[Image, ...] or None] + Image | tuple[Image, ...] | None] The result of the ufunc applied to the Image object(s). If the ufunc returns a tuple, each element is wrapped in an Image. For the `at` method, returns `None`. @@ -1090,7 +1115,7 @@ def __array_ufunc__( return result def __array_function__( - self: Image, + self: Image | np.ndarray, func: Callable[..., Any], types: tuple[type, ...], args: tuple[Any, ...], @@ -1189,7 +1214,7 @@ def __array_function__( return result def __array__( - self: Image, + self: Image | np.ndarray, *args: tuple[Any, ...], **kwargs: dict[str, Any], ) -> np.ndarray: @@ -1236,7 +1261,7 @@ def __array__( return np.array(self.to_numpy()._value, *args) def to_cupy( - self: Image, + self: Image | np.ndarray, ) -> Image: """Convert the image's underlying value to a CuPy array. @@ -1285,7 +1310,7 @@ def to_cupy( return self def to_numpy( - self: Image, + self: Image | np.ndarray, ) -> Image: """Convert the image's underlying value to a NumPy array. @@ -1337,7 +1362,7 @@ def to_numpy( return self def __getattr__( - self: Image, + self: Image | np.ndarray, key: str, ) -> Any: """Access attributes of the underlying value. @@ -1366,7 +1391,7 @@ def __getattr__( return getattr(self._value, key) def __getitem__( - self: Image, + self: Image | np.ndarray, idx: int | slice | tuple[int | slice, ...] | Any, ) -> Image | int | float | bool | complex | np.ndarray: """Access and return an item or a slice from the Image. @@ -1378,12 +1403,12 @@ def __getitem__( Parameters ---------- - idx: int or slice or tuple[int or slice, ...] or Any + idx: int | slice | tuple[int | slice, ...] | Any The index or indices used to access elements of the Image. Returns ------- - Image or int or float or bool or complex or np.ndarray + Image | int | float | bool | complex | np.ndarray The accessed value, either as an Image (for array-like results) or as a scalar for single-element results. @@ -1416,7 +1441,7 @@ def __getitem__( return out def __setitem__( - self: Image, + self: Image | np.ndarray, key: int | slice | tuple[int | slice, ...] | list[int], value: int | slice | tuple[int | slice, ...] | list[int], ) -> None: @@ -1428,12 +1453,12 @@ def __setitem__( Parameters ---------- - key: int or slice or tuple[int or slice, ...] or list[int] + key: int | slice | tuple[int | slice, ...] | list[int] The index or slice to update. It can be a single integer to update a specific position, a slice to update a range of positions, a tuple of integers or slices for multi-dimensional indexing, or a list of integers for advanced indexing. - value: Image or numpy.ndarray or int or float or bool or complex + value: Image | numpy.ndarray | int | float | bool | complex The value to assign to the specified index or slice. If `value` is an `Image`, its `_value` attribute is extracted before assignment. Other types are assigned directly after being stripped if @@ -1498,7 +1523,7 @@ def __int__( return int(self._value) def __float__( - self: Image, + self: Image | np.ndarray, ) -> float: """Convert the Image's value to a float. @@ -1512,7 +1537,7 @@ def __float__( return float(self._value) def __bool__( - self: Image, + self: Image | np.ndarray, ) -> bool: """Check if the Image's value is truthy. @@ -1526,7 +1551,7 @@ def __bool__( return bool(self._value) def __round__( - self: Image, + self: Image | np.ndarray, ndigits: int = 0, ) -> float: """Round the Image's value to a specified number of digits. @@ -1546,7 +1571,7 @@ def __round__( return round(self._value, ndigits) def __len__( - self: Image, + self: Image | np.ndarray, ) -> int: """Return the length of the Image's value. @@ -1560,7 +1585,7 @@ def __len__( return len(self._value) def __repr__( - self: Image, + self: Image | np.ndarray, ) -> str: """Return the string representation of the Image. @@ -1611,7 +1636,7 @@ def __repr__( def strip( - element: Image | list | tuple | Any, + element: Image | np.ndarray | list | tuple | Any, ) -> Any: """Recursively extract the underlying value from an Image object. @@ -1622,7 +1647,7 @@ def strip( Parameters ---------- - element: Image or list or tuple or Any + element: Image | np.ndarray | list | tuple | Any The input to process. Returns @@ -1732,7 +1757,7 @@ def coerce( def pad_image_to_fft( - image: Image | np.ndarray, + image: Image | np.ndarray | np.ndarray, axes: Iterable[int] = (0, 1), ) -> Image | np.ndarray: """Pads an image to optimize Fast Fourier Transform (FFT) performance. @@ -1743,7 +1768,7 @@ def pad_image_to_fft( Parameters ---------- - image: Image or np.ndarray + image: Image | np.ndarray The input image to pad. It should be an instance of the `Image` class or any array-like structure compatible with FFT operations. axes: Iterable[int], optional @@ -1751,7 +1776,7 @@ def pad_image_to_fft( Returns ------- - Image or np.ndarray + Image | np.ndarray The padded image with dimensions optimized for FFT performance. Raises @@ -1821,12 +1846,12 @@ def maybe_cupy( Parameters ---------- - array: np.ndarray or list or tuple + array: np.ndarray | list | tuple The input array to be potentially converted to a CuPy array. Returns ------- - cupy.ndarray or np.ndarray + cupy.ndarray | np.ndarray A CuPy array if GPU is enabled, otherwise the original array. Raises