A tiny Python library for writing multi-channel TIFF stacks.

Overview

xtiff

PyPI PyPI - Python Version PyPI - License Codecov GitHub Workflow Status (branch) GitHub issues GitHub pull requests

A tiny Python library for writing multi-channel TIFF stacks.

The aim of this library is to provide an easy way to write multi-channel image stacks for external visualization and analysis. It acts as an interface to the popular tifffile package and supports xarray DataArrays as well as numpy-compatible data structures.

To maximize compatibility with third-party software, the images are written in standard-compliant fashion, with minimal metadata and in TZCYX channel order. In particular, a minimal (but customizable) subset of the OME-TIFF standard is supported, enabling the naming of channels.

Requirements

This package requires Python 3.7 or later.

Python package dependencies are listed in requirements.txt.

Using virtual environments is strongly recommended.

Installation

Install xtiff and its dependencies with:

pip install xtiff

Usage

The package provides the following main function for writing TIFF files:

to_tiff(img, file, image_name=None, image_date=None, channel_names=None, description=None, 
        profile=TiffProfile.OME_TIFF, big_endian=None, big_tiff=None, big_tiff_threshold=4261412864, 
        compression_type=None, compression_level=0, pixel_size=None, pixel_depth=None, 
        interleaved=True, software='xtiff', ome_xml_fun=get_ome_xml, **ome_xml_kwargs)


img: The image to write, as xarray DataArray or numpy-compatible data structure.
    Supported shapes:
    - (y, x),
    - (c, y, x)
    - (z, c, y, x)
    - (t, z, c, y, x)
    - (t, z, c, y, x, s)
    Supported data types:
    - any numpy data type when using TiffProfile.TIFF
    - uint8, uint16, float32 when using TiffProfile.IMAGEJ (uint8 for RGB images)
    - bool, int8, int16, int32, uint8, uint16, uint32, float32, float64 when using TiffProfile.OME_TIFF

file: File target supported by tifffile TiffWriter, e.g. path to file (str, pathlib.Path) or binary stream.

image_name: Image name for OME-TIFF images. If True, the image name is determined using the DataArray name or
    the file name (in that order); if False, the image name is not set. If None, defaults to the behavior for True
    for named DataArrays and when the file path is provided, and to the behavior of False otherwise. Only relevant
    when writing OME-TIFF files, any value other than None or False will raise a warning for other TIFF profiles.

image_date: Date and time of image creation in '%Y:%m:%d %H:%M:%S' format or as datetime object. Defaults to
    the current date and time if None. Note: this does not determine the OME-XML AcquisitionDate element value.

channel_names: A list of channel names. If True, channel names are determined using the DataArray channel
    coordinate; if False, channel names are not set. If None, defaults to the behavior for True for DataArrays when
    writing multi-channel OME-TIFFs, and to the behavior for False otherwise. Only relevant when writing
    multi-channel OME-TIFF files, any value other than None or False will raise a warning for other TIFF profiles.

description: TIFF description tag. Will default to the OME-XML header when writing OME-TIFF files. Any value
    other than None will raise a warning in this case.

profile: TIFF specification of the written file.
    Supported TIFF profiles:
    - TIFF (no restrictions apply)
    - ImageJ (undocumented file format that is supported by the ImageJ software)
    - OME-TIFF (Open Microscopy Environment TIFF standard-compliant file format with minimal OME-XML header)

big_endian: If true, stores data in big endian format, otherwise uses little endian byte order. If None, the
    byte order is set to True for the ImageJ TIFF profile and defaults to the system default otherwise.

big_tiff: If True, enables support for writing files larger than 4GB. Not supported for TiffProfile.IMAGEJ.

big_tiff_threshold: Threshold for enabling BigTIFF support when big_tiff is set to None, in bytes. Defaults
    to 4GB, minus 32MB for metadata.

compression_type: Compression algorithm, see tifffile.TIFF.COMPRESSION() for available values. Compression is
    not supported for TiffProfile.IMAGEJ. Note: Compression prevents from memory-mapping images and should therefore
    be avoided when images are compressed externally, e.g. when they are stored in compressed archives.

