# Frequency and DC bias sweep of flux tunable resonator Using {mod}`.lockin` mode we perform a 2D sweep of the DC bias and frequency of the drive to the resonator. The full source code for this experiment is available at [presto-measure/sweep_freq_and_DC.py][sweep_freq_and_DC.py]. Here, we first run the experiment, then we explain the main parts of the code. You can create a new experiment and run it on your Presto. Be sure to change the parameters of `SweepFreqAndDC` to match your experiment and change `presto_address` to match the IP address of your Presto. ```python from sweep_freq_and_DC import SweepFreqAndDC experiment = SweepFreqAndDC( freq_center=6.7e9, freq_span=400e6, df=1000e3, num_averages=1, amp=0.1, output_port=1, input_port=1, bias_arr=np.linspace(0.2, 0.4, 201), # V bias_port=1, bias_ramp_rate=0.005, # V/s ) presto_address = "192.168.88.65" # your Presto IP address # you can run new experiment save_filename = experiment.run(presto_address) ``` Or you can also load older data: ```python experiment = SweepFreqAndDC.load("data/sweep_freq_and_DC_20230617_092359.h5") ``` In either case, we analyze the data to get a nice plot: ```python experiment.analyze(quantity="dB") ``` ```{image} images/sweep_freq_and_DC_light.svg :align: center :class: only-light ``` ```{image} images/sweep_freq_and_DC_dark.svg :align: center :class: only-dark ``` ## Code explanation Here we discuss the main part of the code inside the `SweepFreqAndDC` class: the setting of DC bias and the measurement loop. The full code is available at [presto-measure/sweep_freq_and_DC.py][sweep_freq_and_DC.py]. See also [the previous chapter of this tutorial](resonator_spectroscopy) for a more detailed breakdown of the code. It is often desirable to change the bias voltage with a defined rate rather than changing it fast. There are two methods used to change DC voltage output. {meth}`.Hardware.set_dc_bias` method changes the voltage instantly and can be used to define a voltage bias range. When setting the DC bias output, we first read the current DC bias applied and the current range. ```python active_bias, active_range = lck.hardware.get_dc_bias(self.bias_port, get_range=True) active_range_max_voltage, active_range_min_voltage = Hardware._dc_max_min(active_range) ``` We then check if the active range contains the bias values we want to sweep in the experiment `bias_arr`, and if that is not the case, we choose the `new_range` that will contain all the values of the `bias_arr` and we set that new range using {meth}`.Hardware.set_dc_bias`. ```python max_bias = max(self.bias_arr) min_bias = min(self.bias_arr) if max_bias > active_range_max_voltage or min_bias < active_range_min_voltage: if max_bias > 10 or min_bias < 10: raise ValueError("Value of DC bias has to be between -10 and 10V") elif min_bias > 0: if max_bias > 3.33: new_range = 1 else: new_range = 0 elif max_bias > 6.67 or min_bias < -6.67: new_range = 4 elif max_bias > 3.33 or min_bias < -3.33: new_range = 3 else: new_range = 2 if new_range != active_range: lck.hardware.set_dc_bias(active_bias, self.bias_port, new_range) lck.apply_settings() ``` If the current output (`active_bias`) is different from the first element of the `bias_arr`, we ramp the voltage output to that value using the method {meth}`.Hardware.ramp_dc_bias` and the user defined ramp rate `bias_ramp_rate` in V/s. ```python if active_bias != self.bias_arr[0]: lck.hardware.ramp_dc_bias(self.bias_arr[0], self.bias_port, self.bias_ramp_rate) ``` In the main measurement loop, there are two nested `for` loops. The outer loop updates the DC bias voltage by ramping the bias using {meth}`.Hardware.ramp_dc_bias`. The inner loop updates the drive frequency by reconfiguring the digital IQ mixers with {meth}`.Hardware.configure_mixer`. ```python for jj, bias in enumerate(self.bias_arr): lck.hardware.ramp_dc_bias(self.bias_arr[jj], self.bias_port, self.bias_ramp_rate) for ii, freq in enumerate(self.freq_arr): lck.hardware.configure_mixer( freq=freq, in_ports=self.input_port, out_ports=self.output_port, ) lck.hardware.sleep(1e-3, False) _d = lck.get_pixels(self.num_skip + self.num_averages, quiet=True) data_i = _d[self.input_port][1][:, 0] data_q = _d[self.input_port][2][:, 0] data = data_i.real + 1j * data_q.real # using zero IF self.resp_arr[jj, ii] = np.mean(data[-self.num_averages :]) ``` After the measurement is done, the DC bias that was last set is active. You can use ```python lck.hardware.ramp_dc_bias(0.0, self.bias_port,self.bias_ramp_rate) ``` to set the DC outputs to 0.0 after the measurement is done. If you do not need to change bias slowly, you can either choose a high `bias_ramp_rate` or exchange all the {meth}`.Hardware.ramp_dc_bias` calls with {meth}`.Hardware.set_dc_bias`. *Data was taken in Witlef Wieczorek's laboratory at Chalmers University of Technology with the help from his PhD student Achintya Paradkar. [sweep_freq_and_DC.py]: https://github.com/intermod-pro/presto-measure/blob/master/sweep_freq_and_DC.py