Skip to navigation

Overview

Stanza is an open-source Python framework for tuning up quantum devices. We built it while automating the tune-up of 128 double quantum dots, designing it to be easy to use while solving the real challenges we hit along the way. We open-sourced it so the community can use and build upon it too.

What is Stanza?

Stanza helps you characterize and calibrate quantum devices by providing:

  • YAML-based device configuration - Define your device topology once, reuse it everywhere
  • Decorator-based routines - Write tune-up sequences as simple Python functions
  • Automatic logging - Sessions and data are logged automatically in HDF5 or JSONL formats
  • Resource management - Access devices, loggers, and instruments through a unified context
  • Result chaining - Build complex workflows by passing results between routines
  • Type safety - Built on Pydantic for configuration validation and type checking

Architecture

Stanza separates concerns into three layers:

1. Configuration Layer (YAML)

Define your device topology, routine parameters, and instrument connections:

name: "My Quantum Device"
gates:
G1: {type: BARRIER, control_channel: 1, v_lower_bound: -3.0, v_upper_bound: 3.0}
G2: {type: PLUNGER, control_channel: 2, v_lower_bound: -3.0, v_upper_bound: 3.0}
contacts:
DRAIN: {type: DRAIN, control_channel: 4, measure_channel: 2, v_lower_bound: -3.0, v_upper_bound: 3.0}
routines:
- name: sweep_barrier
parameters:
gate: G1
v_start: -2.0
v_stop: 0.0
n_points: 100
instruments:
- name: qdac2-control
type: CONTROL
driver: qdac2
ip_addr: 127.0.0.1
slew_rate: 1.0

2. Routine Layer (Python)

Implement your tune-up logic as decorated functions:

import numpy as np
from stanza.routines import routine
@routine
def sweep_barrier(ctx, gate, v_start, v_stop, n_points, contact="DRAIN"):
"""Sweep a barrier gate and measure current."""
device = ctx.resources.device
voltages = np.linspace(v_start, v_stop, n_points)
v_data, i_data = device.sweep_1d(gate, voltages.tolist(), contact)
return {"voltages": v_data, "currents": i_data}

3. Execution Layer (Runner)

Orchestrate resources, merge parameters, and execute routines:

from stanza.routines import RoutineRunner
from stanza.models import DeviceConfig
# Load configuration
config = DeviceConfig.from_yaml("device.yaml")
# Create runner - automatically loads routine parameters from config
runner = RoutineRunner(configs=[config])
# Execute with config parameters
result = runner.run("sweep_barrier")
# Or override specific parameters at runtime
result = runner.run("sweep_barrier", gate="G2", n_points=50)

Key Features

Device Abstraction

Access quantum devices through a unified interface:

# Jump to voltages
device.jump({"G1": -1.5, "G2": -0.8})
# Measure current
current = device.measure("DRAIN")
# Check current voltage
voltage = device.check("G1")
# Sweep operations
v_data, i_data = device.sweep_1d("G1", voltages, "DRAIN")
v_data, i_data = device.sweep_2d("G1", v1, "G2", v2, "DRAIN")

Automatic Logging

Data is logged automatically when you use a RoutineRunner:

@routine
def my_routine(ctx, session=None):
device = ctx.resources.device
# Sweeps are automatically logged if session is provided
v, i = device.sweep_1d("G1", voltages, "DRAIN", session=session)
# Manual logging also available
if session:
session.log_measurement("gate_voltages", {"G1": v, "currents": i})
return {"voltages": v, "currents": i}

Result Chaining

Build multi-step workflows by accessing results from previous routines:

@routine
def sweep_gate(ctx, gate):
device = ctx.resources.device
voltages = np.linspace(-2, 0, 100)
v_data, i_data = device.sweep_1d(gate, voltages.tolist(), "DRAIN")
return {"voltages": v_data, "currents": i_data}
@routine
def analyze_sweep(ctx):
# Get results from previous routine
data = ctx.results.get("sweep_gate")
currents = np.array(data["currents"])
return {
"max_current": float(np.max(np.abs(currents))),
"mean_current": float(np.mean(np.abs(currents)))
}

Nested Routines

Organize complex tune-up sequences hierarchically:

routines:
- name: full_characterization
parameters:
threshold: 50e6
routines:
- name: leakage_test
parameters:
gate: G1
- name: accumulation_test
parameters:
gate: G2

Execute all nested routines with a single call:

runner.run_all(parent_routine="full_characterization")

Supported Instruments

Stanza includes drivers for:

  • QDAC-II (QDevil) - Control and measurement via TCPIP
  • OPX (Quantum Machines) - RF measurement with QUA integration

Custom drivers can be implemented using the protocol-based interface.

Installation

Install the base package:

pip install cq-stanza

Or with Quantum Machines support:

pip install "cq-stanza[qm]"

Next Steps