Skip to content

Commit

Permalink
use channel names as signal names, instead of inventing new name
Browse files Browse the repository at this point in the history
  • Loading branch information
hay-k committed Feb 8, 2024
1 parent ba4d920 commit ed2eab6
Showing 1 changed file with 51 additions and 39 deletions.
90 changes: 51 additions & 39 deletions src/qibolab/instruments/zhinst.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@
"""Maximum number of subsequences in a single sequence."""


def acquire_signal_name(qubit: Qubit) -> str:
"""Construct and return a name for qubit's acquire signal line.
For other types of signals (drive, flux, etc.) we use the channel name as signal name. Currently we do not have a concept
of an acquire channel, so there is no source for acquire signal names, hence this function exists.
FIXME: this function will become redundant and shall be removed once all the channel refactoring is done.
"""
return f"acquire{qubit.name}"


def select_pulse(pulse, pulse_type):
"""Pulse translation."""

Expand Down Expand Up @@ -218,7 +228,7 @@ def __init__(self, sweeper, qubit=None, sequence=None, pulse=None):
channel=qubit.flux.name,
qubit=qubit.name,
)
self.signal = f"flux{qubit.name}"
self.signal = qubit.flux.name
if isinstance(qubit, Coupler):
pulse = CouplerFluxPulse(
start=0,
Expand All @@ -228,7 +238,7 @@ def __init__(self, sweeper, qubit=None, sequence=None, pulse=None):
channel=qubit.flux.name,
qubit=qubit.name,
)
self.signal = f"couplerflux{qubit.name}"
self.signal = qubit.flux.name

self.pulse = pulse

Expand All @@ -241,7 +251,7 @@ def __init__(self, sweeper, qubit=None, sequence=None, pulse=None):
elif sweeper.parameter is Parameter.start:
if pulse:
self.pulse = pulse
self.signal = f"flux{qubit}"
self.signal = qubit.flux.name

self.zhpulse = ZhPulse(pulse).zhpulse

