diff --git a/ndbioimage/__init__.py b/ndbioimage/__init__.py index 7b2b09a..ccd37a1 100755 --- a/ndbioimage/__init__.py +++ b/ndbioimage/__init__.py @@ -106,7 +106,7 @@ def get_ome(path): class Shape(tuple): - def __new__(cls, shape, axes='xyczt'): + def __new__(cls, shape, axes='yxczt'): if isinstance(shape, Shape): axes = shape.axes instance = super().__new__(cls, shape) @@ -122,8 +122,8 @@ class Shape(tuple): return super().__getitem__(n) @cached_property - def xyczt(self): - return tuple(self[i] for i in 'xyczt') + def yxczt(self): + return tuple(self[i] for i in 'yxczt') class Imread(np.lib.mixins.NDArrayOperatorsMixin, ABC): @@ -225,8 +225,8 @@ class Imread(np.lib.mixins.NDArrayOperatorsMixin, ABC): for idx in unique_yield([key[:3] for key in self.cache.keys()], product(range(self.shape['c']), range(self.shape['z']), range(self.shape['t']))): - xyczt = (slice(None), slice(None)) + idx - in_idx = tuple(xyczt['xyczt'.find(i)] for i in self.axes) + yxczt = (slice(None), slice(None)) + idx + in_idx = tuple(yxczt['yxczt'.find(i)] for i in self.axes) if item in np.asarray(self[in_idx]): return True return False @@ -266,7 +266,7 @@ class Imread(np.lib.mixins.NDArrayOperatorsMixin, ABC): while len(n) < self.ndim: n.append(None) - axes_idx = [self.shape.axes.find(i) for i in 'xyczt'] + axes_idx = [self.shape.axes.find(i) for i in 'yxczt'] n = [n[j] if 0 <= j < len(n) else None for j in axes_idx] # reorder n new_slice = [] @@ -283,7 +283,7 @@ class Imread(np.lib.mixins.NDArrayOperatorsMixin, ABC): new = View(self) new.slice = new_slice new._shape = Shape([1 if isinstance(s, Number) else len(s) for s in new_slice]) - new.axes = ''.join(j for j in self.axes if j in [i for i, s in zip('xyczt', new_slice) + new.axes = ''.join(j for j in self.axes if j in [i for i, s in zip('yxczt', new_slice) if not isinstance(s, Number)]) return new @@ -308,7 +308,7 @@ class Imread(np.lib.mixins.NDArrayOperatorsMixin, ABC): def __array__(self, dtype=None): block = self.block(*self.slice) - axes_idx = [self.shape.axes.find(i) for i in 'xyczt'] + axes_idx = [self.shape.axes.find(i) for i in 'yxczt'] axes_squeeze = tuple({i for i, j in enumerate(axes_idx) if j == -1}.union( {i for i, j in enumerate(self.slice) if isinstance(j, Number)})) block = block.squeeze(axes_squeeze) @@ -316,7 +316,7 @@ class Imread(np.lib.mixins.NDArrayOperatorsMixin, ABC): block = block.astype(dtype) if block.ndim == 0: return block.item() - axes = ''.join(j for i, j in enumerate('xyczt') if i not in axes_squeeze) + axes = ''.join(j for i, j in enumerate('yxczt') if i not in axes_squeeze) return block.transpose([axes.find(i) for i in self.shape.axes if i in axes]) def __array_arg_fun__(self, fun, axis=None, out=None): @@ -324,8 +324,8 @@ class Imread(np.lib.mixins.NDArrayOperatorsMixin, ABC): if axis is None: value = arg = None for idx in product(range(self.shape['c']), range(self.shape['z']), range(self.shape['t'])): - xyczt = (slice(None), slice(None)) + idx - in_idx = tuple(xyczt['xyczt'.find(i)] for i in self.axes) + yxczt = (slice(None), slice(None)) + idx + in_idx = tuple(yxczt['yxczt'.find(i)] for i in self.axes) new = np.asarray(self[in_idx]) new_arg = np.unravel_index(fun(new), new.shape) new_value = new[new_arg] @@ -336,7 +336,7 @@ class Imread(np.lib.mixins.NDArrayOperatorsMixin, ABC): i = fun((value, new_value)) arg = (arg, new_arg + idx)[i] value = (value, new_value)[i] - axes = ''.join(i for i in self.axes if i in 'xy') + 'czt' + axes = ''.join(i for i in self.axes if i in 'yx') + 'czt' arg = np.ravel_multi_index([arg[axes.find(i)] for i in self.axes], self.shape) if out is None: return arg @@ -356,19 +356,19 @@ class Imread(np.lib.mixins.NDArrayOperatorsMixin, ABC): out_axes.pop(axis_idx) if out is None: out = np.zeros(out_shape, int) - if axis_str in 'xy': + if axis_str in 'yx': for idx in product(range(self.shape['c']), range(self.shape['z']), range(self.shape['t'])): - xyczt = (slice(None), slice(None)) + idx - out_idx = tuple(xyczt['xyczt'.find(i)] for i in out_axes) - in_idx = tuple(xyczt['xyczt'.find(i)] for i in self.axes) + yxczt = (slice(None), slice(None)) + idx + out_idx = tuple(yxczt['yxczt'.find(i)] for i in out_axes) + in_idx = tuple(yxczt['yxczt'.find(i)] for i in self.axes) new = self[in_idx] out[out_idx] = fun(np.asarray(new), new.axes.find(axis_str)) else: value = np.zeros(out.shape, self.dtype) for idx in product(range(self.shape['c']), range(self.shape['z']), range(self.shape['t'])): - xyczt = (slice(None), slice(None)) + idx - out_idx = tuple(xyczt['xyczt'.find(i)] for i in out_axes) - in_idx = tuple(xyczt['xyczt'.find(i)] for i in self.axes) + yxczt = (slice(None), slice(None)) + idx + out_idx = tuple(yxczt['yxczt'.find(i)] for i in out_axes) + in_idx = tuple(yxczt['yxczt'.find(i)] for i in self.axes) new_value = self[in_idx] new_arg = np.full_like(new_value, idx['czt'.find(axis_str)]) if idx['czt'.find(axis_str)] == 0: @@ -401,8 +401,8 @@ class Imread(np.lib.mixins.NDArrayOperatorsMixin, ABC): # TODO: smarter transforms if axis is None: for idx in product(range(self.shape['c']), range(self.shape['z']), range(self.shape['t'])): - xyczt = (slice(None), slice(None)) + idx - in_idx = tuple(xyczt['xyczt'.find(i)] for i in self.axes) + yxczt = (slice(None), slice(None)) + idx + in_idx = tuple(yxczt['yxczt'.find(i)] for i in self.axes) w = where if where is None or isinstance(where, bool) else where[in_idx] initials = [fun(np.asarray(ffun(self[in_idx])), initial=initial, where=w) for fun, ffun, initial in zip(funs, ffuns, initials)] @@ -430,13 +430,13 @@ class Imread(np.lib.mixins.NDArrayOperatorsMixin, ABC): out_axes.pop(axis_idx) if out is None: out = np.zeros(out_shape, dtype) - if axis_str in 'xy': - xy = 'xy' if self.axes.find('x') < self.axes.find('y') else 'yx' - frame_ax = xy.find(axis_str) + if axis_str in 'yx': + yx = 'yx' if self.axes.find('x') > self.axes.find('y') else 'yx' + frame_ax = yx.find(axis_str) for idx in product(range(self.shape['c']), range(self.shape['z']), range(self.shape['t'])): - xyczt = (slice(None), slice(None)) + idx - out_idx = tuple(xyczt['xyczt'.find(i)] for i in out_axes) - in_idx = tuple(xyczt['xyczt'.find(i)] for i in self.axes) + yxczt = (slice(None), slice(None)) + idx + out_idx = tuple(yxczt['yxczt'.find(i)] for i in out_axes) + in_idx = tuple(yxczt['yxczt'.find(i)] for i in self.axes) w = where if where is None or isinstance(where, bool) else where[in_idx] res = cfun(*[fun(ffun(self[in_idx]), frame_ax, initial=initial, where=w) for fun, ffun, initial in zip(funs, ffuns, initials)]) @@ -444,9 +444,9 @@ class Imread(np.lib.mixins.NDArrayOperatorsMixin, ABC): else: tmps = [np.zeros(out_shape) for _ in ffuns] for idx in product(range(self.shape['c']), range(self.shape['z']), range(self.shape['t'])): - xyczt = (slice(None), slice(None)) + idx - out_idx = tuple(xyczt['xyczt'.find(i)] for i in out_axes) - in_idx = tuple(xyczt['xyczt'.find(i)] for i in self.axes) + yxczt = (slice(None), slice(None)) + idx + out_idx = tuple(yxczt['yxczt'.find(i)] for i in out_axes) + in_idx = tuple(yxczt['yxczt'.find(i)] for i in self.axes) if idx['czt'.find(axis_str)] == 0: w = where if where is None or isinstance(where, bool) else (where[in_idx],) @@ -512,7 +512,7 @@ class Imread(np.lib.mixins.NDArrayOperatorsMixin, ABC): if isinstance(value, Shape): self._shape = value else: - self._shape = Shape((value['xyczt'.find(i.lower())] for i in self.axes), self.axes) + self._shape = Shape((value['yxczt'.find(i.lower())] for i in self.axes), self.axes) @property def summary(self): @@ -730,13 +730,13 @@ class Imread(np.lib.mixins.NDArrayOperatorsMixin, ABC): new.dtype = dtype return new - def block(self, x=None, y=None, c=None, z=None, t=None): + def block(self, y=None, x=None, c=None, z=None, t=None): """ returns 5D block of frames """ - x, y, c, z, t = (np.arange(self.shape[i]) if e is None else np.array(e, ndmin=1) - for i, e in zip('xyczt', (x, y, c, z, t))) - d = np.empty((len(x), len(y), len(c), len(z), len(t)), self.dtype) + y, x, c, z, t = (np.arange(self.shape[i]) if e is None else np.array(e, ndmin=1) + for i, e in zip('yxczt', (y, x, c, z, t))) + d = np.empty((len(y), len(x), len(c), len(z), len(t)), self.dtype) for (ci, cj), (zi, zj), (ti, tj) in product(enumerate(c), enumerate(z), enumerate(t)): - d[:, :, ci, zi, ti] = self.frame(cj, zj, tj)[x][:, y] + d[:, :, ci, zi, ti] = self.frame(cj, zj, tj)[y][:, x] return d def copy(self): @@ -906,7 +906,7 @@ class Imread(np.lib.mixins.NDArrayOperatorsMixin, ABC): view.transform = Transforms.from_file(file, C=False) except Exception: # noqa view.transform = Transforms().with_drift(self) - view.transform.adapt(view.frameoffset, view.shape.xyczt, view.channel_names) + view.transform.adapt(view.frameoffset, view.shape.yxczt, view.channel_names) return view @staticmethod @@ -944,7 +944,7 @@ class AbstractReader(Imread, metaclass=ABCMeta): @abstractmethod def __frame__(self, c, z, t): # Override this, return the frame at c, z, t - return np.random.randint(0, 255, self.shape['xy']) + return np.random.randint(0, 255, self.shape['yx']) @cached_property def ome(self): @@ -989,7 +989,7 @@ class AbstractReader(Imread, metaclass=ABCMeta): instrument = self.ome.instruments[0] if self.ome.instruments else None image = self.ome.images[0] pixels = image.pixels - self.shape = pixels.size_x, pixels.size_y, pixels.size_c, pixels.size_z, pixels.size_t + self.shape = pixels.size_y, pixels.size_x, pixels.size_c, pixels.size_z, pixels.size_t self.dtype = pixels.type.value if dtype is None else dtype self.pxsize = pixels.physical_size_x_quantity try: @@ -1053,12 +1053,12 @@ class AbstractReader(Imread, metaclass=ABCMeta): self.exposuretime_s = [None if i is None else i.to(self.ureg.s).m for i in self.exposuretime] if axes is None: - self.axes = ''.join(i for i in 'cztxy' if self.shape[i] > 1) + self.axes = ''.join(i for i in 'cztyx' if self.shape[i] > 1) elif axes.lower() == 'full': - self.axes = 'cztxy' + self.axes = 'cztyx' else: self.axes = axes - self.slice = [np.arange(s, dtype=int) for s in self.shape.xyczt] + self.slice = [np.arange(s, dtype=int) for s in self.shape.yxczt] m = self.extrametadata if m is not None: diff --git a/ndbioimage/readers/cziread.py b/ndbioimage/readers/cziread.py index 2e5ad22..fe22fce 100644 --- a/ndbioimage/readers/cziread.py +++ b/ndbioimage/readers/cziread.py @@ -570,7 +570,7 @@ class Reader(AbstractReader, ABC): return ome def __frame__(self, c=0, z=0, t=0): - f = np.zeros(self.base.shape['xy'], self.dtype) + f = np.zeros(self.base.shape['yx'], self.dtype) if (c, z, t) in self.filedict: directory_entries = self.filedict[c, z, t] x_min = min([f.start[f.axes.index('X')] for f in directory_entries]) @@ -582,7 +582,7 @@ class Reader(AbstractReader, ABC): axes_min = [xy_min.get(ax, 0) for ax in directory_entry.axes] index = [slice(i - j - m, i - j + k) for i, j, k, m in zip(directory_entry.start, self.reader.start, tile.shape, axes_min)] - index = tuple(index[self.reader.axes.index(i)] for i in 'XY') + index = tuple(index[self.reader.axes.index(i)] for i in 'YX') f[index] = tile.squeeze() return f diff --git a/ndbioimage/readers/ndread.py b/ndbioimage/readers/ndread.py index 717f9bc..c671fad 100644 --- a/ndbioimage/readers/ndread.py +++ b/ndbioimage/readers/ndread.py @@ -52,7 +52,7 @@ class Reader(AbstractReader, ABC): # in_idx = tuple(xyczt['xyczt'.find(i)] for i in self.axes) # print(f'{in_idx = }') frame = self.array[:, :, c, z, t] - if self.axes.find('y') < self.axes.find('x'): + if self.axes.find('y') > self.axes.find('x'): return frame.T else: return frame diff --git a/ndbioimage/readers/tifread.py b/ndbioimage/readers/tifread.py index fa6c68b..a1b581d 100644 --- a/ndbioimage/readers/tifread.py +++ b/ndbioimage/readers/tifread.py @@ -30,8 +30,8 @@ class Reader(AbstractReader, ABC): page = self.reader.pages[0] self.p_ndim = page.ndim # noqa - size_x = page.imagelength - size_y = page.imagewidth + size_y = page.imagelength + size_x = page.imagewidth if self.p_ndim == 3: size_c = page.samplesperpixel self.p_transpose = [i for i in [page.axes.find(j) for j in 'SYX'] if i >= 0] # noqa diff --git a/pyproject.toml b/pyproject.toml index a689a55..49b55ae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "ndbioimage" -version = "2024.3.2" +version = "2024.3.3" description = "Bio image reading, metadata and some affine registration." authors = ["W. Pomp "] license = "GPLv3"