compression_level: Compression level, between 0 and 9. Compression is not supported for TiffProfile.IMAGEJ.
    Note: Compression prevents from memory-mapping images and should therefore be avoided when images are compressed
    externally, e.g. when they are stored in compressed archives.

pixel_size: Planar (x/y) size of one pixel, in micrometer.

pixel_depth: Depth (z size) of one pixel, in micrometer. Only relevant when writing OME-TIFF files, any value
    other than None will raise a warning for other TIFF profiles.

interleaved: If True, OME-TIFF images are saved as interleaved (this only affects OME-XML metadata). Always
    True for RGB(A) images (i.e., S=3 or 4) - a warning will be raised if explicitly set to False for RGB(A) images.

software: Name of the software used to create the file. Must be 7-bit ASCII. Saved with the first page only.

ome_xml_fun: Function that will be used for generating the OME-XML header. See the default implementation for
    reference of the required signature. Only relevant when writing OME-TIFF files, ignored otherwise.

ome_xml_kwargs: Optional arguments that are passed to the ome_xml_fun function. Only relevant when writing
    OME-TIFF files, will raise a warning if provided for other TIFF profiles.

In addition, get_ome_xml() is provided as the default OME-XML-generating function.

FAQ

What metadata is included in the written images?

In general, written metadata is kept at a minimum and only information that can be inferred from the raw image data is included (image dimensions, data type, number of channels, channel names for xarrays). Additional metadata natively supported by the tifffile package can be specified using function parameters. For OME-TIFF files, the OME-XML "Description" tag contents can be further refined by specifying custom OME-XML-generating functions.

Why should I care about TIFF? I use Zarr/NetCDF/whatever.

That's good! TIFF is an old and complex file format, has many disadvantages and is impractical for storing large images. However, it also remains one of the most widely used scientific image formats and is (at least partially) supported by many popular tools, such as ImageJ. With xtiff, you can continue to store your images in your favorite file format, while having the opportunity to easily convert them to a format that can be read by (almost) any tool.

Why can't I use the tifffile package directly?

Of course you can! Christoph Gohlke's tifffile package provides a very powerful and feature-complete interface for writing TIFF files and is the backend for xtiff. Essentially, the xtiff package is just a wrapper for tifffile. While you can in principle write any image directly with tifffile, in many cases, the flexibility of the TIFF format can be daunting. The xtiff package reduces the configuration burden and metadata to an essential minimum.

Authors

Created and maintained by Jonas Windhager [email protected]

Contributing

Contributing

Changelog

Changelog

License

MIT

