Qibosoq - Qibolab - Qibocal¶
In these examples, we will see how to perform some basic qubit calibration experiments using the three levels of abstraction provided by the Qibo ecosystem:
Qibosoq: basic pulse level and direct RFSoC connection
Qibolab: higher pulse level and integrated control of the complete setup
Qibocal: experiment level
With these three packages, we perform the exact same experiments, showcasing how to implement the same program with different complexity levels. In particular, Qibosoq is the lowest-level language and requires explicit definition of all the pulses, sweepers and experiment parameters. Qibolab is slightly more intuitive, but still requires to define the entire experiment. Qibocal, implements a set of these experiments, and gives the user chance to compose them.
For these experiments we are considering to not yet have the final calibration parameters, but for the sake of clarity, the following parameters are final ones of the calibration:
Lines:
Drive line DAC: 0
Readout line DAC: 1
Feedback line ADC: 0
Qubit parameters:
Qubit frequency: 5_755_000_000 Hz
Pi-pulse duration: 43 ns
Pi-pulse amplitude: 0.02
Pi-pulse shape: Gaussian(3)
Resonator parameters:
Resonator frequency: 6_953_000_000 Hz
Measurement duration: 1000 ns
Measurement amplitude: 0.1
Measurement shape: Rectangular()
Experiments parameters:
Relaxation time: 50_000 ns
Warning
For this examples we used qibolab version 0.1.0 and qibocal version 0.0.4. While Qibosoq is compatible with newer versions, some part of the code could be different. Make sure to use the correct versions.
Preparation pre-experiments¶
For all the control modes, we are supposing to have a Qibosoq server running on board.
Qibosoq¶
For control through Qibosoq, no particular preparation is required.
In any case, for every experiment, we have to start the script with:
import json
import socket
import numpy as np
from qibosoq.client import execute
from qibosoq.components.base import (
Qubit,
OperationCode,
Config
)
HOST = "192.168.0.200"
PORT = 6000
Qibolab¶
For Qibolab, we first need to setup the platform. This includes writing the my_platform.py
and the my_platform.yml
files.
For more detailed instructions to write these experiments, please refer to the Qibolab documentation .
In this section we will provide a base platform that includes only a RFSoC4x2 board (with o additional instruments) that controls a single qubit.
The path of these two files will have to be exported in an environment variable with:
export QIBOLAB_PLATFORMS=<path-to-platform-files>
File my_platform.py
:
import pathlib
from qibolab.channels import Channel, ChannelMap
from qibolab.instruments.rfsoc import RFSoC
from qibolab.platform import Platform
from qibolab.serialize import load_qubits, load_runcard, load_settings
NAME = "my_platform" # name of the platform
ADDRESS = "192.168.0.200" # ip address of the RFSoC
PORT = 6000 # port of the controller
# path to runcard file with calibration parameter
RUNCARD = pathlib.Path(__file__).parent / "my_platform.yml"
def create(runcard_path=RUNCARD):
# Instantiate controller instruments
controller = RFSoC(NAME, ADDRESS, PORT)
# Create channel objects and port assignment
channels = ChannelMap()
channels |= Channel("readout", port=controller[1]) # QICK DAC number
channels |= Channel("feedback", port=controller[0]) # QICK ADC number
channels |= Channel("drive", port=controller[0]) # QICK DAC number
# create qubit objects
runcard = load_runcard(runcard_path)
qubits, pairs = load_qubits(runcard)
# assign channels to qubits
qubits[0].readout = channels["readout"]
qubits[0].feedback = channels["feedback"]
qubits[0].drive = channels["drive"]
instruments = {controller.name: controller}
settings = load_settings(runcard)
return Platform(NAME, qubits, pairs, instruments, settings, resonator_type="3D")
File my_platform.yml
(note that this file is just a starting one, with the parameters not completely calibrated):
nqubits: 1
qubits: [0]
topology: []
settings: {nshots: 1024, relaxation_time: 50_000}
native_gates:
single_qubit:
0:
RX: # pi-pulse for X gate
duration: 40
amplitude: 0.1
frequency: 5_700_000_000
shape: Gaussian(3)
type: qd
start: 0
phase: 0
MZ: # measurement pulse
duration: 1000
amplitude: 0.1
frequency: 7_000_000_000
shape: Rectangular()
type: ro
start: 0
phase: 0
two_qubits: {}
characterization:
single_qubit:
0:
readout_frequency: 7000000000
drive_frequency: 5700000000
anharmonicity: 0
Ec: 0
Ej: 0
g: 0
T1: 0.0
T2: 0.0
threshold: 0.0
iq_angle: 0.0
mean_gnd_states: [0.0, 0.0]
mean_exc_states: [0.0, 0.0]
Every experiment, will then start with:
from qibolab import create_platform
from qibolab import AcquisitionType, AveragingMode, ExecutionParameters
from qibolab.pulses import (
DrivePulse,
ReadoutPulse,
PulseSequence,
)
# Define platform and load specific runcard
platform = create_platform("my_platform")
Qibocal¶
For Qibocal, we first need to setup Qibolab as presented in the last section.
Note then that, for Qibocal “programs” we need a new file actions.yml
that will contain all the parameters required for the experiments: this file will be presented for all the different experiments.
For Qibosoq and Qibolab “programs”, a standard Python script or a Jupyter Notebook will suffice.
Time Of Flight¶
In the time-of-flight experiment, our objective is to measure the time it takes for a pulse to travel from the RFSoC to the qubit through the readout line and then return to the ADC via the feedback line.
During the experiment, a single pulse is transmitted through the readout line. We initiate data acquisition immediately, without any delay, in order to precisely determine the delay required for measurements. After this experiment, we will always start acquiring after the delay found, so that the acquisition corresponds to the pulse.
Qibosoq¶
For Qibosoq, we need to define the pulses explicitly at the beginning of each experiment. Along with them, other components are required by the server: in particular the operation_code, the configuration object, qubits and then, eventually, sweepers.
import json
import socket
import numpy as np
from qibosoq.client import execute
from qibosoq.components.base import (
Qubit,
OperationCode,
Config
)
from qibosoq.components.pulses import Rectangular
HOST = "192.168.0.200"
PORT = 6000
pulse = Rectangular(
frequency = 7000, #MHz
amplitude = 0.5,
relative_phase = 0,
start_delay = 0,
duration = 1,
name = "readout_pulse",
type = "readout",
dac = 1,
adc = 0
)
sequence = [pulse]
config = Config(
relaxation_time=50, # us
ro_time_of_flight=0,
reps=1,
soft_avgs=1000,
average=True
)
qubit = Qubit()
server_commands = {
"operation_code": OperationCode.EXECUTE_PULSE_SEQUENCE_RAW,
"cfg": config,
"sequence": sequence,
"qubits": [qubit],
}
i, q = execute(server_commands, HOST, PORT)
import matplotlib.pyplot as plt
plt.plot(np.abs(np.array(i[0][0]) + 1j * np.array(q[0][0])))
Qibolab¶
For Qibolab, the pulses are generally created from the values saved in the platform runcard. This enables to save some time in the definition of the experiments. Moreover, the results object are more accessible through the API.
It is still required to define the pulse sequence and the whole experiment.
import matplotlib.pyplot as plt
from qibolab import create_platform
from qibolab import AcquisitionType, AveragingMode, ExecutionParameters
from qibolab.pulses import (
DrivePulse,
ReadoutPulse,
PulseSequence,
)
# Define platform and load specific runcard
platform = create_platform("my_platform")
# Define PulseSequence
sequence = PulseSequence()
readout_pulse = platform.create_MZ_pulse(qubit=0, start=0)
readout_pulse.amplitude = 0.5
sequence.add(readout_pulse)
options=ExecutionParameters(
nshots=1000,
relaxation_time=50_000, # ns
acquisition_type=AcquisitionType.RAW,
averaging_mode=AveragingMode.CYCLIC,
)
results = platform.execute_pulse_sequence(sequence, options=options)
plt.plot(results[sequence[0].serial].magnitude)
Qibocal¶
For Qibocal, the experiment does not need to be defined again and just some basic parameters are required, on top of the ones defined in the platform runcard.
Executing the experiment with qq auto actions.yml -o OUTPUT_FOLDER will produce a new platform runcard with the updated parameters, as well as plots and data of the experiment.
File actions.yml
.
platform: my_platform
qubits: [0]
actions:
- id: time of flight
priority: 0
operation: time_of_flight_readout
parameters:
nshots: 1000
readout_amplitude: 0.5
Resonator Spectroscopy¶
In the resonator spectroscopy experiment, we aim to find the frequency of the resonator.
We perform a measurement, composed of a pulse and a subsequent acquisition, repeating it with different frequencies of the pulse. In the plot of the measured amplitude, we expect to see a Lorentzian shape, with the peak being the resonator one.
Qibosoq¶
For Qibosoq, the experiment needs to be defined from scratch as per the time of flight one. Indeed, the only real difference with that experiment is the use of the sweeper functionality.
import json
import socket
import numpy as np
from qibosoq.client import execute
from qibosoq.components.base import (
Qubit,
OperationCode,
Config
)
from qibosoq.components.pulses import Rectangular
HOST = "192.168.0.200"
PORT = 6000
frequencies = np.arange(6800, 7200, 1)
pulse = Rectangular(
frequency = 7000, #MHz
amplitude = 0.5,
relative_phase = 0,
start_delay = 0,
duration = 1,
name = "readout_pulse",
type = "readout",
dac = 1,
adc = 0
)
sequence = [pulse]
config = Config(
relaxation_time=50,
ro_time_of_flight=200,
reps=1000,
average=True
)
qubit = Qubit()
server_commands = {
"operation_code": OperationCode.EXECUTE_PULSE_SEQUENCE,
"cfg": config,
"sequence": sequence,
"qubits": [qubit],
}
results = []
for freq in frequencies:
server_commands["sequence"][0].frequency = int(freq)
i, q = execute(server_commands, HOST, PORT)
results.append(np.abs(np.array(i[0][0]) + 1j * np.array(q[0][0])))
import matplotlib.pyplot as plt
plt.plot(results)
Qibolab¶
For Qibolab, the situation is more or less equal to the one of the last experiment. Also here, the big difference is the use of sweepers.
import numpy as np
import matplotlib.pyplot as plt
from qibolab import create_platform
from qibolab import AcquisitionType, AveragingMode, ExecutionParameters
from qibolab.sweeper import Parameter, Sweeper, SweeperType
from qibolab.pulses import (
DrivePulse,
ReadoutPulse,
PulseSequence,
)
# Define platform and load specific runcard
platform = create_platform("my_platform")
# Define PulseSequence
sequence = PulseSequence()
# Add some pulses to the pulse sequence
readout_pulse = platform.create_MZ_pulse(qubit=0, start=0)
readout_pulse.amplitude = 0.5
sequence.add(readout_pulse)
options=ExecutionParameters(
nshots=1000,
relaxation_time=50,
acquisition_type=AcquisitionType.INTEGRATION,
averaging_mode=AveragingMode.CYCLIC,
)
sweeper = Sweeper(
parameter=Parameter.frequency,
values=np.arange(-2e8, +2e8, 1e6),
pulses=[readout_pulse],
type=SweeperType.OFFSET,
)
results = platform.sweep(sequence, options, sweeper)
amplitudes = results[readout_pulse.serial].magnitude
frequencies = np.arange(-2e8, +2e8, 1e6) + readout_pulse.frequency
plt.plot(frequencies, amplitudes)
Qibocal¶
Qibocal, on the other hand, maintains a higher level of abstraction.
File actions.yml
.
platform: my_platform
qubits: [0]
actions:
- id: resonator high power
priority: 0
operation: resonator_spectroscopy
parameters:
power_level: high
freq_width: 400_000_000
freq_step: 1_000_000
amplitude: 0.5
nshots: 1000
Qubit Spectroscopy¶
This is a two tone spectroscopy where a first pulse is sent to excite the qubit and then a measurement is performed. The experiment is repeated with different drive frequencies and we expect to see a Lorentzian peak in correspondence of the qubit transition frequency.
Qibosoq¶
As Qibosoq does not have a way of natively storing results of experiments, the numbers found for the last experiments are just explicitly written here.
import json
import socket
import numpy as np
from qibosoq.client import execute
from qibosoq.components.base import (
Qubit,
OperationCode,
Config,
Sweeper,
Parameter
)
from qibosoq.components.pulses import Rectangular
HOST = "192.168.0.200"
PORT = 6000
pulse_1 = Rectangular(
frequency = 5400, #MHz
amplitude = 0.1,
relative_phase = 0,
start_delay = 0,
duration = 2,
name = "drive_pulse",
type = "drive",
dac = 0,
adc = None
)
pulse_2 = Rectangular(
frequency = 6953, #MHz
amplitude = 0.1,
relative_phase = 0,
start_delay = 2,
duration = 1,
name = "readout_pulse",
type = "readout",
dac = 1,
adc = 0
)
sequence = [pulse_1, pulse_2]
sweeper = Sweeper(
parameters = [Parameter.FREQUENCY],
indexes = [0],
starts = [5400],
stops = [6000],
expts = 600
)
config = Config(
relaxation_time = 50,
reps = 1000
)
qubit = Qubit()
server_commands = {
"operation_code": OperationCode.EXECUTE_SWEEPS,
"cfg": config,
"sequence": sequence,
"qubits": [qubit],
"sweepers": [sweeper],
}
i, q = execute(server_commands, HOST, PORT)
import matplotlib.pyplot as plt
frequency = np.linspace(sweeper.starts[0], sweeper.stops[0], sweeper.expts)
results = np.abs(np.array(i[0][0]) + 1j * np.array(q[0][0]))
plt.plot(frequency, np.abs(results))
Qibolab¶
For Qibolab, we have the runcard platform to contain the parameters found in calibration. In particular, we can see that the readout parameters are not explicitly written here, since they are included in the platform runcard.
import numpy as np
import matplotlib.pyplot as plt
from qibolab import create_platform
from qibolab import AcquisitionType, AveragingMode, ExecutionParameters
from qibolab.sweeper import Parameter, Sweeper, SweeperType
from qibolab.pulses import (
DrivePulse,
ReadoutPulse,
PulseSequence,
)
# Define platform and load specific runcard
platform = create_platform("my_platform")
sequence = PulseSequence()
drive_pulse = platform.create_RX_pulse(qubit=0, start=0)
drive_pulse.duration = 2000
drive_pulse.amplitude = 0.1
readout_pulse = platform.create_MZ_pulse(qubit=0, start=drive_pulse.finish)
sequence.add(drive_pulse)
sequence.add(readout_pulse)
# allocate frequency sweeper
sweeper = Sweeper(
parameter=Parameter.frequency,
values=np.arange(-3e8, +3e8, 1e6),
pulses=[drive_pulse],
type=SweeperType.OFFSET,
)
options = ExecutionParameters(
nshots=1000,
relaxation_time=50,
averaging_mode=AveragingMode.CYCLIC,
acquisition_type=AcquisitionType.INTEGRATION,
)
results = platform.sweep(sequence, options, sweeper)
amplitudes = results[readout_pulse.serial].magnitude
frequencies = np.arange(-3e8, +3e8, 1e6) + drive_pulse.frequency
plt.plot(frequencies, amplitudes)
Qibocal¶
Also Qibocal maintains all the parameters in the platform runcard.
File actions.yml
.
platform: my_platform
qubits: [0]
actions:
- id: qubit spectroscopy
priority: 0
operation: qubit_spectroscopy
parameters:
drive_amplitude: 0.01
drive_duration: 2000
freq_width: 600_000_000
freq_step: 1_000_000
nshots: 1000
Rabi Oscillations (amplitude)¶
In the Rabi experiment, we fire a drive pulse with a varying parameter (in this case the amplitude of the pulse) and then measure. We expect to see a sinusoidal oscillation between the state 0 and 1 of the qubit.
Qibosoq¶
The experiment is similar to the ones before it, we just need to change a couple of parameters and specify as amplitude the parameter type of the sweeper.
import json
import socket
import numpy as np
from qibosoq.client import execute
from qibosoq.components.base import (
Qubit,
OperationCode,
Config,
Sweeper,
Parameter
)
from qibosoq.components.pulses import Rectangular, Gaussian
HOST = "192.168.0.200"
PORT = 6000
pulse_1 = Gaussian(
frequency = 5755, #MHz
amplitude = 0.01,
relative_phase = 0,
start_delay = 0,
duration = 0.043,
rel_sigma = 3,
name = "drive_pulse",
type = "drive",
dac = 0,
adc = None
)
pulse_2 = Rectangular(
frequency = 6953, #MHz
amplitude = 0.1,
relative_phase = 0,
start_delay = 0.043,
duration = 1,
name = "readout_pulse",
type = "readout",
dac = 1,
adc = 0
)
sequence = [pulse_1, pulse_2]
sweeper = Sweeper(
parameters = [Parameter.AMPLITUDE],
indexes = [0],
starts = [0],
stops = [1],
expts = 100
)
config = Config(
relaxation_time = 50,
reps = 1000
)
qubit = Qubit()
server_commands = {
"operation_code": OperationCode.EXECUTE_SWEEPS,
"cfg": config,
"sequence": sequence,
"qubits": [qubit],
"sweepers": [sweeper],
}
i, q = execute(server_commands, HOST, PORT)
import matplotlib.pyplot as plt
amplitudes = np.linspace(sweeper.starts[0], sweeper.stops[0], sweeper.expts)
results = np.abs(np.array(i[0][0]) + 1j * np.array(q[0][0]))
plt.plot(amplitudes, np.abs(results))
Qibolab¶
For Qibolab, considering that the pulses are defined from the runcard parameters, we just need to change the sweeper definition to change the whole experiment.
import numpy as np
import matplotlib.pyplot as plt
from qibolab import create_platform
from qibolab import AcquisitionType, AveragingMode, ExecutionParameters
from qibolab.sweeper import Parameter, Sweeper, SweeperType
from qibolab.pulses import (
DrivePulse,
ReadoutPulse,
PulseSequence,
)
# Define platform and load specific runcard
platform = create_platform("my_platform")
sequence = PulseSequence()
drive_pulse = platform.create_RX_pulse(qubit=0, start=0)
readout_pulse = platform.create_MZ_pulse(qubit=0, start=drive_pulse.finish)
sequence.add(drive_pulse)
sequence.add(readout_pulse)
# allocate frequency sweeper
sweeper = Sweeper(
parameter=Parameter.amplitude,
values=np.arange(0, 1, 0.01),
pulses=[drive_pulse],
type=SweeperType.ABSOLUTE,
)
options = ExecutionParameters(
nshots=1000,
relaxation_time=50,
averaging_mode=AveragingMode.CYCLIC,
acquisition_type=AcquisitionType.INTEGRATION,
)
results = platform.sweep(sequence, options, sweeper)
magnitudes = results[readout_pulse.serial].magnitude
amplitudes = np.arange(0, 1, 0.01)
plt.plot(amplitudes, magnitudes)
Qibocal¶
As we learnt, Qibocal always requires just minimal experiments definitions.
File actions.yml
.
platform: my_platform
qubits: [0]
actions:
- id: rabi
priority: 0
operation: rabi_amplitude
parameters:
min_amp_factor: 0.0
max_amp_factor: 10
step_amp_factor: 0.1
pulse_length: 43
T1¶
In the T1 experiment we use already calibrated pulses (the Pi-pulse for the X gate and the measurement) to extract the relaxation parameter of the qubit.
We first excite the qubit, wait a certain time and then measure. Increasing the delay between excitation and measurement will lead to an exponential decrease of the excited state population.
Qibosoq¶
As we already saw, Qibosoq is a rather low level API, however it enables to focus on the experiments themselves. In this case, for example, we can see a new type of sweeper (the delay one) that has an identical implementation in respect to the others already seen, despite being internally treated differently.
import json
import socket
import numpy as np
from qibosoq.client import execute
from qibosoq.components.base import (
Qubit,
OperationCode,
Config,
Sweeper,
Parameter
)
from qibosoq.components.pulses import Rectangular, Gaussian
HOST = "192.168.0.200"
PORT = 6000
pulse_1 = Gaussian(
frequency = 5755, #MHz
amplitude = 0.02,
relative_phase = 0,
start_delay = 0,
duration = 0.043,
rel_sigma = 3,
name = "drive_pulse",
type = "drive",
dac = 0,
adc = None
)
pulse_2 = Rectangular(
frequency = 6953, #MHz
amplitude = 0.1,
relative_phase = 0,
start_delay = 0.043,
duration = 1,
name = "readout_pulse",
type = "readout",
dac = 1,
adc = 0
)
sequence = [pulse_1, pulse_2]
sweeper = Sweeper(
parameters = [Parameter.DELAY],
indexes = [1],
starts = [0.043],
stops = [100.043],
expts = 100
)
config = Config(
relaxation_time = 50,
reps = 1000
)
qubit = Qubit()
server_commands = {
"operation_code": OperationCode.EXECUTE_SWEEPS,
"cfg": config,
"sequence": sequence,
"qubits": [qubit],
"sweepers": [sweeper],
}
i, q = execute(server_commands, HOST, PORT)
import matplotlib.pyplot as plt
delays = np.linspace(sweeper.starts[0], sweeper.stops[0], sweeper.expts)
results = np.abs(np.array(i[0][0]) + 1j * np.array(q[0][0]))
plt.plot(delays, np.abs(results))
Qibolab¶
Qibolab always behaves as an intermediate language step between Qibosoq and Qibocal.
import numpy as np
import matplotlib.pyplot as plt
from qibolab import create_platform
from qibolab import AcquisitionType, AveragingMode, ExecutionParameters
from qibolab.sweeper import Parameter, Sweeper, SweeperType
from qibolab.pulses import (
DrivePulse,
ReadoutPulse,
PulseSequence,
)
# Define platform and load specific runcard
platform = create_platform("my_platform")
sequence = PulseSequence()
drive_pulse = platform.create_RX_pulse(qubit=0, start=0)
readout_pulse = platform.create_MZ_pulse(qubit=0, start=drive_pulse.finish)
sequence.add(drive_pulse)
sequence.add(readout_pulse)
# allocate frequency sweeper
sweeper = Sweeper(
parameter=Parameter.start,
values=np.arange(0, 100_000, 1000),
pulses=[readout_pulse],
type=SweeperType.OFFSET,
)
options = ExecutionParameters(
nshots=1000,
relaxation_time=50,
averaging_mode=AveragingMode.CYCLIC,
acquisition_type=AcquisitionType.INTEGRATION,
)
results = platform.sweep(sequence, options, sweeper)
magnitudes = results[readout_pulse.serial].magnitude
start_times = np.arange(0, 100_000, 1000)
plt.plot(start_times, magnitudes)
Qibocal¶
File actions.yml
.
platform: my_platform
qubits: [0]
actions:
- id: t1
priority: 0
operation: t1
parameters:
delay_before_readout_start: 0
delay_before_readout_end: 100_000
delay_before_readout_step: 1000
Classification experiment¶
In the classification experiment, we perform just single shot measurements with and without previously having excited the qubit. Plotting the non-averaged results, we should be able to identify two different “blobs” for the qubit when is prepared in the state 1 and when is prepared in the state 0.
Qibosoq¶
For Qibosoq we just need to deactivate the averaging option in the Config object.
import json
import socket
import numpy as np
from qibosoq.client import execute
from qibosoq.components.base import (
Qubit,
OperationCode,
Config
)
from qibosoq.components.pulses import Rectangular, Gaussian
HOST = "192.168.0.200"
PORT = 6000
pulse_1 = Gaussian(
frequency = 5755, #MHz
amplitude = 0.02,
relative_phase = 0,
start_delay = 0,
duration = 0.043,
rel_sigma = 3,
name = "drive_pulse",
type = "drive",
dac = 0,
adc = None
)
pulse_2 = Rectangular(
frequency = 6953, #MHz
amplitude = 0.1,
relative_phase = 0,
start_delay = 0.043,
duration = 1,
name = "readout_pulse",
type = "readout",
dac = 1,
adc = 0
)
sequence = [pulse_1, pulse_2]
config = Config(
relaxation_time = 50,
reps = 10000,
average = False
)
qubit = Qubit()
server_commands = {
"operation_code": OperationCode.EXECUTE_PULSE_SEQUENCE,
"cfg": config,
"sequence": sequence,
"qubits": [qubit],
}
i1, q1 = execute(server_commands, HOST, PORT)
server_commands = {
"operation_code": OperationCode.EXECUTE_PULSE_SEQUENCE,
"cfg": config,
"sequence": sequence[1:],
"qubits": [qubit],
}
i2, q2 = execute(server_commands, HOST, PORT)
import matplotlib.pyplot as plt
plt.scatter(i1[0][0], q1[0][0])
plt.scatter(i2[0][0], q2[0][0])
Qibolab¶
Also for Qibolab, it is sufficient to change the AveragingMode to SINGLESHOT.
import numpy as np
import matplotlib.pyplot as plt
from qibolab import create_platform
from qibolab import AcquisitionType, AveragingMode, ExecutionParameters
from qibolab.pulses import (
DrivePulse,
ReadoutPulse,
PulseSequence,
)
# Define platform and load specific runcard
platform = create_platform("my_platform")
sequence_0 = PulseSequence()
readout_pulse_0 = platform.create_MZ_pulse(qubit=0, start=0)
sequence_0.add(readout_pulse_0)
sequence_1 = PulseSequence()
drive_pulse = platform.create_RX_pulse(qubit=0, start=0)
readout_pulse_1 = platform.create_MZ_pulse(qubit=0, start=drive_pulse.finish)
sequence_1.add(drive_pulse)
sequence_1.add(readout_pulse_1)
options = ExecutionParameters(
nshots=10000,
relaxation_time=50,
averaging_mode=AveragingMode.SINGLESHOT,
acquisition_type=AcquisitionType.INTEGRATION,
)
results_1 = platform.execute_pulse_sequence(sequence_1, options=options)[0]
results_0 = platform.execute_pulse_sequence(sequence_0, options=options)[0]
plt.scatter(results_0.voltage_i, results_0.voltage_q)
plt.scatter(results_1.voltage_i, results_1.voltage_q)
Qibocal¶
For Qibocal there are no substantial changes, since everything is taken into account under the hood.
File actions.yml
.
platform: my_platform
qubits: [0]
actions:
- id: single shot classification
priority: 0
operation: single_shot_classification
parameters:
nshots: 10000