Документация Engee
Notebook

Настройка параметров фильтра через пользовательскую форму

Построим небольшое приложение (маску ячеек), которое поможет нам подбирать параметры фильтров, не покидая интерактивного скрипта.

Загрузка данных

Предположим, у нас есть следующий сигнал:

In [ ]:
gr()
using CSV, DataFrames
d = CSV.read( "$(@__DIR__)/scope_data.csv", DataFrame );

В качестве частоты дискретизации возьмем усредненную разницу между временными шагами.

In [ ]:
using Statistics
Fs = 1 / mean(diff(d.Time));    # Частот дискретизации
Fn = Fs/2;                      # Частота Найквиста
L = length( d.Time );           # Количество отсчетов в сигнале

И попробуем построить фильтр, который удовлетворит каким-нибудь техническим требованиям.

In [ ]:
using FFTW, DSP
Fl = round.(Int, round(L/2)+1)           # Количество точек в дискретном преобразовани Фурье
Fv = range(1/Fl, 1, length=Fl) .* Fn;    # Вектор частот (исключая первую точку – 0)
Iv = 1:length(Fv);                       # Вектор индексов
In [ ]:
# @markdown ## Настройка параметров фильтра

# Значения по умолчанию
pT, pB, sT, sB, Rp, Rs = 20, 30, 18, 35, 1, 50;

# @markdown ### Границы пропускаемых частот фильтра
Нижняя_граница_пропускаемых_частот = 19 # @param {type:"slider", min:2, max:100, step:1}
Верхняя_граница_пропускаемых_частот = 45 # @param {type:"slider", min:2, max:100, step:1}
# @markdown ### Границы поглощаемых частот фильтра
Нижняя_граница_поглощамеых_частот = 12 # @param {type:"slider", min:2, max:100, step:1}
Верхняя_граница_поглощаемых_частот = 60 # @param {type:"slider", min:2, max:100, step:1}
# @markdown ### Параметры пиков
Пик_в_полосе_пропускания = 8 # @param {type:"slider", min:2, max:100, step:1}
Пик_в_полосе_поглощения = 39 # @param {type:"slider", min:2, max:100, step:1}

pB, pT = Нижняя_граница_пропускаемых_частот, Верхняя_граница_пропускаемых_частот
sB, sT = Нижняя_граница_поглощамеых_частот, Верхняя_граница_поглощаемых_частот
Rp = Пик_в_полосе_пропускания
Rs = Пик_в_полосе_поглощения
Wp = (pB, pT) ./ Fn;
Ws = (sB, sT) ./ Fn;

n,Ws = ellipord( Wp, Ws, Rp, Rs);            # Найдем порядок фильтра с желаемыми характеристиками
designmethod = Elliptic( n, Rp, Rs );        # Создадим эллиптический фильтр
responsetype = Bandpass( Rp, Rs; fs=Fn );    # И полосной фильтр

# Сглаженный спектр
TF = fft( d.Measurement ) ./ L
TF1 = filt( digitalfilter(responsetype, designmethod), TF );

plot(
    plot( Fv, 20 .* log10.(abs.([TF[Iv] TF1[Iv]])), xscale=:log10, lw=[1 2] ),
    plot( Fv, angle.([TF[Iv] TF1[Iv]]) .* 180/pi, xscale=:log10, lw=[1 2] ),
    layout=(2,1)
)

plot!( ylabel=["Амплитуда (дБ)" "Фаза (град)"], leg=:false )
plot!( title=["ЛАФЧХ системы" ""], xlabel=["" "Частота (Гц)"] )
Out[0]:

Если скрыть код и включить опцию "Автовыполнения ячейки при изменении параметров" (кнопка слева от маски ячейки), то можно интерактивно настраивать параметры фильтрации.

image.png

Заключение

Инструментарий масок для кодовых ячеек позволяет создать собственный интерфейс для настройки алгоритмов. С его помощью мы можем подобрать параметры фильтра, которые нужным образом отразятся на выходном сигнале некоторого звена.