Skip to content

API reference

Auto-generated reference for the qprogram_qblox package. Everything listed here is exported from the top-level module, so from qprogram_qblox import X works for every name on this page.

Program entry points

Two ways to get a QProgram with a typed .qblox namespace. Use the pre-combined class for a qblox-only setup, and the mixin when a platform combines several vendor extensions on one program class.

Neither is needed at runtime: importing qprogram_qblox registers the namespace on the base qprogram.QProgram, so program.qblox.acquire(...) resolves through the dynamic vendor lookup on any program. The typed surface is what editors and type checkers read.

QProgram

Bases: QbloxMixin, QProgram

QProgram pre-combined with QbloxMixin.

Identical to qprogram.QProgram but with IDE autocomplete for qp.qblox.*.

QbloxMixin

Mixin that adds a typed .qblox property to QProgram.

Compose it with qprogram.QProgram through multiple inheritance to get editor autocomplete for the Qblox operations. The property caches the namespace on the program, so repeated program.qblox accesses return the same object.

qblox property

qblox: QbloxNamespace

This program's typed Qblox namespace.

The first access builds a QbloxNamespace bound to the program and stores it under a private attribute; later accesses return that same instance. Both the load and the store go through object so they bypass the program's own attribute hooks: a cache miss has to surface as a plain AttributeError here rather than reach QProgram's vendor-registry __getattr__.

Vendor namespace

The builder surface. Each method appends one AST node to the program's current block, so the methods obey the same nesting as the core builder calls around them. acquire returns a MeasurementHandle; the rest return None.

QbloxNamespace

Bases: VendorNamespace

Qblox vendor namespace, reached as program.qblox.<operation>().

Attached to every QProgram instance as .qblox once the qprogram_qblox package is imported. Each method validates its arguments through the typed signature, constructs the matching operation, and appends it to the program's currently active block.

acquire

acquire(
    bus: str,
    weights: IQWaveform | str,
    fields: Iterable[MeasurementField] = (
        MeasurementField.IQ,
    ),
    *,
    name: str | None = None,
) -> MeasurementHandle

Append an Acquire operation.

The handle's name comes from the same per-bus counter core measure draws on, so two acquisitions on q[0].readout produce q0/readout/m0 and q0/readout/m1 whether or not a core measure also runs on that qubit. A raw-string bus carries no coordinates to build that prefix from, so it falls back to the bare m0, m1, ... counter shared by every raw-string measurement.

Parameters:

  • bus (str) –

    Readout bus to acquire on.

  • weights (IQWaveform | str) –

    Integration weights, either a concrete IQWaveform or a string alias.

  • fields (Iterable[MeasurementField], default: (IQ,) ) –

    Which measurement fields to produce, as an iterable of MeasurementField members. Default (MeasurementField.IQ,); RAW asks for the raw ADC trace.

  • name (str | None, default: None ) –

    Explicit measurement name. Auto-allocated when omitted.

Returns:

Raises:

  • ValidationError

    If name is empty, is not a string, or is already used by another measurement in the program, if fields names a field that is not registered, or if bus is a BusRef from another schema than the one attached to the program.

Source code in src/qprogram_qblox/namespace.py
def acquire(
    self,
    bus: str,
    weights: IQWaveform | str,
    fields: Iterable[MeasurementField] = (MeasurementField.IQ,),
    *,
    name: str | None = None,
) -> MeasurementHandle:
    """Append an [`Acquire`][qprogram_qblox.Acquire] operation.

    The handle's name comes from the same per-bus counter core
    [`measure`][qprogram.QProgram.measure] draws on, so two acquisitions on ``q[0].readout`` produce
    ``q0/readout/m0`` and ``q0/readout/m1`` whether or not a core ``measure`` also runs on that
    qubit. A raw-string bus carries no coordinates to build that prefix from, so it falls back
    to the bare ``m0``, ``m1``, ... counter shared by every raw-string measurement.

    Args:
        bus (str): Readout bus to acquire on.
        weights (IQWaveform | str): Integration weights, either a concrete
            [`IQWaveform`][qprogram.waveforms.IQWaveform] or a string alias.
        fields (Iterable[MeasurementField]): Which measurement fields to produce, as an iterable
            of [`MeasurementField`][qprogram.MeasurementField] members. Default ``(MeasurementField.IQ,)``;
            `RAW` asks for the raw ADC trace.
        name (str | None): Explicit measurement name. Auto-allocated when omitted.

    Returns:
        The [`MeasurementHandle`][qprogram.MeasurementHandle] this acquisition writes to, for retrieving the
        result and for referencing the outcome in a conditional.

    Raises:
        ValidationError: If ``name`` is empty, is not a string, or is already used by another
            measurement in the program, if ``fields`` names a field that is not registered, or
            if ``bus`` is a [`BusRef`][qprogram.BusRef] from another schema than the one attached
            to the program.
    """
    return self._append_measurement(
        Acquire,
        bus=bus,
        weights=weights,
        fields=fields,
        name=name,
    )

