What it does
By default a circuit with measurements is read out in the computational (Z) basis, so you get counts of Z-basis bitstrings.readout_bases rotates the qubits into a different Pauli basis
just before readout, and still returns counts — one distribution per basis, per circuit.
This is different from passing observables. Observables give you expectation values, with the
distribution collapsed away. Readout bases keep the full distribution, so you can compute your
own estimators, look at correlations, or do basis-resolved tomography-style analysis.
Your circuits keep their own measurements, exactly as for a normal distribution job. Haiqu
strips the final measurements, inserts the basis rotation, and re-measures.
Basis strings and qubit order
A basis is one Pauli character per qubit, using Qiskit’s little-endian convention — the same oneobservables uses. The last character applies to qubit 0:
X, Y and Z are allowed. Use Z for a qubit you do not want rotated.
1
Build a circuit whose basis you can predict
Put qubit 0 into
|+⟩ and leave qubit 1 in |0⟩.2
Read qubit 0 in X and qubit 1 in Z
Because the last character is qubit 0, the basis is
"ZX" — not "XZ".3
Check the result
|+⟩ is an X eigenstate and |0⟩ is a Z eigenstate, so "ZX" is deterministic. Reading the
same state in "XZ" measures qubit 0 in Z and qubit 1 in X, which is uniformly random.Reading the results
Results gain one nesting level for the basis axis, in the order you supplied the bases:result_by_basis() saves you from indexing by position — it returns one dict per circuit, keyed
by the basis string:
result_by_basis() blocks until the job reaches a terminal state, like result(). Use
retrieve_status() first if you do not want to block.Cost
Each basis is a separate execution of the circuit, so a job costslen(readout_bases) * shots
shots in total. Three bases at 8000 shots is 24000 shots on the device.
What you do not pay twice for is compilation: all bases of a circuit share a single
transpilation and a single layout, because the rotation is applied after transpilation. The bases
are therefore directly comparable — they run on the same physical qubits with the same routing.
Combining with other features
Error mitigation
Error mitigation
use_mitigation=True works as usual. Readout error acts on the post-rotation bitstring, which
is exactly what the mitigation stack models, so no special handling is needed.Circuit packing
Circuit packing
use_packing=True is supported. Packing replicates one circuit across the device, and every
copy is read out in the same basis, so a basis string still has one character per circuit
qubit — not per packed qubit.Parameterized circuits
Parameterized circuits
Parameters combine freely with bases. The parameter axis is the inner one, so
result()[circuit][basis][parameter].Hybrid programs
Hybrid programs
In a hybrid program, add a The layer and the bases go together: supplying one without the other is rejected, because a
layer with no bases would silently return computational-basis counts.
ReadoutBasisLayer to mark where the rotation happens, and pass
the bases to flow(). Place the layer after the transpilation layer so all bases share one
transpilation.