impy-array 2.5.0__py3-none-any.whl → 2.5.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.5.0"
1
+ __version__ = "2.5.2"
2
2
  __author__ = "Hanjin Liu"
3
3
  __email__ = "liuhanjin-sc@g.ecc.u-tokyo.ac.jp"
4
4
 
impy/arrays/imgarray.py CHANGED
@@ -2675,7 +2675,7 @@ class ImgArray(LabeledArray):
2675
2675
  out = pd.concat(out, axis=0)
2676
2676
 
2677
2677
  out = MarkerFrame(out.reindex(columns=list(coords._axes)),
2678
- columns=str(coords._axes), dtype=np.float32).as_standard_type()
2678
+ columns=str(coords._axes), dtype=np.float32)
2679
2679
  out.set_scale(coords.scale)
2680
2680
 
2681
2681
  return out
@@ -3801,7 +3801,7 @@ class ImgArray(LabeledArray):
3801
3801
 
3802
3802
  def regionprops(
3803
3803
  self,
3804
- properties: Iterable[str] | str = ("mean_intensity",),
3804
+ properties: Iterable[str] | str = ("intensity_mean",),
3805
3805
  *,
3806
3806
  extra_properties: Iterable[Callable] | None = None,
3807
3807
  ) -> DataDict[str, PropArray]:
@@ -4111,8 +4111,6 @@ class ImgArray(LabeledArray):
4111
4111
 
4112
4112
  if along is None:
4113
4113
  along = find_first_appeared("tpzcia", include=self.axes)
4114
- elif len(along) != 1:
4115
- raise ValueError("`along` must be single character.")
4116
4114
  if not isinstance(upsample_factor, int):
4117
4115
  raise TypeError(f"upsample-factor must be integer but got {type(upsample_factor)}")
4118
4116
  if max_shift is not None:
@@ -4122,7 +4120,7 @@ class ImgArray(LabeledArray):
4122
4120
  c_axes = complement_axes(along, self.axes)
4123
4121
  last_img = None
4124
4122
  img_fft = self.fft(shift=False, dims=c_axes)
4125
- for i, (_, img) in enumerate(img_fft.iter(along)):
4123
+ for i, (_, img) in enumerate(img_fft.iter([along])):
4126
4124
  img = xp.asarray(img)
4127
4125
  if last_img is not None:
4128
4126
  result[i] = xp.asnumpy(
@@ -4198,8 +4196,6 @@ class ImgArray(LabeledArray):
4198
4196
 
4199
4197
  if along is None:
4200
4198
  along = find_first_appeared("tpzcia", include=self.axes, exclude=dims)
4201
- elif len(along) != 1:
4202
- raise ValueError("`along` must be single character.")
4203
4199
 
4204
4200
  if shift is None:
4205
4201
  # determine 'ref'
@@ -302,16 +302,6 @@ class LabeledArray(MetaArray):
302
302
  ext = ".tif"
303
303
  save_path = save_path.parent / (save_path.name + ext)
304
304
 
305
- if not Path(save_path).is_absolute():
306
- if self.source is None:
307
- raise ValueError(
308
- "Image directory path is unknown. Set by \n"
309
- " >>> img.source = \"...\"\n"
310
- "or specify absolute path like\n"
311
- " >>> img.imsave(\"/path/to/XXX.tif\")"
312
- )
313
- save_path = self.source.parent / save_path
314
-
315
305
  if not overwrite and save_path.exists():
316
306
  raise FileExistsError(f"File {save_path!r} already exists.")
317
307
  if self.metadata is None:
impy/arrays/lazy.py CHANGED
@@ -352,16 +352,6 @@ class LazyImgArray(AxesMixin):
352
352
  ext = ".tif"
353
353
  save_path = save_path.parent / (save_path.name + ext)
354
354
 
355
- if not Path(save_path).is_absolute():
356
- if self.source is None:
357
- raise ValueError(
358
- "Image directory path is unknown. Set by \n"
359
- " >>> img.source = \"...\"\n"
360
- "or specify absolute path like\n"
361
- " >>> img.imsave(\"/path/to/XXX.tif\")"
362
- )
363
- save_path = self.source.parent / save_path
364
-
365
355
  if not overwrite and save_path.exists():
366
356
  raise FileExistsError(f"File {save_path!r} already exists.")
367
357
  if dtype is None:
@@ -776,12 +766,13 @@ class LazyImgArray(AxesMixin):
776
766
  sigma: nDFloat = 1.0,
777
767
  *,
778
768
  dims: Dims = None,
769
+ fourier: bool = False,
779
770
  update: bool = False
780
771
  ) -> LazyImgArray:
781
772
  c_axes = complement_axes(dims, self.axes)
782
773
  depth = _ceilint(sigma*4)
783
774
  return self._apply_map_overlap(
784
- xp.ndi.gaussian_filter,
775
+ _filters.gaussian_filter_fourier if fourier else _filters.gaussian_filter,
785
776
  c_axes=c_axes,
786
777
  depth=depth,
787
778
  kwargs=dict(sigma=sigma),
@@ -795,13 +786,14 @@ class LazyImgArray(AxesMixin):
795
786
  low_sigma: nDFloat = 1.0,
796
787
  high_sigma: nDFloat = 2.0,
797
788
  *,
789
+ fourier: bool = False,
798
790
  dims: Dims = None,
799
791
  update: bool = False
800
792
  ) -> LazyImgArray:
801
793
  c_axes = complement_axes(dims, self.axes)
802
794
  depth = _ceilint(high_sigma*4)
803
795
  return self._apply_map_overlap(
804
- _filters.dog_filter,
796
+ _filters.dog_filter_fourier if fourier else _filters.dog_filter,
805
797
  c_axes=c_axes,
806
798
  depth=depth,
807
799
  kwargs=dict(low_sigma=low_sigma, high_sigma=high_sigma),
@@ -1317,8 +1309,6 @@ class LazyImgArray(AxesMixin):
1317
1309
  def track_drift(self, along: str = None, upsample_factor: int = 10) -> DaskArray:
1318
1310
  if along is None:
1319
1311
  along = find_first_appeared("tpzc<i", include=self.axes)
1320
- elif len(along) != 1:
1321
- raise ValueError("`along` must be single character.")
1322
1312
 
1323
1313
  dims = complement_axes(along, self.axes)
1324
1314
  chunks = switch_slice(dims, self.axes, ifin=self.shape, ifnot=1)
@@ -1370,8 +1360,6 @@ class LazyImgArray(AxesMixin):
1370
1360
  ) -> LazyImgArray:
1371
1361
  if along is None:
1372
1362
  along = find_first_appeared("tpzcia", include=self.axes, exclude=dims)
1373
- elif len(along) != 1:
1374
- raise ValueError("`along` must be single character.")
1375
1363
 
1376
1364
  from impy.frame import MarkerFrame
1377
1365
 
@@ -1387,7 +1375,7 @@ class LazyImgArray(AxesMixin):
1387
1375
  dims = _dims
1388
1376
  elif not isinstance(ref, self.__class__):
1389
1377
  ref = self[ref]
1390
- if ref.axes != along + dims:
1378
+ if ref.axes != [along] + dims:
1391
1379
  raise ValueError(f"Arguments `along`({along}) + `dims`({dims}) do not match "
1392
1380
  f"axes of `ref`({ref.axes})")
