impy-array 2.2.1__py3-none-any.whl → 2.2.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
impy/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "2.2.1"
1
+ __version__ = "2.2.2"
2
2
  __author__ = "Hanjin Liu"
3
3
  __email__ = "liuhanjin-sc@g.ecc.u-tokyo.ac.jp"
4
4
 
@@ -15,19 +15,17 @@ from .arrays import ImgArray, LazyImgArray, BigImgArray, Label # for typing
15
15
  from . import random, io
16
16
  from .axes import slicer
17
17
 
18
- r"""
19
- Inheritance
20
- -----------
18
+ # Inheritance
19
+ # -----------
20
+ #
21
+ # AxesMixin -----> LazyImgArray ------> BigImgArray
22
+ # |
23
+ # +-----> MetaArray --+--> LabeledArray --+--> ImgArray
24
+ # | | |
25
+ # np.ndarray +--> Label +--> PhaseArray
26
+ # |
27
+ # +--> PropArray
21
28
 
22
- AxesMixin -----> LazyImgArray ------> BigImgArray
23
- |
24
- +-----> MetaArray --+--> LabeledArray --+--> ImgArray
25
- | | |
26
- np.ndarray +--> Label +--> PhaseArray
27
- |
28
- +--> PropArray
29
-
30
- """
31
29
 
32
30
  logging.getLogger("skimage").setLevel(logging.ERROR)
33
31
  logging.getLogger("tifffile").setLevel(logging.ERROR)
impy/arrays/__init__.py CHANGED
@@ -16,3 +16,13 @@ try:
16
16
 
17
17
  except Exception:
18
18
  pass
19
+
20
+ __all__ = [
21
+ "ImgArray",
22
+ "LabeledArray",
23
+ "Label",
24
+ "PhaseArray",
25
+ "PropArray",
26
+ "LazyImgArray",
27
+ "BigImgArray",
28
+ ]
@@ -1,7 +1,13 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
1
4
  from functools import partial
2
5
  import numpy as np
3
- from ...array_api import xp
6
+ from impy.array_api import xp
4
7
 
8
+ if TYPE_CHECKING:
9
+ from impy.arrays import ImgArray
10
+
5
11
  try:
6
12
  gradient = xp.gradient
7
13
  except AttributeError:
@@ -11,11 +17,7 @@ except AttributeError:
11
17
  out = numpy.gradient(a.get(), axis=axis)
12
18
  return xp.asarray(out)
13
19
 
14
- __all__ = ["wiener",
15
- "lucy",
16
- "lucy_tv",
17
- "check_psf",
18
- ]
20
+ __all__ = ["wiener", "lucy", "lucy_tv", "check_psf"]
19
21
 
20
22
  def wiener(obs, psf_ft, psf_ft_conj, lmd):
21
23
  obs = xp.asarray(obs)
@@ -67,20 +69,23 @@ def richardson_lucy_tv(obs, psf_ft, psf_ft_conj, max_iter, lmd, tol, eps):
67
69
  return xp.fft.fftshift(est_new)
68
70
 
69
71
 
70
- def _safe_div(a, b, eps=1e-8):
72
+ def _safe_div(a: np.ndarray, b: np.ndarray, eps: float = 1e-8):
71
73
  out = xp.zeros(a.shape, dtype=np.float32)
72
74
  mask = b > eps
73
- out[mask] = a[mask]/b[mask]
75
+ out[mask] = a[mask] / b[mask]
74
76
  return out
75
77
 
76
78
 
77
- def check_psf(img, psf, dims):
79
+ def check_psf(img_shape: tuple[int, ...], img_scale: tuple[float, ...], psf):
80
+ if callable(psf):
81
+ psf = psf(img_shape, img_scale)
78
82
  psf = xp.asarray(psf, dtype=np.float32)
79
83
  psf /= xp.sum(psf)
80
84
 
81
- if img.sizesof(dims) != psf.shape:
82
- raise ValueError("observation and PSF have different shape: "
83
- f"{img.sizesof(dims)} and {psf.shape}")
85
+ if img_shape != psf.shape:
86
+ raise ValueError(
87
+ f"observation and PSF have different shape: {img_shape} and {psf.shape}"
88
+ )
84
89
  psf_ft = xp.fft.rfftn(psf)
85
90
  psf_ft_conj = xp.conjugate(psf_ft)
86
- return psf_ft, psf_ft_conj
91
+ return psf_ft, psf_ft_conj
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from typing import Iterable, NamedTuple, Sequence, TYPE_CHECKING
4
+ import math
4
5
  import numpy as np
5
6
 
6
7
  from ._skimage import sktrans
