photonsfile
Pure-Python reader for Photonscore LINCam .photons files (the D7 container).
numpy only, with optional numba acceleration for the varint decode.
Photonscore LINCam is a position-sensitive single-photon detector: every photon
carries an (x, y) detector position, a TCSPC micro time (dt), and a macro time
in milliseconds (ms). This library decodes those per-photon streams and can bin
them into an intensity image, a TCSPC decay, or a (Y, X, H) FLIM cube.
The D7 format
A .photons file is a paged container: 16 KB pages, each carrying a 2-byte page
marker, holding a protobuf-style header, a per-dataset index, and an epilogue. Each
dataset (/photons/x, /photons/y, /photons/dt, /photons/ms, and on dual-TDC
detectors /start/time and /stop/time) is stored as a seed value followed by
zigzag-varint delta blocks. dt to time is calibrated from the file's
/photons/TacChannel attribute (picoseconds per raw unit).
The format is documented at github.com/photonscore/d7 (Apache-2.0). This reader was written from that specification and validated bit-exact against the Photonscore SDK. No vendor source is redistributed.
Install
pip install photonsfile # numpy only
pip install photonsfile[all] # + numba, for a faster varint decode
Usage
from photonsfile import PhotonsFile, imread
with PhotonsFile('sample.photons') as f:
ph = f.photons() # {'x', 'y', 'dt', 'ms'} arrays, one per photon
img = f.image(pixels=512) # (Y, X) intensity image
decay = f.decay(bins=256) # summed TCSPC histogram
cube = f.flim_image(512, 256) # (Y, X, H) FLIM cube
dt_res = f.tcspc_resolution(256) # seconds per bin, from TacChannel
print(f.attributes) # D7 file attributes
img = imread('sample.photons') # shortcut for the intensity image
Large files
image(), decay() and flim_image() stream the file a few blocks at a time,
so peak memory is about the size of the output, not the file. A 40-million-photon
file bins to a 512 x 512 x 256 cube at about 0.5 GB peak, where loading every
photon first took about 2.5 GB. To stream photons yourself:
from photonsfile import iter_photons
for chunk in iter_photons('big.photons'): # dicts of equal-length arrays
x, y, dt = chunk['x'], chunk['y'], chunk['dt']
iter_photons covers x, y and dt. ms is not per photon (it indexes the
photon stream once per millisecond), so read it with read_photons, which still
loads whole datasets into memory.
Low-level access to the decoder is also exported: read_header,
read_attributes, read_photons, iter_photons, dataset_names, has_dual_tdc.
numba is optional; without it the varint decode uses a vectorised numpy fallback.
photonsfile.have_numba() reports which path is active.
Acknowledgement
Thank you to Yury Prokazov (Photonscore) for supporting this work: sharing the
LINCam SDK and a sample .photons file, and open-sourcing the D7 storage format at
github.com/photonscore/d7.
Provenance
The decoder is original code, first worked out from the SDK and the sample file, then checked field for field and bit-exact against the public D7 specification on a 284-million-photon sample. No Photonscore source is redistributed here; the reader is pure Python (numpy, with an optional numba path) and needs none of Photonscore's native libraries.
Citation
If you use photonsfile, please cite it via the DOI. Archived on Zenodo:
Hunt, A. and A. Akram. photonsfile: a pure-Python reader for Photonscore LINCam .photons (D7) files. Zenodo. https://doi.org/10.5281/zenodo.21360199
The DOI above is the concept DOI and always resolves to the latest version. To cite a specific version, use its own DOI (2026.7.14 is 10.5281/zenodo.21360200).
Machine-readable metadata is in CITATION.cff; GitHub shows a
"Cite this repository" button from it.
License
MIT - see LICENSE.
Metadata
Release files for photonsfile 2026.9.29.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| photonsfile-2026.9.29.1.tar.gz | 14.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| photonsfile-2026.9.29.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 25.8 kB
Release files / photonsfile-2026.9.29.1.tar.gz
| Download URL | photonsfile-2026.9.29.1.tar.gz |
|---|---|
| Size | 14.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b99bbe25198374a9e8d66b19de5f37cb8033a50122ccf6f236dc64afe2ccfecd
|
|
BLAKE2b-256 checksum How to use checksums |
5556f44ead7a33e9bcbb918096a68d5065f62671971e62d80677a6bf356de5d4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency logRelease files / photonsfile-2026.9.29.1-py3-none-any.whl
| Download URL | photonsfile-2026.9.29.1-py3-none-any.whl |
|---|---|
| Size | 11.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
bced521090b0d792d83d2980051053f13d1bfb88f618032ce701c3bb4facfd6e
|
|
BLAKE2b-256 checksum How to use checksums |
748ab5acfc9b369aabdefaebfa09bb05df4f6d099e5989173011947f94db60c3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency log