Skip to main content

Data Analysis Package for KELpie (DAPKEL)

Tests Docs PyPI - Version PyPI - License

Unpacking and analysis of the binary data written by the Kelpie SPAD camera: dark count rate, optical cross-talk, hitmaps, TDC calibration and photon coincidences.

Documentation: https://rngkomorebi.github.io/dapkel/

The detector

The Kelpie detector was developed at EPFL by Dr. Tommaso Milanese. It features a 64x64 Single-Photon Avalanche Diode (SPAD) sensor built from 2x2 macropixels. It is fully reprogrammable, with high PDE across the whole visible spectrum peaking at 780 nm, 40 ps (rms) jitter, low dark count rate and reasonable cross-talk.

This package was derived from the original MATLAB functions written by Dr. Milanese for offline unpacking and analysis of the detector's data.

Installation

A fresh virtual environment is recommended (how).

pip install dapkel

To work on the package itself, clone the repo and install it in editable mode with the test and documentation extras:

git clone https://github.com/rngKomorebi/dapkel.git
cd dapkel
pip install -e ".[dev,docs]"

requirements.txt lists the runtime dependencies alone, for the pip install -r requirements.txt path; pyproject.toml is the source of truth.

How it works

Every analysis is the same pipeline with a different reduction in the middle:

folder of .bin  ->  discover files  ->  fold frames into a sensor map
                ->  scale to physical units  ->  save
                ->  load  ->  plot
stage what it does on disk
0. raw the camera writes .bin; dapkel decodes it *.bin (read-only)
1. process fold frames into an array, scale to units, save processed/
2. plot load the saved array, render figures results/<kind>/

The rule that keeps this honest: processed/ holds data, results/ holds pictures, and stage 2 never re-unpacks .bin files. Retrying a colormap costs a load, not a re-read of the raw data.

Quick start

On a fresh acquisition, run the data-quality check first. A TDC that never stopped produces data that looks completely normal to every other analysis in this package.

from dapkel.functions import data_quality, dcr_analysis

# 0. Did the TDC actually record timing? Codes should spread over 0..~1300,
#    not collapse onto a handful of values.
data_quality.plot_time_code_histogram("path/to/data", pixel=(16, 16))

# 1 + 2. Compute the full-sensor DCR map and save both figures.
dcr_analysis.collect_and_plot_dcr_64("path/to/data", nframes=1000, acq_window=1000)

Stages 1 and 2 are also separable, so a saved map can be re-plotted without re-reading the raw files:

from dapkel.core import store
from dapkel.functions import dcr_analysis

dcr_analysis.compute_and_save_dcr_64("path/to/data", 1000, acq_window=1000)

dcr, meta = store.load_map("path/to/data", kind="dcr", tag="64")
fig = dcr_analysis.plot_heatmap(dcr)

Each driver can also skip straight to stage 2 from what is already in processed/: dcr_analysis and crosstalk_analysis take from_saved=True, hitmap_analysis takes npy_path=, delta_t takes feather_path=, and TDC lookup tables come back through tdc_calibration.load_lut.

What's in the package

dapkel.functions holds one module per measurement. Each declares its public surface in __all__ - read that list to see what you can call.

module what it measures
unpack decodes the raw .bin files; the shared foundation
data_quality is this acquisition usable at all?
dcr_analysis per-pixel dark count rate, in cps
crosstalk_analysis optical cross-talk, per direction and combined
hitmap_analysis occupancy and photon rate
tdc_calibration per-pixel TDC LUTs from the code density test
calc_diff, delta_t timestamp differences, coincidences and jitter

Anything shared between two analyses lives in dapkel.core rather than being copied - a test fails if a function name is defined in two analysis modules.

A standalone app for starting acquisitions and plotting the hitmap in real time is at dapkel-rtp.

Plot styling

Importing dapkel applies its matplotlib house style through komorebi_mpl, so plots look consistent out of the box. Your choice always wins - the plotting functions never touch rcParams themselves, so whatever style is active when they draw is what you get:

import dapkel                     # applies the default style on import
import komorebi_mpl

komorebi_mpl.use("night_wave")    # or any registered style, or "default"

Development

pytest              # test suite, including the API-surface guards
ruff check .        # lint
mkdocs serve        # preview the documentation at localhost:8000

Releasing

There is no version number to bump anywhere: setuptools_scm derives it from the git tag, so creating the tag is the version bump.

  1. Add a ## [X.Y.Z] - YYYY-MM-DD section to CHANGELOG.md and merge it into main. Preview what the release will say with python tools/changelog.py X.Y.Z.
  2. On GitHub, Releases -> Draft a new release, create the tag vX.Y.Z there and publish.

Publishing runs publish.yml, which validates the tag, refuses to ship a version with no changelog entry, runs the tests, checks the built version matches the tag, uploads to PyPI, and rewrites the release body from the changelog. PyPI versions cannot be reused, so a bad release costs the next number.

Contributing

main is the release branch: tested, and what PyPI is cut from. Work on a feature branch and open a pull request against it. Contributions are welcome; please follow PEP 8 and PEP 257. If you are adding a new measurement, start from Adding an analysis - it describes the contract the tests enforce.

License and contact

MIT - see LICENSE. To get in touch, write to sergei.kulkov23@gmail.com.

Metadata

Release files for dapkel 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dapkel 0.1.1
File Size Uploaded
dapkel-0.1.1.tar.gz 41.4 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for dapkel 0.1.1
File Interpreter ABI Platform
dapkel-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 82.7 MB

Release files / dapkel-0.1.1.tar.gz

Download URL dapkel-0.1.1.tar.gz
Size 41.4 MB
Tags Source
SHA-256 checksum
How to use checksums
b208552b925a409e61577348f861cbf25868548a242a1faeeb4205c702342040
BLAKE2b-256 checksum
How to use checksums
bd77e6159bc7f6275b92aec8682331888612f8f1acc854f0314a70e0b44ba0e5
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 Aug 1, 2026.

Transparency log

Release files / dapkel-0.1.1-py3-none-any.whl

Download URL dapkel-0.1.1-py3-none-any.whl
Size 41.3 MB
Tags Python 3
SHA-256 checksum
How to use checksums
50cd0210330bc156b7d9081dde5ad5c9652a549a4891f922bd5e6d5c69032609
BLAKE2b-256 checksum
How to use checksums
7a0a99472f50ce1662f83886195d5f4fdde238d75e72460457b897c25f0b4532
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 Aug 1, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.0

2 release files

0.2.0

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

This release

0.1.1 This release

2 release files

0.1.0

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page