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)
A python wrapper for libmagic

python-magic python-magic is a Python interface to the libmagic file type identification library. libmagic identifies file types by checking their hea

Adam Hupp 2.3k Dec 29, 2022
LightCSV - This CSV reader is implemented in just pure Python.

LightCSV Simple light CSV reader This CSV reader is implemented in just pure Python. It allows to specify a separator, a quote char and column titles

Jose Rodriguez 6 Mar 05, 2022
Extract an archive file (zip file or tar file) stored on AWS S3

S3 Extract Extract an archive file (zip file or tar file) stored on AWS S3. Details Downloads archive from S3 into memory, then extract and re-upload

Evan 1 Dec 14, 2021
pydicom - Read, modify and write DICOM files with python code

pydicom is a pure Python package for working with DICOM files. It lets you read, modify and write DICOM data in an easy "pythonic" way.

DICOM in Python 1.5k Jan 04, 2023
Organizer is a python program that organizes your downloads folder

Organizer Organizer is a python program that organizes your downloads folder, it can run as a service and so will start along with the system, and the

Gustavo 2 Oct 18, 2021
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
Some-tasks - Files for some of the tasks for the group sessions

Files for some of the tasks for the group sessions Here you can find some of the

<a href=[email protected] Computer Networks"> 0 Aug 25, 2022
Uproot is a library for reading and writing ROOT files in pure Python and NumPy.

Uproot is a library for reading and writing ROOT files in pure Python and NumPy. Unlike the standard C++ ROOT implementation, Uproot is only an I/O li

Scikit-HEP Project 164 Dec 31, 2022
A python script to pull the transactions of an Algorand wallet and put them into a CSV file.

AlgoCSV A python script to pull the transactions of an Algorand wallet and put them into a CSV file. Dependancies: Requests Main features: Groups: Com

21 Jun 25, 2022
useful files for the Freenove Big Hexapod

FreenoveBigHexapod useful files for the Freenove Big Hexapod HexaDogPos is a utility for converting the Freenove xyz co-ordinate system to servo angle

Alex 2 May 28, 2022
Pti-file-format - Reverse engineering the Polyend Tracker instrument file format

pti-file-format Reverse engineering the Polyend Tracker instrument file format.

Jaap Roes 14 Dec 30, 2022
A Python script to backup your favorite Discord gifs

About the project Discord recently felt like it would be a good idea to limit the favorites to 250, which made me lose most of my gifs... Luckily for

4 Aug 03, 2022
This python project contains a class FileProcessor which allows one to grab a file and get some meta data and header information from it

This python project contains a class FileProcessor which allows one to grab a file and get some meta data and header information from it. In the current state, it outputs a PrettyTable to txt file as

Joshua Wren 1 Nov 09, 2021
An universal file format tool kit. At present will handle the ico format problem.

An universal file format tool kit. At present will handle the ico format problem.

Sadam·Sadik 1 Dec 26, 2021
Simple Python File Manager

This script lets you automatically relocate files based on their extensions. Very useful from the downloads folder !

Aimé Risson 22 Dec 27, 2022
A JupyterLab extension that allows opening files and directories with external desktop applications.

A JupyterLab extension that allows opening files and directories with external desktop applications.

martinRenou 0 Oct 14, 2021
Python codes for the server and client end that facilitates file transfers. (Using AWS EC2 instance as the server)

Server-and-Client-File-Transfer Python codes for the server and client end that facilitates file transfers. I will be using an AWS EC2 instance as the

Amal Farhad Shaji 2 Oct 13, 2021
Vericopy - This Python script provides various usage modes for secure local file copying and hashing.

Vericopy This Python script provides various usage modes for secure local file copying and hashing. Hash data is captured and logged for paths before

15 Nov 05, 2022
Various converters to convert value sets from CSV to JSON, etc.

ValueSet Converters Tools for converting value sets in different formats. Such as converting extensional value sets in CSV format to JSON format able

Health Open Terminology Ecosystem 4 Sep 08, 2022
Python virtual filesystem for SQLite to read from and write to S3

Python virtual filesystem for SQLite to read from and write to S3

Department for International Trade 70 Jan 04, 2023