From 3a8b20b9f592ff43116c7a0e066f7b6c4798b7a6 Mon Sep 17 00:00:00 2001 From: Alessandro Candido Date: Fri, 16 Aug 2024 16:34:50 +0200 Subject: [PATCH] fix: Fix doctests and import --- doc/source/getting-started/experiment.rst | 4 +- doc/source/main-documentation/qibolab.rst | 17 ++++--- doc/source/tutorials/calibration.rst | 8 ++- doc/source/tutorials/lab.rst | 60 ++++++++++++++--------- doc/source/tutorials/pulses.rst | 8 +-- src/qibolab/sequence.py | 2 +- 6 files changed, 59 insertions(+), 40 deletions(-) diff --git a/doc/source/getting-started/experiment.rst b/doc/source/getting-started/experiment.rst index 5b6ba0703..6776335b6 100644 --- a/doc/source/getting-started/experiment.rst +++ b/doc/source/getting-started/experiment.rst @@ -241,7 +241,9 @@ We leave to the dedicated tutorial a full explanation of the experiment, but her # plot the results amplitudes = magnitude(results[probe_pulse.id][0]) - frequencies = np.arange(-2e8, +2e8, 1e6) + platform.config(qubit.probe.name).frequency + frequencies = ( + np.arange(-2e8, +2e8, 1e6) + platform.config(str(qubit.probe.name)).frequency + ) plt.title("Resonator Spectroscopy") plt.xlabel("Frequencies [Hz]") diff --git a/doc/source/main-documentation/qibolab.rst b/doc/source/main-documentation/qibolab.rst index d2f1d1a08..55e451280 100644 --- a/doc/source/main-documentation/qibolab.rst +++ b/doc/source/main-documentation/qibolab.rst @@ -43,14 +43,14 @@ We can easily access the names of channels and other components, and based on th drive_channel = platform.qubits[0].drive print(f"Drive channel name: {drive_channel.name}") - print(f"Drive frequency: {platform.config(drive_channel.name).frequency}") + print(f"Drive frequency: {platform.config(str(drive_channel.name)).frequency}") drive_lo = drive_channel.lo if drive_lo is None: print(f"Drive channel {drive_channel.name} does not use an LO.") else: print(f"Name of LO for channel {drive_channel.name} is {drive_lo}") - print(f"LO frequency: {platform.config(drive_lo).frequency}") + print(f"LO frequency: {platform.config(str(drive_lo)).frequency}") .. testoutput:: python :hide: @@ -304,12 +304,12 @@ To organize pulses into sequences, Qibolab provides the :class:`qibolab.pulses.P relative_phase=0, # phases are in radians envelope=Rectangular(), ) - sequence = PulseSequence( + sequence = PulseSequence.load( [ - ("channel", pulse1), - ("channel", pulse2), - ("channel", pulse3), - ("channel", pulse4), + ("qubit/drive", pulse1), + ("qubit/drive", pulse2), + ("qubit/drive", pulse3), + ("qubit/drive", pulse4), ], ) @@ -336,13 +336,14 @@ Typical experiments may include both pre-defined pulses and new ones: .. testcode:: python from qibolab.pulses import Rectangular + from qibolab.identifier import ChannelId natives = platform.parameters.native_gates.single_qubit[0] sequence = PulseSequence() sequence.concatenate(natives.RX.create_sequence()) sequence.append( ( - "some_channel", + ChannelId.load("some/drive"), Pulse(duration=10, amplitude=0.5, relative_phase=0, envelope=Rectangular()), ) ) diff --git a/doc/source/tutorials/calibration.rst b/doc/source/tutorials/calibration.rst index 7a50df96f..b32697c94 100644 --- a/doc/source/tutorials/calibration.rst +++ b/doc/source/tutorials/calibration.rst @@ -75,7 +75,9 @@ In few seconds, the experiment will be finished and we can proceed to plot it. probe_pulse = sequence.probe_pulses[0] amplitudes = magnitude(results[probe_pulse.id][0]) - frequencies = np.arange(-2e8, +2e8, 1e6) + platform.config(qubit.probe.name).frequency + frequencies = ( + np.arange(-2e8, +2e8, 1e6) + platform.config(str(qubit.probe.name)).frequency + ) plt.title("Resonator Spectroscopy") plt.xlabel("Frequencies [Hz]") @@ -166,7 +168,9 @@ We can now proceed to launch on hardware: probe_pulse = next(iter(sequence.probe_pulses)) amplitudes = magnitude(results[probe_pulse.id][0]) - frequencies = np.arange(-2e8, +2e8, 1e6) + platform.config(qubit.drive.name).frequency + frequencies = ( + np.arange(-2e8, +2e8, 1e6) + platform.config(str(qubit.drive.name)).frequency + ) plt.title("Resonator Spectroscopy") plt.xlabel("Frequencies [Hz]") diff --git a/doc/source/tutorials/lab.rst b/doc/source/tutorials/lab.rst index 22fcfb8b7..8d254c65f 100644 --- a/doc/source/tutorials/lab.rst +++ b/doc/source/tutorials/lab.rst @@ -38,14 +38,18 @@ using different Qibolab primitives. qubit = Qubit(name=0) # assign channels to the qubit - qubit.probe = IqChannel(name="probe", mixer=None, lo=None, acquisition="acquire") - qubit.acquisition = AcquireChannel(name="acquire", twpa_pump=None, probe="probe") - qubit.drive = Iqchannel(name="drive", mixer=None, lo=None) + qubit.probe = IqChannel( + name="0/probe", mixer=None, lo=None, acquisition="0/acquisition" + ) + qubit.acquisition = AcquireChannel( + name="0/acquisition", twpa_pump=None, probe="probe" + ) + qubit.drive = Iqchannel(name="0/drive", mixer=None, lo=None) # define configuration for channels configs = {} - configs[qubit.drive.name] = IqConfig(frequency=3e9) - configs[qubit.probe.name] = IqConfig(frequency=7e9) + configs[str(qubit.drive.name)] = IqConfig(frequency=3e9) + configs[str(qubit.probe.name)] = IqConfig(frequency=7e9) # create sequence that drives qubit from state 0 to 1 drive_seq = PulseSequence( @@ -120,13 +124,21 @@ the native gates, but separately from the single-qubit ones. qubit1 = Qubit(name=1) # assign channels to the qubits - qubit0.probe = IqChannel(name="probe_0", mixer=None, lo=None, acquisition="acquire_0") - qubit0.acquisition = AcquireChannel(name="acquire_0", twpa_pump=None, probe="probe_0") - qubit0.drive = IqChannel(name="drive_0", mixer=None, lo=None) - qubit0.flux = DcChannel(name="flux_0") - qubit1.probe = IqChannel(name="probe_1", mixer=None, lo=None, acquisition="acquire_1") - qubit1.acquisition = AcquireChannel(name="acquire_1", twpa_pump=None, probe="probe_1") - qubit1.drive = IqChannel(name="drive_1", mixer=None, lo=None) + qubit0.probe = IqChannel( + name="0/probe", mixer=None, lo=None, acquisition="0/acquisition" + ) + qubit0.acquisition = AcquireChannel( + name="0/acquisition", twpa_pump=None, probe="probe_0" + ) + qubit0.drive = IqChannel(name="0/drive", mixer=None, lo=None) + qubit0.flux = DcChannel(name="0/flux") + qubit1.probe = IqChannel( + name="1/probe", mixer=None, lo=None, acquisition="1/acquisition" + ) + qubit1.acquisition = AcquireChannel( + name="1/acquisition", twpa_pump=None, probe="probe_1" + ) + qubit1.drive = IqChannel(name="1/drive", mixer=None, lo=None) # assign single-qubit native gates to each qubit single_qubit = {} @@ -219,10 +231,10 @@ will take them into account when calling :class:`qibolab.native.TwoQubitNatives` # create the qubit and coupler objects qubit0 = Qubit(name=0) qubit1 = Qubit(name=1) - coupler_01 = Qubit(name=100) + coupler_01 = Qubit(name="c01") # assign channel(s) to the coupler - coupler_01.flux = DcChannel(name="flux_coupler_01") + coupler_01.flux = DcChannel(name="c01/flux") # assign single-qubit native gates to each qubit # Look above example @@ -295,26 +307,26 @@ a two-qubit system: "relaxation_time": 50000 }, "components": { - "drive_0": { + "0/drive": { "frequency": 4855663000 }, - "drive_1": { + "1/drive": { "frequency": 5800563000 }, - "flux_0": { + "0/flux": { "bias": 0.0 }, - "probe_0": { + "0/probe": { "frequency": 7453265000 }, - "probe_1": { + "1/probe": { "frequency": 7655107000 }, - "acquire_0": { + "0/acquisition": { "delay": 0, "smearing": 0 }, - "acquire_1": { + "1/acquisition": { "delay": 0, "smearing": 0 } @@ -510,7 +522,7 @@ the above runcard: # define channels and load component configs qubits = {} for q in range(2): - probe_name, acquire_name = f"qubit_{q}/probe", f"qubit_{q}/acquire" + probe_name, acquire_name = f"qubit_{q}/probe", f"qubit_{q}/acquisition" qubits[q] = Qubit( name=q, drive=IqChannel(f"qubit_{q}/drive", mixer=None, lo=None), @@ -540,7 +552,7 @@ With the following additions for coupler architectures: qubits = {} # define channels and load component configs for q in range(2): - probe_name, acquire_name = f"qubit_{q}/probe", f"qubit_{q}/acquire" + probe_name, acquire_name = f"qubit_{q}/probe", f"qubit_{q}/acquisition" qubits[q] = Qubit( name=q, drive=IqChannel(f"qubit_{q}/drive", mixer=None, lo=None), @@ -622,7 +634,7 @@ in this case ``"twpa_pump"``. # define channels and load component configs qubits = {} for q in range(2): - probe_name, acquire_name = f"qubit_{q}/probe", f"qubit_{q}/acquire" + probe_name, acquire_name = f"qubit_{q}/probe", f"qubit_{q}/acquisition" qubits[q] = Qubit( name=q, drive=IqChannel(f"qubit_{q}/drive", mixer=None, lo=None), diff --git a/doc/source/tutorials/pulses.rst b/doc/source/tutorials/pulses.rst index 76cfae4f9..0c330d2a8 100644 --- a/doc/source/tutorials/pulses.rst +++ b/doc/source/tutorials/pulses.rst @@ -12,10 +12,10 @@ pulses (:class:`qibolab.pulses.Pulse`) through the from qibolab.sequence import PulseSequence # Define PulseSequence - sequence = PulseSequence( + sequence = PulseSequence.load( [ ( - "channel_0", + "0/drive", Pulse( amplitude=0.3, duration=60, @@ -23,9 +23,9 @@ pulses (:class:`qibolab.pulses.Pulse`) through the envelope=Gaussian(rel_sigma=0.2), ), ), - ("channel_1", Delay(duration=100)), + ("1/drive", Delay(duration=100)), ( - "channel_1", + "1/drive", Pulse( amplitude=0.5, duration=3000, relative_phase=0, envelope=Rectangular() ), diff --git a/src/qibolab/sequence.py b/src/qibolab/sequence.py index 02292c961..1cfdc3572 100644 --- a/src/qibolab/sequence.py +++ b/src/qibolab/sequence.py @@ -7,7 +7,7 @@ from pydantic import TypeAdapter from pydantic_core import core_schema -from .identifier import ChannelId +from .identifier import ChannelId, ChannelType from .pulses import Delay, Pulse, PulseLike __all__ = ["PulseSequence"]