@@ -307,8 +308,8 @@ def iradon(
307
308
  # Reconstruct image by interpolation
308
309
  reconstructed = np.zeros(output_shape, dtype=dtype)
309
310
  xpr, ypr = np.indices(output_shape)
310
- xpr -= output_shape[0] // 2
311
- ypr -= output_shape[1] // 2
311
+ xpr = xpr - output_shape[0] // 2
312
+ ypr = ypr - output_shape[1] // 2
312
313
 
313
314
  from scipy.interpolate import interp1d
314
315
  x = np.arange(img_shape) - img_shape // 2 # NOTE: use CPU!
@@ -322,12 +323,13 @@ def iradon(
322
323
  # This function is almost ported from `skimage.transform`.
323
324
  def get_fourier_filter(size: int, filter_name: str):
324
325
  n = xp.concatenate(
325
- [xp.arange(1, size / 2 + 1, 2, dtype=int),
326
- xp.arange(size / 2 - 1, 0, -2, dtype=int)]
326
+ [xp.arange(1, size // 2 + 1, 2, dtype=np.float32),
327
+ xp.arange(size // 2 - 1, 0, -2, dtype=np.float32)]
327
328
  )
328
329
  f = xp.zeros(size)
329
330
  f[0] = 0.25
330
331
  f[1::2] = -1 / (np.pi * n[:len(f[1::2])]) ** 2
332
+
331
333
  fourier_filter = 2 * xp.real(xp.fft.fft(f)) # ramp filter
332
334
  if filter_name == "ramp":
333
335
  pass
impy/arrays/axesmixin.py CHANGED
@@ -200,6 +200,9 @@ class AxesMixin:
200
200
  {a: s for a, s in other.scale.items() if a in self.axes} # type: ignore
201
201
  )
202
202
 
203
+ elif isinstance(other, (list, tuple)):
204
+ for a, s in zip(self.axes, other):
205
+ a.scale = s
203
206
  else:
204
207
  raise TypeError(
205
208
  f"'other' must be str or axes supported object, but got {type(other)}"
@@ -27,7 +27,7 @@ SupportSlicing = Union[
27
27
  Mapping[str, SupportOneSlicing],
28
28
  ]
29
29
 
30
- class MetaArray(AxesMixin, np.ndarray):
30
+ class MetaArray(AxesMixin, np.ndarray[Any, np.dtype[np.number]]):
31
31
  additional_props = ["_source", "_metadata", "_name"]
32
32
  NP_DISPATCH = {}
33
33
  _name: str
@@ -747,7 +747,7 @@ class MetaArray(AxesMixin, np.ndarray):
747
747
  except ImageAxesError:
748
748
  self.axes = None
749
749
 
750
- return None
750
+ return self
751
751
 
752
752
  def _process_output(self, func, args, kwargs):
753
753
  # find the largest MetaArray. Largest because of broadcasting.
@@ -229,6 +229,41 @@ def _(
229
229
  out._set_info(img, new_axes=img.axes)
230
230
  return out
231
231
 
232
+ @MetaArray.implements(np.diff)
233
+ def _(
234
+ img: MetaArray,
235
+ n: int = 1,
236
+ axis: int | AxisLike = -1,
237
+ prepend=None,
238
+ append=None,
239
+ ):
240
+ if isinstance(axis, (str, Axis)):
241
+ axis = img.axisof(axis)
242
+ kwargs = dict(n=n, axis=axis)
243
+ if prepend is not None:
244
+ kwargs["prepend"] = prepend
245
+ if append is not None:
246
+ kwargs["append"] = append
247
+ out = np.diff(img.value, **kwargs)
248
+ out = out.view(img.__class__)
249
+ out._set_info(img, new_axes=img.axes)
250
+ return out
251
+
252
+ @MetaArray.implements(np.gradient)
253
+ def _(img: MetaArray, *varargs, axis=None, edge_order=1):
254
+ if isinstance(axis, (str, Axis)):
255
+ axis = img.axisof(axis)
256
+ elif isinstance(axis, Axes):
257
+ axis = tuple(img.axisof(ax) for ax in axis)
258
+ out = np.gradient(img.value, *varargs, axis=axis, edge_order=edge_order)
259
+ if isinstance(out, np.ndarray):
260
+ out = out.view(img.__class__)._set_info(img, new_axes=img.axes)
261
+ else:
262
+ out = [arr.view(img.__class__)._set_info(img, new_axes=img.axes) for arr in out]
263
+ out = DataList(out)
264
+ return out
265
+
266
+
232
267
  # This function is ported from numpy.core.numeric.normalize_axis_tuple
233
268
  def np_normalize_axis_tuple(axis, ndim, argname=None, allow_duplicate=False):
234
269
  # Optimization to speed-up the most common cases.
impy/arrays/imgarray.py CHANGED
@@ -13,25 +13,24 @@ from .specials import PropArray
13
13
  from ._utils._skimage import skexp, skfeat, skfil, skimage, skmes, skres, skseg, sktrans
14
14
  from ._utils import _filters, _linalg, _deconv, _misc, _glcm, _docs, _transform, _structures, _corr
15
15
 
16
- from ..utils.axesop import add_axes, switch_slice, complement_axes, find_first_appeared
17
- from ..utils.deco import check_input_and_output, dims_to_spatial_axes, same_dtype
18
- from ..utils.gauss import GaussianBackground, GaussianParticle
19
- from ..utils.misc import check_nd, largest_zeros
20
- from ..utils.slicer import solve_slicer
21
-
22
- from ..collections import DataDict
23
- from ..axes import AxisLike, slicer, Axes, Axis
24
- from .._types import nDInt, nDFloat, Dims, Coords, AxesTargetedSlicer, PaddingMode
25
- from .._const import Const
26
- from ..array_api import xp, cupy_dispatcher
16
+ from impy.utils.axesop import add_axes, switch_slice, complement_axes, find_first_appeared
17
+ from impy.utils.deco import check_input_and_output, dims_to_spatial_axes, same_dtype
18
+ from impy.utils.gauss import GaussianBackground, GaussianParticle
19
+ from impy.utils.misc import check_nd, largest_zeros
20
+ from impy.utils.slicer import solve_slicer
21
+
22
+ from impy.collections import DataDict
23
+ from impy.axes import AxisLike, slicer, Axes, Axis
24
+ from impy._types import nDInt, nDFloat, Dims, Coords, AxesTargetedSlicer, PaddingMode
25
+ from impy._const import Const
26
+ from impy.array_api import xp, cupy_dispatcher
27
27
 
28
28
  if TYPE_CHECKING:
29
29
  from ..frame import MarkerFrame
30
30
  from typing import Literal, Union
31
- ThreasholdMethod = Union[
32
- Literal["isodata"], Literal["li"], Literal["local"], Literal["mean"], Literal["min"],
33
- Literal["minimum"], Literal["niblack"], Literal["otsu"], Literal["sauvola"],
34
- Literal["triangle"], Literal["yen"]
31
+ ThreasholdMethod = Literal[
32
+ "isodata", "li", "local", "mean", "min", "minimum", "niblack", "otsu", "sauvola",
33
+ "triangle", "yen"
35
34
  ]
36
35
  FftShape = Literal["same", "square"]
37
36
 
@@ -220,7 +219,7 @@ class ImgArray(LabeledArray):
220
219
  @same_dtype(asfloat=True)
221
220
  def rescale(
222
221
  self,
223
- scale: float = 1/16,
222
+ scale: nDFloat = 1/16,
224
223
  *,
225
224
  order: int = None,
226
225
  mode: PaddingMode = "reflect",
@@ -228,31 +227,45 @@ class ImgArray(LabeledArray):
228
227
  dims: Dims = None,
229
228
  ) -> ImgArray:
230
229
  """
231
- Rescale image.
230
+ Rescale image by applying the diagonal component of Affine matrix.
232
231
 
233
232
  Parameters
234
233
  ----------
235
234
  scale : float, optional
236
- scale of the new image.
235
+ Relative scale of the new image. scale 1/2 means that the shape of
236
+ the output image will be (N/2, ...).
237
237
  {order}{mode}{cval}{dims}
238
238
 
239
239
  Returns
240
240
  -------
241
241
  ImgArray
242
242
  Rescaled image.
243
- """
244
- outshape = switch_slice(
245
- dims, self.axes, ifin=np.array(self.shape)*scale, ifnot=self.shape
246
- )
247
- gb = np.prod(outshape) * 4/1e9
243
+ """
244
+ scale_is_seq = hasattr(scale, "__iter__")
245
+
246
+ # Check if output is too large.
247
+ gb = -1
248
+ if not scale_is_seq and scale > 1:
249
+ gb = np.prod(self.shape) * (scale ** len(dims)) / 1e9
250
+ elif scale_is_seq and np.prod(list(scale)) > 1:
251
+ gb = np.prod(self.shape) * np.prod(list(scale)) / 1e9
248
252
  if gb > Const["MAX_GB"]:
249
- raise MemoryError(f"Too large: {gb} GB")
250
- scale_ = [scale if a in dims else 1 for a in self.axes]
253
+ raise MemoryError(f"Output image is too large: {gb} GB")
254
+
255
+ if scale_is_seq:
256
+ scale = list(scale)
257
+ if len(scale) != len(dims):
258
+ raise ValueError(
259
+ "scale must have the same length as the spatial dimensions."
260
+ )
261
+ it = iter(scale)
262
+ scale_ = [next(it) if a in dims else 1 for a in self.axes]
263
+ else:
264
+ scale_ = [scale if a in dims else 1 for a in self.axes]
251
265
  out = sktrans.rescale(
252
266
  self.value, scale_, order=order, mode=mode, cval=cval, anti_aliasing=False
253
267
  )
254
- out: ImgArray = out.view(self.__class__)
255
- out._set_info(self)
268
+ out = out.view(self.__class__)._set_info(self)
256
269
  out.axes = self.axes.copy()
257
270
  out.set_scale({a: self.scale[a]/scale for a, scale in zip(self.axes, scale_)})
258
271
  return out
@@ -303,7 +316,7 @@ class ImgArray(LabeledArray):
303
316
  )
304
317
 
305
318
  reshaped_img = img_to_reshape.reshape(shape)
306
- axes_to_reduce = tuple(i*2+1 for i in range(self.ndim))
319
+ axes_to_reduce = tuple(i * 2 + 1 for i in range(self.ndim))
307
320
  out: np.ndarray = binfunc(reshaped_img, axis=axes_to_reduce)
308
321
  out: ImgArray = out.view(self.__class__)
309
322
  out._set_info(self)
@@ -318,7 +331,7 @@ class ImgArray(LabeledArray):
318
331
  def radial_profile(
319
332
  self,
320
333
  nbin: int = 32,
321
- center: Iterable[float] = None,
334
+ center: Iterable[float] | None = None,
322
335
  r_max: float = None,
323
336
  *,
324
337
  method: str = "mean",
@@ -3111,8 +3124,7 @@ class ImgArray(LabeledArray):
3111
3124
  if out.ndim == 3:
3112
3125
  out = np.moveaxis(out, 0, 1)
3113
3126
  out = out[::-1]
3114
- out._set_info(self, new_axes)
3115
- return out
3127
+ return out._set_info(self, new_axes)
3116
3128
 
3117
3129
  @check_input_and_output
3118
3130
  def threshold(
@@ -4195,7 +4207,7 @@ class ImgArray(LabeledArray):
4195
4207
  @check_input_and_output
4196
4208
  def wiener(
4197
4209
  self,
4198
- psf: np.ndarray,
4210
+ psf: np.ndarray | Callable[[tuple[int, ...]], np.ndarray],
4199
4211
  lmd: float = 0.1,
4200
4212
  *,
4201
4213
  dims: Dims = None,
@@ -4213,8 +4225,9 @@ class ImgArray(LabeledArray):
4213
4225
 
4214
4226
  Parameters
4215
4227
  ----------
4216
- psf : np.ndarray
4217
- Point spread function.
4228
+ psf : ndarray or callable
4229
+ Point spread function. If a function is given, `psf(shape)` will be
4230
+ called to generate the PSF.
4218
4231
  lmd : float, default is 0.1
4219
4232
  Constant value used in the deconvolution. See Formulation below.
4220
4233
  {dims}{update}
@@ -4233,22 +4246,23 @@ class ImgArray(LabeledArray):
4233
4246
  if lmd <= 0:
4234
4247
  raise ValueError(f"lmd must be positive, but got: {lmd}")
4235
4248
 
4236
- psf_ft, psf_ft_conj = _deconv.check_psf(self, psf, dims)
4249
+ psf_ft, psf_ft_conj = _deconv.check_psf(
4250
+ self.sizesof(dims), tuple(self.scale[axis] for axis in dims), psf,
4251
+ )
4237
4252
 
4238
4253
  return self._apply_dask(
4239
4254
  _deconv.wiener,
4240
4255
  c_axes=complement_axes(dims, self.axes),
4241
4256
  args=(psf_ft, psf_ft_conj, lmd)
4242
- )
4243
-
4244
-
4257
+ )
4258
+
4245
4259
  @_docs.write_docs
4246
4260
  @dims_to_spatial_axes
4247
4261
  @same_dtype(asfloat=True)
4248
4262
  @check_input_and_output
4249
4263
  def lucy(
4250
4264
  self,
4251
- psf: np.ndarray,
4265
+ psf: np.ndarray | Callable[[tuple[int, ...]], np.ndarray],
4252
4266
  niter: int = 50,
4253
4267
  eps: float = 1e-5,
4254
4268
  *,
@@ -4260,14 +4274,15 @@ class ImgArray(LabeledArray):
4260
4274
 
4261
4275
  Parameters
4262
4276
  ----------
4263
- psf : np.ndarray
4264
- Point spread function.
4277
+ psf : ndarray or callable
4278
+ Point spread function. If a function is given, `psf(shape)` will be
4279
+ called to generate the PSF.
4265
4280
  niter : int, default is 50.
4266
4281
  Number of iterations.
4267
4282
  eps : float, default is 1e-5
4268
- During deconvolution, division by small values in the convolve image of estimation and
4269
- PSF may cause divergence. Therefore, division by values under `eps` is substituted
4270
- to zero.
4283
+ During deconvolution, division by small values in the convolve image
4284
+ of estimation and PSF may cause divergence. Therefore, division by
4285
+ values under `eps` is substituted to zero.
4271
4286
  {dims}{update}
4272
4287
 
4273
4288
  Returns
@@ -4281,7 +4296,9 @@ class ImgArray(LabeledArray):
4281
4296
  wiener
4282
4297
  """
4283
4298
 
4284
- psf_ft, psf_ft_conj = _deconv.check_psf(self, psf, dims)
4299
+ psf_ft, psf_ft_conj = _deconv.check_psf(
4300
+ self.sizesof(dims), tuple(self.scale[axis] for axis in dims), psf,
4301
+ )
4285
4302
 
4286
4303
  return self._apply_dask(
4287
4304
  _deconv.richardson_lucy,
@@ -4295,7 +4312,7 @@ class ImgArray(LabeledArray):
4295
4312
  @check_input_and_output
4296
4313
  def lucy_tv(
4297
4314
  self,
4298
- psf: np.ndarray,
4315
+ psf: np.ndarray | Callable[[tuple[int, ...]], np.ndarray],
4299
4316
  max_iter: int = 50,
4300
4317
  lmd: float = 1e-3,
4301
4318
  tol: float = 1e-3,
@@ -4319,8 +4336,9 @@ class ImgArray(LabeledArray):
4319
4336
 
4320
4337
  Parameters
4321
4338
  ----------
4322
- psf : np.ndarray
4323
- Point spread function.
4339
+ psf : ndarray or callable
4340
+ Point spread function. If a function is given, `psf(shape)` will be
4341
+ called to generate the PSF.
4324
4342
  max_iter : int, default is 50.
4325
4343
  Maximum number of iterations.
4326
4344
  lmd : float, default is 1e-3
@@ -4361,7 +4379,9 @@ class ImgArray(LabeledArray):
4361
4379
  "In Richadson-Lucy with total-variance-regularization, "
4362
4380
  "parameter `lmd` must be positive."
4363
4381
  )
4364
- psf_ft, psf_ft_conj = _deconv.check_psf(self, psf, dims)
4382
+ psf_ft, psf_ft_conj = _deconv.check_psf(
4383
+ self.sizesof(dims), tuple(self.scale[axis] for axis in dims), psf
4384
+ )
4365
4385
 
4366
4386
  return self._apply_dask(
4367
4387
  _deconv.richardson_lucy_tv,
@@ -4369,6 +4389,39 @@ class ImgArray(LabeledArray):
4369
4389
  args=(psf_ft, psf_ft_conj, max_iter, lmd, tol, eps)
4370
4390
  )
4371
4391
 
4392
+ @_docs.write_docs
4393
+ @dims_to_spatial_axes
4394
+ @same_dtype(asfloat=True)
4395
+ @check_input_and_output
4396
+ def tiled_lucy(
4397
+ self,
4398
+ psf: np.ndarray | Callable[[tuple[int, ...]], np.ndarray],
4399
+ niter: int = 50,
4400
+ eps: float = 1e-5,
4401
+ chunks = "auto",
4402
+ overlap: int = 32,
4403
+ *,
4404
+ dims: Dims = None,
4405
+ update: bool = False
4406
+ ) -> ImgArray:
4407
+ from dask import array as da
4408
+
4409
+ input = da.from_array(self.value, chunks=chunks)
4410
+ depth = switch_slice(dims, self.axes, overlap, 0)
4411
+ scale = tuple(self.scale[axis] for axis in dims)
4412
+
4413
+ def func(arr: np.ndarray):
4414
+ psf_ft, psf_ft_conj = _deconv.check_psf(arr.shape, scale, psf)
4415
+ return _deconv.richardson_lucy(arr, psf_ft, psf_ft_conj, niter, eps)
4416
+
4417
+ out = da.map_overlap(
4418
+ func,
4419
+ input,
4420
+ depth=depth,
4421
+ boundary="reflect",
4422
+ dtype=self.dtype,
4423
+ ).compute()
4424
+ return out
4372
4425
 
4373
4426
  def _check_coordinates(coords, img: ImgArray, dims: Dims = None):
4374
4427
  from impy.frame import MarkerFrame
@@ -337,6 +337,7 @@ class LabeledArray(MetaArray):
337
337
  def _set_info(self, other: Self, new_axes: Any = MetaArray._INHERIT):
338
338
  super()._set_info(other, new_axes)
339
339
  self._inherit_covariates(other)
340
+ return self
340
341
 
341
342
  def _inherit_covariates(self, other: Self):
342
343
  if isinstance(other, LabeledArray):
impy/arrays/lazy.py CHANGED
@@ -1526,7 +1526,7 @@ class LazyImgArray(AxesMixin):
1526
1526
  except ImageAxesError:
1527
1527
  self.axes = None
1528
1528
 
1529
- return None
1529
+ return self
1530
1530
 
1531
1531
 
1532
1532
  def _replace_inputs(img: LazyImgArray, args, kwargs):
impy/core.py CHANGED
@@ -143,10 +143,10 @@ def array(
143
143
  @_write_docs
144
144
  def asarray(
145
145
  arr: ArrayLike,
146
- dtype: DTypeLike = None,
146
+ dtype: DTypeLike | None = None,
147
147
  *,
148
- name: str = None,
149
- axes: str = None,
148
+ name: str | None = None,
149
+ axes: str | None = None,
150
150
  like: MetaArray | None = None,
151
151
  ) -> ImgArray:
152
152
  """
@@ -172,8 +172,8 @@ def aslabel(
172
172
  arr: ArrayLike,
173
173
  dtype: DTypeLike = None,
174
174
  *,
175
- name: str = None,
176
- axes: str = None,
175
+ name: str | None = None,
176
+ axes: str | None = None,
177
177
  like: MetaArray | None = None,
178
178
  ) -> ImgArray:
179
179
  """
@@ -227,8 +227,8 @@ def aslazy(
227
227
  arr: ArrayLike,
228
228
  dtype: DTypeLike = None,
229
229
  *,
230
- name: str = None,
231
- axes: str = None,
230
+ name: str | None = None,
231
+ axes: str | None = None,
232
232
  chunks="auto",
233
233
  like: MetaArray | None = None,
234
234
  ) -> LazyImgArray:
@@ -284,8 +284,8 @@ def asbigarray(
284
284
  arr: ArrayLike,
285
285
  dtype: DTypeLike = None,
286
286
  *,
287
- name: str = None,
288
- axes: str = None,
287
+ name: str | None = None,
288
+ axes: str | None = None,
289
289
  like: MetaArray | None = None,
290
290
  ) -> BigImgArray:
291
291
  """
@@ -354,7 +354,9 @@ def _inject_numpy_function(func: Callable[_P, Any | None]) -> Callable[_P, ImgAr
354
354
  Image axes. Must be same length as image dimension.
355
355
  name: str, optional
356
356
  Image name.
357
-
357
+ like: MetaArray, optional
358
+ Reference array from which name and axes will be copied.
359
+
358
360
  {npfunc.__doc__}
359
361
  """
360
362
  )
@@ -374,7 +376,11 @@ def ones(shape: ShapeLike, dtype: DTypeLike = np.uint16, *, name: str | None = N
374
376
  def full(shape: ShapeLike, fill_value: Any, dtype: DTypeLike = np.uint16, *, name: str | None = None, axes: AxesLike | None = None, like: MetaArray | None = None): ...
375
377
 
376
378
  @_inject_numpy_function
377
- def arange(stop: int, dtype: DTypeLike = ..., like: Any = ...): ...
379
+ def arange(stop: int, dtype: DTypeLike = None): ...
380
+
381
+ @_inject_numpy_function
382
+ def fromiter(iterable: Iterable, dtype: DTypeLike, count: int = -1): ...
383
+
378
384
 
379
385
  def indices(
380
386
  dimensions: ShapeLike,
@@ -1,27 +1,60 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: impy-array
3
- Version: 2.2.1
3
+ Version: 2.2.2
4
4
  Summary: Speed up coding/extending image analysis in Python.
5
- Download-URL: https://github.com/hanjinliu/impy
6
- Author: Hanjin Liu
7
- Author-email: liuhanjin-sc@g.ecc.u-tokyo.ac.jp
8
- License: BSD 3-Clause
9
- Requires-Python: >=3.8
10
- Description-Content-Type: text/markdown
5
+ Project-URL: Download, https://github.com/hanjinliu/impy
6
+ Author-email: Hanjin Liu <liuhanjin-sc@g.ecc.u-tokyo.ac.jp>
7
+ License: BSD 3-Clause License
8
+
9
+ Copyright (c) 2021, hanjinliu
10
+ All rights reserved.
11
+
12
+ Redistribution and use in source and binary forms, with or without
13
+ modification, are permitted provided that the following conditions are met:
14
+
15
+ 1. Redistributions of source code must retain the above copyright notice, this
16
+ list of conditions and the following disclaimer.
17
+
18
+ 2. Redistributions in binary form must reproduce the above copyright notice,
19
+ this list of conditions and the following disclaimer in the documentation
20
+ and/or other materials provided with the distribution.
21
+
22
+ 3. Neither the name of the copyright holder nor the names of its
23
+ contributors may be used to endorse or promote products derived from
24
+ this software without specific prior written permission.
25
+
26
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
30
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
34
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11
36
  License-File: LICENSE
12
- Requires-Dist: numpy (>=1.22)
13
- Requires-Dist: scikit-image (>=0.20.0)
14
- Requires-Dist: pandas (>=1.3)
15
- Requires-Dist: dask (>=2021.6.0)
16
- Requires-Dist: napari (>=0.4.17)
17
- Requires-Dist: qtpy (>=1.10.0)
37
+ Classifier: Programming Language :: Python :: 3 :: Only
38
+ Classifier: Programming Language :: Python :: 3.8
39
+ Classifier: Programming Language :: Python :: 3.9
40
+ Classifier: Programming Language :: Python :: 3.10
41
+ Classifier: Programming Language :: Python :: 3.11
42
+ Classifier: Programming Language :: Python :: Implementation :: CPython
43
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
44
+ Requires-Python: >=3.8
45
+ Requires-Dist: dask>=2021.6.0
46
+ Requires-Dist: napari>=0.4.17
47
+ Requires-Dist: numpy>=1.22
48
+ Requires-Dist: pandas>=1.3
49
+ Requires-Dist: scikit-image>=0.20.0
18
50
  Provides-Extra: all
19
- Requires-Dist: mrcfile ; extra == 'all'
20
- Requires-Dist: zarr ; extra == 'all'
51
+ Requires-Dist: mrcfile; extra == 'all'
52
+ Requires-Dist: zarr; extra == 'all'
21
53
  Provides-Extra: mrc
22
- Requires-Dist: mrcfile ; extra == 'mrc'
54
+ Requires-Dist: mrcfile; extra == 'mrc'
23
55
  Provides-Extra: zarr
24
- Requires-Dist: zarr ; extra == 'zarr'
56
+ Requires-Dist: zarr; extra == 'zarr'
57
+ Description-Content-Type: text/markdown
25
58
 
26
59
  [![Downloads](https://pepy.tech/badge/impy-array/month)](https://pepy.tech/project/impy-array)
27
60
  [![PyPI version](https://badge.fury.io/py/impy-array.svg)](https://badge.fury.io/py/impy-array)
@@ -117,7 +150,7 @@ and it's ready for batch processing!
117
150
  img.imfilter(param=1.0)
118
151
  ```
119
152
 
120
- ### Commaind line usage
153
+ ### Command line usage
121
154
 
122
155
  `impy` also supports command line based image analysis. All method of `ImgArray` is available
123
156
  from commad line, such as
@@ -143,9 +176,3 @@ impy path/to/image.tif -i
143
176
  ```python
144
177
  thr = img.gaussian_filter().threshold()
145
178
  ```
146
-
147
- or to `napari`
148
-
149
- ```
150
- impy path/to/image.tif -n
151
- ```
@@ -1,29 +1,30 @@
1
- impy/__init__.py,sha256=II-V8ywKApCUt_hmjxr475QC9to-846xsxN2I5KDbBQ,1076
1
+ setup.py,sha256=EVgemUNpwbaqXxTcA04v_cr25SHJghq8zG_nkb0Mx4o,966
2
+ impy/__init__.py,sha256=CRD1afMAeAfMqpQ056IFiDkYG0v3MOVoyD1nOmM1Vho,1084
2
3
  impy/__main__.py,sha256=BAQkQ4X8EFo42pbNx__EqpZ5KL4MTfTUWsVbJIQF0O0,4974
3
4
  impy/_const.py,sha256=N94lStP7Xt_9yFImieKjYeED-teV8p5o0aoW3CMFn1c,3688
4
5
  impy/_types.py,sha256=gO4l0hx9qxe6eI0PyC4ukW3k4IYxCEZ9gT-rQ3jj3zU,808
5
6
  impy/array_api.py,sha256=lVHgxubTtQ6CVaLib8uIUsI1xSEB_6tmoo1ktyDmPsw,4839
6
7
  impy/binder.py,sha256=CTMb11g6uYDVVQV5Wtef865IO0G2V3vGXc8SiGYRD5k,9651
7
8
  impy/collections.py,sha256=2e55bLjZN7W4LFUCkyxekcDfLwZodMaU4JG5NQ3RS54,10946
8
- impy/core.py,sha256=_qF78KUy8FamzwsCW3FTUEg60JdoxdQC4EsjQuFdo8w,29407
9
+ impy/core.py,sha256=nMfZFVwzoDQUkx0_1Q3kYMFBZD72HQsoICpu5GByBqc,29654
9
10
  impy/correlation.py,sha256=CoNboXiZjO1VYqA0rHe4Jp6gDYt6hyJtSgI3TWepxKk,28398
10
11
  impy/io.py,sha256=O270L-hFW_nXA1QPOcgIDjEsrWnQjzX_UglXYCxUpS8,19241
11
12
  impy/random.py,sha256=SJdRFopKJu0oVsI7AoromF6qpfvV4YWBoSLiIYGYc6A,7035
12
13
  impy/roi.py,sha256=p9ttjBl5SGHHXj0xg5UjPlg_V9cY3MnNZxFfYIjTYsg,14164
13
- impy/arrays/__init__.py,sha256=EMPDAKhUwllcrgd4SGZ-xw66qDyIpM-EGe6UhmYcy4k,397
14
+ impy/arrays/__init__.py,sha256=qth0jRXkS3p-x3Rb_tTGZqPHcwX90rycMx-ihWKQCn4,545
14
15
  impy/arrays/_deprecated.py,sha256=YTnQNkse-tN3xRkH9pCqJhHd_MgZg1CY2woCVTzcX5A,13111
15
16
  impy/arrays/_imshow.py,sha256=nhCEBwYC8LMjwwfLw5nUrlSWLhCTuBy569X_VpWV8H8,6517
16
- impy/arrays/axesmixin.py,sha256=XQmUNck1VCFKJxwMgdIUGNctpBBPTcanvgKHGbj9ji0,10445
17
+ impy/arrays/axesmixin.py,sha256=ZNf_1tp6x6Qohtd8REP_8m5S8fk0JniiIAm0Rrlg2jo,10570
17
18
  impy/arrays/big.py,sha256=0KPG_V7yKiVYLFwzGfHRxyFD2kysIyVppsq6hh7TFPg,2809
18
- impy/arrays/imgarray.py,sha256=rYqtej6eB5JGvv65FwnjadDJAzi1676T8XehHP-2IVs,155198
19
+ impy/arrays/imgarray.py,sha256=z38ATBeaU3_Gqquy3ZXR45tJYhnqLti2Cfq-a-8IBgs,157482
19
20
  impy/arrays/label.py,sha256=f8Gef1JI7nZUwFpq6YYTB4rP3XheMAJXU32PnfxRaTs,6415
20
- impy/arrays/labeledarray.py,sha256=rBEpo8o7rhqisS2oMkPI7zZbv4HlYmeyH-0XFPHq5uQ,56924
21
- impy/arrays/lazy.py,sha256=k0xTjhPfxlr4-OeajD93YK7Dk-welz_-fSrN8sB0Xow,55489
21
+ impy/arrays/labeledarray.py,sha256=tbsqKn_OjiTg9rOt15tfogRiqnyYHktUxu4lqycSq4A,56945
22
+ impy/arrays/lazy.py,sha256=noFbaYJrJmgEaPlG30JqIzhqG1eWKJtfNDSGfzg57ak,55489
22
23
  impy/arrays/phasearray.py,sha256=23E7ZTw8vni61rvhlgPyi-1j1kBg4Q2gxQ0wlE_CFE8,13937
23
24
  impy/arrays/specials.py,sha256=FiVap4iBA96TG3zDNeQG02TCZZDawg5KLzX7DRKQ6-4,7886
24
25
  impy/arrays/_utils/__init__.py,sha256=M5HogfyUBvV8kp-X1ZthS8vDLUP7-O2f9Gvsc1ZXdT8,271
25
26
  impy/arrays/_utils/_corr.py,sha256=8RM_OeaDsrewhiYhf6wFkDYRfl1gQ8Sg2TTK4CT22K4,10031
26
- impy/arrays/_utils/_deconv.py,sha256=BOegQ_muDlD-hU34eT1yIEjR2AHlkaAGvybDo-J6Iuk,2887
27
+ impy/arrays/_utils/_deconv.py,sha256=-3kfLAHP_E8-t45JXVgY-1Y5D9ZDQaXc06Z5DcbMC4I,3101
27
28
  impy/arrays/_utils/_docs.py,sha256=AwVschAFOBFDeUJPvB1pJvBbJ6JJj3q4IpJqYbBrJ60,4548
28
29
  impy/arrays/_utils/_filters.py,sha256=FRN-YX-5KiKsuDOK1siBBMD52HLPL9twiPl6ByWhEZQ,6794
29
30
  impy/arrays/_utils/_glcm.py,sha256=8vkjgDIywVqmmWniK4vgLrssvYA8XOudePMoW44JMMY,4206
@@ -33,10 +34,10 @@ impy/arrays/_utils/_plot.py,sha256=LeUKFI9H9iYKKksc3GaPgZsxEHOmhMAkNw9HArbV5b8,5
33
34
  impy/arrays/_utils/_process_numba.py,sha256=1WjNRwqggSMYyKLeXo6W97lm93A47cAFvR6sBF086PI,3428
34
35
  impy/arrays/_utils/_skimage.py,sha256=sox3kvl9u3wbK6RwbakCl2jlTkwzp6WD9o6-d4Lbmuw,1283
35
36
  impy/arrays/_utils/_structures.py,sha256=lTwceW3sjv4DThRmBsCtB9nkfZ51NaCpCGyzkces0AM,1305
36
- impy/arrays/_utils/_transform.py,sha256=vhMBYh1ykmKIEWVk5U6FHAPgirJkcsDWWXOY2V3_6Kc,12721
37
+ impy/arrays/_utils/_transform.py,sha256=6HMBOItV9zMFjvB4qOUmRPg92A0hiG6moFesRkfdtBE,12762
37
38
  impy/arrays/bases/__init__.py,sha256=aHsAYta5CQkEDlbFShEtEGYN89N2qYedg99SM6Oo7wk,99
38
- impy/arrays/bases/metaarray.py,sha256=NnnuAWJSuYP_sz2ADuqdLbu9ftkhKtUoEXTNl1wDfQs,27078
39
- impy/arrays/bases/overload.py,sha256=Hx8kySgR0rtHSpTryTnR02bMCrg8-c1mnQzWp6O7wEk,8244
39
+ impy/arrays/bases/metaarray.py,sha256=bqZ0I-3nsEDbFlu1iwPdbaUbphOMyC5Z1W-JCMZQOLw,27104
40
+ impy/arrays/bases/overload.py,sha256=ECLxRCumEUJb4KEu1K8k4vZWbufyPEPBj-Atzv4AosU,9359
40
41
  impy/axes/__init__.py,sha256=qzhWAJMT_mc-MXcuaMEDjVd_n0dFRmZxaphh6x_Wzb4,239
41
42
  impy/axes/_axes.py,sha256=lpTPzcs_hHslbxSUBGTjicIu4XLUs79zXPfDi5ZyGLI,12134
42
43
  impy/axes/_axes_tuple.py,sha256=hkgTr_n36gFcnnffmSp3z4oJ_52MxT1JnaszdJ3JnrY,1522
@@ -54,9 +55,9 @@ impy/utils/utilcls.py,sha256=3Td9G2ZkU4C0BiW2LH0sq7RBjdco_BtyxNr-s-seLhs,437
54
55
  impy/viewer/__init__.py,sha256=NTVonxd7HMfbRXHhjLBMG_07NjFia-O1QCv5IOKdbgw,286
55
56
  impy/viewer/utils.py,sha256=fn1gA4bD9Zlabc8EJcpSC3VCy40ljDD3pffsHl4ck2U,12187
56
57
  impy/viewer/viewer.py,sha256=KVg3BceGGT1pj17md2zHRg5iaIHdBXaWVi0vDWWVOmI,17561
57
- impy_array-2.2.1.dist-info/LICENSE,sha256=rpxKafH9r42sxLLYYB5VbZBHOdtYeLuYJjVU1LBwrxk,1546
58
- impy_array-2.2.1.dist-info/METADATA,sha256=1sDIm3dUkezMDe9N6kfw6M6Z-0UAaSmmrIgX8xMG2-E,4294
59
- impy_array-2.2.1.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
60
- impy_array-2.2.1.dist-info/entry_points.txt,sha256=reyrgy4odXvi1CcPOIIyRYBmsNGG2tO7ZkFOdG5CBkU,44
61
- impy_array-2.2.1.dist-info/top_level.txt,sha256=3Sw5wiwivoN-t8aUxS8YSBWZu8_MFJhP53XSC66xxyg,5
62
- impy_array-2.2.1.dist-info/RECORD,,
58
+ rst/conf.py,sha256=CBA2_0Qkkj7U5gYS2hY-DW0znc8BO42cSyZqjTp7InE,2341
59
+ impy_array-2.2.2.dist-info/METADATA,sha256=ky4sYNVbmkZ6Y4D42x_R3V1rWij-YW7VK4w0V39pcXg,6322
60
+ impy_array-2.2.2.dist-info/WHEEL,sha256=y1bSCq4r5i4nMmpXeUJMqs3ipKvkZObrIXSvJHm1qCI,87
61
+ impy_array-2.2.2.dist-info/entry_points.txt,sha256=reyrgy4odXvi1CcPOIIyRYBmsNGG2tO7ZkFOdG5CBkU,44
62
+ impy_array-2.2.2.dist-info/licenses/LICENSE,sha256=rpxKafH9r42sxLLYYB5VbZBHOdtYeLuYJjVU1LBwrxk,1546
63
+ impy_array-2.2.2.dist-info/RECORD,,
@@ -1,5 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.37.1)
2
+ Generator: hatchling 1.17.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
-
rst/conf.py ADDED
@@ -0,0 +1,64 @@
1
+ # Configuration file for the Sphinx documentation builder.
2
+ #
3
+ # This file only contains a selection of the most common options. For a full
4
+ # list see the documentation:
5
+ # https://www.sphinx-doc.org/en/master/usage/configuration.html
6
+
7
+ # -- Path setup --------------------------------------------------------------
8
+
9
+ # If extensions (or modules to document with autodoc) are in another directory,
10
+ # add these directories to sys.path here. If the directory is relative to the
11
+ # documentation root, use os.path.abspath to make it absolute, like shown here.
12
+ #
13
+ import os
14
+ import sys
15
+ sys.path.insert(0, os.path.abspath('../'))
16
+ import impy
17
+ import sphinx_rtd_theme
18
+
19
+ # -- Project information -----------------------------------------------------
20
+
21
+ project = 'impy'
22
+ copyright = '2021, Hanjin Liu'
23
+ author = 'Hanjin Liu'
24
+
25
+ # The full version, including alpha/beta/rc tags
26
+ version = impy.__version__
27
+ release = impy.__version__
28
+
29
+
30
+ # -- General configuration ---------------------------------------------------
31
+
32
+ # Add any Sphinx extension module names here, as strings. They can be
33
+ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
34
+ # ones.
35
+ extensions = ['sphinx.ext.autodoc',
36
+ 'sphinx.ext.napoleon',
37
+ 'sphinx.ext.viewcode',
38
+ 'sphinx.ext.githubpages',
39
+ 'sphinxcontrib.blockdiag',
40
+ ]
41
+
42
+ blockdiag_html_image_format = 'SVG'
43
+
44
+ # Add any paths that contain templates here, relative to this directory.
45
+ templates_path = ['_templates']
46
+
47
+ # List of patterns, relative to source directory, that match files and
48
+ # directories to ignore when looking for source files.
49
+ # This pattern also affects html_static_path and html_extra_path.
50
+ exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
51
+
52
+
53
+ # -- Options for HTML output -------------------------------------------------
54
+
55
+ # The theme to use for HTML and HTML Help pages. See the documentation for
56
+ # a list of builtin themes.
57
+ #
58
+ html_theme = 'sphinx_rtd_theme'
59
+ html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
60
+
61
+ # Add any paths that contain custom static files (such as style sheets) here,
62
+ # relative to this directory. They are copied after the builtin static files,
63
+ # so a file named "default.css" will overwrite the builtin "default.css".
64
+ html_static_path = ['_static']
setup.py ADDED
@@ -0,0 +1,37 @@
1
+ import sys
2
+
3
+ sys.stderr.write(
4
+ """
5
+ ===============================================================
6
+ impy does not support `python setup.py install`. Please use
7
+
8
+ $ python -m pip install .
9
+
10
+ instead.
11
+ ===============================================================
12
+ """
13
+ )
14
+ sys.exit(1)
15
+
16
+ setup(
17
+ name="impy-array",
18
+ author="Hanjin Liu",
19
+ author_email="liuhanjin-sc@g.ecc.u-tokyo.ac.jp",
20
+ long_description_content_type="text/markdown",
21
+ license="BSD 3-Clause",
22
+ download_url="https://github.com/hanjinliu/impy",
23
+ install_requires=[
24
+ "numpy>=1.22",
25
+ "scikit-image>=0.20.0",
26
+ "pandas>=1.3",
27
+ "dask>=2021.6.0",
28
+ "napari>=0.4.17",
29
+ ],
30
+ python_requires=">=3.8",
31
+ entry_points={"console_scripts": ["impy=impy.__main__:main",],},
32
+ extras_require={
33
+ "all": ["mrcfile", "zarr"],
34
+ "zarr": ["zarr"],
35
+ "mrc": ["mrcfile"],
36
+ },
37
+ )
@@ -1 +0,0 @@
1
- impy