Skip to content

ReadoutCalibration

from cascaqit import ReadoutCalibration

ReadoutCalibration

ReadoutCalibration(
    calibration_id: str,
    calibration_hash: str,
    logical_order: tuple[str, ...],
    matrices: tuple[ReadoutCalibrationMatrixIR, ...],
    source: str,
    metadata: Mapping[str, Any] = dict(),
    schema_version: str = READOUT_MITIGATION_SCHEMA_VERSION,
)

Store per-qubit readout response matrices and their provenance. Usually call from_probabilities() to derive a calibration ID and digest from known or estimated error rates. This does not measure a device or infer calibration from NoiseModel.

p01 is the probability of measuring 1 after preparing 0; p10 is the probability of measuring 0 after preparing 1. Matrix rows represent measured states and columns true states: A = [[1-p01, p10], [p01, 1-p10]], so observed probabilities satisfy q = A @ p. The per-qubit model assumes a tensor product of these responses and cannot represent arbitrary correlated readout errors.

logical_order must be nonempty and unique, with matrices covering every logical qubit in exactly that order. source records provenance, such as an independent calibration experiment or explicitly labeled simulation input; metadata can retain conditions and dates. Direct construction requires a matching calibration_hash and calibration_id equal to readout.calibration.<first 20 digest characters>. Prefer the factory to assembling them manually.

from cascaqit import ReadoutCalibration

calibration = ReadoutCalibration.from_probabilities(
    logical_order=("q0", "q1"), p01={"q0": 0.1, "q1": 0.2},
    p10=0.05, source="teaching_simulation",
)
matrix = calibration.matrix_for("q0")
assert matrix.response_matrix == ((0.9, 0.05), (0.1, 0.95))
assert calibration.total_condition_number >= 1.0
assert ReadoutCalibration.from_json(calibration.to_json()) == calibration

A serializable calibration need not be suitable for inversion. ReadoutMitigationConfig additionally rejects singular or poorly conditioned inputs.

from_probabilities

from_probabilities(
    *,
    logical_order: Sequence[str],
    p01: ProbabilityInput,
    p10: ProbabilityInput | None = None,
    source: str,
    metadata: Mapping[str, Any] | None = None,
) -> ReadoutCalibration

Return ReadoutCalibration from scalar error rates or per-qubit mappings. Probabilities must be finite and in [0, 1]; mapping keys must exactly cover logical_order. Omitting p10 uses the same symmetric error rates as p01. source is required and nonempty. Content, order, source and metadata contribute to the calibration digest.

matrix_for

matrix_for(target: str) -> ReadoutCalibrationMatrixIR

Return ReadoutCalibrationMatrixIR for a logical qubit, exposing response_matrix, determinant and condition_number. An unknown target raises KeyError.

condition_numbers

condition_numbers: Mapping[str, float]

Return a read-only mapping from logical qubits to their response matrices’ 2-norm condition numbers. Singular matrices can yield infinity; reading this property does not repair them.

total_condition_number

total_condition_number: float

Return the product of per-qubit condition numbers, equal to the tensor-product response’s 2-norm condition number without constructing the exponentially large matrix. The total can become much larger than any individual factor as qubits are added.

from_dict

from_dict(data: Mapping[str, Any]) -> ReadoutCalibration

Restore ReadoutCalibration from a dictionary. Restore matrices and provenance, then verify calibration_hash and calibration_id again. Editing saved fields while retaining the old digest raises. Missing required fields or invalid values can raise KeyError, TypeError or ValueError.

from_json

from_json(text: str) -> ReadoutCalibration

Parse a JSON object and call from_dict(), returning ReadoutCalibration. Invalid JSON raises a parsing error; a non-object root raises TypeError.

to_dict

to_dict() -> dict[str, Any]

Return a JSON-compatible dictionary, serializing nested objects and converting tuples to arrays. This stores the declaration, not an execution result.

to_json

to_json(*, indent: int | None = None) -> str

Return a JSON string without writing a file. indent=None uses compact formatting; supply an indentation width for readable output.

stable_hash

stable_hash() -> str

Return the SHA-256 hex digest of canonical JSON. Fields, identifiers and metadata can affect it. Use it to compare saved content, not to decide physical equivalence.