{"id":19671217,"url":"https://github.com/cgohlke/ptufile","last_synced_at":"2026-02-08T00:04:52.763Z","repository":{"id":205000742,"uuid":"711727755","full_name":"cgohlke/ptufile","owner":"cgohlke","description":"Read and write PicoQuant PTU and related files.","archived":false,"fork":false,"pushed_at":"2026-01-14T23:28:17.000Z","size":566,"stargazers_count":15,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-01-17T03:39:03.971Z","etag":null,"topics":["flim","fluorescence-lifetime-spectroscopy","fluorescence-microscopy-imaging","format-reader","life-sciences-image","photon-counting","picoquant","ptu","python","tcspc","tttr"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/ptufile","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cgohlke.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGES.rst","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-10-30T03:44:42.000Z","updated_at":"2026-01-14T23:28:24.000Z","dependencies_parsed_at":"2023-11-13T21:28:05.723Z","dependency_job_id":"3d1ee811-05cd-4115-bd15-818869c61a1d","html_url":"https://github.com/cgohlke/ptufile","commit_stats":{"total_commits":78,"total_committers":1,"mean_commits":78.0,"dds":0.0,"last_synced_commit":"1b0a629d2dd8abda16d9b6b3eb91d43cc1c84630"},"previous_names":["cgohlke/ptufile"],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/cgohlke/ptufile","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cgohlke%2Fptufile","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cgohlke%2Fptufile/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cgohlke%2Fptufile/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cgohlke%2Fptufile/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cgohlke","download_url":"https://codeload.github.com/cgohlke/ptufile/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cgohlke%2Fptufile/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29213513,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-07T23:58:20.073Z","status":"ssl_error","status_checked_at":"2026-02-07T23:58:07.729Z","response_time":63,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["flim","fluorescence-lifetime-spectroscopy","fluorescence-microscopy-imaging","format-reader","life-sciences-image","photon-counting","picoquant","ptu","python","tcspc","tttr"],"created_at":"2024-11-11T17:08:10.916Z","updated_at":"2026-02-08T00:04:52.758Z","avatar_url":"https://github.com/cgohlke.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"..\n  This file is generated by setup.py\n\nRead and write PicoQuant PTU and related files\n==============================================\n\nPtufile is a Python library to\n\n1. read data and metadata from PicoQuant PTU and related files\n   (PHU, PCK, PCO, PFS, PUS, PQRES, PQDAT, PQUNI, SPQR, and BIN), and\n2. write TCSPC histograms to T3 image mode PTU files.\n\nPTU files contain time correlated single photon counting (TCSPC)\nmeasurement data and instrumentation parameters.\n\n:Author: `Christoph Gohlke \u003chttps://www.cgohlke.com\u003e`_\n:License: BSD-3-Clause\n:Version: 2026.2.6\n:DOI: `10.5281/zenodo.10120021 \u003chttps://doi.org/10.5281/zenodo.10120021\u003e`_\n\nQuickstart\n----------\n\nInstall the ptufile package and all dependencies from the\n`Python Package Index \u003chttps://pypi.org/project/ptufile/\u003e`_::\n\n    python -m pip install -U \"ptufile[all]\"\n\nSee `Examples`_ for using the programming interface.\n\nSource code and support are available on\n`GitHub \u003chttps://github.com/cgohlke/ptufile\u003e`_.\n\nRequirements\n------------\n\nThis revision was tested with the following requirements and dependencies\n(other versions may work):\n\n- `CPython \u003chttps://www.python.org\u003e`_ 3.11.9, 3.12.10, 3.13.12, 3.14.3 64-bit\n- `NumPy \u003chttps://pypi.org/project/numpy\u003e`_ 2.4.2\n- `Xarray \u003chttps://pypi.org/project/xarray\u003e`_ 2026.1.0 (recommended)\n- `Matplotlib \u003chttps://pypi.org/project/matplotlib/\u003e`_ 3.10.8 (optional)\n- `Tifffile \u003chttps://pypi.org/project/tifffile/\u003e`_ 2026.1.28 (optional)\n- `Numcodecs \u003chttps://pypi.org/project/numcodecs/\u003e`_ 0.16.5 (optional)\n- `Python-dateutil \u003chttps://pypi.org/project/python-dateutil/\u003e`_ 2.9.0\n  (optional)\n- `Cython \u003chttps://pypi.org/project/cython/\u003e`_ 3.2.4 (build)\n\nRevisions\n---------\n\n2026.2.6\n\n- Fix code review issues.\n\n2026.1.14\n\n- Improve code quality.\n\n2025.12.12\n\n- Add PQUNI file type.\n- Add attrs properties and return with xarray DataSets.\n- Improve code quality.\n\n2025.11.8\n\n- Fix reading files with negative TTResult_NumberOfRecords.\n- Remove cache argument from PtuFile.read_records (breaking).\n- Add cache_records property to PtuFile to control caching behavior.\n- Derive PqFileError from ValueError.\n- Factor out BinaryFile base class.\n- Build ABI3 wheels.\n\n2025.9.9\n\n- Log error when decoding image with invalid line or frame masks.\n\n2025.7.30\n\n- Add option to specify pixel time for decoding images.\n- Add functions to read and write PicoQuant BIN files.\n- Drop support for Python 3.10.\n\n2025.5.10\n\n- Mark Cython extension free-threading compatible.\n- Support Python 3.14.\n\n2025.2.20\n\n- Rename PqFileMagic to PqFileType (breaking).\n- Rename PqFile.magic to PqFile.type (breaking).\n- Add PQDAT and SPQR file types.\n\n2025.2.12\n\n- Add options to specify file open modes to PqFile and PtuFile.read_records.\n- Add convenience properties to PqFile and PtuFile.\n- Cache records read from file.\n\n2025.1.13\n\n- Fall back to file size if TTResult_NumberOfRecords is zero (#2).\n\n2024.12.28\n\n- …\n\nRefer to the CHANGES file for older revisions.\n\nNotes\n-----\n\n`PicoQuant GmbH \u003chttps://www.picoquant.com/\u003e`_ is a manufacturer of photonic\ncomponents and instruments.\n\nThe PicoQuant unified file formats are documented at the\n`PicoQuant-Time-Tagged-File-Format-Demos\n\u003chttps://github.com/PicoQuant/PicoQuant-Time-Tagged-File-Format-Demos/tree/master/doc\u003e`_.\n\nThe following features are currently not implemented due to the lack of\ntest files or documentation: PT2 and PT3 files, decoding images from\nT2 and SPQR formats, bidirectional per frame, and deprecated image\nreconstruction.\n\nCompatibility with PTU files written by non-PicoQuant software (for example,\nLeica LAS X or Abberior Imspector) is limited, as is decoding line,\nbidirectional, and sinusoidal scanning.\n\nOther modules for reading or writing PicoQuant files are\n`Read_PTU.py\n\u003chttps://github.com/PicoQuant/PicoQuant-Time-Tagged-File-Format-Demos/blob/master/PTU/Python/Read_PTU.py\u003e`_,\n`readPTU \u003chttps://github.com/qpl-public/readPTU\u003e`_,\n`readPTU_FLIM \u003chttps://github.com/SumeetRohilla/readPTU_FLIM\u003e`_,\n`fastFLIM \u003chttps://github.com/RobertMolenaar-UT/fastFLIM\u003e`_,\n`PyPTU \u003chttps://gitlab.inria.fr/jrye/pyptu\u003e`_,\n`PTU_Reader \u003chttps://github.com/UU-cellbiology/PTU_Reader\u003e`_,\n`PTU_Writer \u003chttps://github.com/ekatrukha/PTU_Writer\u003e`_,\n`FlimReader \u003chttps://github.com/flimfit/FlimReader\u003e`_,\n`tangy \u003chttps://github.com/Peter-Barrow/tangy\u003e`_,\n`tttrlib \u003chttps://github.com/Fluorescence-Tools/tttrlib\u003e`_,\n`picoquantio \u003chttps://github.com/tsbischof/picoquantio\u003e`_,\n`ptuparser \u003chttps://pypi.org/project/ptuparser/\u003e`_,\n`phconvert \u003chttps://github.com/Photon-HDF5/phconvert/\u003e`_,\n`trattoria \u003chttps://pypi.org/project/trattoria/\u003e`_ (wrapper of\n`trattoria-core \u003chttps://pypi.org/project/trattoria-core/\u003e`_,\n`tttr-toolbox \u003chttps://github.com/GCBallesteros/tttr-toolbox/\u003e`_),\n`PAM \u003chttps://gitlab.com/PAM-PIE/PAM/-/blob/master/functions/readin/Read_PTU.m\u003e`_,\n`FLOPA \u003chttps://github.com/IMCF-Biocev/FLOPA/tree/main/src/flopa/io/ptuio\u003e`_,\nand\n`napari-flim-phasor-plotter\n\u003chttps://github.com/zoccoler/napari-flim-phasor-plotter/blob/0.0.6/src/napari_flim_phasor_plotter/_io/readPTU_FLIM.py\u003e`_.\n\nExamples\n--------\n\nRead properties and tags from any type of PicoQuant unified tagged file:\n\n.. code-block:: python\n\n    \u003e\u003e\u003e pq = PqFile('tests/data/Settings.pfs')\n    \u003e\u003e\u003e pq.type\n    \u003cPqFileType.PFS: ...\u003e\n    \u003e\u003e\u003e pq.guid\n    UUID('86d428e2-cb0b-4964-996c-04456ba6be7b')\n    \u003e\u003e\u003e pq.tags\n    {...'CreatorSW_Name': 'SymPhoTime 64', 'CreatorSW_Version': '2.1'...}\n    \u003e\u003e\u003e pq.close()\n\nRead metadata from a PicoQuant PTU FLIM file:\n\n.. code-block:: python\n\n    \u003e\u003e\u003e ptu = PtuFile('tests/data/FLIM.ptu')\n    \u003e\u003e\u003e ptu.type\n    \u003cPqFileType.PTU: ...\u003e\n    \u003e\u003e\u003e ptu.record_type\n    \u003cPtuRecordType.PicoHarpT3: 66307\u003e\n    \u003e\u003e\u003e ptu.measurement_mode\n    \u003cPtuMeasurementMode.T3: 3\u003e\n    \u003e\u003e\u003e ptu.measurement_submode\n    \u003cPtuMeasurementSubMode.IMAGE: 3\u003e\n\nDecode TTTR records from the PTU file to ``numpy.recarray``:\n\n.. code-block:: python\n\n    \u003e\u003e\u003e decoded = ptu.decode_records()\n    \u003e\u003e\u003e decoded.dtype\n    dtype([('time', '\u003cu8'), ('dtime', '\u003ci2'), ('channel', 'i1'), ('marker', 'u1')])\n\nGet global times of frame changes from markers:\n\n.. code-block:: python\n\n    \u003e\u003e\u003e decoded['time'][(decoded['marker'] \u0026 ptu.frame_change_mask) \u003e 0]\n    array([1571185680], dtype=uint64)\n\nDecode TTTR records to overall delay-time histograms per channel:\n\n.. code-block:: python\n\n    \u003e\u003e\u003e ptu.decode_histogram(dtype='uint8')\n    array([[ 5,  7,  7, ..., 10,  9,  2]], shape=(2, 3126), dtype=uint8)\n\nGet information about the FLIM image histogram in the PTU file:\n\n.. code-block:: python\n\n    \u003e\u003e\u003e ptu.shape\n    (1, 256, 256, 2, 3126)\n    \u003e\u003e\u003e ptu.dims\n    ('T', 'Y', 'X', 'C', 'H')\n    \u003e\u003e\u003e ptu.coords\n    {'T': ..., 'Y': ..., 'X': ..., 'H': ...}\n    \u003e\u003e\u003e ptu.dtype\n    dtype('uint16')\n    \u003e\u003e\u003e ptu.active_channels\n    (0, 1)\n\nDecode parts of the image histogram to ``numpy.ndarray`` using slice notation.\nSlice step sizes define binning, -1 being used to integrate along axis:\n\n.. code-block:: python\n\n    \u003e\u003e\u003e ptu[:, ..., 0, ::-1]\n    array([[[103, ..., 38],\n                  ...\n            [ 47, ..., 30]]],\n          shape=(1, 256, 256), dtype=uint16)\n\nAlternatively, decode the first channel and integrate all histogram bins\ninto a ``xarray.DataArray``, keeping reduced axes:\n\n.. code-block:: python\n\n    \u003e\u003e\u003e ptu.decode_image(channel=0, dtime=-1, asxarray=True)\n    \u003cxarray.DataArray (T: 1, Y: 256, X: 256, C: 1, H: 1)\u003e ...\n    array([[[[[103]],\n               ...\n             [[ 30]]]]], shape=(1, 256, 256, 1, 1), dtype=uint16)\n    Coordinates:\n      * T        (T) float64... 0.05625\n      * Y        (Y) float64... -0.0001304 ... 0.0001294\n      * X        (X) float64... -0.0001304 ... 0.0001294\n      * C        (C) uint8... 0\n      * H        (H) float64... 0.0\n    Attributes...\n        name:                     FLIM.ptu\n    ...\n\nWrite the TCSPC histogram and metadata to a PicoHarpT3 image mode PTU file:\n\n.. code-block:: python\n\n    \u003e\u003e\u003e imwrite(\n    ...     '_test.ptu',\n    ...     ptu[:],\n    ...     ptu.global_resolution,\n    ...     ptu.tcspc_resolution,\n    ...     # optional metadata\n    ...     pixel_time=ptu.pixel_time,\n    ...     record_type=PtuRecordType.PicoHarpT3,\n    ...     comment='Written by ptufile.py',\n    ...     tags={'File_RawData_GUID': [ptu.guid]},\n    ... )\n\nRead back the TCSPC histogram from the file:\n\n.. code-block:: python\n\n    \u003e\u003e\u003e tcspc_histogram = imread('_test.ptu')\n    \u003e\u003e\u003e import numpy\n    \u003e\u003e\u003e numpy.array_equal(tcspc_histogram, ptu[:])\n    True\n\nClose the file handle:\n\n.. code-block:: python\n\n    \u003e\u003e\u003e ptu.close()\n\nPreview the image and metadata in a PTU file from the console::\n\n    python -m ptufile tests/data/FLIM.ptu","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcgohlke%2Fptufile","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcgohlke%2Fptufile","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcgohlke%2Fptufile/lists"}