1393
1381
 
impy/arrays/specials.py CHANGED
@@ -20,23 +20,23 @@ SCALAR_PROP = (
20
20
  class PropArray(MetaArray):
21
21
  additional_props = ["_source", "_metadata", "_name", "propname"]
22
22
  propname: str
23
- def __new__(cls, obj, *, name=None, axes=None, source=None,
23
+ def __new__(cls, obj, *, name=None, axes=None, source=None,
24
24
  metadata=None, propname=None, dtype=None):
25
25
  if propname is None:
26
26
  propname = "User_Defined"
27
-
27
+
28
28
  if dtype is None and propname in SCALAR_PROP:
29
29
  dtype = np.float32
30
30
  elif dtype is None:
31
31
  dtype = object
32
32
  else:
33
33
  dtype = dtype
34
-
34
+
35
35
  self = super().__new__(cls, obj, name, axes, source, metadata, dtype=dtype)
36
36
  self.propname = propname
37
-
37
+
38
38
  return self
39
-
39
+
40
40
  def _repr_dict_(self):
41
41
  return {
42
42
  "name": self.name,
@@ -44,7 +44,7 @@ class PropArray(MetaArray):
44
44
  "dtype": self.dtype,
45
45
  "source": self.source,
46
46
  "property name": self.propname}
47
-
47
+
48
48
  def plot(self, along=None, cmap="jet", cmap_range=(0, 1)):
49
49
  """
50
50
  Plot all the results with x-axis defined by `along`.
@@ -57,7 +57,7 @@ class PropArray(MetaArray):
57
57
  Colormap of each graph.
58
58
  cmap_range : tuple, default is (0, 1)
59
59
  Range of float for colormap iteration.
60
- """
60
+ """
61
61
  import matplotlib.pyplot as plt
62
62
  if self.dtype == object:
63
63
  raise TypeError(f"Cannot call plot_profile for {self.propname} "
@@ -67,21 +67,21 @@ class PropArray(MetaArray):
67
67
  along = find_first_appeared("tzp<yxc", include=self.axes)
68
68
  except ValueError:
69
69
  along = self.axes[-1]
70
-
70
+
71
71
  iteraxes = self.axes.drop(along)
72
72
  cmap = plt.get_cmap(cmap)
73
73
  positions = np.linspace(*cmap_range, self.size//self.sizeof(along), endpoint=False)
74
74
  x = np.arange(self.sizeof(along))*self.scale[along]
75
75
  for i, (sl, y) in enumerate(self.iter(iteraxes)):
76
76
  plt.plot(x, y, color=cmap(positions[i]))
77
-
77
+
78
78
  plt.title(f"{self.propname}")
79
79
  plt.xlabel(along)
80
80
  plt.show()
81
-
81
+
82
82
  return self
83
-
84
- def hist(self, along: str = "N", bins: int = None, cmap: str = "jet",
83
+
84
+ def hist(self, along: str = "N", bins: int = None, cmap: str = "jet",
85
85
  cmap_range: tuple[float, float] = (0., 1.)) -> PropArray:
86
86
  """
87
87
  Plot histogram.
@@ -96,31 +96,31 @@ class PropArray(MetaArray):
96
96
  Colormap of each graph.
97
97
  cmap_range : tuple, default is (0, 1)
98
98
  Range of float for colormap iteration.
99
-
99
+
100
100
  Returns
101
101
  -------
102
102
  self
103
- """
103
+ """
104
104
  import matplotlib.pyplot as plt
105
105
 
106
106
  if self.dtype == object:
107
107
  raise TypeError(f"Cannot call plot_profile for {self.propname} "
108
108
  "because dtype == object.")
109
-
109
+
110
110
  if along is None:
111
111
  along = find_first_appeared("pxyzt<c", include=self.axes)
112
-
112
+
113
113
  iteraxes = self.axes.drop(along)
114
114
  cmap = plt.get_cmap(cmap)
115
115
  positions = np.linspace(*cmap_range, self.size//self.sizeof(along), endpoint=False)
116
116
  for i, (sl, y) in enumerate(self.iter(iteraxes)):
117
117
  plt.hist(y, color=cmap(positions[i]), bins=bins, alpha=0.5)
118
-
118
+
119
119
  plt.title(f"{self.propname}")
120
120
  plt.show()
121
-
121
+
122
122
  return self
123
-
123
+
124
124
  def curve_fit(self, f: Callable, p0 = None, dims = "t", return_fit: bool = True) -> DataDict[str, PropArray]:
125
125
  """
126
126
  Run scipy.optimize.curve_fit for each dimesion.
@@ -130,12 +130,12 @@ class PropArray(MetaArray):
130
130
  f : callable
131
131
  Model function.
132
132
  p0 : array or callable, optional
133
- Initial parameter. Callable object that estimate initial paramter can also
133
+ Initial parameter. Callable object that estimate initial paramter can also
134
134
  be passed here.
135
135
  dims : str, by default "t"
136
136
  Along which axes fitting algorithms are conducted.
137
137
  return_fit : bool, by default True
138
- If fitting trajectories are returned. If the input array is large, this will
138
+ If fitting trajectories are returned. If the input array is large, this will
139
139
  save much memory.
140
140
 
141
141
  Returns
@@ -144,23 +144,23 @@ class PropArray(MetaArray):
144
144
  params : Fitting parameters
145
145
  covs : Covariances
146
146
  fit : fitting trajectories (if return_fit==True)
147
- """
147
+ """
148
148
  from scipy import optimize as opt
149
149
 
150
150
  c_axes = complement_axes(dims, all_axes=self.axes)
151
-
151
+
152
152
  if len(dims)!=1:
153
153
  raise NotImplementedError("Only 1-dimensional fitting is implemented.")
154
-
154
+
155
155
  n_params = len(signature(f).parameters)-1
156
-
156
+
157
157
  params = np.empty(self.sizesof(c_axes) + (n_params,), dtype=np.float32)
158
158
  errs = np.empty(self.sizesof(c_axes) + (n_params,), dtype=np.float32)
159
159
  if return_fit:
160
160
  fit = np.empty(self.sizesof(c_axes) + (self.sizeof(dims),), dtype=self.dtype)
161
-
161
+
162
162
  xdata = np.arange(self.sizeof(dims))*self.scale[dims]
163
-
163
+
164
164
  for sl, data in self.iter(c_axes, exclude=dims):
165
165
  p0_ = p0 if not callable(p0) else p0(data)
166
166
  result = opt.curve_fit(f, xdata, data, p0_)
@@ -168,22 +168,22 @@ class PropArray(MetaArray):
168
168
  errs[sl] = np.sqrt(np.diag(cov))
169
169
  if return_fit:
170
170
  fit[sl] = f(xdata, *(result[0]))
171
-
171
+
172
172
  # set infos
173
173
  params = params.view(self.__class__)
174
174
  errs = errs.view(self.__class__)
175
175
  params._set_info(self, new_axes=self.axes.drop(dims).extend("m"))
176
176
  errs._set_info(self, new_axes=self.axes.drop(dims).extend("m"))
177
-
177
+
178
178
  if return_fit:
179
179
  fit = fit.view(self.__class__)
180
180
  fit._set_info(self, new_axes=self.axes.drop(dims).extend(dims))
181
-
181
+
182
182
  if return_fit:
183
183
  return DataDict(params=params, errs=errs, fit=fit)
184
184
  else:
185
185
  return DataDict(params=params, errs=errs)
186
-
186
+
187
187
  def as_frame(self, colname: str = "f") -> AxesFrame:
188
188
  """
189
189
  N-dimensional data to DataFrame. The intensity data is stored in the `colname` column.
@@ -197,7 +197,7 @@ class PropArray(MetaArray):
197
197
  -------
198
198
  AxesFrame
199
199
  DataFrame with PropArray data.
200
- """
200
+ """
201
201
  from ..frame import AxesFrame
202
202
  if colname in self.axes:
203
203
  raise ImageAxesError(f"Axis {colname} already exists.")
@@ -210,4 +210,3 @@ class PropArray(MetaArray):
210
210
  df = AxesFrame(data_dict, columns=new_axes)
211
211
  df.set_scale(self)
212
212
  return df
213
-
impy/core.py CHANGED
@@ -1,4 +1,5 @@
1
1
  from __future__ import annotations
2
+ from contextlib import suppress
2
3
  import os
3
4
  from pathlib import Path
4
5
  import re
@@ -489,12 +490,12 @@ def broadcast_arrays(*arrays: MetaArray) -> list[MetaArray]:
489
490
  out = [a.broadcast_to(shape, axes) for a in arrays]
490
491
  return out
491
492
 
492
- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
493
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
493
494
  # Imread functions
494
- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
495
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
495
496
 
496
497
  def imread(
497
- path: str,
498
+ path: str | Path,
498
499
  dtype: DTypeLike = None,
499
500
  key: AxesTargetedSlicer | None = None,
500
501
  *,
@@ -502,6 +503,7 @@ def imread(
502
503
  squeeze: bool = False,
503
504
  ) -> ImgArray:
504
505
  """Load image(s) from a path.
506
+
505
507
  You can read list of images from directories with wildcards or ``"$"`` in ``path``.
506
508
 
507
509
  Parameters
@@ -535,12 +537,30 @@ def imread(
535
537
  Wall time: 3.01 ms
536
538
 
537
539
  """
538
- path = str(Path(path).expanduser())
540
+ if str(path).startswith("~"):
541
+ path = str(Path(path).expanduser())
542
+ else:
543
+ path = str(path)
544
+
545
+ # if a directory of a ome.tiff is given, read the first image (which will eventually
546
+ # read all the positions) and use the directory name as source/name.
547
+ if (_fp := Path(path)).is_dir() and _fp.suffix != ".zarr":
548
+ _first_tif = next(_fp.glob("*.ome.tif"), None)
549
+ if _first_tif is None:
550
+ raise ValueError(
551
+ "If a directory is given to imread, only directory of ome.tif is "
552
+ "supported. Please use wildcard like `path/to/dir/*.tif` to read "
553
+ "images in a directory."
554
+ )
555
+ out = imread(_first_tif, dtype=dtype, key=key, name=_fp.name, squeeze=squeeze)
556
+ out.source = _fp
557
+ return out
558
+
539
559
  is_memmap = (key is not None)
540
560
 
541
561
  if "$" in path:
542
562
  return _imread_stack(path, dtype=dtype, key=key, squeeze=squeeze)
543
- elif "*" in path:
563
+ elif "*" in path or "?" in path or "[" in path:
544
564
  return _imread_glob(path, dtype=dtype, key=key, squeeze=squeeze)
545
565
  elif not Path(path).exists():
546
566
  raise FileNotFoundError(f"No such file or directory: {path}")
@@ -575,7 +595,8 @@ def imread(
575
595
  # In case the image is in yxc-order. This sometimes happens.
576
596
  self: ImgArray = np.moveaxis(self, -1, -3)
577
597
  if labels is not None:
578
- self.set_axis_label(c=labels)
598
+ with suppress(ValueError):
599
+ self.set_axis_label(c=labels)
579
600
 
580
601
  if dtype is None:
581
602
  dtype = self.dtype
@@ -619,8 +640,9 @@ def _imread_glob(path: str, squeeze: bool = False, **kwargs) -> ImgArray:
619
640
  out: ImgArray = np.stack(imgs, axis="p")
620
641
  if squeeze:
621
642
  out = np.squeeze(out)
643
+ sep = "*" if "*" in path else "?"
622
644
  try:
623
- base = os.path.split(path.split("*")[0])[0]
645
+ base = os.path.split(path.split(sep)[0])[0]
624
646
  out.source = base
625
647
  except Exception:
626
648
  pass
impy/frame/frames.py CHANGED
@@ -18,11 +18,11 @@ else:
18
18
 
19
19
  class AxesFrame(pd.DataFrame):
20
20
  _metadata = ["_axes"]
21
-
21
+
22
22
  @property
23
23
  def _constructor(self):
24
24
  return AxesFrame
25
-
25
+
26
26
  def __init__(self, data=None, columns=None, **kwargs):
27
27
  if isinstance(columns, (str, Axes)):
28
28
  kwargs["columns"] = [a for a in columns]
@@ -32,17 +32,17 @@ class AxesFrame(pd.DataFrame):
32
32
  columns = str(data._axes)
33
33
  else:
34
34
  kwargs["columns"] = columns
35
-
35
+
36
36
  super().__init__(data, **kwargs)
37
37
  self._axes = Axes(self.columns)
38
-
38
+
39
39
  def _get_coords_cols(self):
40
40
  return [a for a in self.columns if len(a) == 1]
41
-
41
+
42
42
  def get_coords(self):
43
43
  return self[self.columns[self.columns.isin([a for a in self.columns if len(a) == 1])]]
44
-
45
-
44
+
45
+
46
46
  def __getitem__(self, k):
47
47
  # sl_tuple = solve_slicer(key, self.axes)
48
48
  # drops: list[int] = []
@@ -56,7 +56,7 @@ class AxesFrame(pd.DataFrame):
56
56
  # binary = np.logical_and(binary, (arr - s0) % step == 0)
57
57
  # elif step < 0:
58
58
  # raise NotImplementedError
59
-
59
+
60
60
  # else:
61
61
  # binary = arr == sl
62
62
  # drops.append(i)
@@ -72,9 +72,9 @@ class AxesFrame(pd.DataFrame):
72
72
  for each in k.split(";"):
73
73
  self = self.__getitem__(each.strip())
74
74
  return self
75
-
75
+
76
76
  elif "=" in k:
77
- axis, sl = [a.strip() for a in k.split("=")]
77
+ axis, sl = (a.strip() for a in k.split("="))
78
78
  sl = str_to_slice(sl)
79
79
  if isinstance(sl, int):
80
80
  out = self[self[axis]==sl]
@@ -87,19 +87,19 @@ class AxesFrame(pd.DataFrame):
87
87
  elif "" == k:
88
88
  return self
89
89
  else:
90
- out = super().__getitem__(k)
90
+ out = super().__getitem__(k)
91
91
  else:
92
92
  out = super().__getitem__(k)
93
-
93
+
94
94
  if isinstance(out, AxesFrame):
95
95
  out._axes = Axes(out._get_coords_cols())
96
96
  out.set_scale(self)
97
97
  return out
98
-
98
+
99
99
  @property
100
100
  def col_axes(self):
101
101
  return self._axes
102
-
102
+
103
103
  @col_axes.setter
104
104
  def col_axes(self, value):
105
105
  naxes = self.shape[1]
@@ -113,11 +113,11 @@ class AxesFrame(pd.DataFrame):
113
113
  f"array (ndim={naxes}) and axes ({value})"
114
114
  )
115
115
  self._axes = axes
116
-
116
+
117
117
  @property
118
118
  def scale(self):
119
119
  return self._axes.scale
120
-
120
+
121
121
  def set_scale(self, other=None, **kwargs) -> None:
122
122
  """
123
123
  Set scales of each axis.
@@ -127,7 +127,7 @@ class AxesFrame(pd.DataFrame):
127
127
  other : dict, AxesFrame or MetaArray, optional
128
128
  New scales. If dict, it should be like {"x": 0.1, "y": 0.1}. If MetaArray, only
129
129
  scales of common axes are copied.
130
- kwargs :
130
+ kwargs :
131
131
  This enables function call like set_scale(x=0.1, y=0.1).
132
132
 
133
133
  """
@@ -142,40 +142,29 @@ class AxesFrame(pd.DataFrame):
142
142
  # check if all the keys are contained in axes.
143
143
  for a, val in other.items():
144
144
  if a not in self._axes:
145
- raise ImageAxesError(f"Image does not have axis {a}.")
145
+ raise ImageAxesError(f"Image does not have axis {a}.")
146
146
  elif not np.isscalar(val):
147
147
  raise TypeError(f"Cannot set non-numeric value as scales.")
148
-
148
+
149
149
  for k, v in other.items():
150
150
  self.col_axes[k].scale = v
151
-
151
+
152
152
  elif hasattr(other, "scale"):
153
153
  self.set_scale({a: s for a, s in other.scale.items() if a in self._axes})
154
-
154
+
155
155
  elif kwargs:
156
156
  self.set_scale(dict(kwargs))
157
-
157
+
158
158
  else:
159
159
  raise TypeError(f"'other' must be str or MetaArray, but got {type(other)}")
160
-
160
+
161
161
  return None
162
-
163
- def as_standard_type(self) -> AxesFrame:
164
- """
165
- t or c -> uint16
166
- p -> uint32
167
- z, y, x -> float32
168
- """
169
- dtype = lambda a: np.uint16 if a in ["t", "c"] else (np.uint32 if a == Const["ID_AXIS"] else np.float32)
170
- out = self.__class__(self.astype({a: dtype(a) for a in self.col_axes}))
171
- out._axes = self._axes
172
- return out
173
-
174
-
162
+
163
+
175
164
  def split(self, axis="c") -> list[AxesFrame]:
176
165
  """
177
166
  Split DataFrame according to its indices. For example, if self is an DataFrame with columns
178
- "t", "c", "y", "x" and it is split along "c" axis, then output is a list of DataFrame with
167
+ "t", "c", "y", "x" and it is split along "c" axis, then output is a list of DataFrame with
179
168
  columns "t", "y", "x".
180
169
 
181
170
  Parameters
@@ -204,7 +193,7 @@ class AxesFrame(pd.DataFrame):
204
193
  ----------
205
194
  axes : str
206
195
  Along which axes to iterate.
207
-
196
+
208
197
  Yields
209
198
  -------
210
199
  tuple and AxesFrame
@@ -214,10 +203,10 @@ class AxesFrame(pd.DataFrame):
214
203
  outsl = [slice(None)] * len(self.col_axes)
215
204
  cols = [a for a in self.col_axes if a not in axes]
216
205
  groupkeys = [a for a in axes]
217
-
206
+
218
207
  if len(groupkeys) == 0:
219
208
  yield (slice(None),), self
220
-
209
+
221
210
  else:
222
211
  if len(groupkeys) == 1:
223
212
  groupkeys = groupkeys[0]
@@ -227,21 +216,21 @@ class AxesFrame(pd.DataFrame):
227
216
  sl = (sl,)
228
217
  [outsl.__setitem__(i, s) for i, s in zip(indices, sl)]
229
218
  yield tuple(outsl), af
230
-
219
+
231
220
  def sort(self):
232
221
  ids = self._axes.argsort()
233
222
  return self[[self._axes[i] for i in ids]]
234
-
223
+
235
224
  def proj(self, axis=None):
236
225
  if axis is None:
237
226
  axis = complement_axes("yx", self._axes)
238
227
  cols = [a for a in self.col_axes if a not in axis]
239
228
  return self[cols]
240
-
229
+
241
230
  def tp_no_verbose(func):
242
231
  """
243
232
  Temporary suppress logging in trackpy.
244
- """
233
+ """
245
234
  @wraps(func)
246
235
  def wrapper(self, *args, **kwargs):
247
236
  tp.quiet(suppress=True)
@@ -277,19 +266,19 @@ class MarkerFrame(AxesFrame):
277
266
  -------
278
267
  TrackFrame
279
268
  Result of particle tracking.
280
- """
281
-
269
+ """
270
+
282
271
  linked = tp.link(pd.DataFrame(self), search_range=search_range, t_column="t", memory=memory, **kwargs)
283
-
272
+
284
273
  linked.rename(columns = {"particle":Const["ID_AXIS"]}, inplace=True)
285
274
  linked = linked.reindex(columns=[a for a in Const["ID_AXIS"]+str(self.col_axes)])
286
-
275
+
287
276
  track = TrackFrame(linked, columns="".join(linked.columns.tolist()))
288
277
  track.set_scale(self)
289
278
  if min_dwell > 0:
290
279
  out = track.filter_stubs(min_dwell)
291
280
  else:
292
- out = track.as_standard_type()
281
+ out = track
293
282
  out.index = np.arange(len(out))
294
283
  return out
295
284
 
@@ -298,7 +287,7 @@ class TrackFrame(AxesFrame):
298
287
  df = pd.DataFrame(self, copy=True, dtype=np.float32)
299
288
  df.rename(columns = {"t":"frame", Const["ID_AXIS"]:"particle"}, inplace=True)
300
289
  return df
301
-
290
+
302
291
  @tp_no_verbose
303
292
  def track_drift(self, smoothing=0):
304
293
  df = self._renamed_df()
@@ -307,25 +296,25 @@ class TrackFrame(AxesFrame):
307
296
  ori = pd.DataFrame({"y":[0.], "x":[0.]}, dtype=np.float32)
308
297
  shift = pd.concat([ori, shift], axis=0)
309
298
  return MarkerFrame(shift)
310
-
299
+
311
300
  @tp_no_verbose
312
301
  def msd(self, max_lagt:int=100, detail:bool=False):
313
302
  df = self._renamed_df()
314
- return tp.motion.msd(df, self.scale["x"], self.scale["t"],
303
+ return tp.motion.msd(df, self.scale["x"], self.scale["t"],
315
304
  max_lagtime=max_lagt, detail=detail)
316
-
305
+
317
306
  @tp_no_verbose
318
307
  def imsd(self, max_lagt=100):
319
308
  df = self._renamed_df()
320
- return tp.motion.imsd(df, self.scale["x"], self.scale["t"],
309
+ return tp.motion.imsd(df, self.scale["x"], self.scale["t"],
321
310
  max_lagtime=max_lagt)
322
-
311
+
323
312
  @tp_no_verbose
324
313
  def emsd(self, max_lagt=100, detail=False):
325
314
  df = self._renamed_df()
326
- return tp.motion.emsd(df, self.scale["x"], self.scale["t"],
315
+ return tp.motion.emsd(df, self.scale["x"], self.scale["t"],
327
316
  max_lagtime=max_lagt, detail=detail)
328
-
317
+
329
318
  @tp_no_verbose
330
319
  def filter_stubs(self, min_dwell=3):
331
320
  df = self._renamed_df()
@@ -334,8 +323,8 @@ class TrackFrame(AxesFrame):
334
323
  df = df.astype({"t":np.uint16, Const["ID_AXIS"]:np.uint32})
335
324
  out = TrackFrame(df, columns=self.col_axes)
336
325
  out.set_scale(self)
337
- return out.as_standard_type()
338
-
326
+ return out
327
+
339
328
  def as_path(self):
340
329
  df = self[[a for a in self._axes if a != "t"]]
341
330
  return PathFrame(df, columns=df._axes)
@@ -346,4 +335,4 @@ class PathFrame(AxesFrame):
346
335
  dims = [a for a in "zyx" if a in self._axes]
347
336
  path_len = lambda df: np.sum(np.sqrt(sum(np.diff(df[a])**2 for a in dims)))
348
337
  c_axes = complement_axes(dims, self._axes)
349
- return self.groupby(list(c_axes)).apply(path_len)
338
+ return self.groupby(list(c_axes)).apply(path_len)
impy/lazy/core.py CHANGED
@@ -278,7 +278,7 @@ def imread(
278
278
  if k in "zyx":
279
279
  self.axes[k].unit = spatial_scale_unit.get(k)
280
280
 
281
- return self.sort_axes()
281
+ return self
282
282
 
283
283
 
284
284
  def _imread_glob(path: str, squeeze: bool = False, **kwargs) -> LazyImgArray:
impy/viewer/utils.py CHANGED
@@ -16,7 +16,7 @@ if TYPE_CHECKING:
16
16
  from napari.layers import Shapes
17
17
 
18
18
 
19
- def iter_layer(viewer:"napari.Viewer", layer_type: str):
19
+ def iter_layer(viewer:napari.Viewer, layer_type: str):
20
20
  """
21
21
  Iterate over layers and yield only certain type of layers.
22
22
 
@@ -29,31 +29,31 @@ def iter_layer(viewer:"napari.Viewer", layer_type: str):
29
29
  -------
30
30
  napari.layers
31
31
  Layers specified by layer_type
32
- """
32
+ """
33
33
  from napari import layers
34
34
  if isinstance(layer_type, str):
35
35
  layer_type = [layer_type]
36
36
  layer_type = tuple(getattr(layers, t) for t in layer_type)
37
-
37
+
38
38
  for layer in viewer.layers:
39
39
  if isinstance(layer, layer_type):
40
40
  yield layer
41
41
 
42
- def iter_selected_layer(viewer: "napari.Viewer", layer_type: str | list[str]):
42
+ def iter_selected_layer(viewer: napari.Viewer, layer_type: str | list[str]):
43
43
  """Iterate over selected layers and yield only certain type of layers."""
44
-
44
+
45
45
  from napari import layers
46
46
  if isinstance(layer_type, str):
47
47
  layer_type = [layer_type]
48
48
  layer_type = tuple(getattr(layers, t) for t in layer_type)
49
-
49
+
50
50
  for layer in viewer.layers.selection:
51
51
  if isinstance(layer, layer_type):
52
52
  yield layer
53
53
 
54
- def front_image(viewer:"napari.Viewer"):
55
- """From list of image layers return the most front visible image."""
56
-
54
+ def front_image(viewer:napari.Viewer):
55
+ """From list of image layers return the most front visible image."""
56
+
57
57
  front = None
58
58
  for img in iter_layer(viewer, "Image"):
59
59
  if img.visible:
@@ -62,7 +62,7 @@ def front_image(viewer:"napari.Viewer"):
62
62
  raise ValueError("There is no visible image layer.")
63
63
  return front
64
64
 
65
- def to_labels(layer: "Shapes", labels_shape: tuple[int, ...], zoom_factor: float = 1.):
65
+ def to_labels(layer: Shapes, labels_shape: tuple[int, ...], zoom_factor: float = 1.):
66
66
  """Convert a Shapes layer to labels, with given zoom factor."""
67
67
  return layer._data_view.to_labels(
68
68
  labels_shape=labels_shape, zoom_factor=zoom_factor
@@ -79,9 +79,9 @@ def make_world_scale(obj):
79
79
  scale.append(1)
80
80
  return scale
81
81
 
82
- def viewer_imread(viewer: "napari.Viewer", path: str):
82
+ def viewer_imread(viewer: napari.Viewer, path: str):
83
83
  """Read an image into the viewer."""
84
-
84
+
85
85
  if "*" in path or os.path.getsize(path)/2**30 < Const["MAX_GB"]:
86
86
  img = imread(path)
87
87
  else:
@@ -89,9 +89,9 @@ def viewer_imread(viewer: "napari.Viewer", path: str):
89
89
  layer = add_labeledarray(viewer, img)
90
90
  return layer
91
91
 
92
- def add_labeledarray(viewer: "napari.Viewer", img: LabeledArray, **kwargs):
92
+ def add_labeledarray(viewer: napari.Viewer, img: LabeledArray, **kwargs):
93
93
  """Add a LabeledArray to the viewer."""
94
-
94
+
95
95
  if not img.axes.is_sorted() and img.ndim > 2:
96
96
  msg = (
97
97
  f"Input image has axes that are not correctly sorted: {img.axes}. "
@@ -99,15 +99,15 @@ def add_labeledarray(viewer: "napari.Viewer", img: LabeledArray, **kwargs):
99
99
  )
100
100
  warnings.warn(msg, UserWarning)
101
101
  chn_ax = img.axisof("c") if "c" in img.axes else None
102
-
102
+
103
103
  if isinstance(img, PhaseArray) and not "colormap" in kwargs.keys():
104
104
  kwargs["colormap"] = "hsv"
105
105
  kwargs["contrast_limits"] = img.border
106
106
  elif img.dtype.kind == "c" and not "colormap" in kwargs.keys():
107
107
  kwargs["colormap"] = "plasma"
108
-
108
+
109
109
  scale = make_world_scale(img)
110
-
110
+
111
111
  if "name" in kwargs:
112
112
  name = kwargs.pop("name")
113
113
  else:
@@ -116,20 +116,20 @@ def add_labeledarray(viewer: "napari.Viewer", img: LabeledArray, **kwargs):
116
116
  name = [f"[C{i}]{name}" for i in range(img.shape.c)]
117
117
  else:
118
118
  name = [name]
119
-
119
+
120
120
  if img.dtype.kind == "c":
121
121
  input = ComplexArrayView(img)
122
122
  else:
123
123
  input = img
124
-
124
+
125
125
  layer = viewer.add_image(
126
126
  input,
127
127
  channel_axis=chn_ax,
128
- scale=scale,
128
+ scale=scale,
129
129
  name=name if len(name) > 1 else name[0],
130
130
  **kwargs
131
131
  )
132
-
132
+
133
133
  if viewer.scale_bar.unit:
134
134
  if viewer.scale_bar.unit != img.scale_unit:
135
135
  msg = (
@@ -139,7 +139,7 @@ def add_labeledarray(viewer: "napari.Viewer", img: LabeledArray, **kwargs):
139
139
  warnings.warn(msg)
140
140
  else:
141
141
  viewer.scale_bar.unit = img.scale_unit
142
-
142
+
143
143
  new_axes = [str(a) for a in img.axes if a != "c"]
144
144
  # add axis labels to slide bars and image orientation.
145
145
  if len(new_axes) >= len(viewer.dims.axis_labels):
@@ -147,10 +147,10 @@ def add_labeledarray(viewer: "napari.Viewer", img: LabeledArray, **kwargs):
147
147
  return layer
148
148
 
149
149
  def add_labels(
150
- viewer: "napari.Viewer",
150
+ viewer: napari.Viewer,
151
151
  labels: Label,
152
152
  opacity: float = 0.3,
153
- name: str | list[str] | None = None,
153
+ name: str | list[str] | None = None,
154
154
  **kwargs
155
155
  ):
156
156
  scale = make_world_scale(labels)
@@ -159,7 +159,7 @@ def add_labels(
159
159
  lbls = labels.split("c")
160
160
  else:
161
161
  lbls = [labels]
162
-
162
+
163
163
  # prepare name list
164
164
  if isinstance(name, list):
165
165
  names = [f"[L]{n}" for n in name]
@@ -167,19 +167,19 @@ def add_labels(
167
167
  names = [f"[L]{name}"] * len(lbls)
168
168
  else:
169
169
  names = [labels.name]
170
-
170
+
171
171
  kw = dict(opacity=opacity, scale=scale)
172
172
  kw.update(kwargs)
173
-
173
+
174
174
  out_layers = []
175
175
  for lbl, name in zip(lbls, names):
176
176
  layer = viewer.add_labels(lbl.value, name=name, **kw)
177
177
  out_layers.append(layer)
178
178
  return out_layers
179
179
 
180
- def add_dask(viewer: "napari.Viewer", img: LazyImgArray, **kwargs):
180
+ def add_dask(viewer: napari.Viewer, img: LazyImgArray, **kwargs):
181
181
  chn_ax = img.axisof("c") if "c" in img.axes else None
182
-
182
+
183
183
  scale = make_world_scale(img)
184
184
  name = img.name
185
185
 
@@ -188,7 +188,7 @@ def add_dask(viewer: "napari.Viewer", img: LazyImgArray, **kwargs):
188
188
  else:
189
189
  name = ["[Lazy]" + name]
190
190
 
191
- layer = viewer.add_image(img, channel_axis=chn_ax, scale=scale,
191
+ layer = viewer.add_image(img, channel_axis=chn_ax, scale=scale,
192
192
  name=name if len(name)>1 else name[0], **kwargs)
193
193
  viewer.scale_bar.unit = img.scale_unit
194
194
  new_axes = [str(a) for a in img.axes if a != "c"]
@@ -197,19 +197,19 @@ def add_dask(viewer: "napari.Viewer", img: LazyImgArray, **kwargs):
197
197
  viewer.dims.axis_labels = new_axes
198
198
  return layer
199
199
 
200
- def add_points(viewer:"napari.Viewer", points: AxesFrame, **kwargs):
200
+ def add_points(viewer:napari.Viewer, points: AxesFrame, **kwargs):
201
201
  from ..frame import MarkerFrame
202
202
  if isinstance(points, MarkerFrame):
203
203
  scale = make_world_scale(points)
204
204
  points = points.get_coords()
205
205
  else:
206
206
  scale=None
207
-
207
+
208
208
  if "c" in points._axes:
209
209
  pnts = points.split("c")
210
210
  else:
211
211
  pnts = [points]
212
-
212
+
213
213
  for each in pnts:
214
214
  metadata = {"axes": str(each._axes), "scale": each.scale}
215
215
  kw = dict(
@@ -219,30 +219,30 @@ def add_points(viewer:"napari.Viewer", points: AxesFrame, **kwargs):
219
219
  )
220
220
  kw.update(kwargs)
221
221
  viewer.add_points(each.values, scale=scale, **kw)
222
-
222
+
223
223
  return None
224
224
 
225
- def add_tracks(viewer:"napari.Viewer", track: "TrackFrame", **kwargs):
225
+ def add_tracks(viewer:napari.Viewer, track: TrackFrame, **kwargs):
226
226
  if "c" in track._axes:
227
227
  track_list = track.split("c")
228
228
  else:
229
229
  track_list = [track]
230
-
230
+
231
231
  scale = make_world_scale(
232
232
  track[[a for a in track._axes if a != Const["ID_AXIS"]]]
233
233
  )
234
234
  for tr in track_list:
235
235
  metadata = {"axes": str(tr._axes), "scale": tr.scale}
236
236
  viewer.add_tracks(tr, scale=scale, metadata=metadata, **kwargs)
237
-
237
+
238
238
  return None
239
239
 
240
- def add_paths(viewer: "napari.Viewer", paths: PathFrame, **kwargs):
240
+ def add_paths(viewer: napari.Viewer, paths: PathFrame, **kwargs):
241
241
  if "c" in paths._axes:
242
242
  path_list = paths.split("c")
243
243
  else:
244
244
  path_list = [paths]
245
-
245
+
246
246
  scale = make_world_scale(
247
247
  paths[[a for a in paths._axes if a != Const["ID_AXIS"]]]
248
248
  )
@@ -253,19 +253,19 @@ def add_paths(viewer: "napari.Viewer", paths: PathFrame, **kwargs):
253
253
  metadata = {"axes": str(path._axes), "scale": path.scale}
254
254
  paths = [single_path.values for single_path in path.split(Const["ID_AXIS"])]
255
255
  viewer.add_shapes(paths, scale=scale, metadata=metadata, **kw)
256
-
256
+
257
257
  return None
258
258
 
259
- def add_rois(viewer: "napari.Viewer", rois: Iterable[Roi], **kwargs):
259
+ def add_rois(viewer: napari.Viewer, rois: Iterable[Roi], **kwargs):
260
260
  from ..roi import LineRoi, PointRoi, PolygonRoi, PolyLineRoi, RectangleRoi
261
-
261
+
262
262
  _map = {
263
263
  LineRoi: "line",
264
264
  PolygonRoi: "polygon",
265
265
  PolyLineRoi: "path",
266
266
  RectangleRoi: "rectangle",
267
267
  }
268
-
268
+
269
269
  shapes = []
270
270
  shape_types = []
271
271
  for roi in rois:
@@ -274,16 +274,16 @@ def add_rois(viewer: "napari.Viewer", rois: Iterable[Roi], **kwargs):
274
274
  else:
275
275
  shape_types.append(_map[type(roi)])
276
276
  shapes.append(np.array(roi))
277
-
277
+
278
278
  viewer.add_shapes(shapes, shape_type=shape_types, **kwargs)
279
-
279
+
280
280
  return None
281
281
 
282
- def get_viewer_scale(viewer: "napari.Viewer"):
282
+ def get_viewer_scale(viewer: napari.Viewer):
283
283
  """Get the scale of the viewer."""
284
284
  return {a: r[2] for a, r in zip(viewer.dims.axis_labels, viewer.dims.range)}
285
285
 
286
- def layer_to_impy_object(viewer: "napari.Viewer", layer):
286
+ def layer_to_impy_object(viewer: napari.Viewer, layer):
287
287
  """
288
288
  Convert layer to real data.
289
289
 
@@ -295,7 +295,7 @@ def layer_to_impy_object(viewer: "napari.Viewer", layer):
295
295
  Returns
296
296
  -------
297
297
  ImgArray, Label, MarkerFrame or TrackFrame, or Shape features.
298
- """
298
+ """
299
299
  data = layer.data
300
300
  axes = "".join(viewer.dims.axis_labels)
301
301
  scale = get_viewer_scale(viewer)
@@ -321,21 +321,21 @@ def layer_to_impy_object(viewer: "napari.Viewer", layer):
321
321
  ndim = data.shape[1]
322
322
  axes = axes[-ndim:]
323
323
  df = MarkerFrame(data, columns=layer.metadata.get("axes", axes))
324
- df.set_scale(layer.metadata.get("scale",
324
+ df.set_scale(layer.metadata.get("scale",
325
325
  {k: v for k, v in scale.items() if k in axes}))
326
- return df.as_standard_type()
326
+ return df
327
327
  elif isinstance(layer, Tracks):
328
328
  from ..frame import TrackFrame
329
329
  ndim = data.shape[1]
330
330
  axes = axes[-ndim:]
331
331
  df = TrackFrame(data, columns=layer.metadata.get("axes", axes))
332
- df.set_scale(layer.metadata.get("scale",
332
+ df.set_scale(layer.metadata.get("scale",
333
333
  {k: v for k, v in scale.items() if k in axes}))
334
- return df.as_standard_type()
334
+ return df
335
335
  else:
336
336
  raise NotImplementedError(type(layer))
337
337
 
338
- def get_a_selected_layer(viewer:"napari.Viewer"):
338
+ def get_a_selected_layer(viewer:napari.Viewer):
339
339
  selected = list(viewer.layers.selection)
340
340
  if len(selected) == 0:
341
341
  raise ValueError("No layer is selected.")
@@ -352,34 +352,34 @@ class ComplexArrayView:
352
352
  if data.dtype.kind != "c":
353
353
  raise TypeError("Input was not a complex array.")
354
354
  self._data = data
355
-
355
+
356
356
  def __array__(self, dtype=None, copy=False) -> np.ndarray:
357
357
  return np.abs(self._data)
358
-
358
+
359
359
  @property
360
360
  def data_raw(self) -> _A:
361
361
  """Return the raw data."""
362
362
  return self._data
363
-
363
+
364
364
  @property
365
365
  def shape(self) -> tuple:
366
366
  """Shape of array."""
367
367
  return self._data.shape
368
-
368
+
369
369
  @property
370
370
  def ndim(self) -> int:
371
371
  """Number of dimensions of array."""
372
372
  return self._data.ndim
373
-
373
+
374
374
  @property
375
375
  def dtype(self) -> np.dtype:
376
376
  """Data type of array."""
377
377
  return self._data.dtype
378
-
378
+
379
379
  @property
380
380
  def nbytes(self) -> int:
381
381
  """Bytes of array."""
382
382
  return self._data.nbytes
383
-
383
+
384
384
  def __getitem__(self, key):
385
- return self.__class__(self._data[key])
385
+ return self.__class__(self._data[key])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: impy-array
3
- Version: 2.5.0
3
+ Version: 2.5.2
4
4
  Summary: Speed up coding/extending image analysis in Python.
5
5
  Project-URL: Download, https://github.com/hanjinliu/impy
6
6
  Author-email: Hanjin Liu <liuhanjin-sc@g.ecc.u-tokyo.ac.jp>
@@ -1,11 +1,11 @@
1
- impy/__init__.py,sha256=HIf0has95uJ0K2gmcvEEzYy1YhiTmA5FYy4sk5y4AL0,1638
1
+ impy/__init__.py,sha256=aibzVT5sn4GqWH_rElWQlVWdtgap0hDKqlCnALbn1P8,1638
2
2
  impy/__main__.py,sha256=BAQkQ4X8EFo42pbNx__EqpZ5KL4MTfTUWsVbJIQF0O0,4974
3
3
  impy/_const.py,sha256=uNHxxY5ltZuOsJWpwlBWFmUM0QfMgIk5WODqlHuBomo,3700
4
4
  impy/_types.py,sha256=gO4l0hx9qxe6eI0PyC4ukW3k4IYxCEZ9gT-rQ3jj3zU,808
5
5
  impy/array_api.py,sha256=9suP_Wck9maSiEa5qK6aZrCfaky6xhCMfIRcc9WuIs8,5585
6
6
  impy/binder.py,sha256=CTMb11g6uYDVVQV5Wtef865IO0G2V3vGXc8SiGYRD5k,9651
7
7
  impy/collections.py,sha256=2e55bLjZN7W4LFUCkyxekcDfLwZodMaU4JG5NQ3RS54,10946
8
- impy/core.py,sha256=d7TsgpVcPQi_CqATgFa_QZ1ojTKxTWEfSlpE_UKOQ9A,25610
8
+ impy/core.py,sha256=ntvPvL48PvX_tlxb7_KXMF8HGV8q-7Hh_wlIuMljxb4,26527
9
9
  impy/correlation.py,sha256=Yw1T_0eL9FmsMcnCysc49oRJQMn8ho5z9bAzNg5i59Y,28232
10
10
  impy/random.py,sha256=MQl0ViN6A7xDtM8BS4gbv1atgPKsrmp0TXzV1OtsDlU,7004
11
11
  impy/roi.py,sha256=p9ttjBl5SGHHXj0xg5UjPlg_V9cY3MnNZxFfYIjTYsg,14164
@@ -13,12 +13,12 @@ impy/arrays/__init__.py,sha256=IHpTBIJysomS64rOZsv960YBmM1vc4M-asTSs1OJBWg,454
13
13
  impy/arrays/_imshow.py,sha256=6mJ_PDqmE4UZO9e9SUgyY_YrzQdR2QKlTG7KF_aC_tI,6949
14
14
  impy/arrays/axesmixin.py,sha256=NwiPldNbD3rYpvuydviJMEoH88-joHdfQuuXLE6Rs7c,10454
15
15
  impy/arrays/big.py,sha256=tHNijyPgyIfTltLP3hQwZdHOpSX3IwG5DHPamajZ8Kg,2745
16
- impy/arrays/imgarray.py,sha256=rpwu9uGMKAO3raw1qli5FBvDer0TFWL_X2Z8a3eU5nQ,161974
16
+ impy/arrays/imgarray.py,sha256=qAZ_ZtK4rFisXta1W5jrF7b71ivoLLT6NbzY-MIHVWA,161761
17
17
  impy/arrays/label.py,sha256=l0SZXcZxU8qwUgj0QZPZ32XsNaoBtenlrn6hNR03SPI,6406
18
- impy/arrays/labeledarray.py,sha256=GRjgZ5IfXIq-Iwj9cEYazo7oPNiBveRekUnKcSts91I,59455
19
- impy/arrays/lazy.py,sha256=y3IXPs6mRE2I8yiOnMsjO0gqi2EFjrNxHMOExUF_xM0,61450
18
+ impy/arrays/labeledarray.py,sha256=9fT0bVqyByYG1ifyQzzC1y8KdEUx_hrfNI7Vex_EAvs,59026
19
+ impy/arrays/lazy.py,sha256=lRRRN25WE9v2TwOl37Dny6OuyPv-be8dsBJ6vqHnkQY,60982
20
20
  impy/arrays/phasearray.py,sha256=IojWaNs5sEujn6Lhgqe00H0xF-4CZEFWt5cVW6U_DWQ,13981
21
- impy/arrays/specials.py,sha256=4sNg_zeJUce_rwnasPoyL2eZ0-gx_4Z-KwitmLB4a5k,7896
21
+ impy/arrays/specials.py,sha256=M2EmpYNChc4FoAAZvkRq8OKq2zLAd6TWqKIF_lfpCqg,7666
22
22
  impy/arrays/tiled.py,sha256=T44sS6v1Ovln1z1g61Eg8irgZR1Jmpb6BCY3nS6TmDE,9400
23
23
  impy/arrays/_utils/__init__.py,sha256=M5HogfyUBvV8kp-X1ZthS8vDLUP7-O2f9Gvsc1ZXdT8,271
24
24
  impy/arrays/_utils/_corr.py,sha256=ThGQV3KSv8ir8BTWDoV83ysalPB2p--LmSCv-J9qq2w,10047
@@ -42,7 +42,7 @@ impy/axes/_axes_tuple.py,sha256=hkgTr_n36gFcnnffmSp3z4oJ_52MxT1JnaszdJ3JnrY,1522
42
42
  impy/axes/_axis.py,sha256=TlaF_Ya1DLcNwz8LFAL4xWC0Xt8HA0WR4ZUC3SYJPP0,7469
43
43
  impy/axes/_slicer.py,sha256=Ts4m9V3PBlEb3xeHd6j1XdMEb1SwYGbBF5rnC9WWYZE,2657
44
44
  impy/frame/__init__.py,sha256=Z4XfXzFSDq49tMrVoeYx1ThnHyw43iLVSVcte6b6-as,65
45
- impy/frame/frames.py,sha256=7NxDeuaG8CxzMnzczarmLz6ANBpl1tZIhn8KwdvBYg8,12450
45
+ impy/frame/frames.py,sha256=RGFbRd5h7fSI-t1b2lt2GCF_Y9N8dkIFvkH6E63qFJ4,11720
46
46
  impy/io/__init__.py,sha256=Xz7SeHkDDbLm3Z9gqav3iByLsmsBoLjol4nDtEq-WeY,315
47
47
  impy/io/_czi.py,sha256=0FQsrzL9ygaB6IHITceAmLsOxkLFKwlQFKSLQCmJbyY,1667
48
48
  impy/io/_mrc.py,sha256=i3_GHxBdM8f0NYnqU7Oklw6wM7boYcLzWwBTU7V3Y2U,3936
@@ -53,7 +53,7 @@ impy/io/_tiff.py,sha256=kfRB6H-fKBk-lrv_y6tY2fNbG_BEcPm2Ja41-0EtZ_8,6528
53
53
  impy/io/_utils.py,sha256=WHAiuCC1_tdsZ07HLM8jKjptKnQGevG7eXdnuJd069o,3723
54
54
  impy/io/_zarr.py,sha256=Nfr5VJ3DzKN5d7nYoq_ZG9AG2GIDWHYJ33LpG9SwGcs,1336
55
55
  impy/lazy/__init__.py,sha256=hRjpE2zCy5qDAr_27imwRM9J0C7q-a_b5wfC3ux8ZLE,59
56
- impy/lazy/core.py,sha256=RNGavMvPW6_Yfi-L0WDIWfRZKo1My8Fw8Qo1e0pQA1k,9682
56
+ impy/lazy/core.py,sha256=LQMHl8cKBiGc972PFRP3jJungv8MtBn6B24bI4aFQWs,9670
57
57
  impy/lazy/random.py,sha256=2rwHRsHPOvi8tI9kTtGuZ5SzN0MA7yn-30bZSvHeLVc,7713
58
58
  impy/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
59
  impy/utils/axesop.py,sha256=c86XdNlUBFLrwHhAT2j0eELxopNe2QEVaNeOQhXr2do,3076
@@ -63,10 +63,10 @@ impy/utils/misc.py,sha256=zV_NeqEaiTW4Rki5fqWfspQjczRaoTJ5MxTOUx6qstY,622
63
63
  impy/utils/slicer.py,sha256=otDrizWdzoUjFUMlsha0zNFSS4TkgAmLPOAotaTVaUA,4316
64
64
  impy/utils/utilcls.py,sha256=3Td9G2ZkU4C0BiW2LH0sq7RBjdco_BtyxNr-s-seLhs,437
65
65
  impy/viewer/__init__.py,sha256=MH-jhpFxP8JVJwUzbKMLRhhWSEYavVHuik9uOS3dDNU,292
66
- impy/viewer/utils.py,sha256=_RWV9LePbmYeC8qRBUBf3qG70BaLOndlzRLcvUYgTtE,12248
66
+ impy/viewer/utils.py,sha256=Giv1Q50gXDHQZoJyrGJEBUKCKfOQLkRB6fC5NE2rzg0,11971
67
67
  impy/viewer/viewer.py,sha256=Sfq-obSLoHkBkIW0NDWCxEEaX7-YsC4ifAJ-nxpvJws,17632
68
- impy_array-2.5.0.dist-info/METADATA,sha256=Mezd4xl2BG99x3NrWc1O2uXn86erZm2PV5xcCElQs5E,7567
69
- impy_array-2.5.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
70
- impy_array-2.5.0.dist-info/entry_points.txt,sha256=reyrgy4odXvi1CcPOIIyRYBmsNGG2tO7ZkFOdG5CBkU,44
71
- impy_array-2.5.0.dist-info/licenses/LICENSE,sha256=rpxKafH9r42sxLLYYB5VbZBHOdtYeLuYJjVU1LBwrxk,1546
72
- impy_array-2.5.0.dist-info/RECORD,,
68
+ impy_array-2.5.2.dist-info/METADATA,sha256=_HvcusR2hwLfWqpdpTaYv7x3Zhi73k5kDb6zaKECFeY,7567
69
+ impy_array-2.5.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
70
+ impy_array-2.5.2.dist-info/entry_points.txt,sha256=reyrgy4odXvi1CcPOIIyRYBmsNGG2tO7ZkFOdG5CBkU,44
71
+ impy_array-2.5.2.dist-info/licenses/LICENSE,sha256=rpxKafH9r42sxLLYYB5VbZBHOdtYeLuYJjVU1LBwrxk,1546
72
+ impy_array-2.5.2.dist-info/RECORD,,