vacspin
How well can a single trapped spin in diamond talk to light? A
vacancy colour centre (SiV-, GeV-, SnV-, PbV-) holds one electron
spin whose optical transitions depend on strain, magnetic field and
the cavity around it -- and every quantum-network number you care
about (how many photons before the spin flips, how fast you can read
it out, how often two nodes entangle) follows from that chain.
vacspin computes the whole chain: the spin Hamiltonian, the optical
transitions and their cyclicity, the cavity Purcell budget, the exact
single-shot readout statistics, and the remote-entanglement rate --
with every physics claim pinned in the test suite to a closed form, a
published measurement, or two independent code paths.
Install
pip install vacspin # NumPy only
For development: clone the repository and pip install -e .[test].
The chain in one example
import vacspin as vs
spin = vs.snv_rosenthal2023() # cited SnV- parameters
b = vs.field_on_circle(147.0, 0.125) # 125 mT at 147 degrees
f_q = vs.qubit_frequency(spin, b) # -> 3.64 GHz (measured 3.677)
ci = vs.CavityInterface(
q_loaded=500, v_rel=0.68, eta_wg=0.9996, # your cavity
budget=vs.snv_emission(), # cited emission budget
lambda0=2244.0, # measured cyclicity
omega_q_hz=f_q * 1e9,
xi_pol=vs.xi_pol_overlap(), xi_pos=0.5,
t_link=0.99, eta_chip=0.8, eta_det=0.9).require_valid()
out = vs.fidelity(ci.eta, ci.lambda_cav, ci.gamma_cav, tau=50e-9, s=2.0)
print(ci.f_c, ci.eta, out["fidelity"]) # Purcell ~19, eta ~0.65
require_valid() is not decoration: the Purcell formulas assume the
bad-cavity, weak-coupling, spin-selective regime, and the interface
refuses -- naming the failed condition -- rather than extrapolating
outside it.
What is inside
- The spin Hamiltonian (
h_manifold,solve,qubit_frequency): the effective Hamiltonian all group-IV centres share (spin-orbit + strain + Zeeman; Rosenthal et al., PRX 13, 031022 (2023)), in pure NumPy, with the exact frame rotation from your lab coordinates, the closed-form zero-field splitting, a strain-tuning axis, and the perturbative transverse-field formula held against full diagonalisation. - Transitions and cyclicity (
transition_table,cyclicity,rabi_rate): all sixteen optical transitions with their strengths (which obey an exact sum rule the tests assert), the cyclicity that decides how many photons a spin emits before it flips -- including its exact divergence when the field is aligned with the symmetry axis -- and microwave Rabi rates. - The cavity budget (
CavityInterface,purcell_max): the transition-resolved Purcell factor, the lifetime-reduction factor, the fraction of decays that reach your detector through the full chain (cavity mode, out-coupling port, link, chip, detector), the cavity-boosted cyclicity (the cavity enhances only the spin-conserving line; its partner is detuned by the qubit frequency), and the coupling rate g with F = 4 g^2 / (kappa gamma) holding as an exact identity. - Single-shot readout (
fidelity,required_efficiency,required_window): exact counting statistics -- the bright record is a Poisson photon stream terminated by the spin flip, evaluated in closed form, no numerical quadrature -- with background counts, off-resonant scattering of the dark spin, and the dark-state switch-on channel, at the optimal integer threshold. The inverse tools answer the questions an experiment actually asks (what efficiency, how long a window) and refuse when the target is unreachable, naming the best achievable value. - Remote entanglement (
barrett_kok_success,entanglement_rate): the two-photon heralding budget, with its intrinsic factor 1/2 stated as a ceiling no detector removes. - Your sample, your numbers (
fit_spin_parameters,parameter_information,design_fields): fit the spin parameters of your own centre to your measured frequencies, with error bars -- and, before measuring, check whether the planned measurements can determine those parameters at all.
Cited parameters
No physical number is made up, and none is accepted without a source
-- the reference field of both parameter dataclasses is mandatory.
snv_rosenthal2023()+snv_emission(): the SnV- device values of Rosenthal et al., PRX 13, 031022 (2023) with the Thiering-Gali quenching factors, and the emission budget of arXiv:2403.13110 / Goerlitz et al. / Lee et al. (arXiv:2511.05740). Validated against measurement in the tests with no free parameters: the 902.98 GHz splitting, the 3.677 GHz qubit frequency, the cyclicity landscape (2244 near alignment, 8.6 at 53 degrees), the MHz Rabi scale.siv_hepp2014(): the unstrained SiV- splittings (50 and 260 GHz) of Hepp et al., PRL 112, 036405 (2014). Strain and orbital quenching are sample-specific and deliberately not shipped; the reference string says so.gev_bhaskar2017(): the measured GeV- splittings (152 and 981 GHz, zero-phonon line 602 nm) of Bhaskar et al., PRL 118, 223603 (2017), with the same deliberate omissions as SiV- -- strain and quenching are your sample's numbers, andvacspin.labexists to fit them.
The lead-vacancy (PbV-) centre is documented but not shipped, on purpose: its ground splitting is measured (about 3900 GHz; Wang et al., ACS Photonics 8, 2947 (2021), confirmed in 2026), but no verified measured excited-state splitting was available, and this package does not ship half a parameter set.
For PbV-, or your own sample of any centre, populate SpinParameters and
EmissionBudget from your measurements or the literature; the
provenance travels with every prediction.
Adapting it to your lab
Every sample is different, so the numbers that describe your centre
should come from your own measurements. The lab tools close that
loop in the order a lab actually works -- plan first, then measure,
then calibrate:
import vacspin as vs
p0 = vs.snv_rosenthal2023() # starting point
# 1. Before measuring: can 6 planned points determine lam_g and ups_g,
# and how small would the error bars be at 0.05 GHz per point?
kinds = ["qubit", "orbital_g"] * 3
fields = [vs.field_on_circle(z, 0.15) for z in (20, 60, 100, 140, 160, 80)]
info = vs.parameter_information(kinds, fields, p0,
vary=("lam_g", "ups_g"), sigmas_ghz=0.05)
print(info["identifiable"], info["sigma"])
# 2. Or let the package pick the best subset of your candidate points:
pick = vs.design_fields(kinds, fields, 4, p0, vary=("lam_g", "ups_g"))
# 3. After measuring: fit, and get a ready-to-use parameter set whose
# `reference` records exactly where it came from.
fit = vs.fit_spin_parameters(kinds, fields, measured_ghz, p0,
vary=("lam_g", "ups_g"), sigmas_ghz=0.05)
print(fit.values, fit.sigma)
my_sample = fit.params # use it anywhere in the package
A set of measurements that cannot tell the fitted parameters apart is
refused with an explanation rather than silently answered -- the
classic case being zero-field splittings alone, which can never
separate the spin-orbit constant from strain because they only enter
together as one number. Observation records travel in a plain CSV
format (save_observations_csv / load_observations_csv) whose
round trip is exact.
How it is checked
59 tests (Python 3.9-3.14 in CI on every push), every claim anchored to an exact result, a published measurement, or two independent code paths -- never a stored number. Highlights: exact Kramers doublets and the closed-form splitting against full diagonalisation; the measured SnV- landscape reproduced with no free parameters; the exact aligned-field cyclicity divergence; the dipole sum rule (total strength exactly 3 per ground state) as an identity; the Purcell relation F = 4 g^2/(kappa gamma) as an exact round trip; exact Lorentzian and polarisation-overlap limits; the photon budget bounded and monotone; the bright-count distribution hitting its Poisson and geometric limits at machine precision (the closed-form recurrence makes them exact, not approximate); the measured confocal operating point (about 4 detected photons at 0.2% efficiency) reproduced; the source study's design point (Purcell factor ~19, end-to-end efficiency ~0.65, >98% fidelity at the optimal window, a >100x speedup over confocal readout) recovered end to end from its stated inputs; inverse-tool round trips and refusals throughout; and the lab-calibration tools checked four ways -- noiseless fits recover the truth, the exact linear case hits its textbook closed form, seeded Monte Carlo matches the reported error bars, and the non-identifiable zero-field design is refused via an exact rank argument.
Honest limits
Deliberate scope, designed out with reasons: no photonic device
design (cavity Q, mode volume and taper transfer are inputs you
simulate or measure -- the companion study's pipeline shows how);
the readout model is the two-level bad-cavity treatment, and
require_valid() refuses the strong-coupling regime rather than
mis-describing it; spin coherence times (T1, T2) are
sample-dependent measurements, not shipped constants; and the
switch-on dark channel is treated by a union bound, so the reported
fidelity is the conservative side of the exact answer.
Associated study
T. M. Mahim, M. M. Rahman and A. S. M. Mohsin, "Fast single-shot readout of tin-vacancy spins with an overcoupled diamond nanocavity on thin-film lithium niobate" (submitted to Optics Express, 2026); pipeline: https://github.com/Tanvir-Mahmud-Mahim/snv-tfln-cavity-interface
This package is the general-purpose engine; the paper repository holds the device design (FEM/EME/GME photonics) and reproduces the specific study. Formalism: Rosenthal et al., PRX 13, 031022 (2023) and arXiv:2403.13110; transition-resolved cavity conventions: Lee et al., arXiv:2511.05740; heralding: Barrett and Kok, PRA 71, 060310(R) (2005).
Support and governance
Written and maintained by Tanvir Mahmud Mahim (Department of Electrical and Electronic Engineering, BRAC University), who reviews every change and takes the final decision on scope and releases. Design questions are discussed in the open in issues and pull requests, and the standing rule of CONTRIBUTING.md binds the maintainer exactly as it binds contributors: a change that touches physics arrives with a test, and a constant arrives with its source.
Support runs through the issue tracker. Usage questions are welcome alongside bug reports; a docstring that left a unit or a sign convention unclear is treated as a documentation bug, not user error. While the version is below 1.0 the API may still move between minor versions; such changes are called out in the release notes.
License
Apache-2.0. Every release is archived on Zenodo under the concept DOI 10.5281/zenodo.22819698, which always resolves to the latest version.
Release files for vacspin 0.3.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 | |
|---|---|---|---|
| vacspin-0.3.0.tar.gz | 48.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| vacspin-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 83.7 kB
Release files / vacspin-0.3.0.tar.gz
| Download URL | vacspin-0.3.0.tar.gz |
|---|---|
| Size | 48.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
247db364f1a42f18f2fca552906ed63767d57a65c11f2b60c147d0b2f3696741
|
|
BLAKE2b-256 checksum How to use checksums |
6f0869a0b5b799078d3470e4290fa477c187e19f917177c9479589e394145865
|
| 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 / vacspin-0.3.0-py3-none-any.whl
| Download URL | vacspin-0.3.0-py3-none-any.whl |
|---|---|
| Size | 35.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6b30aecc6faa1f5e7a543b827b2f39db66984449f28526c7ef06d9af6883e68e
|
|
BLAKE2b-256 checksum How to use checksums |
49e5d0d89a015e01065966ed3b5b6111b581a95daaca14e4cf674c9769be6f97
|
| 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