Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

from cirq import circuits, ops, work
from cirq.contrib.shuffle_circuits import run_shuffled_with_readout_benchmarking
from cirq.experiments.single_qubit_readout_calibration import SingleQubitReadoutCalibrationResult
from cirq.experiments.readout_confusion_matrix import TensoredConfusionMatrices

if TYPE_CHECKING:
Expand Down Expand Up @@ -217,6 +218,31 @@ def _normalize_input_paulis(
return cast(dict[circuits.FrozenCircuit, list[list[ops.PauliString]]], circuits_to_pauli)


def _extract_readout_qubits(pauli_strings: list[ops.PauliString]) -> list[ops.Qid]:
"""Extracts unique qubits from a list of QWC Pauli strings."""
qubits = set()
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
qubits = set()
return sorted(set(q for ps in pauli_strings for q in op.qubits))

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

for pauli_str in pauli_strings:
for qubit in pauli_str.qubits:
qubits.add(qubit)
return sorted(qubits)


def _build_pauli_string_calibration_result(
qubits_to_error: SingleQubitReadoutCalibrationResult, readout_qubits: list[ops.Qid]
) -> SingleQubitReadoutCalibrationResult:
"""Builds a calibration result for the specific readout qubits."""
return SingleQubitReadoutCalibrationResult(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this should be a SingleQubitReadoutCalibrationResult method

class SingleQubitReadoutCalibrationResult:
    ...


    def readout_result_for_qubits(self, qubits) -> 'SingleQubitReadoutCalibrationResult':
         ...

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure! Moved the method to under SingleQubitReadoutCalibrationResult

zero_state_errors={
qubit: qubits_to_error.zero_state_errors[qubit] for qubit in readout_qubits
},
one_state_errors={
qubit: qubits_to_error.one_state_errors[qubit] for qubit in readout_qubits
},
timestamp=qubits_to_error.timestamp,
repetitions=qubits_to_error.repetitions,
)


def _pauli_strings_to_basis_change_ops(
pauli_strings: list[ops.PauliString], qid_list: list[ops.Qid]
):
Expand Down Expand Up @@ -315,13 +341,25 @@ def _process_pauli_measurement_results(
for pauli_group_index, circuit_result in enumerate(circuit_results):
measurement_results = circuit_result.measurements["m"]
pauli_strs = pauli_string_groups[pauli_group_index]
pauli_readout_qubits = _extract_readout_qubits(pauli_strs)

calibration_result = (
calibration_results[tuple(pauli_readout_qubits)]
if disable_readout_mitigation is False
else None
)

for pauli_str in pauli_strs:
qubits_sorted = sorted(pauli_str.qubits)
qubit_indices = [qubits.index(q) for q in qubits_sorted]

pauli_str_calibration_result = (
_build_pauli_string_calibration_result(calibration_result, qubits_sorted)
if disable_readout_mitigation is False
else None
)
confusion_matrices = (
_build_many_one_qubits_confusion_matrix(calibration_results[tuple(qubits_sorted)])
_build_many_one_qubits_confusion_matrix(pauli_str_calibration_result)
if disable_readout_mitigation is False
else _build_many_one_qubits_empty_confusion_matrix(len(qubits_sorted))
)
Expand Down Expand Up @@ -356,11 +394,7 @@ def _process_pauli_measurement_results(
mitigated_stddev=d_m_with_coefficient,
unmitigated_expectation=unmitigated_value_with_coefficient,
unmitigated_stddev=d_unmit_with_coefficient,
calibration_result=(
calibration_results[tuple(qubits_sorted)]
if disable_readout_mitigation is False
else None
),
calibration_result=(pauli_str_calibration_result),
)
)

Expand Down Expand Up @@ -428,8 +462,7 @@ def measure_pauli_strings(
unique_qubit_tuples = set()
for pauli_string_groups in normalized_circuits_to_pauli.values():
for pauli_strings in pauli_string_groups:
for pauli_string in pauli_strings:
unique_qubit_tuples.add(tuple(sorted(pauli_string.qubits)))
unique_qubit_tuples.add(tuple(_extract_readout_qubits(pauli_strings)))
# qubits_list is a list of qubit tuples
qubits_list = sorted(unique_qubit_tuples)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

import cirq
from cirq.contrib.paulistring import measure_pauli_strings
from cirq.experiments import SingleQubitReadoutCalibrationResult
from cirq.experiments.single_qubit_readout_calibration import SingleQubitReadoutCalibrationResult
from cirq.experiments.single_qubit_readout_calibration_test import NoisySingleQubitReadoutSampler


Expand Down
Loading