-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into QWG_Release_v1.0
- Loading branch information
Showing
105 changed files
with
8,607 additions
and
1,534 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,6 +41,7 @@ htmlcov/ | |
.coverage | ||
.coverage.* | ||
.cache | ||
*.pytest_cache* | ||
nosetests.xml | ||
coverage.xml | ||
*,cover | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
|
||
import numpy as np | ||
import matplotlib as mpl | ||
import matplotlib.pyplot as plt | ||
from scipy import signal | ||
|
||
|
||
import pycqed.measurement.kernel_functions_ZI as ZI_kern | ||
|
||
|
||
mpl.rcParams['font.size'] = 12 | ||
mpl.rcParams['legend.fontsize'] = 12 | ||
mpl.rcParams['figure.titlesize'] = 'medium' | ||
|
||
|
||
# Settings | ||
fs = 2.4e9 | ||
time_start = -100e-9 | ||
time_start = np.around(time_start*fs)/fs | ||
time_end = 100e-9 | ||
time = np.arange(time_start, time_end, 1/fs) | ||
|
||
delay = 10.1e-9 | ||
amplitude = 0.1 | ||
|
||
|
||
# Construct impulse_response | ||
impulse = np.zeros(len(time)) | ||
zero_ind = np.argmin(np.abs(time)) | ||
impulse[zero_ind] = 1.0 | ||
delay_ind = np.argmin(np.abs(time-delay)) | ||
impulse_response = np.copy(impulse) | ||
impulse_response[delay_ind] = amplitude | ||
|
||
|
||
# Derive step response | ||
step = np.zeros(len(time)) | ||
step[time >= 0.0] = 1.0 | ||
step_response = signal.lfilter(impulse_response[zero_ind:], 1.0, step) | ||
|
||
|
||
# Compute ideal inverted filter kernel | ||
a = ZI_kern.ideal_inverted_fir_kernel(impulse_response, zero_ind) | ||
a1 = ZI_kern.first_order_bounce_kern(delay, -amplitude, fs) | ||
|
||
# Apply ideal inverted filter to impulse response and step response | ||
impulse_response_corr = signal.lfilter(a, 1.0, impulse_response) | ||
step_response_corr = signal.lfilter(a, 1.0, step_response) | ||
|
||
# Apply first-order inverted filter to impulse response and step response | ||
impulse_response_corr1 = signal.lfilter(a1, 1.0, impulse_response) | ||
step_response_corr1 = signal.lfilter(a1, 1.0, step_response) | ||
|
||
# Apply hardware-friendly filter to impulse response and step response | ||
impulse_response_corr_hw = ZI_kern.multipath_first_order_bounce_correction(impulse_response, round(delay*fs), amplitude) | ||
step_response_corr_hw = ZI_kern.multipath_first_order_bounce_correction(step_response, round(delay*fs), amplitude) | ||
|
||
|
||
# Plot impulse response comparison | ||
plt.figure(1, figsize=(14,10)) | ||
|
||
plt.subplot(2, 2, 1) | ||
plt.plot(time*1e9, impulse_response) | ||
plt.xlabel('Time, t (ns)') | ||
plt.ylabel('Amplitude (a.u)') | ||
plt.title('(a) Impulse response') | ||
|
||
plt.subplot(2, 2, 2) | ||
plt.plot(time*1e9, impulse_response_corr) | ||
plt.xlabel('Time, t (ns)') | ||
plt.ylabel('Amplitude (a.u)') | ||
plt.title('(b) Ideal corrected impulse response') | ||
|
||
plt.subplot(2, 2, 3) | ||
plt.plot(time*1e9, impulse_response_corr1) | ||
plt.xlabel('Time, t (ns)') | ||
plt.ylabel('Amplitude (a.u)') | ||
plt.title('(b) First-order corrected impulse response') | ||
|
||
plt.subplot(2, 2, 4) | ||
plt.plot(time*1e9, impulse_response_corr_hw) | ||
plt.xlabel('Time, t (ns)') | ||
plt.ylabel('Amplitude (a.u)') | ||
plt.title('(c) Simulated hardware-corrected impulse response') | ||
|
||
plt.tight_layout() | ||
plt.savefig('impulse_response.png',dpi=600,bbox_inches='tight') | ||
plt.show() | ||
|
||
|
||
# Plot step response comparison | ||
plt.figure(1, figsize=(14,10)) | ||
|
||
plt.subplot(2, 2, 1) | ||
plt.plot(time*1e9, step_response) | ||
plt.xlabel('Time, t (ns)') | ||
plt.ylabel('Amplitude (a.u)') | ||
plt.title('(a) Step response') | ||
|
||
plt.subplot(2, 2, 2) | ||
plt.plot(time*1e9, step_response_corr) | ||
plt.xlabel('Time, t (ns)') | ||
plt.ylabel('Amplitude (a.u)') | ||
plt.title('(b) Ideal corrected step response') | ||
|
||
plt.subplot(2, 2, 3) | ||
plt.plot(time*1e9, step_response_corr1) | ||
plt.xlabel('Time, t (ns)') | ||
plt.ylabel('Amplitude (a.u)') | ||
plt.title('(b) First-order corrected step response') | ||
|
||
plt.subplot(2, 2, 4) | ||
plt.plot(time*1e9, step_response_corr_hw) | ||
plt.xlabel('Time, t (ns)') | ||
plt.ylabel('Amplitude (a.u)') | ||
plt.title('(c) Simulated hardware-corrected step response') | ||
|
||
plt.tight_layout() | ||
plt.savefig('step_response.png',dpi=600,bbox_inches='tight') | ||
plt.show() | ||
|
||
|
||
# Sawtooth test waveform | ||
sawtooth_period = 50e-9 | ||
ideal_waveform = np.remainder(2*time/sawtooth_period, 1) | ||
distorted_waveform = signal.lfilter(impulse_response[zero_ind:], 1.0, ideal_waveform) | ||
|
||
# Apply ideal inverted filter to the waveform | ||
distorted_waveform_corr = signal.lfilter(a, 1.0, distorted_waveform) | ||
|
||
# Apply first-order filter to the waveform | ||
distorted_waveform_corr1 = signal.lfilter(a1, 1.0, distorted_waveform) | ||
|
||
# Apply hardware-friendly filter to the waveform | ||
distorted_waveform_corr_hw = ZI_kern.multipath_first_order_bounce_correction(distorted_waveform, round(delay*fs), amplitude) | ||
|
||
# Compute errors with respect to the ideal waveform | ||
err = ideal_waveform - distorted_waveform_corr | ||
err1 = ideal_waveform - distorted_waveform_corr1 | ||
err_hw = ideal_waveform - distorted_waveform_corr_hw | ||
|
||
# Plot the test waveform comparison | ||
plt.figure(1, figsize=(14,14)) | ||
|
||
plt.subplot(4, 2, 1) | ||
plt.plot(time*1e9, ideal_waveform) | ||
plt.xlabel('Time, t (ns)') | ||
plt.ylabel('Amplitude (a.u)') | ||
plt.title('(a) Ideal waveform') | ||
|
||
plt.subplot(4, 2, 2) | ||
plt.plot(time*1e9, distorted_waveform) | ||
plt.xlabel('Time, t (ns)') | ||
plt.ylabel('Amplitude (a.u)') | ||
plt.title('(b) Distorted waveform') | ||
|
||
plt.subplot(4, 2, 3) | ||
plt.plot(time*1e9, distorted_waveform_corr) | ||
plt.xlabel('Time, t (ns)') | ||
plt.ylabel('Amplitude (a.u)') | ||
plt.title('(c) Ideal corrected waveform') | ||
|
||
plt.subplot(4, 2, 4) | ||
plt.plot(time*1e9, err) | ||
plt.xlabel('Time, t (ns)') | ||
plt.ylabel('Amplitude (a.u)') | ||
plt.title('(d) Error of ideal correction') | ||
|
||
plt.subplot(4, 2, 5) | ||
plt.plot(time*1e9, distorted_waveform_corr1) | ||
plt.xlabel('Time, t (ns)') | ||
plt.ylabel('Amplitude (a.u)') | ||
plt.title('(c) First-order correction') | ||
|
||
plt.subplot(4, 2, 6) | ||
plt.plot(time*1e9, err1) | ||
plt.xlabel('Time, t (ns)') | ||
plt.ylabel('Amplitude (a.u)') | ||
plt.title('(d) Error of first-order correction') | ||
|
||
plt.subplot(4, 2, 7) | ||
plt.plot(time*1e9, distorted_waveform_corr_hw) | ||
plt.xlabel('Time, t (ns)') | ||
plt.ylabel('Amplitude (a.u)') | ||
plt.title('(e) Simulated hardware-frienldy first-order corrected waveform') | ||
|
||
plt.subplot(4, 2, 8) | ||
plt.plot(time*1e9, err_hw) | ||
plt.xlabel('Time, t (ns)') | ||
plt.ylabel('Amplitude (a.u)') | ||
plt.title('(f) Error of hardware-friendly correction') | ||
|
||
plt.tight_layout() | ||
plt.savefig('test_waveform.png', dpi=600, bbox_inches='tight') | ||
plt.show() |
165 changes: 165 additions & 0 deletions
165
examples/Adaptive sampling example using a mock device object.ipynb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"%matplotlib inline\n", | ||
"import adaptive\n", | ||
"import matplotlib.pyplot as plt\n", | ||
"import pycqed as pq\n", | ||
"import numpy as np\n", | ||
"from pycqed.measurement import measurement_control\n", | ||
"import pycqed.measurement.detector_functions as det\n", | ||
"from qcodes import station\n", | ||
"station = station.Station()\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Setting up the mock device\n", | ||
"\n", | ||
"Measurements are controlled through the `MeasurementControl` usually instantiated as `MC`" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"from pycqed.instrument_drivers.virtual_instruments.mock_device import Mock_Device\n", | ||
"MC = measurement_control.MeasurementControl('MC',live_plot_enabled=True, verbose=True)\n", | ||
"MC.station = station\n", | ||
"station.add_component(MC)\n", | ||
"\n", | ||
"mock_device = Mock_Device('mock_device')\n", | ||
"mock_device.mw_pow(-20)\n", | ||
"mock_device.res_freq(7.400023457e9)\n", | ||
"mock_device.cw_noise_level(.0005)\n", | ||
"mock_device.acq_delay(.05)\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Measuring a resonator using the conventional method\n", | ||
"Points are chosen on a linspace of 100 points. This is enough to identify the location of the resonator. " | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"freqs = np.linspace(7.39e9, 7.41e9, 100)\n", | ||
"\n", | ||
"d = det.Function_Detector(mock_device.S21,value_names=['Magn', 'Phase'], \n", | ||
" value_units=['V', 'deg'])\n", | ||
"MC.set_sweep_function(mock_device.mw_freq)\n", | ||
"MC.set_sweep_points(freqs)\n", | ||
"MC.set_detector_function(d)\n", | ||
"dat=MC.run('test')" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Using 1D adaptive sampler from the MC \n", | ||
"\n", | ||
"This can also be done using an adaptive `Leaner1D` object, chosing 100 points optimally in the interval. " | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"mock_device.acq_delay(.05)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"\n", | ||
"d = det.Function_Detector(mock_device.S21, value_names=['Magn', 'Phase'], value_units=['V', 'deg'])\n", | ||
"\n", | ||
"MC.set_sweep_function(mock_device.mw_freq)\n", | ||
"MC.set_detector_function(d)\n", | ||
"MC.set_adaptive_function_parameters({'adaptive_function': adaptive.Learner1D, \n", | ||
" 'goal':lambda l: l.npoints>100, \n", | ||
" 'bounds':(7.39e9, 7.41e9)})\n", | ||
"dat = MC.run(mode='adaptive')\n", | ||
"from pycqed.analysis import measurement_analysis as ma\n", | ||
"# ma.Homodyne_Analysis(close_fig=False, label='M')" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Two D learner\n", | ||
"\n", | ||
"The learner can also be used to adaptively sample a 2D /heatmap type experiment. \n", | ||
"However, currently we do not have easy plotting function for that and we still need to rely on the adaptive Learner plotting methods. \n", | ||
"\n", | ||
"It would be great to have this working with a realtime pyqtgraph based plotting window so that we can use this without the notebooks. " | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"d = det.Function_Detector(mock_device.S21, value_names=['Magn', 'Phase'], value_units=['V', 'deg'])\n", | ||
"MC.set_sweep_function(mock_device.mw_freq)\n", | ||
"MC.set_sweep_function_2D(mock_device.mw_pow)\n", | ||
"MC.set_detector_function(d)\n", | ||
"MC.set_adaptive_function_parameters({'adaptive_function': adaptive.Learner2D, \n", | ||
" 'goal':lambda l: l.npoints>20*20, \n", | ||
" 'bounds':((7.398e9, 7.402e9), \n", | ||
" (-20, -10))})\n", | ||
"dat = MC.run(mode='adaptive')\n", | ||
"\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# Required to be able to use the fancy interpolating plot \n", | ||
"adaptive.notebook_extension()\n", | ||
"MC.learner.plot(tri_alpha=.1)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [] | ||
} | ||
], | ||
"metadata": { | ||
"language_info": { | ||
"name": "python", | ||
"pygments_lexer": "ipython3" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |
Oops, something went wrong.