set_markers

set_markers(bus: str, mask: str) -> None

Append a SetMarkers operation.

Parameters:

  • bus (str) –

    Bus whose marker outputs to drive.

  • mask (str) –

    Four characters of 0 and 1, one per marker line, e.g. "0001".

Raises:

  • ValidationError

    If bus is a BusRef from another schema than the one attached to the program.

Source code in src/qprogram_qblox/namespace.py
def set_markers(self, bus: str, mask: str) -> None:
    """Append a [`SetMarkers`][qprogram_qblox.SetMarkers] operation.

    Args:
        bus (str): Bus whose marker outputs to drive.
        mask (str): Four characters of ``0`` and ``1``, one per marker line, e.g. ``"0001"``.

    Raises:
        ValidationError: If ``bus`` is a [`BusRef`][qprogram.BusRef] from another schema than the
            one attached to the program.
    """
    self._append(SetMarkers(bus=bus, mask=mask))

set_trigger

set_trigger(
    bus: str,
    duration: int,
    outputs: list[int] | int | None = None,
    position: str = "start",
) -> None

Append a SetTrigger operation.

Parameters:

  • bus (str) –

    Bus whose trigger outputs to arm.

  • duration (int) –

    Trigger-active duration in nanoseconds.

  • outputs (list[int] | int | None, default: None ) –

    Trigger output indices to arm, one index or a list of them. None leaves the selection to the platform.

  • position (str, default: 'start' ) –

    Point in the operation at which the trigger fires, either "start" or "end". Default "start".

Raises:

  • ValidationError

    If bus is a BusRef from another schema than the one attached to the program.

Source code in src/qprogram_qblox/namespace.py
def set_trigger(
    self,
    bus: str,
    duration: int,
    outputs: list[int] | int | None = None,
    position: str = "start",
) -> None:
    """Append a [`SetTrigger`][qprogram_qblox.SetTrigger] operation.

    Args:
        bus (str): Bus whose trigger outputs to arm.
        duration (int): Trigger-active duration in nanoseconds.
        outputs (list[int] | int | None): Trigger output indices to arm, one index or a list of
            them. ``None`` leaves the selection to the platform.
        position (str): Point in the operation at which the trigger fires, either ``"start"`` or
            ``"end"``. Default ``"start"``.

    Raises:
        ValidationError: If ``bus`` is a [`BusRef`][qprogram.BusRef] from another schema than the
            one attached to the program.
    """
    self._append(SetTrigger(bus=bus, duration=duration, outputs=outputs, position=position))

wait_trigger

wait_trigger(
    bus: str, duration: int, port: int | None = None
) -> None

Append a WaitTrigger operation.

Parameters:

  • bus (str) –

    Bus whose sequencer waits.

  • duration (int) –

    Timeout in nanoseconds, after which the sequencer stops waiting.

  • port (int | None, default: None ) –

    Trigger input port to listen on. None leaves the choice to the platform.

Raises:

  • ValidationError

    If bus is a BusRef from another schema than the one attached to the program.

Source code in src/qprogram_qblox/namespace.py
def wait_trigger(self, bus: str, duration: int, port: int | None = None) -> None:
    """Append a [`WaitTrigger`][qprogram_qblox.WaitTrigger] operation.

    Args:
        bus (str): Bus whose sequencer waits.
        duration (int): Timeout in nanoseconds, after which the sequencer stops waiting.
        port (int | None): Trigger input port to listen on. ``None`` leaves the choice to the
            platform.

    Raises:
        ValidationError: If ``bus`` is a [`BusRef`][qprogram.BusRef] from another schema than the
            one attached to the program.
    """
    self._append(WaitTrigger(bus=bus, duration=duration, port=port))

set_acquisition_threshold

set_acquisition_threshold(
    bus: str, value: float | Expression
) -> None

Append a SetAcquisitionThreshold operation.

