- bugfix: reading wrong frame in some cases when opened with custom axes argument

- some more try except in czi metadata reading
- bugfix: Pos pattern in seqread
This commit is contained in:
Wim Pomp
2025-01-24 15:53:51 +01:00
parent 00abb8a684
commit c34b52cb55
6 changed files with 41 additions and 25 deletions

View File

@@ -1200,6 +1200,7 @@ class AbstractReader(Imread, metaclass=ABCMeta):
image = self.ome.images[self.series if len(self.ome.images) > 1 else 0] image = self.ome.images[self.series if len(self.ome.images) > 1 else 0]
pixels = image.pixels pixels = image.pixels
self.shape = pixels.size_y, pixels.size_x, 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.base_shape = Shape((pixels.size_y, pixels.size_x, pixels.size_c, pixels.size_z, pixels.size_t), 'yxczt')
self.dtype = pixels.type.value if dtype is None else dtype self.dtype = pixels.type.value if dtype is None else dtype
self.pxsize = pixels.physical_size_x_quantity self.pxsize = pixels.physical_size_x_quantity
try: try:

View File

@@ -184,7 +184,7 @@ class Reader(AbstractReader, ABC):
return OmeParse.get_ome(self.reader, self.filedict) return OmeParse.get_ome(self.reader, self.filedict)
def __frame__(self, c: int = 0, z: int = 0, t: int = 0) -> np.ndarray: def __frame__(self, c: int = 0, z: int = 0, t: int = 0) -> np.ndarray:
f = np.zeros(self.base.shape['yx'], self.dtype) f = np.zeros(self.base_shape['yx'], self.dtype)
if (c, z, t) in self.filedict: if (c, z, t) in self.filedict:
directory_entries = self.filedict[c, z, t] directory_entries = self.filedict[c, z, t]
x_min = min([f.start[f.axes.index('X')] for f in directory_entries]) x_min = min([f.start[f.axes.index('X')] for f in directory_entries])
@@ -340,11 +340,14 @@ class OmeParse:
if self.version == '1.0': if self.version == '1.0':
for idx, tube_lens in enumerate({self.text(track_setup.find('TubeLensPosition')) for idx, tube_lens in enumerate({self.text(track_setup.find('TubeLensPosition'))
for track_setup in self.multi_track_setup}): for track_setup in self.multi_track_setup}):
try:
nominal_magnification = float(re.findall(r'\d+[,.]\d*', tube_lens)[0].replace(',', '.'))
except Exception: # noqa
nominal_magnification = 1.0
self.ome.instruments[0].objectives.append( self.ome.instruments[0].objectives.append(
model.Objective(id=f'Objective:Tubelens:{idx}', model=tube_lens, model.Objective(id=f'Objective:Tubelens:{idx}', model=tube_lens,
nominal_magnification=float( nominal_magnification=nominal_magnification))
re.findall(r'\d+[,.]\d*', tube_lens)[0].replace(',', '.'))
))
elif self.version in ('1.1', '1.2'): elif self.version in ('1.1', '1.2'):
for tubelens in self.instrument.find('TubeLenses'): for tubelens in self.instrument.find('TubeLenses'):
try: try:
@@ -362,22 +365,28 @@ class OmeParse:
def get_light_sources(self) -> None: def get_light_sources(self) -> None:
if self.version == '1.0': if self.version == '1.0':
for light_source in self.def_list(self.instrument.find('LightSources')): for light_source in self.def_list(self.instrument.find('LightSources')):
if light_source.find('LightSourceType').find('Laser') is not None: try:
self.ome.instruments[0].lasers.append( if light_source.find('LightSourceType').find('Laser') is not None:
model.Laser( self.ome.instruments[0].lasers.append(
id=light_source.attrib['Id'], model.Laser(
model=self.text(light_source.find('Manufacturer').find('Model')), id=light_source.attrib['Id'],
power=float(self.text(light_source.find('Power'))), model=self.text(light_source.find('Manufacturer').find('Model')),
wavelength=float( power=float(self.text(light_source.find('Power'))),
self.text(light_source.find('LightSourceType').find('Laser').find('Wavelength'))))) wavelength=float(
self.text(light_source.find('LightSourceType').find('Laser').find('Wavelength')))))
except AttributeError:
pass
elif self.version in ('1.1', '1.2'): elif self.version in ('1.1', '1.2'):
for light_source in self.def_list(self.instrument.find('LightSources')): for light_source in self.def_list(self.instrument.find('LightSources')):
if light_source.find('LightSourceType').find('Laser') is not None: try:
self.ome.instruments[0].lasers.append( if light_source.find('LightSourceType').find('Laser') is not None:
model.Laser( self.ome.instruments[0].lasers.append(
id=f"LightSource:{light_source.attrib['Id']}", model.Laser(
power=float(self.text(light_source.find('Power'))), id=f"LightSource:{light_source.attrib['Id']}",
wavelength=float(light_source.attrib['Id'][-3:]))) power=float(self.text(light_source.find('Power'))),
wavelength=float(light_source.attrib['Id'][-3:])))
except AttributeError:
pass
def get_filters(self) -> None: def get_filters(self) -> None:
if self.version == '1.0': if self.version == '1.0':

