Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions qiskit_experiments/framework/composite/composite_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"""

from typing import List, Dict
import numpy as np
from qiskit.result import marginal_counts
from qiskit_experiments.framework import BaseAnalysis, ExperimentData, AnalysisResultData
from qiskit_experiments.database_service.device_component import Qubit
Expand Down Expand Up @@ -159,6 +160,13 @@ def _marginalize_data(self, composite_data: List[Dict]) -> List[Dict]:
sub_data["counts"] = marginal_counts(datum["counts"], composite_clbits[i])
else:
sub_data["counts"] = datum["counts"]
if "memory" in datum:
if composite_clbits is not None:
sub_data["memory"] = (
np.array(datum["memory"])[composite_clbits[i]]
).tolist()
else:
sub_data["memory"] = datum["memory"]
marginalized_data[index].append(sub_data)

# Sort by index
Expand Down
2 changes: 2 additions & 0 deletions qiskit_experiments/library/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
~characterization.Rabi
~characterization.EFRabi
~characterization.RamseyXY
~characterization.ReadoutAngle


.. _calibration:
Expand Down Expand Up @@ -135,6 +136,7 @@ class instance to manage parameters and pulse schedules.
FineXAmplitude,
FineSXAmplitude,
RamseyXY,
ReadoutAngle,
)
from .randomized_benchmarking import StandardRB, InterleavedRB
from .tomography import StateTomography, ProcessTomography
Expand Down
4 changes: 4 additions & 0 deletions qiskit_experiments/library/characterization/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
FineSXAmplitude
RamseyXY
RoughDrag
ReadoutAngle
FineDrag
FineXDrag
FineSXDrag
Expand All @@ -57,6 +58,7 @@
analysis.FineAmplitudeAnalysis
analysis.FineXAmplitudeAnalysis
analysis.RamseyXYAnalysis
analysis.ReadoutAngleAnalysis
"""

from .analysis import (
Expand All @@ -69,6 +71,7 @@
T2RamseyAnalysis,
T1Analysis,
CrossResonanceHamiltonianAnalysis,
ReadoutAngleAnalysis,
)

from .t1 import T1
Expand All @@ -81,4 +84,5 @@
from .fine_amplitude import FineAmplitude, FineXAmplitude, FineSXAmplitude
from .ramsey_xy import RamseyXY
from .drag import RoughDrag
from .readout_angle import ReadoutAngle
from .fine_drag import FineDrag, FineXDrag, FineSXDrag
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@
from .t2ramsey_analysis import T2RamseyAnalysis
from .t1_analysis import T1Analysis
from .cr_hamiltonian_analysis import CrossResonanceHamiltonianAnalysis
from .readout_angle_analysis import ReadoutAngleAnalysis
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2021.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
"""
Readout Angle Analysis class.
"""

import numpy as np

from qiskit_experiments.framework import BaseAnalysis, AnalysisResultData


class ReadoutAngleAnalysis(BaseAnalysis):
"""
A class to analyze readout angle experiments
"""

# pylint: disable=unused-argument
def _run_analysis(self, experiment_data, **kwargs):
angles = []
for i in range(2):
center = complex(*experiment_data.data(i)["memory"][0])
angles.append(np.angle(center))

angle = (angles[0] + angles[1]) / 2
if (np.abs(angles[0] - angles[1])) % (2 * np.pi) > np.pi:
angle += np.pi

analysis_results = [
AnalysisResultData(
name="ReadoutAngle",
value=angle,
extra={"angle_ground": angles[0], "angle_excited": angles[1]},
)
]

return analysis_results, []
101 changes: 101 additions & 0 deletions qiskit_experiments/library/characterization/readout_angle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2021.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
"""
Readout Angle Experiment class.
"""

from typing import List, Optional

from qiskit.circuit import QuantumCircuit
from qiskit.qobj.utils import MeasLevel
from qiskit.providers.backend import Backend

from qiskit_experiments.framework import BaseExperiment, Options
from qiskit_experiments.library.characterization.analysis.readout_angle_analysis import (
ReadoutAngleAnalysis,
)


class ReadoutAngle(BaseExperiment):
r"""
Readout angle experiment class

# section: overview

Design and analyze experiments for estimating readout angle of the qubit.
The readout angle is the average of two angles: the angle of the IQ
cluster center of the ground state, and the angle of the IQ cluster center
of the excited state.

Each experiment consists of the following steps:

1. Circuits generation: two circuits, the first circuit measures the qubit
in the ground state, the second circuit sets the qubit in the excited state
and measures it. Measurements are in level 1 (kerneled).

2. Backend execution: actually running the circuits on the device
(or a simulator that supports level 1 measurements). The backend returns
the cluster centers of the ground and excited states.

3. Analysis of results: return the average of the angles of the two centers.

"""

__analysis_class__ = ReadoutAngleAnalysis

@classmethod
def _default_run_options(cls) -> Options:
"""Default run options."""
options = super()._default_run_options()

options.meas_level = MeasLevel.KERNELED
options.meas_return = "avg"

return options

def __init__(
self,
qubit: int,
backend: Optional[Backend] = None,
):
"""
Initialize the readout angle experiment class

Args:
qubit: the qubit whose readout angle is to be estimated
backend: Optional, the backend to run the experiment on.
"""
# Initialize base experiment
super().__init__([qubit], backend=backend)

def circuits(self) -> List[QuantumCircuit]:
"""
Return a list of experiment circuits

Returns:
The experiment circuits
"""
circ0 = QuantumCircuit(1, 1)
circ0.measure(0, 0)

circ1 = QuantumCircuit(1, 1)
circ1.x(0)
circ1.measure(0, 0)

for i, circ in enumerate([circ0, circ1]):
circ.metadata = {
"experiment_type": self._type,
"qubit": self.physical_qubits[0],
"xval": i,
}

return [circ0, circ1]
4 changes: 4 additions & 0 deletions releasenotes/notes/readout-angle-4d3be1d584ba5ac1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
features:
- |
A new readout angle experiment. The experiment computes the average of the angles of the IQ clusters of the ground and excited states.
51 changes: 51 additions & 0 deletions test/test_readout_angle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2021.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
"""
Test readout angle experiment
"""

import numpy as np

from qiskit.test import QiskitTestCase
from qiskit_experiments.library import ReadoutAngle
from qiskit_experiments.test.mock_iq_backend import MockIQBackend


class ReadoutAngleBackend(MockIQBackend):
"""
Mock IQ backend tailored to the readout angle test
"""

def _compute_probability(self, circuit):
return 1 - circuit.metadata["xval"]


class TestReadoutAngle(QiskitTestCase):
"""
Test the readout angle experiment
"""

def test_readout_angle_end2end(self):
"""
Test readout angle experiment using a simulator.
"""
backend = ReadoutAngleBackend(iq_cluster_centers=(5.0, 5.0, -3.0, 3.0))
exp = ReadoutAngle(0)
expdata = exp.run(backend, shots=100000).block_for_results()
res = expdata.analysis_results(0)
self.assertAlmostEqual(res.value % (2 * np.pi), np.pi / 2, places=2)

backend = ReadoutAngleBackend(iq_cluster_centers=(5.0, 5.0, 0, -3.0))
exp = ReadoutAngle(0)
expdata = exp.run(backend, shots=100000).block_for_results()
res = expdata.analysis_results(0)
self.assertAlmostEqual(res.value % (2 * np.pi), 15 * np.pi / 8, places=2)