Host-side-only: the platform realizes it as a slow-control parameter write at execution time, not as a sequencer instruction. A vendor namespace can expose operations whose effect is entirely off-sequencer, and the platform decides at execution time how to realize each one.

Parameters:

  • bus (str) –

    Readout bus whose discrimination threshold to set.

  • value (float | Expression) –

    Threshold, in volts after integration. Accepts an Expression so an enclosing loop can sweep it.

Raises:

  • ValidationError

    If bus is a BusRef from another schema than the one attached to the program.

Source code in src/qprogram_qblox/namespace.py
def set_acquisition_threshold(self, bus: str, value: float | Expression) -> None:
    """Append a [`SetAcquisitionThreshold`][qprogram_qblox.SetAcquisitionThreshold] operation.

    Host-side-only: the platform realizes it as a slow-control parameter write at execution
    time, not as a sequencer instruction. A vendor namespace can expose operations whose effect
    is entirely off-sequencer, and the platform decides at execution time how to realize each
    one.

    Args:
        bus (str): Readout bus whose discrimination threshold to set.
        value (float | Expression): Threshold, in volts after integration. Accepts an
            [`Expression`][qprogram.Expression] so an enclosing loop can sweep it.

    Raises:
        ValidationError: If ``bus`` is a [`BusRef`][qprogram.BusRef] from another schema than the
            one attached to the program.
    """
    self._append(SetAcquisitionThreshold(bus=bus, value=value))

set_acquisition_rotation

set_acquisition_rotation(
    bus: str, angle: float | Expression
) -> None

Append a SetAcquisitionRotation operation.

The companion to set_acquisition_threshold: the integrated IQ point is rotated by angle before the comparison against the threshold, so the two populations separate along one axis. Host-side-only as well, a parameter write rather than a sequencer instruction.

Parameters:

  • bus (str) –

    Readout bus whose acquisition rotation to set.

  • angle (float | Expression) –

    Rotation angle in radians, the unit convention of core set_phase. Accepts an Expression so an enclosing loop can sweep it, which is how it is normally calibrated.

Raises:

  • ValidationError

    If bus is a BusRef from another schema than the one attached to the program.

Source code in src/qprogram_qblox/namespace.py
def set_acquisition_rotation(self, bus: str, angle: float | Expression) -> None:
    """Append a [`SetAcquisitionRotation`][qprogram_qblox.SetAcquisitionRotation] operation.

    The companion to `set_acquisition_threshold`: the integrated IQ point is rotated by
    ``angle`` before the comparison against the threshold, so the two populations separate along
    one axis. Host-side-only as well, a parameter write rather than a sequencer instruction.

    Args:
        bus (str): Readout bus whose acquisition rotation to set.
        angle (float | Expression): Rotation angle in radians, the unit convention of core
            [`set_phase`][qprogram.QProgram.set_phase]. Accepts an [`Expression`][qprogram.Expression] so an
            enclosing loop can sweep it, which is how it is normally calibrated.

    Raises:
        ValidationError: If ``bus`` is a [`BusRef`][qprogram.BusRef] from another schema than the
            one attached to the program.
    """
    self._append(SetAcquisitionRotation(bus=bus, angle=angle))

Operations

The AST nodes the namespace methods append. They are structural value objects: two nodes with equal attributes compare equal, which is what makes a program survive a .qp round trip unchanged. Each one reports the capability tokens a platform has to declare in required_capabilities.

Construct them directly for tests and program transformations; build programs through the namespace.

Acquire

Acquire(
    bus: str,
    weights: IQWaveform | str,
    handle: MeasurementHandle,
    fields: Iterable[MeasurementField] = (
        MeasurementField.IQ,
    ),
)

Bases: MeasurementOperation

An acquisition on a readout bus, with no readout pulse of its own.

Where core measure plays a readout pulse and integrates the response, acquire only integrates, which is what a program wants when the pulse is driven separately. It is a MeasurementOperation like measure, so it takes part in the program's per-bus measurement-name counter: an acquire after a measure on the same qubit picks up the next free name on that qubit.

Parameters:

Raises:

  • ValidationError

    If fields is a bare string, is not iterable, requests no field at all, or names a field that is not registered.

Source code in src/qprogram_qblox/operations.py
def __init__(
    self,
    bus: str,
    weights: IQWaveform | str,
    handle: MeasurementHandle,
    fields: Iterable[MeasurementField] = (MeasurementField.IQ,),
) -> None:
    self.bus = bus
    self.weights = weights
    self.handle = handle
    self.fields: tuple[str, ...] = normalize_fields(fields)

