#
# Copyright 2021 Keysight Technologies Inc.
#
"""
Readout Calibration (RCAL)
==========================
"""
#%%
# This example illustrates how to generate readout calibration (:tqdoc:`RCAL`\) circuits
# and use them to correct readout errors in other circuits. While this example uses a
# :doc:`simulator<../../guides/run/simulator>` to execute the circuits, the same
# procedure can be followed for hardware applications.
#
# The code below generates RCAL circuits for qubits ``0`` and ``1``, populates their
# results using a simulator with readout error, and displays their confusion matrices.
#%%
import trueq as tq
# generate RCAL circuits to measure the readout errors on qubits [0, 1]
circuits = tq.make_rcal([0, 1])
# initialize a simulator with a 20% readout error on every qubit
sim = tq.Simulator().add_readout_error(0.2)
# run the circuits on the simulator to populate their results
sim.run(circuits, n_shots=1000)
# display the confusion matrices
circuits.fit()
#%%
# Automatic Correction
# --------------------
#
# If your circuit collection contains RCAL circuits, then that information will be
# used automatically to apply readout correction to your circuits when you call
# :py:meth:`~trueq.CircuitCollection.fit` or :py:meth:`~trueq.CircuitCollection.plot`\.
# The code below illustrates this for :tqdoc:`SRB` circuits executed on a noisy
# simulator with readout error. It also shows how you can view the results with and
# without readout correction being applied.
# generate RCAL circuits to measure the readout errors on qubits [0, 1, 2]
circuits = tq.make_rcal([0, 1, 2])
# generate SRB circuits to simultaneously characterize a single qubit [0] and
# a pair of qubits [1, 2] with 30 circuits for each random cycle in [4, 32, 64]
circuits.append(tq.make_srb([[0], [1, 2]], [4, 32, 64], 30))
# initialize a noisy simulator with a large 10% readout error
sim = tq.Simulator().add_stochastic_pauli(px=0.01).add_readout_error(0.1)
# RCAL generally needs more shots than the other protocols because it is estimating
# an absolute value rather than a decay over randomizations, thus in this simulation
# we use different amounts of shots for SRB and RCAL to populate their results
sim.run(circuits.subset(protocol=["RCAL"]), n_shots=50)
sim.run(circuits.subset(protocol="RCAL"), n_shots=1000)
# plot the exponential decay with readout correction,
# where each expectation value (dot) has been compensated
circuits.plot.raw()
#%%
# To avoid performing readout correction during analysis, we can remove all RCAL
# circuits from the collection before calling :py:meth:`~trueq.CircuitCollection.plot`\.
# Notice that the y-intercept is lower than in the plot above.
# plot the exponential decay without readout correction
circuits.subset(protocol="SRB").plot.raw()