QEC Studio
QEC Studio is Research mode’s quantum-error-correction workflow. It turns a Stim stabilizer circuit into a set of visualizations no other desktop tool has, then sweeps it over noise to measure how well the code protects logical information.
Start from a template
Section titled “Start from a template”The fastest way in is Experiments → New QEC experiment. Pick Repetition code memory or Rotated surface code memory and Nuclei writes two real, editable files into your project:
qec/<name>.py— a Stim-generating entry definingnuclei_circuits(noise) -> dict[str, stim.Circuit]. Nothing is hidden; open it and change the distances, the code task, or build circuits by hand.experiments/<name>.experiment.yaml— aqec_campaignspec pointing at that entry. See Campaigns for every field.
The entry labels its circuits d=3, d=5, d=7; that convention is what lets
the threshold panel fit Λ across distances.
The visualizations
Section titled “The visualizations”Open a .stim file (or run Stim-building Python) and the visualization zone
swaps its Bloch sphere for three QEC panels:
- Timeline — the circuit moment by moment: resets, gates, measurements, and detector/observable annotations per tick.
- Code Lattice — data and measure qubits laid out from the circuit’s qubit coordinates (generated codes include them; hand-built circuits may not, and the panel says so).
- Detector Graph — the circuit’s detector error model (DEM) drawn as a graph: detector nodes placed by their coordinates, edges between the detectors each error mechanism flips, and boundary edges to a virtual node. It’s the panel no other desktop tool has — and where you decode. It gets its own two sections below.
Reading the detector graph
Section titled “Reading the detector graph”The detector graph renders on a canvas, so it stays smooth from a distance-3 code up to the tens of thousands of edges of a large surface code. The drawing is information-dense on purpose:
- Edges are heat-coloured and weighted by error probability — faint slate for rare mechanisms, through teal, to a warm glow for the likeliest ones. A code’s fragile “hotspots” are visible at a glance instead of a uniform mesh.
- Boundary edges (to the virtual boundary node) are dashed; edges that flip a logical observable carry a bright accent, since they move logical information you can’t afford to mis-correct.
- Hover a detector to inspect it — its index, how many edges touch it, and whether it has fired. A legend in the corner spells out the encoding.
Very large graphs are still capped for the initial payload, but nothing is lost: the banner reports the true edge counts and a Render full graph button parses the complete model in the app — a WebAssembly parser runs over the DEM text the kernel forwards — and draws it with no edge limit. A circuit with no valid DEM shows the reason, not a blank box.
Decode a shot — two ways
Section titled “Decode a shot — two ways”The detector graph is where you watch a decoder work. There are two modes, for two different questions.
Sample a shot — accurate
Section titled “Sample a shot — accurate”Press Sample a shot and the kernel runs one Monte-Carlo shot through the real decoder (PyMatching): the fired detectors light up, the decoder’s matching is drawn on top, and you get an honest “logical error this shot” / “corrected” verdict. This is the same decoder a campaign uses — the numbers you’d trust.
Interactive — instant, in the app
Section titled “Interactive — instant, in the app”Toggle Interactive and the graph becomes a sandbox: click detectors to build any syndrome you like, and a decoder re-solves the matching instantly, in the app, with no kernel round-trip. The correction lights up as you click, with a live readout of whether it crosses a logical observable. It’s for building intuition — “what would the decoder do with this syndrome, and would it be a logical error?” — not for publishable numbers.
Run a campaign
Section titled “Run a campaign”With a qec_campaign experiment selected, the analysis view gives you a
Run campaign button and a live progress chip (tasks complete / shots
sampled). A campaign is a set of Stim tasks — labels × noise points × decoders
— sampled by sinter across worker processes.
Quit mid-campaign and the next run resumes without re-sampling: the stats already collected are handed back to sinter as a starting point. Campaigns are Monte-Carlo and not seed-reproducible — sinter has no seeding API, and Nuclei doesn’t pretend otherwise.
Read the threshold / Λ plot
Section titled “Read the threshold / Λ plot”Results stream into the Threshold / Λ panel: logical error rate per shot vs the physical error parameter, on log-log axes, one series per (label × distance × decoder), with Wilson confidence intervals. Below threshold, higher distances sit lower and the curves fan out; the panel reports the fitted Λ (the error-suppression factor between successive distances, Λ > 1 = below threshold) and a projected distance to reach a target logical error rate.
Estimate the cost
Section titled “Estimate the cost”The Resource Estimator panel answers the next question: given a Q# or Qiskit algorithm, how many physical qubits and how much wall-clock time would a fault-tolerant implementation actually need?