diff --git a/extensions/chaeo/accessors.py b/extensions/chaeo/accessors.py index 2b23318beda15924ee613a23f74d03a6a0f0c806..c62a7ff5266219f4f5ae58f4ff1e85bbdbe4b794 100644 --- a/extensions/chaeo/accessors.py +++ b/extensions/chaeo/accessors.py @@ -63,6 +63,39 @@ class MonoPatchStackFromFile(MonoPatchStack): def fpath(self): return self.file_acc.fpath +class PatchStack3D(InMemoryDataAccessor): + + def __init__(self, data): + """ + A sequence of n monochrome 3D images of the same size + :param data: a list of np.ndarrays of size YXZ + """ + + if isinstance(data, list): # list of YXZ patches + nda = np.array(data).squeeze() + assert nda.ndim == 4 + self._data = np.moveaxis( + nda, + [1, 2, 0, 3], + [0, 1, 2, 3] + ) + else: + raise InvalidDataForPatchStackError(f'Cannot create accessor from {type(data)}') + + def iat(self, i): + return self.data[:, :, i, :] + + def iat_yxcz(self, i): + return np.expand_dims(self.iat(i), 2) + + @property + def chroma(self): + return 1 + + @property + def count(self): + return self.shape[2] + class Error(Exception): pass diff --git a/extensions/chaeo/tests/test_accessors.py b/extensions/chaeo/tests/test_accessors.py index c74fdd86ca19c90ab7ed5fb602fa50220eac314f..461c34d718cdc88170723c79841604ae81990c00 100644 --- a/extensions/chaeo/tests/test_accessors.py +++ b/extensions/chaeo/tests/test_accessors.py @@ -3,7 +3,7 @@ import unittest import numpy as np from conf.testing import monozstackmask -from extensions.chaeo.accessors import MonoPatchStack, MonoPatchStackFromFile +from extensions.chaeo.accessors import MonoPatchStack, MonoPatchStackFromFile, PatchStack3D @@ -11,7 +11,7 @@ class TestCziImageFileAccess(unittest.TestCase): def setUp(self) -> None: pass - def test_make_patch_stack_from_list(self): + def test_make_patch_stack_from_3d_array(self): w = 256 h = 512 n = 4 @@ -20,11 +20,11 @@ class TestCziImageFileAccess(unittest.TestCase): self.assertEqual(acc.hw, (h, w)) self.assertEqual(acc.make_tczyx().shape, (n, 1, 1, h, w)) - def test_make_patch_stack_from_3d_array(self): + def test_make_patch_stack_from_list(self): w = 256 h = 512 n = 4 - acc = MonoPatchStack([np.random.rand(h, w) for _ in range(0, 4)]) + acc = MonoPatchStack([np.random.rand(h, w) for _ in range(0, n)]) self.assertEqual(acc.count, n) self.assertEqual(acc.hw, (h, w)) self.assertEqual(acc.make_tczyx().shape, (n, 1, 1, h, w)) @@ -50,4 +50,23 @@ class TestCziImageFileAccess(unittest.TestCase): h = 512 n = 4 acc = MonoPatchStack([np.random.rand(h, w) for _ in range(0, 4)]) - self.assertEqual(acc.iat_yxcz(0).shape, (h, w, 1, 1)) \ No newline at end of file + self.assertEqual(acc.iat_yxcz(0).shape, (h, w, 1, 1)) + + def test_make_3d_patch_stack_from_list(self): + w = 256 + h = 512 + nz = 5 + n = 4 + acc = PatchStack3D([np.random.rand(h, w, nz) for _ in range(0, n)]) + self.assertEqual(acc.count, n) + self.assertEqual(acc.hw, (h, w)) + self.assertEqual(acc.chroma, 1) + self.assertEqual(acc.iat(0).shape, (h, w, nz)) + + def test_3d_patch_as_yxcz_array(self): + w = 256 + h = 512 + nz = 5 + n = 4 + acc = PatchStack3D([np.random.rand(h, w, nz) for _ in range(0, n)]) + self.assertEqual(acc.iat_yxcz(0).shape, (h, w, 1, nz)) \ No newline at end of file