Overview

Stanza is a Python framework for building tune-up sequences for quantum devices. It provides a clean, type-safe architecture that separates device configuration from routine implementation, with automatic logging and resource management.

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:

1name: "My Quantum Device"
2
3gates:
4 G1: {type: BARRIER, control_channel: 1, v_lower_bound: -3.0, v_upper_bound: 3.0}
5 G2: {type: PLUNGER, control_channel: 2, v_lower_bound: -3.0, v_upper_bound: 3.0}
6
7contacts:
8 DRAIN: {type: DRAIN, control_channel: 4, measure_channel: 2, v_lower_bound: -3.0, v_upper_bound: 3.0}
9
10routines:
11 - name: sweep_barrier
12 parameters:
13 gate: G1
14 v_start: -2.0
15 v_stop: 0.0
16 n_points: 100
17
18instruments:
19 - name: qdac2-control
20 type: CONTROL
21 driver: qdac2
22 ip_addr: 127.0.0.1
23 slew_rate: 1.0

2. Routine Layer (Python)

Implement your tune-up logic as decorated functions:

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

3. Execution Layer (Runner)

Orchestrate resources, merge parameters, and execute routines:

1from stanza.routines import RoutineRunner
2from stanza.models import DeviceConfig
3
4# Load configuration
5config = DeviceConfig.from_yaml("device.yaml")
6
7# Create runner - automatically loads routine parameters from config
8runner = RoutineRunner(configs=[config])
9
10# Execute with config parameters
11result = runner.run("sweep_barrier")
12
13# Or override specific parameters at runtime
14result = runner.run("sweep_barrier", gate="G2", n_points=50)

Key Features

Device Abstraction

Access quantum devices through a unified interface:

1# Jump to voltages
2device.jump({"G1": -1.5, "G2": -0.8})
3
4# Measure current
5current = device.measure("DRAIN")
6
7# Check current voltage
8voltage = device.check("G1")
9
10# Sweep operations
11v_data, i_data = device.sweep_1d("G1", voltages, "DRAIN")
12v_data, i_data = device.sweep_2d("G1", v1, "G2", v2, "DRAIN")

Automatic Logging

Data is logged automatically when you use a RoutineRunner:

1@routine
2def my_routine(ctx, session=None):
3 device = ctx.resources.device
4
5 # Sweeps are automatically logged if session is provided
6 v, i = device.sweep_1d("G1", voltages, "DRAIN", session=session)
7
8 # Manual logging also available
9 if session:
10 session.log_measurement("gate_voltages", {"G1": v, "currents": i})
11
12 return {"voltages": v, "currents": i}

Result Chaining

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

1@routine
2def sweep_gate(ctx, gate):
3 device = ctx.resources.device
4 voltages = np.linspace(-2, 0, 100)
5 v_data, i_data = device.sweep_1d(gate, voltages.tolist(), "DRAIN")
6 return {"voltages": v_data, "currents": i_data}
7
8@routine
9def analyze_sweep(ctx):
10 # Get results from previous routine
11 data = ctx.results.get("sweep_gate")
12 currents = np.array(data["currents"])
13
14 return {
15 "max_current": float(np.max(np.abs(currents))),
16 "mean_current": float(np.mean(np.abs(currents)))
17 }

Nested Routines

Organize complex tune-up sequences hierarchically:

1routines:
2 - name: full_characterization
3 parameters:
4 threshold: 50e6
5 routines:
6 - name: leakage_test
7 parameters:
8 gate: G1
9 - name: accumulation_test
10 parameters:
11 gate: G2

Execute all nested routines with a single call:

1runner.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