Rewrite: IJTiffWriter is replaced by IJTiffFile which includes preliminary support for reading.
- Support colormaps per channels via the colors argument. - No writer process anymore, the pool writes to the file by using a filehandle with a lock. - Can save extra tiff tags in every frame and/or per frame individually. - Header and IFD classes with support for reading files. - Multiplexing is now done automatically when multiple IJTiffFiles are initialized: the process pool is shared by all IJTiffFiles.
This commit is contained in:
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/build/
|
||||
/dist/
|
||||
*.egg_info
|
||||
/.idea/
|
||||
58
README.md
58
README.md
@@ -1,14 +1,15 @@
|
||||
# Tiffwrite
|
||||
Exploiting [tifffile](https://pypi.org/project/tifffile/) in parallel to write ImageJ compatible tiffs with good
|
||||
compression.
|
||||
Exploiting [tifffile](https://pypi.org/project/tifffile/) in parallel to write BioFormats/ImageJ compatible tiffs with
|
||||
good compression.
|
||||
|
||||
## Features
|
||||
- Writes bigtiff file that opens in ImageJ as hyperstack with correct dimensions.
|
||||
- Writes bigtiff files that open in ImageJ as hyperstack with correct dimensions.
|
||||
- Parallel compression.
|
||||
- Write individual frames in random order.
|
||||
- Compresses even more by referencing tag or image data which otherwise would have been save several times.
|
||||
- Compresses even more by referencing tag or image data which otherwise would have been saved several times.
|
||||
For example empty frames, or a long string tag on every frame.
|
||||
- Enables memory efficient scripts by saving frames whenever they're ready to be saved, not waiting for the whole stack.
|
||||
- Colormaps, extra tags globally or frame dependent.
|
||||
|
||||
## Installation
|
||||
pip install tiffwrite
|
||||
@@ -18,31 +19,37 @@ or
|
||||
|
||||
# Usage
|
||||
## Write an image stack
|
||||
tiffwrite(file, data, axes='TZCXY', bar=False, colormap=None, pxsize=None)
|
||||
tiffwrite(file, data, axes='TZCXY', dtype=None, bar=False, *args, **kwargs)
|
||||
|
||||
- file: string; filename of the new tiff file.
|
||||
- data: 2 to 5D numpy array in one of these datatypes: (u)int8, (u)int16, float32.
|
||||
- axes: string; order of dimensions in data, default: TZCXY for 5D, ZCXY for 4D, CXY for 3D, XY for 2D data.
|
||||
- dtype: string; cast data to dtype before saving, only (u)int8, (u)int16 and float32 are supported.
|
||||
- bar: bool; whether or not to show a progress bar.
|
||||
- colormap: string; choose any colormap from the colorcet module.
|
||||
- pxsize: float; set tiff tag so ImageJ can read the pixel size (in um).
|
||||
- args, kwargs: arguments to be passed to IJTiffFile, see below.
|
||||
|
||||
|
||||
## Write one frame at a time
|
||||
with IJTiffWriter(file, shape, dtype='uint16', colormap=None, nP=None, extratags=None, pxsize=None) as tif:
|
||||
with IJTiffFile(file, shape, dtype='uint16', colors=None, colormap=None, pxsize=None, deltaz=None,
|
||||
timeinterval=None, **extratags) as tif:
|
||||
some loop:
|
||||
tif.save(frame, c, z, t)
|
||||
|
||||
- file: string; filename of the new tiff file, or list of filenames.
|
||||
- file: string; filename of the new tiff file.
|
||||
- shape: iterable; shape (C, Z, T) of data to be written in file.
|
||||
- dtype: string; cast data to dtype before saving, only (u)int8, (u)int16 and float32 are supported.
|
||||
- colormap: string; choose any colormap from the colorcet module.
|
||||
- nP: int; number of compressor workers to use
|
||||
- extratags: dict {int tagnr: (int type, data)}, extra tags to save on every frame, will cause a crash if not used
|
||||
correctly!
|
||||
- pxsize: float; set tiff tag so ImageJ can read the pixel size (in um).
|
||||
- colors: iterable of strings; one color per channel, valid colors (also html) are defined in matplotlib.colors.
|
||||
Without colormap BioFormats will set the colors in this order: rgbwcmy.
|
||||
Note that the color green is dark, the usual green is named 'lime' here.
|
||||
- colormap: string; choose any colormap from the colorcet module. Colors and colormap cannot be used simultaneously.
|
||||
- pxsize: float; pixel size im um.
|
||||
- deltaz: float; z slice interval in um.
|
||||
- timeinterval: float; time between frames in seconds.
|
||||
- extratags: other tags to be saved, example: Artist='John Doe', Tag4567=[400, 500] or
|
||||
Copyright=Tag('ascii', 'Made by me'). See tiff_tag_registry.items().
|
||||
|
||||
- frame: 2D numpy array with data
|
||||
- c, z, t: int; channel, z, time coordinates of the frame
|
||||
- frame: 2D numpy array with data.
|
||||
- c, z, t: int; channel, z, time coordinates of the frame.
|
||||
|
||||
|
||||
# Examples
|
||||
@@ -55,11 +62,11 @@ correctly!
|
||||
|
||||
## Write one frame at a time
|
||||
from itertools import product
|
||||
from tiffwrite import IJTiffWriter
|
||||
from tiffwrite import IJTiffFile
|
||||
import numpy as np
|
||||
|
||||
shape = (3, 5, 10) # channels, z, time
|
||||
with IJTiffWriter('file.tif', shape, pxsize=0.09707) as tif:
|
||||
with IJTiffFile('file.tif', shape, pxsize=0.09707) as tif:
|
||||
for c in range(shape[0]):
|
||||
for z in range(shape[1]):
|
||||
for t in range(shape[2]):
|
||||
@@ -67,21 +74,22 @@ correctly!
|
||||
|
||||
## Saving multiple tiffs simultaneously
|
||||
from itertools import product
|
||||
from tiffwrite import IJTiffWriter
|
||||
from tiffwrite import IJTiffFile
|
||||
import numpy as np
|
||||
|
||||
shape = (3, 5, 10) # channels, z, time
|
||||
with IJTiffWriter(('fileA.tif', 'fileB.tif'), shape) as tif:
|
||||
with IJTiffFile('fileA.tif', shape) as tif_a, IJTiffFile('fileB.tif', shape) as tif_b:
|
||||
for c in range(shape[0]):
|
||||
for z in range(shape[1]):
|
||||
for t in range(shape[2]):
|
||||
tif.save('fileA.tif', np.random.randint(0, 10, (32, 32)), c, z, t)
|
||||
tif.save('fileB.tif', np.random.randint(0, 10, (32, 32)), c, z, t)
|
||||
tif_a.save(np.random.randint(0, 10, (32, 32)), c, z, t)
|
||||
tif_b.save(np.random.randint(0, 10, (32, 32)), c, z, t)
|
||||
|
||||
## Tricks & tips
|
||||
- ImageJ colors channels in the order rgbwcym, and IJTiffwriter automatically and efficiently writes 0's when a frame is
|
||||
skipped. You can use this when specific colors are important, for example: you want to use only red and blue.
|
||||
- The order of feeding frames to IJTiffWriter is unimportant, IJTiffWriter will order de ifd's such that the file will
|
||||
- The order of feeding frames to IJTiffFile is unimportant, IJTiffFile will order de ifd's such that the file will
|
||||
be opened as a correctly ordered hyperstack.
|
||||
- Using the colormap parameter you can make ImageJ open the file and apply the colormap. colormap='glasbey' is very
|
||||
useful.
|
||||
- IJTiffFile does not allow more than one pool of parallel processes to be open at a time. Therefore, when writing
|
||||
multiple tiff's simultaneously you have to open all before you start saving any frame, in this way all files share the
|
||||
same pool.
|
||||
|
||||
6
setup.py
6
setup.py
@@ -5,7 +5,7 @@ with open('README.md', 'r') as fh:
|
||||
|
||||
setuptools.setup(
|
||||
name='tiffwrite',
|
||||
version='2021.12.0',
|
||||
version='2022.5.0',
|
||||
author='Wim Pomp @ Lenstra lab NKI',
|
||||
author_email='w.pomp@nki.nl',
|
||||
description='Parallel tiff writer compatible with ImageJ.',
|
||||
@@ -18,6 +18,6 @@ setuptools.setup(
|
||||
'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
|
||||
'Operating System :: OS Independent',
|
||||
],
|
||||
python_requires='>=3.5',
|
||||
install_requires=['tifffile', 'numpy', 'tqdm', 'colorcet', 'multipledispatch'],
|
||||
python_requires='>=3.7',
|
||||
install_requires=['tifffile', 'numpy', 'tqdm', 'colorcet', 'matplotlib'],
|
||||
)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user