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)
Test app for importing contact information in CSV files.

Contact Import TestApp Test app for importing contact information in CSV files. Explore the docs » · Report Bug · Request Feature Table of Contents Ab

1 Feb 06, 2022
A Python library that provides basic functions to read / write Aseprite format files

A Python library that provides basic functions to read / write Aseprite format files

Joe Trewin 1 Jan 13, 2022
Creates folders into a directory to categorize files in that directory by file extensions and move all things from sub-directories to current directory.

Categorize and Uncategorize Your Folders Table of Content TL;DR just take me to how to install. What are Extension Categorizer and Folder Dumper Insta

Furkan Baytekin 1 Oct 17, 2021
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 module to parse text files with contains secret variables.

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

0 Dec 05, 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
Nintendo Game Boy music assembly files parser into musicxml format

GBMusicParser Nintendo Game Boy music assembly files parser into musicxml format This python code will get an file.asm from the disassembly of a Game

1 Dec 11, 2021
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
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
CSV To VCF (Multiples en un archivo)

CSV To VCF Convierte archivo CSV a Tarjeta VCF (varias en una) How to use En main.py debes reemplazar CONTACTOS.csv por tu archivo csv, y debes respet

Jorge Ivaldi 2 Jan 12, 2022
Powerful Python library for atomic file writes.

Powerful Python library for atomic file writes.

Markus Unterwaditzer 313 Oct 19, 2022
OnedataFS is a PyFilesystem interface to Onedata virtual file system

OnedataFS OnedataFS is a PyFilesystem interface to Onedata virtual file system. As a PyFilesystem concrete class, OnedataFS allows you to work with On

onedata 0 Jan 10, 2022
Small-File-Explorer - I coded a small file explorer with several options

Petit explorateur de fichier / Small file explorer Pour la première option (création de répertoire) / For the first option (creation of a directory) e

Xerox 1 Jan 03, 2022
Annotate your Python requirements.txt file with summaries of each package.

Summarize Requirements 🐍 📜 Annotate your Python requirements.txt file with a short summary of each package. This tool: takes a Python requirements.t

Zeke Sikelianos 8 Apr 22, 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
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
ValveVMF - A python library to parse Valve's VMF files

ValveVMF ValveVMF is a Python library for parsing .vmf files for the Source Engi

pySourceSDK 2 Jan 02, 2022
Read and write TIFF files

Read and write TIFF files Tifffile is a Python library to store numpy arrays in TIFF (Tagged Image File Format) files, and read image and metadata fro

Christoph Gohlke 346 Dec 18, 2022
A simple bulk file renamer, written in python.

Python File Editor A simple bulk file renamer, written in python. There are two functions, the bulk rename and the bulk file extention change. Bulk Fi

Sam Bloomfield 2 Dec 22, 2021
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