required_capabilities

required_capabilities() -> set[str]

Return vendor.qblox.acquire plus the weights and requested-field tokens.

waveform.iq is always required, since an acquisition integrates an IQ pair. String weights contribute waveform.alias; concrete weights contribute the per-class token from qprogram.protocol.waveform_token when their class is registered. The measure.fields.<name> tokens come from required_capabilities.

Source code in src/qprogram_qblox/operations.py
def required_capabilities(self) -> set[str]:
    """Return ``vendor.qblox.acquire`` plus the weights and requested-field tokens.

    ``waveform.iq`` is always required, since an acquisition integrates an IQ pair. String
    weights contribute ``waveform.alias``; concrete weights contribute the per-class token from
    [`qprogram.protocol.waveform_token`][] when their class is registered. The
    ``measure.fields.<name>`` tokens come from
    [`required_capabilities`][qprogram.operations.operation.MeasurementOperation.required_capabilities].
    """
    from qprogram.protocol import waveform_token  # ruff: ignore[import-outside-top-level]

    caps = super().required_capabilities() | {"vendor.qblox.acquire", "waveform.iq"}
    if isinstance(self.weights, str):
        caps.add("waveform.alias")
    else:
        tok = waveform_token(self.weights)
        if tok is not None:
            caps.add(tok)
    return caps

SetMarkers

SetMarkers(bus: str, mask: str)

Bases: Operation

A new 4-bit marker output mask on a qblox sequencer.

Parameters:

  • bus (str) –

    Bus whose marker outputs to drive.

  • mask (str) –

    Four characters of 0 and 1, one per marker line. "0001" enables marker 1.

Source code in src/qprogram_qblox/operations.py
def __init__(self, bus: str, mask: str) -> None:
    self.bus = bus
    self.mask = mask

required_capabilities

required_capabilities() -> set[str]

Return vendor.qblox.set_markers, the operation's identity token.

Source code in src/qprogram_qblox/operations.py
def required_capabilities(self) -> set[str]:
    """Return ``vendor.qblox.set_markers``, the operation's identity token."""
    return {"vendor.qblox.set_markers"}

SetTrigger

SetTrigger(
    bus: str,
    duration: int,
    outputs: list[int] | int | None = None,
    position: str = "start",
)

Bases: Operation

A trigger output configuration on a qblox sequencer.

Parameters:

  • bus (str) –

    Bus whose trigger outputs to arm.

  • duration (int) –

    Trigger-active duration in nanoseconds.

  • outputs (list[int] | int | None, default: None ) –

    Trigger output indices to arm, one index or a list of them. None leaves the selection to the platform.

  • position (str, default: 'start' ) –

    Point in the operation at which the trigger fires, either "start" or "end". Default "start".

Source code in src/qprogram_qblox/operations.py
def __init__(
    self,
    bus: str,
    duration: int,
    outputs: list[int] | int | None = None,
    position: str = "start",
) -> None:
    self.bus = bus
    self.duration = duration
    self.outputs = outputs
    self.position = position

required_capabilities

required_capabilities() -> set[str]

Return vendor.qblox.set_trigger, the operation's identity token.

Source code in src/qprogram_qblox/operations.py
def required_capabilities(self) -> set[str]:
    """Return ``vendor.qblox.set_trigger``, the operation's identity token."""
    return {"vendor.qblox.set_trigger"}

WaitTrigger

WaitTrigger(
    bus: str, duration: int, port: int | None = None
)

Bases: Operation

A wait for an external trigger on a qblox sequencer.

Parameters:

  • bus (str) –

    Bus whose sequencer waits.

  • duration (int) –

    Timeout in nanoseconds, after which the sequencer stops waiting.

  • port (int | None, default: None ) –

    Trigger input port to listen on. None leaves the choice to the platform.

Source code in src/qprogram_qblox/operations.py
def __init__(self, bus: str, duration: int, port: int | None = None) -> None:
    self.bus = bus
    self.duration = duration
    self.port = port

required_capabilities

required_capabilities() -> set[str]

Return vendor.qblox.wait_trigger, the operation's identity token.

Source code in src/qprogram_qblox/operations.py
def required_capabilities(self) -> set[str]:
    """Return ``vendor.qblox.wait_trigger``, the operation's identity token."""
    return {"vendor.qblox.wait_trigger"}

