Metadata-Version: 2.4
Name: ptufile
Version: 2026.3.21
Summary: Read and write PicoQuant PTU and related files
Home-page: https://www.cgohlke.com
Author: Christoph Gohlke
Author-email: cgohlke@cgohlke.com
License: BSD-3-Clause
Project-URL: Bug Tracker, https://github.com/cgohlke/ptufile/issues
Project-URL: Source Code, https://github.com/cgohlke/ptufile
Platform: any
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Cython
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.12
Description-Content-Type: text/x-rst
License-File: LICENSE
Requires-Dist: numpy>=2.0
Provides-Extra: all
Requires-Dist: matplotlib; extra == "all"
Requires-Dist: numcodecs; extra == "all"
Requires-Dist: python-dateutil; extra == "all"
Requires-Dist: tifffile; extra == "all"
Requires-Dist: xarray; extra == "all"
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license
Dynamic: license-file
Dynamic: platform
Dynamic: project-url
Dynamic: provides-extra
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

Read and write PicoQuant PTU and related files
==============================================

Ptufile is a Python library to

1. read data and metadata from PicoQuant PTU and related files
   (PHU, PCK, PCO, PFS, PUS, PQRES, PQDAT, PQUNI, SPQR, and BIN), and
2. write TCSPC histograms to T3 image mode PTU files.

PTU files contain time correlated single photon counting (TCSPC)
measurement data and instrumentation parameters.

:Author: `Christoph Gohlke <https://www.cgohlke.com>`_
:License: BSD-3-Clause
:Version: 2026.3.21
:DOI: `10.5281/zenodo.10120021 <https://doi.org/10.5281/zenodo.10120021>`_

Quickstart
----------

Install the ptufile package and all dependencies from the
`Python Package Index <https://pypi.org/project/ptufile/>`_::

    python -m pip install -U "ptufile[all]"

See `Examples`_ for using the programming interface.

Source code and support are available on
`GitHub <https://github.com/cgohlke/ptufile>`_.

Requirements
------------

This revision was tested with the following requirements and dependencies
(other versions may work):

- `CPython <https://www.python.org>`_ 3.12.10, 3.13.12, 3.14.3 64-bit
- `NumPy <https://pypi.org/project/numpy>`_ 2.4.3
- `Xarray <https://pypi.org/project/xarray>`_ 2026.2.0 (recommended)
- `Matplotlib <https://pypi.org/project/matplotlib/>`_ 3.10.8 (optional)
- `Tifffile <https://pypi.org/project/tifffile/>`_ 2026.3.3 (optional)
- `Numcodecs <https://pypi.org/project/numcodecs/>`_ 0.16.5 (optional)
- `Python-dateutil <https://pypi.org/project/python-dateutil/>`_ 2.9.0
  (optional)
- `Cython <https://pypi.org/project/cython/>`_ 3.2.4 (build)

Revisions
---------

2026.3.21

- Add bounds checking to encode_t3_image function.
- Use format-dispatch in hot decode loops to allow compiler inlining.
- Build wheels on Windows with LLVM (30% faster decoding than MSVC).
- Drop support for Python 3.11.

2026.2.6

- Fix code review issues.

2026.1.14

- Improve code quality.

2025.12.12

- Add PQUNI file type.
- Add attrs properties and return with xarray DataSets.
- Improve code quality.

2025.11.8

- Fix reading files with negative TTResult_NumberOfRecords.
- Remove cache argument from PtuFile.read_records (breaking).
- Add cache_records property to PtuFile to control caching behavior.
- Derive PqFileError from ValueError.
- Factor out BinaryFile base class.
- Build ABI3 wheels.

2025.9.9

- Log error when decoding image with invalid line or frame masks.

2025.7.30

- Add option to specify pixel time for decoding images.
- Add functions to read and write PicoQuant BIN files.
- Drop support for Python 3.10.

2025.5.10

- Mark Cython extension free-threading compatible.
- Support Python 3.14.

2025.2.20

- …

Refer to the CHANGES file for older revisions.

Notes
-----

`PicoQuant GmbH <https://www.picoquant.com/>`_ is a manufacturer of photonic
components and instruments.

