From d1f692843a78600d550a43e78854a78c83cdd9fe Mon Sep 17 00:00:00 2001 From: TheoQM Date: Wed, 20 Mar 2024 10:06:45 +0100 Subject: [PATCH] exponential decay + readme --- qualang_tools/digital_filters/README.md | 91 ++++++++++++++++------- qualang_tools/digital_filters/__init__.py | 2 + qualang_tools/digital_filters/filters.py | 15 +++- 3 files changed, 81 insertions(+), 27 deletions(-) diff --git a/qualang_tools/digital_filters/README.md b/qualang_tools/digital_filters/README.md index 62d10104..48bee89a 100644 --- a/qualang_tools/digital_filters/README.md +++ b/qualang_tools/digital_filters/README.md @@ -7,50 +7,91 @@ or to correct flux pulses for possible distortions happening on the flux lines o More details about these types of filter and how they are implemented on the OPX can be found [here](https://docs.quantum-machines.co/1.1.7/qm-qua-sdk/docs/Guides/output_filter/?h=iir#output-filter) The goal of the following functions is to allow users to easily implement such filters by deriving the IIR and FIR taps -from the measured distortions. +from the measured distortions: +* [Exponential decay](#exponentialcorrection): fit a low-pass exponential decay `1 + A * exp(-t/tau)`. +* [Exponential correction](#exponentialcorrection): correct for a low-pass exponential decay `1 + A * exp(-t/tau)`. +* [Highpass correction](#highpasscorrection): correct for a high pass exponential decay `exp(-t/tau)`. +* [Bounce and delay correction](#bounceanddelaycorrection): correct for reflections and delays. +* [Calc filter taps](#calcfiltertaps): correct for any combination of the aforementioned compensations. -## calc_filter_taps -Calculate the best FIR and IIR filter taps for a system with any combination of FIR corrections, exponential -corrections (LPF), high pass compensation, reflections (bounce corrections) and a needed delay on the line. +## Usage examples -### Usage examples +### exponential_correction +Calculate the best FIR and IIR filter taps to correct for an exponential decay (low-pass filter) of the shape +`exponential_decay(t, A, tau) = 1 + A * exp(-t/tau)`. #### ```python -from qualang_tools.loops import from_array - +from scipy import optimize +from qualang_tools.digital_filters import exponential_decay, exponential_correction + +# Fit your data with the exponential_decay function +[A, tau_ns], _ = optimize.curve_fit( + exponential_decay, + time_axis_in_ns, + data_to_fit, + ) +# Derive the corresponding taps +feedforward_taps, feedback_tap = exponential_correction(A, tau_ns) +# Update the config with the digital filter parameters +config["controllers"]["con1"]["analog_outputs"][port_number] = { + "offset": 0.0, + "filter": {"feedforward": feedforward_taps, "feedback": feedback_tap}} ``` -## exponential_correction -some explanation - -### Usage examples +### highpass_correction +Calculate the best FIR and IIR filter taps to correct for a highpass decay (high-pass filter) of the shape `exp(-t/tau)`. #### ```python -from qualang_tools.loops import from_array - +from qualang_tools.digital_filters import highpass_correction + +# Derive the taps from the time constant of the exponential highpass decay tau +feedforward_taps, feedback_tap = highpass_correction(tau_ns) +# Update the config with the digital filter parameters +config["controllers"]["con1"]["analog_outputs"][port_number] = { + "offset": 0.0, + "filter": {"feedforward": feedforward_taps, "feedback": feedback_tap}} ``` -## highpass_correction -some explanation - -### Usage examples +### bounce_and_delay_correction +Calculate the FIR filter taps to correct for reflections (bounce corrections) and to add a delay. #### ```python -from qualang_tools.loops import from_array +from qualang_tools.digital_filters import bounce_and_delay_correction -``` -## bounce_and_delay_correction -some explanation +``` -### Usage examples +### calc_filter_taps +Calculate the best FIR and IIR filter taps for a system with any combination of FIR corrections, exponential +corrections (LPF), high pass compensation, reflections (bounce corrections) and a needed delay on the line. #### ```python -from qualang_tools.loops import from_array - -``` \ No newline at end of file +from scipy import optimize +from qualang_tools.digital_filters import exponential_decay +from qualang_tools.digital_filters import calc_filter_taps + + +# Fit your data with the exponential_decay function +[A, tau_ns], _ = optimize.curve_fit( + exponential_decay, + time_axis_in_ns, + data_to_fit, + ) +# Derive the taps for correction all the identified distortions (high-pass, low-pass, reflection and delay) +feedforward_taps, feedback_tap = calc_filter_taps( + fir=None, + exponential=[(A, tau_ns),], + highpass=[tau_hpf], + bounce=[(a_bounce, tau_bounce),], + delay=, +) +# Update the config with the digital filter parameters +config["controllers"]["con1"]["analog_outputs"][port_number] = { + "offset": 0.0, + "filter": {"feedforward": feedforward_taps, "feedback": feedback_tap}} +``` diff --git a/qualang_tools/digital_filters/__init__.py b/qualang_tools/digital_filters/__init__.py index 2597191a..a4eb9468 100644 --- a/qualang_tools/digital_filters/__init__.py +++ b/qualang_tools/digital_filters/__init__.py @@ -1,5 +1,6 @@ from qualang_tools.digital_filters.filters import ( calc_filter_taps, + exponential_decay, exponential_correction, highpass_correction, bounce_and_delay_correction, @@ -7,6 +8,7 @@ __all__ = [ "calc_filter_taps", + "exponential_decay", "exponential_correction", "highpass_correction", "bounce_and_delay_correction", diff --git a/qualang_tools/digital_filters/filters.py b/qualang_tools/digital_filters/filters.py index 15dae7df..0f728df9 100644 --- a/qualang_tools/digital_filters/filters.py +++ b/qualang_tools/digital_filters/filters.py @@ -64,6 +64,17 @@ def calc_filter_taps( return list(feedforward_taps), list(feedback_taps) +def exponential_decay(t, A, tau): + """Exponential decay defined as 1 + A * np.exp(-t / tau). + + :param t: numpy array for the time vector in ns + :param A: float for the exponential amplitude + :param tau: float for the exponential decay time in ns + :return: numpy array for the exponential decay + """ + return 1 + A * np.exp(-t / tau) + + def exponential_correction(A: float, tau: float, Ts: float = 1): """ Calculate the best FIR and IIR filter taps to correct for an exponential decay (LPF) of the shape @@ -176,7 +187,7 @@ def bounce_and_delay_correction( return feedforward_taps[index_start:index_end] -def _iir_correction(values, filter_type, feedforward_taps, feedback_taps, Ts:float=1): +def _iir_correction(values, filter_type, feedforward_taps, feedback_taps, Ts=1.0): b = np.zeros((2, len(values))) feedback_taps = np.append(np.zeros(len(values)), feedback_taps) @@ -195,7 +206,7 @@ def _iir_correction(values, filter_type, feedforward_taps, feedback_taps, Ts:flo return feedforward_taps, feedback_taps -def _get_coefficients_for_delay(tau, full_taps_x, Ts:float=1): +def _get_coefficients_for_delay(tau, full_taps_x, Ts=1.0): full_taps = np.sinc((full_taps_x - tau) / Ts) full_taps = _round_taps_close_to_zero(full_taps) return full_taps