SetAcquisitionThreshold

SetAcquisitionThreshold(
    bus: str, value: float | Expression
)

Bases: Operation

A new qubit-state discrimination threshold on a readout bus.

A host-side-only vendor operation: the qblox platform realizes it as a slow-control parameter write at execution time and emits no sequencer instruction. Vendor operations do not have to map onto sequencer instructions at all: an extension may expose any operation whose execution its platform knows how to interpret, be that a sequencer command, a parameter write, or a multi-step orchestration.

Parameters:

  • bus (str) –

    Readout bus whose discrimination threshold to set.

  • value (float | Expression) –

    Threshold, in volts after integration. Accepts an Expression for sweeps.

Source code in src/qprogram_qblox/operations.py
def __init__(self, bus: str, value: float | Expression) -> None:
    self.bus = bus
    self.value = value

required_capabilities

required_capabilities() -> set[str]

Return vendor.qblox.set_acquisition_threshold plus the value expression tokens.

Source code in src/qprogram_qblox/operations.py
def required_capabilities(self) -> set[str]:
    """Return ``vendor.qblox.set_acquisition_threshold`` plus the ``value`` expression tokens."""
    from qprogram.protocol import expression_tokens  # ruff: ignore[import-outside-top-level]

    return {"vendor.qblox.set_acquisition_threshold"} | expression_tokens(self.value)

SetAcquisitionRotation

SetAcquisitionRotation(bus: str, angle: float | Expression)

Bases: Operation

A new acquisition rotation angle on a readout bus.

The other half of qblox's thresholded acquisition, and the sibling of SetAcquisitionThreshold: the integrated IQ point is rotated by this angle so that the ground and excited populations separate along a single axis, and only then compared against the threshold. Setting one without the other is legal, since they are independent parameters, but a calibrated discrimination usually writes both.

Host-side-only like the threshold: a slow-control parameter write at execution time, not a sequencer instruction.

Parameters:

  • bus (str) –

    Readout bus whose acquisition rotation to set.

  • angle (float | Expression) –

    Rotation angle in radians, the unit convention of the core phase operations (SetPhase). Accepts an Expression for sweeps, which is the usual way to calibrate it. Values outside [0, 2π) are the platform's to normalize or reject, not this node's: a swept angle has no literal value to check at build time.

Source code in src/qprogram_qblox/operations.py
def __init__(self, bus: str, angle: float | Expression) -> None:
    self.bus = bus
    self.angle = angle

required_capabilities

required_capabilities() -> set[str]

Return vendor.qblox.set_acquisition_rotation plus the angle expression tokens.

Source code in src/qprogram_qblox/operations.py
def required_capabilities(self) -> set[str]:
    """Return ``vendor.qblox.set_acquisition_rotation`` plus the ``angle`` expression tokens."""
    from qprogram.protocol import expression_tokens  # ruff: ignore[import-outside-top-level]

    return {"vendor.qblox.set_acquisition_rotation"} | expression_tokens(self.angle)

Capability profile

The bundle a platform puts in the bus slots of every qblox-driven bus: the tokens those buses support, the numeric limits that go with them, and the predicates that flag combinations the tokens alone would let through. See Capabilities and profiles for how a platform assembles it into a PlatformCapabilities.

QBLOX_DEFAULT_V1 module-attribute

QBLOX_DEFAULT_V1 = Profile(
    name="qblox-default-v1",
    version=(0, 1, 0),
    extends=None,
    capabilities=_BUS_OPS | _WAVEFORMS | _FIELDS | _VENDOR,
    limits={"min_wait_duration_ns": 4},
    predicates=(
        _reject_arbitrary_sweep_at_wait_duration,
        _drag_sigma_in_loop_is_host_only,
    ),
    vendor_versions={"qblox": (0, 1, 0)},
)

The default Qblox bus-level capability profile.

Holds every token a qblox-driven bus accepts (_BUS_OPS, _WAVEFORMS, _FIELDS and _VENDOR), the min_wait_duration_ns floor of the wait instruction, and the two predicates above. It carries no block.*, sweep.* or expr.* token: those route to the platform slot, which a qblox platform fills from qprogram-base-v1.

Reach it by name with CompilerCapabilities.from_profile("qblox-default-v1", limit_overrides=...), or extend it with a profile of your own that declares extends="qblox-default-v1" and lists only what differs.