View File

@@ -26,7 +26,7 @@ class Reader(AbstractReader, ABC):
def __frame__(self, c, z, t): # Override this, return the frame at c, z, t def __frame__(self, c, z, t): # Override this, return the frame at c, z, t
self.reader.filehandle.seek(self.offset + t * self.count) self.reader.filehandle.seek(self.offset + t * self.count)
return np.reshape(unpack(self.fmt, self.reader.filehandle.read(self.count)), self.shape['yx']) return np.reshape(unpack(self.fmt, self.reader.filehandle.read(self.count)), self.base_shape['yx'])
def open(self): def open(self):
warn(f'File {self.path.name} is probably damaged, opening with fijiread.') warn(f'File {self.path.name} is probably damaged, opening with fijiread.')

View File

@@ -114,9 +114,15 @@ class Reader(AbstractReader, ABC):
return ome return ome
def open(self): def open(self):
pat = re.compile(r'(?:\d+-)?Pos.*', re.IGNORECASE) # /some_path/Pos4: path = /some_path, series = 4
if pat.match(self.path.name) is None: # /some_path/5-Pos_001_005: path = /some_path/5-Pos_001_005, series = 0
path = sorted(file for file in self.path.iterdir() if pat.match(file.name))[self.series] if re.match(r'(?:\d+-)?Pos.*', self.path.name, re.IGNORECASE) is None:
pat = re.compile(rf'^(?:\d+-)?Pos{self.series}$', re.IGNORECASE)
files = sorted(file for file in self.path.iterdir() if pat.match(file.name))
if len(files):
path = files[0]
else:
raise FileNotFoundError(self.path / pat.pattern)
else: else:
path = self.path path = self.path

View File

@@ -80,6 +80,6 @@ class Reader(AbstractReader, ABC):
def __frame__(self, c, z, t): def __frame__(self, c, z, t):
if self.p_ndim == 3: if self.p_ndim == 3:
return np.transpose(self.reader.asarray(z + t * self.base.shape['z']), self.p_transpose)[c] return np.transpose(self.reader.asarray(z + t * self.base_shape['z']), self.p_transpose)[c]
else: else:
return self.reader.asarray(c + z * self.base.shape['c'] + t * self.base.shape['c'] * self.base.shape['z']) return self.reader.asarray(c + z * self.base_shape['c'] + t * self.base_shape['c'] * self.base_shape['z'])

View File

@@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "ndbioimage" name = "ndbioimage"
version = "2025.1.0" version = "2025.1.1"
description = "Bio image reading, metadata and some affine registration." description = "Bio image reading, metadata and some affine registration."
authors = ["W. Pomp <w.pomp@nki.nl>"] authors = ["W. Pomp <w.pomp@nki.nl>"]
license = "GPLv3" license = "GPLv3"