From 7e451cf07d01e27351506609665032642ae850a5 Mon Sep 17 00:00:00 2001 From: Sander de Snoo <59472150+sldesnoo-Delft@users.noreply.github.com> Date: Wed, 13 Mar 2024 12:31:11 +0100 Subject: [PATCH] Take attenuation into account --- pulse_lib/keysight/qs_sequence.py | 46 +++++++++++++++++++++---------- pulse_lib/keysight/qs_uploader.py | 21 ++++++++++++-- 2 files changed, 51 insertions(+), 16 deletions(-) diff --git a/pulse_lib/keysight/qs_sequence.py b/pulse_lib/keysight/qs_sequence.py index 914a750f..3731e90f 100644 --- a/pulse_lib/keysight/qs_sequence.py +++ b/pulse_lib/keysight/qs_sequence.py @@ -97,11 +97,12 @@ class DigitizerSequenceEntry: class IQSequenceBuilder: - def __init__(self, name, t_start, lo_freq): + def __init__(self, name, t_start, lo_freq, attenuation=1.0): self.name = name self.time = iround(t_start) self.end_pulse = self.time self.lo_freq = lo_freq + self.attenuation = attenuation self.pending_instruction = None self.sequence = [] self.waveforms = [] @@ -187,9 +188,14 @@ class IQSequenceBuilder: if abs(end_frequency) > 450e6: raise Exception(f'Chirp NCO frequency {end_frequency/1e6:5.1f} MHz is out of range') ph_gen = chirp.phase_mod_generator() - return Waveform(chirp.amplitude, 1.0, frequency, - ph_gen(duration, 1.0), - 0, 0, duration) + return Waveform( + chirp.amplitude / self.attenuation, + 1.0, + frequency, + ph_gen(duration, 1.0), + 0, + 0, + duration) def _render_waveform(self, mw_pulse_data, prephase=0, postphase=0): # always render at 1e9 Sa/s @@ -207,9 +213,14 @@ class IQSequenceBuilder: prephase += mw_pulse_data.phase_offset postphase -= mw_pulse_data.phase_offset - return Waveform(mw_pulse_data.amplitude, amp_envelope, - frequency, pm_envelope, - prephase, postphase, duration) + return Waveform( + mw_pulse_data.amplitude / self.attenuation, + amp_envelope, + frequency, + pm_envelope, + prephase, + postphase, + duration) def _render_waveform_start_stop(self, mw_pulse_data): frequency = mw_pulse_data.frequency - self.lo_freq @@ -218,13 +229,20 @@ class IQSequenceBuilder: prephase = mw_pulse_data.phase_offset postphase = -mw_pulse_data.phase_offset - start_wvf = Waveform(mw_pulse_data.amplitude, 1.0, - frequency, 0.0, - prephase=prephase, - duration=2, restore_frequency=False) - stop_wvf = Waveform(mw_pulse_data.amplitude, 1.0, - frequency, 0.0, - postphase=postphase) + start_wvf = Waveform( + mw_pulse_data.amplitude / self.attenuation, + 1.0, + frequency, + 0.0, + prephase=prephase, + duration=2, + restore_frequency=False) + stop_wvf = Waveform( + mw_pulse_data.amplitude / self.attenuation, + 1.0, + frequency, + 0.0, + postphase=postphase) return start_wvf, stop_wvf diff --git a/pulse_lib/keysight/qs_uploader.py b/pulse_lib/keysight/qs_uploader.py index 9f374c2f..99449257 100644 --- a/pulse_lib/keysight/qs_uploader.py +++ b/pulse_lib/keysight/qs_uploader.py @@ -1330,6 +1330,19 @@ class UploadAggregator: raise Exception(f'I/Q Channel delays must be equal ({qubit_channel.channel_name})') return delays[0] + def _get_iq_channel_attenuation(self, qubit_channel): + out_channels = qubit_channel.iq_channel.IQ_out_channels + + if len(out_channels) == 1: + awg_channel_name = out_channels[0].awg_channel_name + return self.channels[awg_channel_name].attenuation + else: + att = [self.channels[output.awg_channel_name].attenuation for output in out_channels] + if min(att) != max(att): + raise Exception('Attenuation for IQ output is not equal for channels ' + f'{[[output.awg_channel_name] for output in out_channels]}') + return att[0] + def _generate_sequencer_iq_upload(self, job): segments = self.segments @@ -1339,13 +1352,17 @@ class UploadAggregator: continue start = time.perf_counter() delay = self._get_iq_channel_delay(qubit_channel) + attenuation = self._get_iq_channel_attenuation(qubit_channel) sequencer_offset = self.sequencer_channels[channel_name].sequencer_offset # subtract offset, because it's started before 'classical' queued waveform t_start = int(-self.max_pre_start_ns - delay) - sequencer_offset - sequence = IQSequenceBuilder(channel_name, t_start, - qubit_channel.iq_channel.LO) + sequence = IQSequenceBuilder( + channel_name, + t_start, + qubit_channel.iq_channel.LO, + attenuation=attenuation) job.iq_sequences[channel_name] = sequence for iseg, (seg, seg_render) in enumerate(zip(job.sequence, segments)): -- GitLab