Comments
  • Non-Latin symbols in channel names

    Non-Latin symbols in channel names

    I don't know if it is an issue with tifffile or xtiff library, but when channel names contain non-Latin symbols then to_tiff method crashes: https://github.com/BodenmillerGroup/xtiff/blob/d0a7b5cf2626aaa8cdb3a1f6403d8edd9353c782/xtiff.py#L311

    Traceback (most recent call last):
      File "/home/anton/bblab/imctools/imctools/converters/mcdfolder2imcfolder.py", line 59, in mcdfolder_to_imcfolder
        imc_writer.write_imc_folder(create_zip=create_zip)
      File "/home/anton/bblab/imctools/imctools/io/imc/imcwriter.py", line 77, in write_imc_folder
        acquisition_data.save_ome_tiff(
      File "/home/anton/bblab/imctools/imctools/data/acquisitiondata.py", line 136, in save_ome_tiff
        to_tiff(
      File "/home/anton/bblab/imctools/venv/lib/python3.8/site-packages/xtiff.py", line 311, in to_tiff
        writer.save(data=img, photometric='MINISBLACK', compress=compression, description=description,
      File "/home/anton/bblab/imctools/venv/lib/python3.8/site-packages/tifffile/tifffile.py", line 1836, in write
        addtag(270, 's', 0, description, writeonce=True)
      File "/home/anton/bblab/imctools/venv/lib/python3.8/site-packages/tifffile/tifffile.py", line 1772, in addtag
        value = bytestr(value, 'ascii') + b'\0'
      File "/home/anton/bblab/imctools/venv/lib/python3.8/site-packages/tifffile/tifffile.py", line 15622, in bytestr
        return s.encode(encoding) if isinstance(s, str) else s
    UnicodeEncodeError: 'ascii' codec can't encode character '\u03b5' in position 1241: ordinal not in range(128)
    
    
    bug 
    opened by plankter 6
  • Fix for deprecated TiffWriter.save method.

    Fix for deprecated TiffWriter.save method.

    TiffWriter.save is deprecated - we should replace replace with TiffWriter.write. Issue: https://github.com/BodenmillerGroup/xtiff/issues/11

    I also added a separate test.yml workflow to make development easier when not intending to deploy.

    Changelog from tifffile

    2022.2.2 Fix TypeError when second ImageDescription tag contains non-ASCII (#112). Fix parsing IJMetadata with many IJMetadataByteCounts (#111). Detect MicroManager NDTiffv2 header (not tested). Remove cache from ZarrFileSequenceStore (use zarr.LRUStoreCache). Raise limit on maximum number of pages. Use J2K format when encoding JPEG2000 segments. Formally deprecate imsave and TiffWriter.save. Drop support for Python 3.7 and numpy < 1.19 (NEP29).

    opened by agvaughan 4
  • Fix Mu Character.

    Fix Mu Character.

    The mu character appeared to somewhat non-functioning previously. I'm not 100% sure what is going on here but the character now prints as μ instead of µ which seems more correct. @LauraKuett could you test this out to confirm?

    opened by ilan-gold 4
  • Memory efficient writing to TIFF and pyramidal tiffs

    Memory efficient writing to TIFF and pyramidal tiffs

    Hi!

    I wanted to discuss two (somewhat related) issues. At the moment we need to load the whole array into memory in order to save it to TIFF. I would like to have an option to write by chunks, this would be memory efficient, but slower since we cannot write in parallel to TIFF.

    Related to this, I would also like to have support for writing pyramidal tiffs, so I can use applications that support them (e.g. QuPath) to visualise really large datasets. Writing the pyramidal structure would again be memory efficient at expense of speed.

    I have code that does this, but I wonder (and hence this issue) if that is something that you want added to xtiff.

    Cheers

    enhancement 
    opened by eddienko 2
  • TiffWriter.save is deprecated - replace with tiffwriter.write

    TiffWriter.save is deprecated - replace with tiffwriter.write

    TiffWriter.save is deprecated - we should replace replace with TiffWriter.write

    Changelog from tifffile

    2022.2.2
        Fix TypeError when second ImageDescription tag contains non-ASCII (#112). Fix parsing IJMetadata with many IJMetadataByteCounts (#111). Detect MicroManager NDTiffv2 header (not tested). Remove cache from ZarrFileSequenceStore (use zarr.LRUStoreCache). Raise limit on maximum number of pages. Use J2K format when encoding JPEG2000 segments. Formally deprecate imsave and TiffWriter.save. Drop support for Python 3.7 and numpy < 1.19 (NEP29).
    

    I wrote and tested a fix in the fork here - will add a PR If that works for you!

    bug 
    opened by agvaughan 1
  • Save OME-TIFF images as interleaved=false for grayscale images

    Save OME-TIFF images as interleaved=false for grayscale images

    As reported by @LauraKuett, when saving (grayscale) TZCYX image stacks (i.e., TZCYXS with S=1, as opposed to S=3 or 4 for RGB(A) images), images can be interpreted as non-interleaved and should therefore be saved as interleaved=false in the OME-XML metadata to improve compatibility with third-party software.

    enhancement 
    opened by jwindhager 0
  • Tifffile updates

    Tifffile updates

    Restores compatibility with recent tifffile updates and adds support for tifffile's software parameter.

    Also see cgohlke/tifffile#21 - many thanks to @cgohlke for the prompt support.

    @plankter please review and approve if it works

    bug 
    opened by jwindhager 0
Releases(v0.7.0)
Listreqs is a simple requirements.txt generator. It's an alternative to pipreqs

⚡ Listreqs Listreqs is a simple requirements.txt generator. It's an alternative to pipreqs. Where in Pipreqs, it helps you to Generate requirements.tx

Soumyadip Sarkar 4 Oct 15, 2021
Simple, convenient and cross-platform file date changing library. 📝📅

Simple, convenient and cross-platform file date changing library.

kubinka0505 15 Dec 18, 2022
Extract the windows major and minor build numbers from an ISO file, and automatically sort the iso files.

WindowsBuildFromISO Extract the windows major and minor build numbers from an ISO file, and automatically sort the iso files. Features Parse multiple

Podalirius 9 Nov 09, 2022
Small Python script to generate a calendar (.ics) file from SIMASTER courses schedule.

simaster.ics Small Python script to generate a calendar (.ics) file from SIMASTER courses schedule. Usage Getting the events.json file from SIMASTER O

Faiz Jazadi 8 Nov 02, 2022
Here is some Python code that allows you to read in SVG files and approximate their paths using a Fourier series.

Here is some Python code that allows you to read in SVG files and approximate their paths using a Fourier series. The Fourier series can be animated and visualized, the function can be output as a tw

Alexander 12 Jan 01, 2023
MetaMove is written in Python3 and aims at easing batch renaming operations based on file meta data.

MetaMove MetaMove is written in Python3 and aims at easing batch renaming operations based on file meta data. MetaMove abuses eval combined with f-str

Jan Philippi 2 Dec 28, 2021
Python module that parse power builder file (PBD) and analyze code

PowerBuilder-decompile Python module that parse power builder file (PBD) and analyze code (Incomplete) this tool is composed of: pbd_dump.py pbd file

Samy Sultan 8 Dec 15, 2022
A platform independent file lock for Python

py-filelock This package contains a single module, which implements a platform independent file lock in Python, which provides a simple way of inter-p

Benedikt Schmitt 497 Jan 05, 2023
FileGenerator - File Generator for sites that accepts documents

File Generator for sites that accepts documents This code generates files as per

Shaunak 2 Mar 19, 2022
A tiny Python library for writing multi-channel TIFF stacks.

xtiff A tiny Python library for writing multi-channel TIFF stacks. The aim of this library is to provide an easy way to write multi-channel image stac

23 Dec 27, 2022
Python function to construct a ZIP archive with on the fly - without having to store the entire ZIP in memory or disk

Python function to construct a ZIP archive with on the fly - without having to store the entire ZIP in memory or disk

Department for International Trade 34 Jan 05, 2023
gitfs is a FUSE file system that fully integrates with git - Version controlled file system

gitfs is a FUSE file system that fully integrates with git. You can mount a remote repository's branch locally, and any subsequent changes made to the files will be automatically committed to the rem

Presslabs 2.3k Jan 08, 2023
A Python script to organize your files in a given directory.

File-Organizer A Python script to organize your files in a given directory. It organizes your files based on the file extension and moves them into sp

Imira Randeniya 1 Sep 11, 2022
PaddingZip - a tool that you can craft a zip file that contains the padding characters between the file content.

PaddingZip - a tool that you can craft a zip file that contains the padding characters between the file content.

phithon 53 Nov 07, 2022
The best way to convert files on your computer, be it .pdf to .png, .pdf to .docx, .png to .ico, or anything you can imagine.

The best way to convert files on your computer, be it .pdf to .png, .pdf to .docx, .png to .ico, or anything you can imagine.

JareBear 2 Nov 20, 2021
Python's Filesystem abstraction layer

PyFilesystem2 Python's Filesystem abstraction layer. Documentation Wiki API Documentation GitHub Repository Blog Introduction Think of PyFilesystem's

pyFilesystem 1.8k Jan 02, 2023
Various technical documentation, in electronically parseable format

a-pile-of-documentation Various technical documentation, in electronically parseable format. You will need Python 3 to run the scripts and programs in

Jonathan Campbell 2 Nov 20, 2022
A python module to parse text files with contains secret variables.

A python module to parse text files with contains secret variables.

0 Dec 05, 2022
Transforme rapidamente seu arquivo CSV (de qualquer tamanho) para SQL de forma rápida.

Transformador de CSV para SQL Transforme rapidamente seu arquivo CSV (de qualquer tamanho) para SQL de forma rápida, e com isso insira seus dados usan

William Rodrigues 4 Oct 17, 2022
MHS2 Save file editing tools. Transfers save files between players, switch and pc version, encrypts and decrypts.

SaveTools MHS2 Save file editing tools. Transfers save files between players, switch and pc version, encrypts and decrypts. Credits Written by Asteris

31 Nov 17, 2022