SPARQ
Is this light source emitting one photon at a time? That question --
the standard test for single-photon emitters, measured as a dip in
the coincidence histogram of a two-detector (HBT) experiment --
usually costs a long dwell at every candidate site. sparq answers
it faster and more rigorously: exact statistical analysis of measured
histograms with honest uncertainties, sequential tests that stop the
moment the data suffice, and a machine-learning layer that learns to
triage many sites efficiently. The installable package behind the
manuscript "Closed-loop, event-driven machine learning for
autonomous triage of single-photon emitters"; the
companion repository
reproduces the paper itself.
Install
pip install sparq-triage # physics core (numpy, scipy)
pip install sparq-triage[ml] # adds PyTorch for the estimators, twin and RL
The core -- analytic correlation functions, the exact-statistics histogram twin, master-equation reference, pulsed analysis, and every analysis tool below -- imports without PyTorch.
Analyze your own measurement
analyze_histogram runs the full conventional pipeline on any
measured CW HBT histogram (dip centering, re-binning, normalization,
multi-start fit) and reports g2(0) with a bootstrap confidence
interval that propagates shot noise through every step;
analyze_pulsed does the same for pulsed data via peak areas.
The pipeline adapts to your emitter and instrument (v0.6) instead of assuming the defaults it was born with:
load_hbt_csv/save_hbt_csv: a documented two-column file contract (delay_ns,counts) with an exact round trip and refusals for malformed files.- Configurable lifetime windows (
t1_bounds/t2_bounds): the defaults suit NV-center-scale emitters; a much faster quantum dot or a slow bunching shoulder needs its own window, and a window that excludes the truth silently rails a fit -- the tests demonstrate both the failure and the recovery. - The fit model is the physical parameterization (dip depth
multiplying both exponentials) and includes the instrument response
(closed-form Gaussian-convolved exponentials at
cfg.sigma_irf), so the estimate targets the true g2(0), not the softened dip the raw histogram shows. register_platformmakes your emitter a first-class citizen everywhere a platform name is accepted; the built-in priors (NV, hBN, GaN, SiV) are literature-anchored defaults, not a limit.- Raw time tags, not just histograms (v0.7):
load_timetags_csvreads a two-column (channel, time) tag list -- the form vendor software exports -- andnormalize_g2turns the coincidence counts into g2 with error bars by dividing by the rate two UNRELATED detectors would produce (the standard normalization g2 = C T / (N1 N2 w)), so uncorrelated light reads exactly 1.correlate_start_stopemulates the classic timing card that only records the first stop after each start, so hardware histograms can be compared like for like; fit the all-pairs correlation, which has none of that card's high-rate distortion.
Four routes to an uncertainty, each honest about what it assumes
- Bootstrap (
analyze_histogram): shot noise propagated through the full pipeline. - Profile likelihood (
profile_likelihood_ci): a Wilks confidence interval from the exact Poisson likelihood, honest at low counts where linearized errors are not. With the normalization free, a slow bunching shoulder trades against the flat level -- a real near-degeneracy of the histogram alone, and the interval says so by being wide; pass the independently measured singles rates asc0_priorand it tightens to what the data genuinely support. - Exact Bayesian posterior (
bayesian_g2): the closed-form finite-count posterior of the raw central-window g2 -- density, quantiles, credible intervals and the verdict probability P[g2 < 1/2 | data] as exact expressions in four counts, no sampling, no asymptotics. The estimand (a window average, an upper bound on g2(0)) is stated plainly. - Sequential certification (
SPRTCertifier): Wald's sequential test on accumulating histograms -- acquisition stops the moment the evidence crosses the chosen error rates, certifying bright sites in a fraction of the fixed dwell.
Exact closed-form corrections complete the toolbox:
background_corrected_g2 inverts the Poissonian-background map (the
same forward model the package's own twin applies, so the round trip
is machine-exact), signal_fraction builds its input from measured
rates, and deadtime_corrected_rate inverts detector dead-time,
refusing rates at or beyond saturation instead of extrapolating.
Plan the acquisition before running it
How long must the correlator run before "single emitter" can be
certified at your confidence -- and can it ever? The lab tools
answer both from plainly named numbers, before any data exist:
from sparq import site_from_numbers, required_acquisition_time
site = site_from_numbers(tau1_ns=12.0, tau2_ns=200.0, a=0.3,
rate_kcps=120.0, rho=0.97)
T, report = required_acquisition_time(site, confidence=0.95)
print(T, "seconds;", report["prob_below"])
The planning device is stated plainly: it evaluates the exact Bayesian verdict on the AVERAGE histogram the site would produce, so the answer is a typical-data time -- individual runs scatter around it, and the test suite shows a 4x margin certifying more than 90% of seeded runs. One exact fact makes the hopeless case refusable rather than slow: the window-averaged g2 does not change with acquisition time at all (both window means scale linearly with it), so a site whose window g2 is not below the threshold is refused with that number -- no run length can certify it.
Heralded sources too
Solid-state emitters are one route to single photons; heralded pair
sources are the other, and their purity budget obeys an exact closed
form in one routinely measured number, the coincidence-to-accidental
ratio: g2_h(0) = (2 CAR - 1)/CAR^2 for a laser-pumped source, with a
thermal-statistics variant (H. Wang et al., arXiv:2404.03236).
heralded_g2_limit and car_for_purity ship both directions --
what purity a measured CAR permits, and the minimum CAR a target
purity requires -- as exact formulas with exact inversions, refusing
uncertifiable inputs. These are floors set by the pair statistics
alone; a real source sits at or above them, and the docstring says
so.
The machine-learning layer (optional)
With the [ml] extra: neural estimators (CNN and spiking network)
trained physics-in-the-loop, a differentiable twin of the whole
measurement protocol, a closed-loop triage environment with a soft
actor-critic agent and prioritized replay, and a graph encoder for
cross-platform transfer. All of it consumes the same exact-statistics
histogram twin the physics core provides.
How it is checked
85 tests (Python 3.10-3.13 plus a torch-free 3.14 job, ML tests skip without torch, run in CI on every push), each pinned to an exact reference: the two-exponential correlation law against the master-equation eigendecomposition; the closed-form instrument-response convolution against brute-force quadrature; Poisson statistics of the histogram twin; the Bayesian posterior against SciPy's independent implementation and a direct numerical marginalization; exact background and dead-time correction round trips; the fast-emitter window failure and recovery; profile intervals covering the truth with and without the singles-rate prior; exact file-contract round trips; the time-tag correlator against a brute-force pair-by-pair count, with independent random detectors normalizing to a flat g2 = 1 within the reported errors; and the shape and gradient contracts of the ML components.
Real data
The experimental quantum-dot HBT measurements used by
sparq.datasets.load_fisequr are from the openly licensed
sps-quality repository
(Kedziora et al., Mach. Learn.: Sci. Technol. 4, 045042
(2023)); they are not redistributed here, and the loader takes the
dataset directory explicitly.
Contributing and support
Bug reports, questions and pull requests are welcome through GitHub issues; see CONTRIBUTING.md for the development setup and the design rules. Tagged releases are published to PyPI by CI.
License and citation
Apache-2.0 (see LICENSE). Please cite the associated paper if you use this code; citation metadata is in CITATION.cff. Every release is archived on Zenodo under the concept DOI 10.5281/zenodo.22278040, which always resolves to the latest version.
Release files for sparq-triage 0.9.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sparq_triage-0.9.0.tar.gz | 69.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sparq_triage-0.9.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 126.7 kB
Release files / sparq_triage-0.9.0.tar.gz
| Download URL | sparq_triage-0.9.0.tar.gz |
|---|---|
| Size | 69.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b6ebe5c86be01ec74d30e0fa910ff248da08cb172620e2ff21f9d291fe172c74
|
|
BLAKE2b-256 checksum How to use checksums |
0ccc8d908c9244a3a84c0db388c776818528f0950ca3ec551b774802142f91e5
|
| 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 18, 2026.
Transparency logRelease files / sparq_triage-0.9.0-py3-none-any.whl
| Download URL | sparq_triage-0.9.0-py3-none-any.whl |
|---|---|
| Size | 57.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
66e8b0d7323329a35269f9d8c3e87c99a5cf279260f5beb946c2738413493b10
|
|
BLAKE2b-256 checksum How to use checksums |
cab84d1c0a89773df3a01341c110ea5906c487cc13a6703d4c73144f2dfdb694
|
| 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 18, 2026.
Transparency log