The PicoQuant unified file formats are documented at the
`PicoQuant-Time-Tagged-File-Format-Demos
<https://github.com/PicoQuant/PicoQuant-Time-Tagged-File-Format-Demos/tree/master/doc>`_.

The following features are currently not implemented due to the lack of
test files or documentation: PT2 and PT3 files, decoding images from
T2 and SPQR formats, bidirectional per frame, and deprecated image
reconstruction.

Compatibility with PTU files written by non-PicoQuant software (for example,
Leica LAS X or Abberior Imspector) is limited, as is decoding line,
bidirectional, and sinusoidal scanning.

Other modules for reading or writing PicoQuant files are
`Read_PTU.py
<https://github.com/PicoQuant/PicoQuant-Time-Tagged-File-Format-Demos/blob/master/PTU/Python/Read_PTU.py>`_,
`readPTU <https://github.com/qpl-public/readPTU>`_,
`readPTU_FLIM <https://github.com/SumeetRohilla/readPTU_FLIM>`_,
`fastFLIM <https://github.com/RobertMolenaar-UT/fastFLIM>`_,
`PyPTU <https://gitlab.inria.fr/jrye/pyptu>`_,
`PTU_Reader <https://github.com/UU-cellbiology/PTU_Reader>`_,
`PTU_Writer <https://github.com/ekatrukha/PTU_Writer>`_,
`FlimReader <https://github.com/flimfit/FlimReader>`_,
`tangy <https://github.com/Peter-Barrow/tangy>`_,
`tttrlib <https://github.com/Fluorescence-Tools/tttrlib>`_,
`picoquantio <https://github.com/tsbischof/picoquantio>`_,
`ptuparser <https://pypi.org/project/ptuparser/>`_,
`phconvert <https://github.com/Photon-HDF5/phconvert/>`_,
`trattoria <https://pypi.org/project/trattoria/>`_ (wrapper of
`trattoria-core <https://pypi.org/project/trattoria-core/>`_,
`tttr-toolbox <https://github.com/GCBallesteros/tttr-toolbox/>`_),
`PAM <https://gitlab.com/PAM-PIE/PAM/-/blob/master/functions/readin/Read_PTU.m>`_,
`FLOPA <https://github.com/IMCF-Biocev/FLOPA/tree/main/src/flopa/io/ptuio>`_,
and
`napari-flim-phasor-plotter
<https://github.com/zoccoler/napari-flim-phasor-plotter/blob/0.0.6/src/napari_flim_phasor_plotter/_io/readPTU_FLIM.py>`_.

Examples
--------

Read properties and tags from any type of PicoQuant unified tagged file:

>>> pq = PqFile('tests/data/Settings.pfs')
>>> pq.type
<PqFileType.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/data/FLIM.ptu')
>>> ptu.type
<PqFileType.PTU: ...>
>>> ptu.record_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()
>>> decoded.dtype
dtype([('time', '<u8'), ('dtime', '<i2'), ('channel', 'i1'), ('marker', 'u1')])

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]], shape=(2, 3126), 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]]],
      shape=(1, 256, 256), dtype=uint16)

Alternatively, decode the first channel and integrate all histogram bins
into 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]]]]], shape=(1, 256, 256, 1, 1), 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...
    name:                     FLIM.ptu
...

Write the TCSPC histogram and metadata to a PicoHarpT3 image mode PTU file:

>>> imwrite(
...     '_test.ptu',
...     ptu[:],
...     ptu.global_resolution,
...     ptu.tcspc_resolution,
...     # optional metadata
...     pixel_time=ptu.pixel_time,
...     record_type=PtuRecordType.PicoHarpT3,
...     comment='Written by ptufile.py',
...     tags={'File_RawData_GUID': [ptu.guid]},
... )

Read back the TCSPC histogram from the file:

>>> tcspc_histogram = imread('_test.ptu')
>>> import numpy
>>> numpy.array_equal(tcspc_histogram, ptu[:])
True

Close the file handle:

>>> ptu.close()

Preview the image and metadata in a PTU file from the console::

    python -m ptufile tests/data/FLIM.ptu
