From 081ec4a73a9df227cc774f4b19ac93e03b19d998 Mon Sep 17 00:00:00 2001 From: sldesnoo-Delft <s.l.desnoo@tudelft.nl> Date: Wed, 20 Dec 2023 09:14:51 +0100 Subject: [PATCH] Added RF parameters frequency, source_amplitude and phase --- pulse_lib/base_pulse.py | 3 + pulse_lib/configuration/rf_parameters.py | 71 +++++++++++++++++++ .../tests/rf_source/test_read_sweep_rf.py | 45 ++++++++++++ .../test_rf_qblox_fast_sweep_frequency.py | 54 ++------------ 4 files changed, 125 insertions(+), 48 deletions(-) create mode 100644 pulse_lib/configuration/rf_parameters.py create mode 100644 pulse_lib/tests/rf_source/test_read_sweep_rf.py diff --git a/pulse_lib/base_pulse.py b/pulse_lib/base_pulse.py index 0c063b94..be2d5f0c 100644 --- a/pulse_lib/base_pulse.py +++ b/pulse_lib/base_pulse.py @@ -11,6 +11,7 @@ from pulse_lib.configuration.physical_channels import ( awg_channel, marker_channel, digitizer_channel, resonator_rf_source) from pulse_lib.configuration.iq_channels import IQ_channel, QubitChannel from pulse_lib.configuration.devices import awg_slave +from pulse_lib.configuration.rf_parameters import RfParameters from pulse_lib.virtual_matrix.virtual_gate_matrices import VirtualGateMatrices logger = logging.getLogger(__name__) @@ -29,6 +30,7 @@ class pulselib: self.awg_channels = dict() self.marker_channels = dict() self.digitizer_channels = dict() + self.rf_params = dict() self._virtual_matrices = VirtualGateMatrices() self.qubit_channels = dict() self.IQ_channels = dict() @@ -171,6 +173,7 @@ class pulselib: self.digitizer_channels[name] = digitizer_channel(name, digitizer_name, [channel_number], iq_out=iq_out) if hw_input_channel is not None: self.set_digitizer_hw_input_channel(name, hw_input_channel) + self.rf_params[name] = RfParameters(self.digitizer_channels[name]) def define_digitizer_channel_iq(self, name, digitizer_name, channel_numbers, phase=0.0, iq_out=False): ''' Defines a digitizer I/Q input pair. diff --git a/pulse_lib/configuration/rf_parameters.py b/pulse_lib/configuration/rf_parameters.py new file mode 100644 index 00000000..b9a4f4ce --- /dev/null +++ b/pulse_lib/configuration/rf_parameters.py @@ -0,0 +1,71 @@ +from qcodes import Parameter + +from .physical_channels import digitizer_channel as DigitizerChannel + + +class RfParameters: + def __init__(self, digitizer_channel: DigitizerChannel): + self._frequency = RfFrequencyParameter(digitizer_channel) + self._source_amplitude = RfAmplitudeParameter(digitizer_channel) + self._phase = RfPhaseParameter(digitizer_channel) + + @property + def frequency(self): + return self._frequency + + @property + def source_amplitude(self): + return self._source_amplitude + + @property + def phase(self): + return self._phase + + +class RfFrequencyParameter(Parameter): + def __init__(self, digitizer_channel: DigitizerChannel): + super().__init__( + name=f'{digitizer_channel.name}_frequency', + label=f'{digitizer_channel.name} resonator frequency', + unit='Hz') + self.channel = digitizer_channel + + def get_raw(self): + return self.channel.frequency + + def set_raw(self, value): + self.channel.frequency = value + + +class RfAmplitudeParameter(Parameter): + def __init__(self, digitizer_channel: DigitizerChannel): + super().__init__( + name=f'{digitizer_channel.name}_amplitude', + label=f'{digitizer_channel.name} rf source amplitude', + unit='mV') + self.channel = digitizer_channel + + def get_raw(self): + if self.channel.rf_source is None: + return None + return self.channel.rf_source.amplitude + + def set_raw(self, value): + if self.channel.rf_source is None: + raise Exception(f'No RF source configured for {self.channel.name}') + self.channel.rf_source.amplitude = value + + +class RfPhaseParameter(Parameter): + def __init__(self, digitizer_channel: DigitizerChannel): + super().__init__( + name=f'{digitizer_channel.name}_phase', + label=f'{digitizer_channel.name} phase', + unit='rad') + self.channel = digitizer_channel + + def get_raw(self): + return self.channel.phase + + def set_raw(self, value): + self.channel.phase = value diff --git a/pulse_lib/tests/rf_source/test_read_sweep_rf.py b/pulse_lib/tests/rf_source/test_read_sweep_rf.py new file mode 100644 index 00000000..4dd377dc --- /dev/null +++ b/pulse_lib/tests/rf_source/test_read_sweep_rf.py @@ -0,0 +1,45 @@ +from pulse_lib.tests.configurations.test_configuration import context + +# %% +import numpy as np +from pulse_lib.scan.read_input import read_channels +from core_tools.sweeps.sweeps import do1D + + +def test_freq(): + pulse = context.init_pulselib(n_gates=2, n_sensors=2, rf_sources=True) + + rf_frequency = pulse.rf_params['SD1'].frequency + meas_param = read_channels(pulse, 2_000, channels=['SD1'], iq_mode='I+Q') + ds = do1D(rf_frequency, 80e6, 120e6, 21, 0.0, meas_param, + name='frequency_search', reset_param=True).run() + + return ds + + +def test_ampl(): + pulse = context.init_pulselib(n_gates=2, n_sensors=2, rf_sources=True) + + rf_amplitude = pulse.rf_params['SD2'].source_amplitude + meas_param = read_channels(pulse, 2_000, channels=['SD1'], iq_mode='I+Q') + ds = do1D(rf_amplitude, 20.0, 200.0, 10, 0.0, meas_param, name='amplitude_sweep', reset_param=True).run() + + return ds + + +def test_phase(): + pulse = context.init_pulselib(n_gates=2, n_sensors=2, rf_sources=True) + + rf_phase = pulse.rf_params['SD1'].phase + meas_param = read_channels(pulse, 2_000, channels=['SD1'], iq_mode='I+Q') + ds = do1D(rf_phase, 0.0, 2*np.pi, 20, 0.0, meas_param, name='phase_sweep', reset_param=True).run() + + return ds + + +# %% +if __name__ == '__main__': + context.init_coretools() + ds1 = test_freq() + ds2 = test_ampl() + ds3 = test_phase() diff --git a/pulse_lib/tests/rf_source/test_rf_qblox_fast_sweep_frequency.py b/pulse_lib/tests/rf_source/test_rf_qblox_fast_sweep_frequency.py index 5de9f139..f2c36e42 100644 --- a/pulse_lib/tests/rf_source/test_rf_qblox_fast_sweep_frequency.py +++ b/pulse_lib/tests/rf_source/test_rf_qblox_fast_sweep_frequency.py @@ -1,73 +1,31 @@ from pulse_lib.tests.configurations.test_configuration import context #%% -from qcodes import Parameter -from pulse_lib.fast_scan.qblox_fast_scans import fast_scan1D_param, fast_scan2D_param +from pulse_lib.fast_scan.qblox_fast_scans import fast_scan1D_param from core_tools.sweeps.sweeps import do1D -class RfParameter(Parameter): - def __init__(self, pulselib, digitizer_channel_name): - super().__init__( - name=f'{digitizer_channel_name}_RF', - label=f'{digitizer_channel_name} resonator frequency', - unit='Hz') - self.channel = pulselib.digitizer_channels[digitizer_channel_name] - - def get_raw(self): - return self.channel.frequency - - def set_raw(self, value): - self.channel.frequency = value - -# TODO: Fix amplitude sweep. THIS DOES NOT WORK!! -class RfAmplitudeParameter(Parameter): - def __init__(self, pulselib, digitizer_channel_name): - super().__init__( - name=f'{digitizer_channel_name}_amplitude', - label=f'{digitizer_channel_name} resonator drive amplitude', - unit='mV') - self.channel = pulselib.digitizer_channels[digitizer_channel_name] - - def get_raw(self): - return self.channel.rf_source.amplitude - - def set_raw(self, value): - self.channel.rf_source.amplitude = value - - -class PhaseParameter(Parameter): - def __init__(self, pulselib, digitizer_channel_name): - super().__init__( - name=f'{digitizer_channel_name} phase', - label=f'{digitizer_channel_name} phase', - unit='degrees') - self.channel = pulselib.digitizer_channels[digitizer_channel_name] - - def get_raw(self): - return self.channel.phase - - def set_raw(self, value): - self.channel.phase = value - def test_freq(): pulse = context.init_pulselib(n_gates=2, n_sensors=2, rf_sources=True) - rf_frequency = RfParameter(pulse, 'SD2') + rf_frequency = pulse.rf_params['SD2'].frequency fast_scan_param = fast_scan1D_param(pulse, 'P1', 50.0, 21, 2_000, iq_mode='I+Q') ds = do1D(rf_frequency, 80e6, 120e6, 21, 0.0, fast_scan_param, name='frequency_search', reset_param=True).run() return ds + def test_ampl(): pulse = context.init_pulselib(n_gates=2, n_sensors=2, rf_sources=True) - rf_amplitude = RfAmplitudeParameter(pulse, 'SD2') + rf_amplitude = pulse.rf_params['SD2'].source_amplitude + # NOTE: reload_seq=True !!! fast_scan_param = fast_scan1D_param(pulse, 'P1', 50.0, 21, 2_000, iq_mode='I+Q', reload_seq=True) ds = do1D(rf_amplitude, 20.0, 200.0, 10, 0.0, fast_scan_param, name='amplitude_sweep', reset_param=True).run() return ds + #%% if __name__ == '__main__': context.init_coretools() -- GitLab