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)
This is a file deletion program that asks you for an extension of a file (.mp3, .pdf, .docx, etc.) to delete all of the files in a dir that have that extension.

FileBulk This is a file deletion program that asks you for an extension of a file (.mp3, .pdf, .docx, etc.) to delete all of the files in a dir that h

Enoc Mena 1 Jun 26, 2022
A simple Python code that takes input from a csv file and makes it into a vcf file.

Contacts-Maker A simple Python code that takes input from a csv file and makes it into a vcf file. Imagine a college or a large community where each y

1 Feb 13, 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
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
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
A file utility for accessing both local and remote files through a unified interface.

A file utility for accessing both local and remote files through a unified interface.

AI2 19 Nov 16, 2022
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
Instant Fuzzy File Search for Alfred

List all the files inside a folder using fd, and instantly fuzzy-search through all of them using fzf, all from inside Alfred with a single keyword: fzf.

Mr. Pennyworth 37 Nov 30, 2022
Publicly Open Amazon AWS S3 Bucket Viewer

S3Viewer Publicly open storage viewer (Amazon S3 Bucket, Azure Blob, FTP server, HTTP Index Of/) s3viewer is a free tool for security researchers that

Sharon Brizinov 377 Dec 02, 2022
Get Your TXT File Length !.

TXTLen Get Your TXT File Length !. Hi šŸ‘‹ , I'm Alireza A Python Developer Boy šŸ”­ I’m currently working on my C# projects 🌱 I’m currently Learning CSh

Alireza Hasanzadeh 1 Jan 06, 2022
File storage with API access. Used as a part of the Swipio project

API File storage File storage with API access. Used as a part of the Swipio project šŸ“ About The Project File storage allows you to upload and downloa

25 Sep 17, 2022
Quick and dirty FAT12 filesystem to ZIP file converter

Quick and Dirty FAT12 Filesystem Converter This is a really crappy Python script I wrote to convert a semi-compatible FAT12 filesystem from my HP150's

Tube Time 2 Feb 12, 2022
Python code snippets for extracting PDB codes from .fasta files

Python_snippets_for_bioinformatics Python code snippets for extracting PDB codes from .fasta files If you have a single .fasta file for all protein se

Sofi-Mukhtar 3 Feb 09, 2022
🧹 Create symlinks for .m2ts files and classify them into directories in yyyy-mm format.

🧹 Create symlinks for .m2ts files and classify them into directories in yyyy-mm format.

Nep 2 Feb 07, 2022
BREP : Binary Search in plaintext and gzip files

BREP : Binary Search in plaintext and gzip files Search large files in O(log n) time using binary search. We support plaintext and Gzipped files. Benc

Arnaud de Saint Meloir 5 Dec 24, 2021
Find potentially sensitive files

find_files Find potentially sensitive files This script searchs for potentially sensitive files based off of file name or string contained in the file

4 Aug 20, 2022
Python library for reading and writing tabular data via streams.

tabulator-py A library for reading and writing tabular data (csv/xls/json/etc). [Important Notice] We have released Frictionless Framework. This frame

Frictionless Data 231 Dec 09, 2022
Add Ranges and page numbers to IIIF Manifest from a CSV.

Add Ranges and page numbers to IIIF Manifest from CSV specific to a workflow of the Bibliotheca Hertziana.

Raffaele Viglianti 3 Apr 28, 2022
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
This is a junk file creator tool which creates junk files in Internal Storage

This is a junk file creator tool which creates junk files in Internal Storage

KiLL3R_xRO 3 Jun 20, 2021