- parallel bugfix

This commit is contained in:
Wim Pomp
2024-10-16 17:03:32 +02:00
parent abd94ee3be
commit eea72dfba9
3 changed files with 34 additions and 17 deletions

View File

@@ -123,6 +123,8 @@ jobs:
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
- name: Publish to PyPI - name: Publish to PyPI
uses: PyO3/maturin-action@v1 uses: PyO3/maturin-action@v1
env:
MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
with: with:
command: upload command: upload
args: --non-interactive --skip-existing wheels-*/* args: --non-interactive --skip-existing wheels-*/*

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "tiffwrite" name = "tiffwrite"
version = "2024.10.4" version = "2024.10.5"
edition = "2021" edition = "2021"
[lib] [lib]

View File

@@ -2,7 +2,7 @@ from __future__ import annotations
from itertools import product from itertools import product
from pathlib import Path from pathlib import Path
from typing import Any, Sequence from typing import Any, Callable, Sequence
from warnings import warn from warnings import warn
import colorcet import colorcet
@@ -18,7 +18,7 @@ __all__ = ['IJTiffFile', 'IJTiffParallel', 'FrameInfo', 'Tag', 'tiffwrite']
Tag = rs.Tag Tag = rs.Tag
FrameInfo = tuple[np.ndarray, int, int, int] FrameInfo = tuple[ArrayLike, int, int, int]
class Header: class Header:
@@ -88,7 +88,7 @@ class IJTiffFile(rs.IJTiffFile):
def __enter__(self) -> IJTiffFile: def __enter__(self) -> IJTiffFile:
return self return self
def __exit__(self, exc_type, exc_val, exc_tb): def __exit__(self, *args: Any, **kwargs: Any) -> None:
self.close() self.close()
def save(self, frame: ArrayLike, c: int, z: int, t: int, extratags: Sequence[Tag] = None) -> None: def save(self, frame: ArrayLike, c: int, z: int, t: int, extratags: Sequence[Tag] = None) -> None:
@@ -179,18 +179,11 @@ try:
from abc import abstractmethod, ABCMeta from abc import abstractmethod, ABCMeta
from functools import wraps from functools import wraps
class IJTiffParallel(ParPool, metaclass=ABCMeta):
""" wraps IJTiffFile.save in a parallel pool, the method 'parallel' needs to be overloaded """
@abstractmethod class Pool(ParPool):
def parallel(self, frame: Any) -> Sequence[tuple[ArrayLike, int, int, int]]: def __init__(self, ijtifffile: IJTiffFile, parallel: Callable[[Any], Sequence[FrameInfo]]):
""" does something with frame in a parallel process, self.ijtifffile = ijtifffile
and returns a sequence of frames and offsets to c, z and t to save in the tif """ super().__init__(parallel) # noqa
@wraps(IJTiffFile.__init__)
def __init__(self, *args: Any, **kwargs: Any) -> None:
self.ijtifffile = IJTiffFile(*args, **kwargs)
super().__init__(self.parallel) # noqa
def done(self, task: Task) -> None: def done(self, task: Task) -> None:
c, z, t = task.handle c, z, t = task.handle
@@ -198,19 +191,41 @@ try:
for frame, cn, zn, tn in self[c, z, t]: for frame, cn, zn, tn in self[c, z, t]:
self.ijtifffile.save(frame, c + cn, z + zn, t + tn) self.ijtifffile.save(frame, c + cn, z + zn, t + tn)
@wraps(IJTiffFile.close)
def close(self) -> None: def close(self) -> None:
while len(self.tasks): while len(self.tasks):
self.get_newest() self.get_newest()
super().close() super().close()
self.ijtifffile.close() self.ijtifffile.close()
class IJTiffParallel(metaclass=ABCMeta):
""" wraps IJTiffFile.save in a parallel pool, the method 'parallel' needs to be overloaded """
@abstractmethod
def parallel(self, frame: Any) -> Sequence[FrameInfo]:
""" does something with frame in a parallel process,
and returns a sequence of frames and offsets to c, z and t to save in the tif """
@wraps(IJTiffFile.__init__)
def __init__(self, *args: Any, **kwargs: Any) -> None:
self.ijtifffile = IJTiffFile(*args, **kwargs)
self.pool = Pool(self.ijtifffile, self.parallel)
def __enter__(self) -> IJTiffParallel:
return self
def __exit__(self, *args: Any, **kwargs: Any) -> None:
self.close()
@wraps(IJTiffFile.save) @wraps(IJTiffFile.save)
def save(self, frame: Any, c: int, z: int, t: int, extratags: Sequence[Tag] = None) -> None: def save(self, frame: Any, c: int, z: int, t: int, extratags: Sequence[Tag] = None) -> None:
self[c, z, t] = frame self.pool[c, z, t] = frame
if extratags is not None: if extratags is not None:
for extra_tag in extratags: for extra_tag in extratags:
self.ijtifffile.append_extra_tag(extra_tag, (c, z, t)) self.ijtifffile.append_extra_tag(extra_tag, (c, z, t))
def close(self) -> None:
self.pool.close()
except ImportError: except ImportError:
IJTiffPool = None IJTiffPool = None