81 lines
2.7 KiB
Python
81 lines
2.7 KiB
Python
import re
|
|
from abc import ABC
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
|
|
import tifffile
|
|
from ome_types import model
|
|
from ome_types.units import _quantity_property # noqa
|
|
|
|
from .. import AbstractReader
|
|
|
|
|
|
class Reader(AbstractReader, ABC):
|
|
priority = 20
|
|
do_not_pickle = 'last_tif'
|
|
|
|
@staticmethod
|
|
def _can_open(path):
|
|
return isinstance(path, Path) and (path.is_dir() or
|
|
(path.parent.is_dir() and path.name.lower().startswith('pos')))
|
|
|
|
@staticmethod
|
|
def get_positions(path: str | Path) -> Optional[list[int]]:
|
|
pat = re.compile(rf's(\d)_t\d+\.(tif|TIF)$')
|
|
return sorted({int(m.group(1)) for file in Path(path).iterdir() if (m := pat.search(file.name))})
|
|
|
|
def get_ome(self):
|
|
ome = model.OME()
|
|
tif = self.get_tif(0)
|
|
metadata = tif.metaseries_metadata
|
|
size_z = len(tif.pages)
|
|
page = tif.pages[0]
|
|
shape = {axis.lower(): size for axis, size in zip(page.axes, page.shape)}
|
|
size_x, size_y = shape['x'], shape['y']
|
|
|
|
ome.instruments.append(model.Instrument())
|
|
|
|
size_c = 1
|
|
size_t = max(self.filedict.keys()) + 1
|
|
pixel_type = f"uint{metadata['PlaneInfo']['bits-per-pixel']}"
|
|
ome.images.append(
|
|
model.Image(
|
|
pixels=model.Pixels(
|
|
size_c=size_c, size_z=size_z, size_t=size_t,
|
|
size_x=size_x, size_y=size_y,
|
|
dimension_order='XYCZT', type=pixel_type),
|
|
objective_settings=model.ObjectiveSettings(id='Objective:0')))
|
|
return ome
|
|
|
|
def open(self):
|
|
pat = re.compile(rf's{self.series}_t\d+\.(tif|TIF)$')
|
|
filelist = sorted([file for file in self.path.iterdir() if pat.search(file.name)])
|
|
pattern = re.compile(r't(\d+)$')
|
|
self.filedict = {int(pattern.search(file.stem).group(1)) - 1: file for file in filelist}
|
|
if len(self.filedict) == 0:
|
|
raise FileNotFoundError
|
|
self.last_tif = 0, tifffile.TiffFile(self.filedict[0])
|
|
|
|
def close(self) -> None:
|
|
self.last_tif[1].close()
|
|
|
|
def get_tif(self, t: int = None):
|
|
last_t, tif = self.last_tif
|
|
if (t is None or t == last_t) and not tif.filehandle.closed:
|
|
return tif
|
|
else:
|
|
tif.close()
|
|
tif = tifffile.TiffFile(self.filedict[t])
|
|
self.last_tif = t, tif
|
|
return tif
|
|
|
|
def __frame__(self, c=0, z=0, t=0):
|
|
tif = self.get_tif(t)
|
|
page = tif.pages[z]
|
|
if page.axes.upper() == 'YX':
|
|
return page.asarray()
|
|
elif page.axes.upper() == 'XY':
|
|
return page.asarray().T
|
|
else:
|
|
raise NotImplementedError(f'reading axes {page.axes} is not implemented')
|