|
| 1 | +""" |
| 2 | +IIR Filters |
| 3 | +=========== |
| 4 | +
|
| 5 | +Design, apply, and evaluate IIR Filters. |
| 6 | +
|
| 7 | +This tutorial covers the design and application of Infinite Impulse Response (IIR) filters |
| 8 | +(``neurodsp.filt.iir``). |
| 9 | +
|
| 10 | +""" |
| 11 | +################################################################################################### |
| 12 | + |
| 13 | +import numpy as np |
| 14 | +from neurodsp.sim import sim_combined |
| 15 | +from neurodsp.filt import filter_signal |
| 16 | +from neurodsp.filt.iir import design_iir_filter, apply_iir_filter |
| 17 | +from neurodsp.filt.utils import compute_frequency_response |
| 18 | +from neurodsp.plts import plot_filter_properties, plot_time_series |
| 19 | + |
| 20 | +################################################################################################### |
| 21 | +# Introduction |
| 22 | +# ------------ |
| 23 | +# |
| 24 | +# In contrast to FIR filters, IIR filters produce an impulse response that is dependent on past and |
| 25 | +# values of the impulse and impulse response (i.e. recursion or feedback), producing a response that |
| 26 | +# is never zero. Due to this, the IIR filters are not typically implemented using convolution. The |
| 27 | +# math introduced in the FIR tutorial may be extended to IIR filters, with a second expression |
| 28 | +# representing feedback: |
| 29 | +# |
| 30 | +# .. math:: |
| 31 | +# |
| 32 | +# y(n) = \sum_{k=0}^M b_k x(n-k) - \sum_{k=1}^N a_k y(n-k) |
| 33 | +# |
| 34 | +# .. math:: |
| 35 | +# |
| 36 | +# H(z) = \frac{\sum_{k=0}^M b_k z^{-k}}{\sum_{k=1}^N a_k z^{-k}} |
| 37 | +# |
| 38 | + |
| 39 | + |
| 40 | +################################################################################################### |
| 41 | +# Design |
| 42 | +# ------ |
| 43 | +# |
| 44 | +# Neurodsp supports the butterworth IIR filter. The order of this filter controls how smooth (low |
| 45 | +# orders) or steep (high order) the roll-off of the transition band is. Below, we will design an |
| 46 | +# IIR filter and plot the frquency response. |
| 47 | +# |
| 48 | + |
| 49 | +# Settings |
| 50 | +fs = 1000 |
| 51 | +pass_type = 'bandpass' |
| 52 | +f_range = (1, 50) |
| 53 | +butterworth_order = 2 |
| 54 | + |
| 55 | +# Get the second-order series (sos) representatino of the filter |
| 56 | +sos = design_iir_filter(fs, pass_type, f_range, butterworth_order) |
| 57 | + |
| 58 | +################################################################################################### |
| 59 | +# Apply |
| 60 | +# ----- |
| 61 | +# |
| 62 | +# The filter we previously designed may now be applied to a signal. Inspecting the filtered signal, |
| 63 | +# relative to the original signal, is recommended. |
| 64 | +# |
| 65 | + |
| 66 | +# Simulate |
| 67 | +n_seconds = 1 |
| 68 | + |
| 69 | +components = {'sim_powerlaw' : {'exponent' : 0}, |
| 70 | + 'sim_oscillation' : {'freq' : 10}} |
| 71 | + |
| 72 | +variances = [0.1, 1] |
| 73 | + |
| 74 | +sig = sim_combined(n_seconds, fs, components, variances) |
| 75 | + |
| 76 | +# Apply the filter |
| 77 | +sig_filt = apply_iir_filter(sig, sos) |
| 78 | + |
| 79 | +# Plot |
| 80 | +times = np.arange(0, len(sig)/fs, 1/fs) |
| 81 | +plot_time_series(times, [sig, sig_filt], ['Raw', 'Filtered']) |
| 82 | + |
| 83 | +################################################################################################### |
| 84 | +# Reporting |
| 85 | +# --------- |
| 86 | +# |
| 87 | +# In addition, to careful filter design, `Widman et al., 2015 <https://pubmed.ncbi.nlm.nih.gov/25128257/>`_ |
| 88 | +# recommends reporting the following filter parameters: |
| 89 | +# |
| 90 | +# - Filter Pass-Type |
| 91 | +# - Cutoff Frequency and Definition |
| 92 | +# - Filter Order |
| 93 | +# - Transition Bandwidth |
| 94 | +# - Passband Ripple and Stopband Attenuation |
| 95 | +# - Filter Delay and Causality |
| 96 | +# - Direction of Computation |
| 97 | +# |
| 98 | +# The design, application, and evaluation of a filter may be performed using the |
| 99 | +# :func:`~.filter_signal` function. The ``plot_properties`` argument plots the frequency response. |
| 100 | +# The frqeuency response and parameters may be saved by passing a path and filename to the |
| 101 | +# ``save_properties`` argument. |
| 102 | +# |
| 103 | + |
| 104 | +sig_filt = filter_signal(sig, fs, pass_type, f_range, filter_type='iir', |
| 105 | + butterworth_order=2, plot_properties=True, print_transitions=True) |
0 commit comments