Expand Down Expand Up @@ -335,13 +345,13 @@ def calibration_step(self, qubits, couplers, options):
for qubit in qubits.values():
if qubit.flux is not None:
self.register_flux_line(qubit)
if len(self.sequence[f"drive{qubit.name}"]) != 0:
if len(self.sequence[qubit.drive.name]) != 0:
self.register_drive_line(
qubit=qubit,
intermediate_frequency=qubit.drive_frequency
- qubit.drive.local_oscillator.frequency,
)
if len(self.sequence[f"readout{qubit.name}"]) != 0:
if len(self.sequence[qubit.readout.name]) != 0:
self.register_readout_line(
qubit=qubit,
intermediate_frequency=qubit.readout_frequency
Expand Down Expand Up @@ -371,7 +381,7 @@ def register_readout_line(self, qubit, intermediate_frequency, options):
"""

q = qubit.name # pylint: disable=C0103
self.signal_map[f"measure{q}"] = self.device_setup.logical_signal_groups[
self.signal_map[qubit.readout.name] = self.device_setup.logical_signal_groups[
f"q{q}"
].logical_signals["measure_line"]
self.calibration[f"/logical_signal_groups/q{q}/measure_line"] = (
Expand All @@ -390,9 +400,11 @@ def register_readout_line(self, qubit, intermediate_frequency, options):
)
)

self.signal_map[f"acquire{q}"] = self.device_setup.logical_signal_groups[
f"q{q}"
].logical_signals["acquire_line"]
self.signal_map[acquire_signal_name(qubit)] = (
self.device_setup.logical_signal_groups[f"q{q}"].logical_signals[
"acquire_line"
]
)

oscillator = lo.Oscillator(
frequency=intermediate_frequency,
Expand Down Expand Up @@ -420,7 +432,7 @@ def register_readout_line(self, qubit, intermediate_frequency, options):
def register_drive_line(self, qubit, intermediate_frequency):
"""Registers qubit drive line to calibration and signal map."""
q = qubit.name # pylint: disable=C0103
self.signal_map[f"drive{q}"] = self.device_setup.logical_signal_groups[
self.signal_map[qubit.drive.name] = self.device_setup.logical_signal_groups[
f"q{q}"
].logical_signals["drive_line"]
self.calibration[f"/logical_signal_groups/q{q}/drive_line"] = (
Expand All @@ -442,7 +454,7 @@ def register_drive_line(self, qubit, intermediate_frequency):
def register_flux_line(self, qubit):
"""Registers qubit flux line to calibration and signal map."""
q = qubit.name # pylint: disable=C0103
self.signal_map[f"flux{q}"] = self.device_setup.logical_signal_groups[
self.signal_map[qubit.flux.name] = self.device_setup.logical_signal_groups[
f"q{q}"
].logical_signals["flux_line"]
self.calibration[f"/logical_signal_groups/q{q}/flux_line"] = (
Expand All @@ -457,7 +469,7 @@ def register_flux_line(self, qubit):
def register_couplerflux_line(self, coupler):
"""Registers qubit flux line to calibration and signal map."""
c = coupler.name # pylint: disable=C0103
self.signal_map[f"couplerflux{c}"] = self.device_setup.logical_signal_groups[
self.signal_map[coupler.flux.name] = self.device_setup.logical_signal_groups[
f"qc{c}"
].logical_signals["flux_line"]
self.calibration[f"/logical_signal_groups/qc{c}/flux_line"] = (
Expand Down Expand Up @@ -505,7 +517,7 @@ def create_sub_sequence(
"""
for quantum_element in quantum_elements.values():
q = quantum_element.name # pylint: disable=C0103
measurements = self.sequence[f"readout{q}"]
measurements = self.sequence[quantum_element.readout.name]
pulses = self.sequence[f"{line_name}{q}"]
pulse_sequences = [[] for _ in measurements]
pulse_sequences.append([])
Expand Down Expand Up @@ -568,8 +580,8 @@ def play(self, qubits, couplers, sequence, options):
results = {}
for qubit in qubits.values():
q = qubit.name # pylint: disable=C0103
if len(self.sequence[f"readout{q}"]) != 0:
for i, ropulse in enumerate(self.sequence[f"readout{q}"]):
if len(self.sequence[qubit.readout.name]) != 0:
for i, ropulse in enumerate(self.sequence[qubit.readout.name]):
data = np.array(self.results.get_data(f"sequence{q}_{i}"))
if options.acquisition_type is AcquisitionType.DISCRIMINATION:
data = (
Expand All @@ -589,7 +601,7 @@ def sequence_zh(self, sequence, qubits, couplers):

# Fill the sequences with pulses according to their lines in temporal order
for pulse in sequence:
zhsequence[f"{pulse.type.name.lower()}{pulse.qubit}"].append(ZhPulse(pulse))
zhsequence[pulse.channel.name].append(ZhPulse(pulse))

def nt_loop(sweeper):
if not self.nt_sweeps:
Expand All @@ -601,7 +613,7 @@ def nt_loop(sweeper):
for sweeper in self.sweepers.copy():
if sweeper.parameter.name in SWEEPER_SET:
for pulse in sweeper.pulses:
aux_list = zhsequence[f"{pulse.type.name.lower()}{pulse.qubit}"]
aux_list = zhsequence[pulse.channel.name]
if (
sweeper.parameter is Parameter.frequency
and pulse.type is PulseType.READOUT
Expand Down Expand Up @@ -642,7 +654,7 @@ def nt_loop(sweeper):
# This may not place the Zhsweeper when the start occurs among different sections or lines
if sweeper.parameter.name in SWEEPER_START:
pulse = sweeper.pulses[0]
aux_list = zhsequence[f"{pulse.type.name.lower()}{pulse.qubit}"]
aux_list = zhsequence[pulse.channel.name]
for element in aux_list:
if pulse == element.pulse:
if isinstance(aux_list[aux_list.index(element)], ZhPulse):
Expand Down Expand Up @@ -838,14 +850,14 @@ def flux(self, exp: lo.Experiment, qubits: Dict[str, Qubit]):
q = qubit.name # pylint: disable=C0103
time = 0
previous_section = None
for i, sequence in enumerate(self.sub_sequences[f"flux{q}"]):
for i, sequence in enumerate(self.sub_sequences[qubit.flux.name]):
section_uid = f"sequence_flux{q}_{i}"
with exp.section(uid=section_uid, play_after=previous_section):
for j, pulse in enumerate(sequence):
if not isinstance(pulse, ZhSweeperLine):
pulse.zhpulse.uid += f"{i}_{j}"
exp.delay(
signal=f"flux{q}",
signal=qubit.flux.name,
time=round(pulse.pulse.start * NANO_TO_SECONDS, 9)
- time,
)
Expand All @@ -857,7 +869,7 @@ def flux(self, exp: lo.Experiment, qubits: Dict[str, Qubit]):
elif isinstance(pulse, ZhSweeper):
self.play_sweep(exp, qubit, pulse, section="flux")
elif isinstance(pulse, ZhPulse):
exp.play(signal=f"flux{q}", pulse=pulse.zhpulse)
exp.play(signal=qubit.flux.name, pulse=pulse.zhpulse)
previous_section = section_uid

def drive(self, exp: lo.Experiment, qubits: Dict[str, Qubit]):
Expand All @@ -871,13 +883,13 @@ def drive(self, exp: lo.Experiment, qubits: Dict[str, Qubit]):
q = qubit.name # pylint: disable=C0103
time = 0
previous_section = None
for i, sequence in enumerate(self.sub_sequences[f"drive{q}"]):
for i, sequence in enumerate(self.sub_sequences[qubit.drive.name]):
section_uid = f"sequence_drive{q}_{i}"
with exp.section(uid=section_uid, play_after=previous_section):
for j, pulse in enumerate(sequence):
if not isinstance(pulse, ZhSweeperLine):
exp.delay(
signal=f"drive{q}",
signal=qubit.drive.name,
time=round(pulse.pulse.start * NANO_TO_SECONDS, 9)
- time,
)
Expand All @@ -889,22 +901,22 @@ def drive(self, exp: lo.Experiment, qubits: Dict[str, Qubit]):
self.play_sweep(exp, qubit, pulse, section="drive")
elif isinstance(pulse, ZhPulse):
exp.play(
signal=f"drive{q}",
signal=qubit.drive.name,
pulse=pulse.zhpulse,
phase=pulse.pulse.relative_phase,
)
elif isinstance(pulse, ZhSweeperLine):
exp.delay(signal=f"drive{q}", time=pulse.zhsweeper)
exp.delay(signal=qubit.drive.name, time=pulse.zhsweeper)

if len(self.sequence[f"readout{q}"]) > 0 and isinstance(
self.sequence[f"readout{q}"][0], ZhSweeperLine
if len(self.sequence[qubit.readout.name]) > 0 and isinstance(
self.sequence[qubit.readout.name][0], ZhSweeperLine
):
exp.delay(
signal=f"drive{q}",
time=self.sequence[f"readout{q}"][0].zhsweeper,
signal=qubit.drive.name,
time=self.sequence[qubit.readout.name][0].zhsweeper,
)
self.sequence[f"readout{q}"].remove(
self.sequence[f"readout{q}"][0]
self.sequence[qubit.readout.name].remove(
self.sequence[qubit.readout.name][0]
)

previous_section = section_uid
Expand Down Expand Up @@ -957,8 +969,8 @@ def measure_relax(self, exp, qubits, couplers, relaxation_time, acquisition_type
for qubit in qubits.values():
q = qubit.name # pylint: disable=C0103
iq_angle = qubit.iq_angle
if len(self.sequence[f"readout{q}"]) != 0:
for i, pulse in enumerate(self.sequence[f"readout{q}"]):
if len(self.sequence[qubit.readout.name]) != 0:
for i, pulse in enumerate(self.sequence[qubit.readout.name]):
readout_schedule[i].append(pulse)
qubit_readout_schedule[i].append(q)
iq_angle_readout_schedule[i].append(iq_angle)
Expand Down Expand Up @@ -993,7 +1005,7 @@ def measure_relax(self, exp, qubits, couplers, relaxation_time, acquisition_type
pulse.zhpulse.uid += str(i)

exp.delay(
signal=f"acquire{q}",
signal=acquire_signal_name(q),
time=self.smearing * NANO_TO_SECONDS,
)

Expand Down Expand Up @@ -1040,18 +1052,18 @@ def measure_relax(self, exp, qubits, couplers, relaxation_time, acquisition_type

measure_pulse_parameters = {"phase": 0}

if i == len(self.sequence[f"readout{q}"]) - 1:
if i == len(self.sequence[q.readout.name]) - 1:
reset_delay = relaxation_time * NANO_TO_SECONDS
else:
reset_delay = 0

exp.measure(
acquire_signal=f"acquire{q}",
acquire_signal=acquire_signal_name(q),
handle=f"sequence{q}_{i}",
integration_kernel=weight,
integration_kernel_parameters=None,
integration_length=None,
measure_signal=f"measure{q}",
measure_signal=q.readout.name,
measure_pulse=pulse.zhpulse,
measure_pulse_length=round(
pulse.pulse.duration * NANO_TO_SECONDS, 9
Expand Down Expand Up @@ -1116,8 +1128,8 @@ def sweep(self, qubits, couplers, sequence: PulseSequence, options, *sweepers):
results = {}
for qubit in qubits.values():
q = qubit.name # pylint: disable=C0103
if len(self.sequence[f"readout{q}"]) != 0:
for i, ropulse in enumerate(self.sequence[f"readout{q}"]):
if len(self.sequence[qubit.readout.name]) != 0:
for i, ropulse in enumerate(self.sequence[qubit.readout.name]):
exp_res = self.results.get_data(f"sequence{q}_{i}")
# if using singleshot, the first axis contains shots,
# i.e.: (nshots, sweeper_1, sweeper_2)
Expand Down

0 comments on commit ed2eab6

Please sign in to comment.