Skip to content
Snippets Groups Projects
Commit c58ab904 authored by Christopher Randolph Rhodes's avatar Christopher Randolph Rhodes
Browse files

base.accessors method to make patch mask from file

parent 87b32bfe
No related branches found
No related tags found
No related merge requests found
......@@ -185,6 +185,14 @@ class CziImageFileAccessor(GenericImageFileAccessor):
def write_accessor_data_to_file(fpath: Path, accessor: GenericImageDataAccessor, mkdir=True) -> bool:
"""
Export an image accessor to file.
:param fpath: complete path including filename and extension
:param accessor: image accessor to be written
:param mkdir: create any needed subdirectories in fpath if True
:return: True
"""
if mkdir:
fpath.parent.mkdir(parents=True, exist_ok=True)
try:
......@@ -207,6 +215,10 @@ def write_accessor_data_to_file(fpath: Path, accessor: GenericImageDataAccessor,
def generate_file_accessor(fpath):
"""
Given an image file path, return an image accessor, assuming the file is a supported format and represents
a single position array, which may be single or multi-channel, single plane or z-stack.
"""
if str(fpath).upper().endswith('.TIF') or str(fpath).upper().endswith('.TIFF'):
return TifSingleSeriesFileAccessor(fpath)
elif str(fpath).upper().endswith('.CZI'):
......@@ -216,27 +228,6 @@ def generate_file_accessor(fpath):
else:
raise FileAccessorError(f'Could not match a file accessor with {fpath}')
class Error(Exception):
pass
class FileAccessorError(Error):
pass
class FileNotFoundError(Error):
pass
class DataShapeError(Error):
pass
class FileWriteError(Error):
pass
class InvalidAxisKey(Error):
pass
class InvalidDataShape(Error):
pass
class PatchStack(InMemoryDataAccessor):
......@@ -293,6 +284,7 @@ class PatchStack(InMemoryDataAccessor):
[0, 3, 4, 1, 2],
[0, 1, 2, 3, 4]
)
@property
def shape(self):
return self.data.shape
......@@ -300,3 +292,41 @@ class PatchStack(InMemoryDataAccessor):
@property
def shape_dict(self):
return dict(zip(('P', 'Y', 'X', 'C', 'Z'), self.data.shape))
def make_patch_stack_from_file(fpath): # interpret z-dimension as patch position
if not Path(fpath).exists():
raise FileNotFoundError(f'Could not find {fpath}')
pyxc = np.moveaxis(
generate_file_accessor(fpath).data, # yxcz
[0, 1, 2, 3],
[1, 2, 3, 0]
)
pyxcz = np.expand_dims(pyxc, axis=3)
return PatchStack(pyxcz)
class Error(Exception):
pass
class FileAccessorError(Error):
pass
class FileNotFoundError(Error):
pass
class DataShapeError(Error):
pass
class FileWriteError(Error):
pass
class InvalidAxisKey(Error):
pass
class InvalidDataShape(Error):
pass
from pathlib import Path
import numpy as np
from skimage.io import imsave
from tifffile import imwrite
from base.process import make_rgb
from model_server.base.accessors import generate_file_accessor, InMemoryDataAccessor
class MonoPatchStackFromFile(MonoPatchStack):
def __init__(self, fpath):
if not Path(fpath).exists():
raise FileNotFoundError(f'Could not find {fpath}')
self.file_acc = generate_file_accessor(fpath)
super().__init__(self.file_acc.data[:, :, 0, :])
@property
def fpath(self):
return self.file_acc.fpath
# TODO: move this as method in base.accessors
def write_patch_to_file(where, fname, yxcz):
ext = fname.split('.')[-1].upper()
where.mkdir(parents=True, exist_ok=True)
......@@ -52,7 +38,4 @@ class Error(Exception):
class InvalidDataForPatchStackError(Error):
pass
class FileNotFoundError(Error):
pass
......@@ -5,16 +5,15 @@ import h5py
import numpy as np
import skimage
from model_server.extensions.chaeo.accessors import MonoPatchStackFromFile
from model_server.extensions.chaeo.accessors import PatchStack
def generate_ilastik_object_classifier(
template_ilp: Path,
target_ilp: Path,
raw_stack: MonoPatchStackFromFile,
mask_stack: MonoPatchStackFromFile,
label_stack: MonoPatchStackFromFile,
raw_stack: PatchStack,
mask_stack: PatchStack,
label_stack: PatchStack,
label_names: list,
lane: int = 0,
allow_multiple_objects=True,
......
......@@ -3,8 +3,7 @@ import unittest
import numpy as np
from model_server.conf.testing import monozstackmask
from model_server.extensions.chaeo.accessors import MonoPatchStackFromFile
from base.accessors import PatchStack
from base.accessors import PatchStack, make_patch_stack_from_file, FileNotFoundError
class TestMultipositionCziImageFileAccess(unittest.TestCase):
......@@ -36,16 +35,15 @@ class TestMultipositionCziImageFileAccess(unittest.TestCase):
w = monozstackmask['w']
c = monozstackmask['c']
n = monozstackmask['z']
acc = MonoPatchStackFromFile(monozstackmask['path'])
acc = make_patch_stack_from_file(monozstackmask['path'])
self.assertEqual(acc.hw, (h, w))
self.assertEqual(acc.count, n)
self.assertEqual(acc.make_tczyx().shape, (n, c, 1, h, w))
self.assertEqual(acc.fpath, monozstackmask['path'])
self.assertEqual(acc.pyxcz.shape, (n, h, w, c, 1))
def test_raises_filenotfound(self):
from model_server.extensions.chaeo.accessors import FileNotFoundError
with self.assertRaises(FileNotFoundError):
acc = MonoPatchStackFromFile('c:/fake/file/name.tif')
acc = make_patch_stack_from_file('c:/fake/file/name.tif')
def test_make_3d_patch_stack_from_nonuniform_list(self):
w = 256
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment