- main_channel and default_transform arguments for Imread.with_transform

This commit is contained in:
w.pomp
2026-01-26 17:03:27 +01:00
parent 066a39719a
commit 8ff52f5af5
3 changed files with 28 additions and 14 deletions

View File

@@ -1253,6 +1253,8 @@ class Imread(np.lib.mixins.NDArrayOperatorsMixin, ABC):
drift: bool = False,
file: Path | str = None,
bead_files: Sequence[Path | str] = (),
main_channel: int = None,
default_transform: Sequence[float] = None,
) -> View:
"""returns a view where channels and/or frames are registered with an affine transformation
channels: True/False register channels using bead_files
@@ -1260,6 +1262,11 @@ class Imread(np.lib.mixins.NDArrayOperatorsMixin, ABC):
file: load registration from file with name file, default: transform.yml in self.path.parent
bead_files: files used to register channels, default: files in self.path.parent,
with names starting with 'beads'
main channel: which channel to transform with default_transform
default_transform: parameters of the default transform: [a, b, c, d, e, f] where the affine transform matrix is
| a b e |
| c d f |
| 0 0 1 |
"""
view = self.view()
if file is None:
@@ -1278,7 +1285,7 @@ class Imread(np.lib.mixins.NDArrayOperatorsMixin, ABC):
try:
view.transform = Transforms.from_file(file, T=drift)
except Exception: # noqa
view.transform = Transforms().with_beads(view.cyllens, bead_files)
view.transform = Transforms().with_beads(view.cyllens, bead_files, main_channel, default_transform)
if drift:
view.transform = view.transform.with_drift(view)
view.transform.save(file.with_suffix(".yml"))

View File

@@ -147,9 +147,11 @@ class Transforms(dict):
else:
raise TypeError("Not a pandas DataFrame or Series.")
def with_beads(self, cyllens, bead_files):
def with_beads(self, cyllens, bead_files, main_channel=None, default_transform=None):
assert len(bead_files) > 0, "At least one file is needed to calculate the registration."
transforms = [self.calculate_channel_transforms(file, cyllens) for file in bead_files]
transforms = [
self.calculate_channel_transforms(file, cyllens, main_channel, default_transform) for file in bead_files
]
for key in {key for transform in transforms for key in transform.keys()}:
new_transforms = [transform[key] for transform in transforms if key in transform]
if len(new_transforms) == 1:
@@ -191,7 +193,7 @@ class Transforms(dict):
return checked_files
@staticmethod
def calculate_channel_transforms(bead_file, cyllens):
def calculate_channel_transforms(bead_file, cyllens, main_channel=None, default_transform=None):
"""When no channel is not transformed by a cylindrical lens, assume that the image is scaled by a factor 1.162
in the horizontal direction"""
from . import Imread
@@ -204,25 +206,30 @@ class Transforms(dict):
untransformed = [c for c in range(im.shape["c"]) if cyllens[im.detector[c]].lower() == "none"]
good_and_untrans = sorted(set(goodch) & set(untransformed))
if main_channel is None:
if good_and_untrans:
masterch = good_and_untrans[0]
main_channel = good_and_untrans[0]
else:
masterch = goodch[0]
main_channel = goodch[0]
transform = Transform()
if not good_and_untrans:
matrix = transform.matrix
if default_transform is None:
matrix[0, 0] = 0.86
else:
for i, t in zip(([0, 0], [0, 1], [1, 0], [1, 1], [0, 2], [1, 2]), default_transform):
matrix[i] = t
transform.matrix = matrix
transforms = Transforms()
for c in tqdm(goodch, desc="Calculating channel transforms"): # noqa
if c == masterch:
if c == main_channel:
transforms[im.channel_names[c]] = transform
else:
transforms[im.channel_names[c]] = Transform.register(max_ims[masterch], max_ims[c]) * transform
transforms[im.channel_names[c]] = Transform.register(max_ims[main_channel], max_ims[c]) * transform
return transforms
@staticmethod
def save_channel_transform_tiff(bead_files, tiffile):
def save_channel_transform_tiff(bead_files, tiffile, default_transform=None):
from . import Imread
n_channels = 0
@@ -232,7 +239,7 @@ class Transforms(dict):
with IJTiffFile(tiffile) as tif:
for t, file in enumerate(bead_files):
with Imread(file) as im:
with Imread(file).with_transform() as jm:
with Imread(file).with_transform(default_transform=default_transform) as jm:
for c in range(im.shape["c"]):
tif.save(np.hstack((im(c=c, t=0).max("z"), jm(c=c, t=0).max("z"))), c, 0, t)

View File

@@ -1,6 +1,6 @@
[project]
name = "ndbioimage"
version = "2026.1.0"
version = "2026.1.1"
description = "Bio image reading, metadata and some affine registration."
authors = [
{ name = "W. Pomp", email = "w.pomp@nki.nl" }