- slice notation for time argument on command line
- fix seqread can_open
This commit is contained in:
@@ -978,13 +978,20 @@ class Imread(np.lib.mixins.NDArrayOperatorsMixin, ABC):
|
|||||||
|
|
||||||
def save_as_movie(self, fname: Path | str = None,
|
def save_as_movie(self, fname: Path | str = None,
|
||||||
c: int | Sequence[int] = None, z: int | Sequence[int] = None, # noqa
|
c: int | Sequence[int] = None, z: int | Sequence[int] = None, # noqa
|
||||||
t: int | Sequence[int] = None, # noqa
|
t: str | int | Sequence[int] = None, # noqa
|
||||||
colors: tuple[str] = None, brightnesses: tuple[float] = None,
|
colors: tuple[str] = None, brightnesses: tuple[float] = None,
|
||||||
scale: int = None, bar: bool = True) -> None:
|
scale: int = None, bar: bool = True) -> None:
|
||||||
""" saves the image as a mp4 or mkv file """
|
""" saves the image as a mp4 or mkv file """
|
||||||
from matplotlib.colors import to_rgb
|
from matplotlib.colors import to_rgb
|
||||||
from skvideo.io import FFmpegWriter
|
from skvideo.io import FFmpegWriter
|
||||||
|
|
||||||
|
if t is None:
|
||||||
|
t = np.arange(self.shape['t'])
|
||||||
|
elif isinstance(t, str):
|
||||||
|
t = eval(f"np.arange(self.shape['t'])[{t}]")
|
||||||
|
elif np.isscalar(t):
|
||||||
|
t = (t,)
|
||||||
|
|
||||||
def get_ab(tyx: Imread, p: tuple[float, float] = (1, 99)) -> tuple[float, float]:
|
def get_ab(tyx: Imread, p: tuple[float, float] = (1, 99)) -> tuple[float, float]:
|
||||||
s = tyx.flatten()
|
s = tyx.flatten()
|
||||||
s = s[s > 0]
|
s = s[s > 0]
|
||||||
@@ -1014,9 +1021,9 @@ class Imread(np.lib.mixins.NDArrayOperatorsMixin, ABC):
|
|||||||
'-vf': f'setpts={25 / 7}*PTS,scale={shape_x}:{shape_y}:flags=neighbor'}
|
'-vf': f'setpts={25 / 7}*PTS,scale={shape_x}:{shape_y}:flags=neighbor'}
|
||||||
) as movie:
|
) as movie:
|
||||||
im = self.transpose('tzcyx')
|
im = self.transpose('tzcyx')
|
||||||
for t in trange(self.shape['t'], desc='Saving movie', disable=not bar):
|
for ti in tqdm(t, desc='Saving movie', disable=not bar):
|
||||||
movie.writeFrame(np.max([cframe(yx, c, a, b / s, scale)
|
movie.writeFrame(np.max([cframe(yx, c, a, b / s, scale)
|
||||||
for yx, a, b, c, s in zip(im[t].max('z'), *ab, colors, brightnesses)], 0))
|
for yx, a, b, c, s in zip(im[ti].max('z'), *ab, colors, brightnesses)], 0))
|
||||||
|
|
||||||
def save_as_tiff(self, fname: Path | str = None, c: int | Sequence[int] = None, z: int | Sequence[int] = None,
|
def save_as_tiff(self, fname: Path | str = None, c: int | Sequence[int] = None, z: int | Sequence[int] = None,
|
||||||
t: int | Sequence[int] = None, split: bool = False, bar: bool = True, pixel_type: str = 'uint16',
|
t: int | Sequence[int] = None, split: bool = False, bar: bool = True, pixel_type: str = 'uint16',
|
||||||
@@ -1311,7 +1318,7 @@ def main() -> None:
|
|||||||
parser.add_argument('-r', '--register', help='register channels', action='store_true')
|
parser.add_argument('-r', '--register', help='register channels', action='store_true')
|
||||||
parser.add_argument('-c', '--channel', help='channel', type=int, default=None)
|
parser.add_argument('-c', '--channel', help='channel', type=int, default=None)
|
||||||
parser.add_argument('-z', '--zslice', help='z-slice', type=int, default=None)
|
parser.add_argument('-z', '--zslice', help='z-slice', type=int, default=None)
|
||||||
parser.add_argument('-t', '--time', help='time', type=int, default=None)
|
parser.add_argument('-t', '--time', help='time', type=str, default=None)
|
||||||
parser.add_argument('-s', '--split', help='split channels', action='store_true')
|
parser.add_argument('-s', '--split', help='split channels', action='store_true')
|
||||||
parser.add_argument('-f', '--force', help='force overwrite', action='store_true')
|
parser.add_argument('-f', '--force', help='force overwrite', action='store_true')
|
||||||
parser.add_argument('-C', '--movie-colors', help='colors for channels in movie', type=str, nargs='*')
|
parser.add_argument('-C', '--movie-colors', help='colors for channels in movie', type=str, nargs='*')
|
||||||
|
|||||||
@@ -46,11 +46,9 @@ class Reader(AbstractReader, ABC):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _can_open(path):
|
def _can_open(path):
|
||||||
if isinstance(path, Path) and path.is_dir():
|
pat = re.compile(r'(?:\d+-)?Pos.*', re.IGNORECASE)
|
||||||
files = [file for file in path.iterdir() if file.name.lower().startswith('pos')]
|
return (isinstance(path, Path) and path.is_dir() and
|
||||||
return len(files) > 0 and files[0].is_dir()
|
(pat.match(path.name) or any(file.is_dir() and pat.match(file.stem) for file in path.iterdir())))
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def get_ome(self):
|
def get_ome(self):
|
||||||
ome = model.OME()
|
ome = model.OME()
|
||||||
@@ -104,7 +102,7 @@ class Reader(AbstractReader, ABC):
|
|||||||
the_c=c, the_z=z, the_t=t, exposure_time=metadata['Info']['Exposure-ms'] / 1000))
|
the_c=c, the_z=z, the_t=t, exposure_time=metadata['Info']['Exposure-ms'] / 1000))
|
||||||
|
|
||||||
# compare channel names from metadata with filenames
|
# compare channel names from metadata with filenames
|
||||||
pattern_c = re.compile(r'img_\d{3,}_(.*)_\d{3,}$')
|
pattern_c = re.compile(r'img_\d{3,}_(.*)_\d{3,}$', re.IGNORECASE)
|
||||||
for c in range(size_c):
|
for c in range(size_c):
|
||||||
ome.images[0].pixels.channels.append(
|
ome.images[0].pixels.channels.append(
|
||||||
model.Channel(
|
model.Channel(
|
||||||
@@ -115,13 +113,13 @@ class Reader(AbstractReader, ABC):
|
|||||||
return ome
|
return ome
|
||||||
|
|
||||||
def open(self):
|
def open(self):
|
||||||
pat = re.compile(r'(?:\d+-)?Pos.*')
|
pat = re.compile(r'(?:\d+-)?Pos.*', re.IGNORECASE)
|
||||||
if pat.match(self.path.name) is None:
|
if pat.match(self.path.name) is None:
|
||||||
path = sorted(file for file in self.path.iterdir() if pat.match(file.name))[self.series]
|
path = sorted(file for file in self.path.iterdir() if pat.match(file.name))[self.series]
|
||||||
else:
|
else:
|
||||||
path = self.path
|
path = self.path
|
||||||
|
|
||||||
pat = re.compile(r'^img_\d{3,}.*\d{3,}.*\.(tif|TIF)$')
|
pat = re.compile(r'^img_\d{3,}.*\d{3,}.*\.tif$', re.IGNORECASE)
|
||||||
filelist = sorted([file for file in path.iterdir() if pat.search(file.name)])
|
filelist = sorted([file for file in path.iterdir() if pat.search(file.name)])
|
||||||
with tifffile.TiffFile(self.path / filelist[0]) as tif:
|
with tifffile.TiffFile(self.path / filelist[0]) as tif:
|
||||||
metadata = {key: yaml.safe_load(value) for key, value in tif.pages[0].tags[50839].value.items()}
|
metadata = {key: yaml.safe_load(value) for key, value in tif.pages[0].tags[50839].value.items()}
|
||||||
@@ -130,9 +128,9 @@ class Reader(AbstractReader, ABC):
|
|||||||
cnamelist = metadata['Info']['Summary']['ChNames']
|
cnamelist = metadata['Info']['Summary']['ChNames']
|
||||||
cnamelist = [c for c in cnamelist if any([c in f.name for f in filelist])]
|
cnamelist = [c for c in cnamelist if any([c in f.name for f in filelist])]
|
||||||
|
|
||||||
pattern_c = re.compile(r'img_\d{3,}_(.*)_\d{3,}$')
|
pattern_c = re.compile(r'img_\d{3,}_(.*)_\d{3,}$', re.IGNORECASE)
|
||||||
pattern_z = re.compile(r'(\d{3,})$')
|
pattern_z = re.compile(r'(\d{3,})$')
|
||||||
pattern_t = re.compile(r'img_(\d{3,})')
|
pattern_t = re.compile(r'img_(\d{3,})', re.IGNORECASE)
|
||||||
self.filedict = {(cnamelist.index(pattern_c.findall(file.stem)[0]), # noqa
|
self.filedict = {(cnamelist.index(pattern_c.findall(file.stem)[0]), # noqa
|
||||||
int(pattern_z.findall(file.stem)[0]),
|
int(pattern_z.findall(file.stem)[0]),
|
||||||
int(pattern_t.findall(file.stem)[0])): file for file in filelist}
|
int(pattern_t.findall(file.stem)[0])): file for file in filelist}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "ndbioimage"
|
name = "ndbioimage"
|
||||||
version = "2024.9.1"
|
version = "2024.9.2"
|
||||||
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"
|
||||||
@@ -22,7 +22,7 @@ pint = "*"
|
|||||||
tqdm = "*"
|
tqdm = "*"
|
||||||
lxml = "*"
|
lxml = "*"
|
||||||
pyyaml = "*"
|
pyyaml = "*"
|
||||||
parfor = ">=2024.9.1"
|
parfor = ">=2024.9.2"
|
||||||
JPype1 = "*"
|
JPype1 = "*"
|
||||||
SimpleITK-SimpleElastix = [
|
SimpleITK-SimpleElastix = [
|
||||||
{ version = "*", python = "<3.12" },
|
{ version = "*", python = "<3.12" },
|
||||||
|
|||||||
Reference in New Issue
Block a user