A Python package for working with .qptiff files which are used in multiplexed fluorescence imaging.
QPTiffFile provides tools for reading, processing, and analyzing QPTIFF image files. The package offers:
- Automatic extraction of biomarker/fluorophore information
- Memory-efficient tools for extracting regions of interest from large images
- Support for multi-channel and multi-resolution imagery
from qptifffile import QPTiffFile
# Open a QPTIFF file
qptiff = QPTiffFile('example_image.qptiff')
# Display available biomarkers
print(qptiff.get_biomarkers())
# Print summary of all channels
qptiff.print_channel_summary()
# Read specific biomarker channels
dapi_image = qptiff.read_region('DAPI')
cd8_image = qptiff.read_region('CD8')
# Read multiple biomarkers
markers = qptiff.read_region(['DAPI', 'CD8', 'PD-L1'])pip install qptifffilegit clone https://github.com/grenkoca/qptifffile.git
cd qptifffile
pip install -e .For full functionality including compressed TIFF support, you'll need:
# For Apple Silicon
brew install libaec
# For Intel Macs
brew install libaecnote: on Apple Silicon chips, you may need to install libaec via conda: https://anaconda.org/conda-forge/libaec/
# Ubuntu/Debian
sudo apt-get install libaec-dev
# CentOS/RHEL
sudo yum install libaec-develCore dependencies:
- tifffile
- numpy
Optional dependencies:
- imagecodecs (recommended for compressed TIFF support)
See this link for publicly available PhenoCycler data:
# Or, pull an image directly:
wget https://downloads.openmicroscopy.org/images/Vectra-QPTIFF/perkinelmer/PKI_scans/LuCa-7color_Scan1.qptiff
In [1]: from qptifffile import QPTiffFile
In [2]: f = QPTiffFile('../Phenocycler/Data/slides/Scan1.qptiff')
In [3]: f.read_region('DAPI')
Out[3]:
memmap([[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]], dtype=uint8)
You can also do more complex calls by specifying:
a set of multiple channels by name (layers)
various x/y locations (pos) or subregions (shape)
different downsampled levels in the image pyramid (level)
# Note, if your stains are named, you can refer to tehm as
In [4]: f.read_region(
...: layers=['DAPI', 'FITC', 'Texas Red'],
...: pos=(500, 1000),
...: shape=(500, 500),
...: level=2
...: )
# Will be a (x, y, # stains) array
Out[4]:
array([[[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
...,
[5, 0, 0],
[2, 0, 0],
[1, 0, 0]],
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
...,
[1, 0, 0],
[1, 0, 0],
[1, 0, 0]]], dtype=uint8)
[output truncated by user]
and the memmap objects can be easily plugged into other methods that accept array-like objects, such as displaying in matplotlib:
In [5]: import matplotlib.pyplot as plt
In [5]: img = f.read_region(
...: layers=['DAPI'],
...: shape=(500, 500),
...: level=4)
In [6]: plt.imshow(img, cmap='gray')
Out[6]: <matplotlib.image.AxesImage at 0x12bcc8cb0>
In [7]: plt.show()
If you use this software in your research, please cite:
@software{qptifffile,
author = {Grenko, Caleb},
title = {QPTiffFile: A Python package for working with Vectra/Akoya QPTIFF files},
url = {https://github.com/grenkoca/qptifffile},
year = {2025},
}
The best way to get in touch is via email: grenko.caleb (at) mayo.edu
- Based on the excellent tifffile library by Christoph Gohlke
