Ptufile is a Python library to read image and metadata from PicoQuant PTU and related files: PHU, PCK, PCO, PFS, PUS, and PQRES. PTU files contain time correlated single photon counting (TCSPC) measurement data and instrumentation parameters.
Author: | Christoph Gohlke |
---|---|
License: | BSD 3-Clause |
Version: | 2024.10.10 |
DOI: | 10.5281/zenodo.10120021 |
Install the ptufile package and all dependencies from the Python Package Index:
python -m pip install -U "ptufile[all]"
See Examples for using the programming interface.
Source code and support are available on GitHub.
This revision was tested with the following requirements and dependencies (other versions may work):
- CPython 3.10.11, 3.11.9, 3.12.7, 3.13.0 64-bit
- NumPy 2.1.2
- Xarray 2024.9.0 (recommended)
- Matplotlib 3.9.2 (optional)
- Tifffile 2024.9.20 (optional)
- Numcodecs 0.13.1 (optional)
- Cython 3.0.11 (build)
2024.10.10
- Also trim leading channels without photons (breaking).
- Add property to identify channels with photons.
2024.9.14
- Improve typing.
2024.7.13
- Detect point scans in image mode.
- Deprecate Python 3.9, support Python 3.13.
2024.5.24
- Fix docstring examples not correctly rendered on GitHub.
2024.4.24
- Build wheels with NumPy 2.
2024.2.20
- Change definition of PtuFile.frequency (breaking).
- Add option to specify number of bins returned by decode_histogram.
- Add option to return histograms of one period.
2024.2.15
- Add PtuFile.scanner property.
- Add numcodecs compatible PTU codec.
2024.2.8
- Support sinusoidal scanning correction.
2024.2.2
- Change positive dtime parameter from index to size (breaking).
- Fix segfault with ImgHdr_TimePerPixel = 0.
- Rename MultiHarp to Generic conforming with changes in PicoQuant reference.
2023.11.16
- Fix empty line when first record is start marker.
2023.11.13
- Change image histogram dimension order to TYXCH (breaking).
- Change frame start to start of first line in frame (breaking).
- Improve trimming of incomplete frames (breaking).
- Remove trim_dtime option (breaking).
- Fix selection handling in PtuFile.decode_image.
- Add option to trim T, C, and H axes of image histograms.
- Add option to decode histograms to memory-mapped or user-provided arrays.
- Add
__getitem__
interface to image histogram.
2023.11.1
- Initial alpha release.
The Chan Zuckerberg Initiative financially supported the development of this library.
PicoQuant GmbH is a manufacturer of photonic components and instruments.
The PicoQuant unified file formats are documented at the PicoQuant-Time-Tagged-File-Format-Demos.
The following features are currently not implemented: PT2 and PT3 files, decoding images from T2 formats, bidirectional scanning, and deprecated image reconstruction. Line-scanning is not tested.
Other Python or C/C++ modules for reading PicoQuant files are:
- Read_PTU.py
- readPTU_FLIM
- PyPTU
- FlimReader
- tttrlib
- picoquantio
- ptuparser
- phconvert
- trattoria (wrapper of trattoria-core and tttr-toolbox)
- napari-flim-phasor-plotter
Read properties and tags from any type of PicoQuant unified tagged file:
>>> pq = PqFile('tests/Settings.pfs')
>>> pq.magic
<PqFileMagic.PFS: ...>
>>> pq.guid
UUID('86d428e2-cb0b-4964-996c-04456ba6be7b')
>>> pq.tags
{...'CreatorSW_Name': 'SymPhoTime 64', 'CreatorSW_Version': '2.1'...}
>>> pq.close()
Read metadata from a PicoQuant PTU FLIM file:
>>> ptu = PtuFile('tests/FLIM.ptu')
>>> ptu.magic
<PqFileMagic.PTU: ...>
>>> ptu.type
<PtuRecordType.PicoHarpT3: 66307>
>>> ptu.measurement_mode
<PtuMeasurementMode.T3: 3>
>>> ptu.measurement_submode
<PtuMeasurementSubMode.IMAGE: 3>
Decode TTTR records from the PTU file to numpy.recarray
:
>>> decoded = ptu.decode_records()
Get global times of frame changes from markers:
>>> decoded['time'][(decoded['marker'] & ptu.frame_change_mask) > 0]
array([1571185680], dtype=uint64)
Decode TTTR records to overall delay-time histograms per channel:
>>> ptu.decode_histogram(dtype='uint8')
array([[ 5, 7, 7, ..., 10, 9, 2]], dtype=uint8)
Get information about the FLIM image histogram in the PTU file:
>>> ptu.shape
(1, 256, 256, 2, 3126)
>>> ptu.dims
('T', 'Y', 'X', 'C', 'H')
>>> ptu.coords
{'T': ..., 'Y': ..., 'X': ..., 'H': ...}
>>> ptu.dtype
dtype('uint16')
>>> ptu.active_channels
(0, 1)
Decode parts of the image histogram to numpy.ndarray
using slice notation.
Slice step sizes define binning, -1 being used to integrate along axis:
>>> ptu[:, ..., 0, ::-1]
array([[[103, ..., 38],
...
[ 47, ..., 30]]], dtype=uint16)
Alternatively, decode the first channel and integrate all histogram bins
to a xarray.DataArray
, keeping reduced axes:
>>> ptu.decode_image(channel=0, dtime=-1, asxarray=True)
<xarray.DataArray (T: 1, Y: 256, X: 256, C: 1, H: 1)> ...
array([[[[[103]],
...
[[ 30]]]]], dtype=uint16)
Coordinates:
* T (T) float64... 0.05625
* Y (Y) float64... -0.0001304 ... 0.0001294
* X (X) float64... -0.0001304 ... 0.0001294
* C (C) uint8... 0
* H (H) float64... 0.0
Attributes...
frequency: 19999200.0
...
>>> ptu.close()
Preview the image and metadata in a PTU file from the console:
python -m ptufile tests/FLIM.ptu