Source code for dmelon.spectral.filters

"""
Lanczos filter port from MATLAB
"""

import math

import numpy as np


[docs]def lanczos_filter_coef(Cf, M): """ Compute the filter coefficients """ hkcs = lowpass_cosine_filter_coef(Cf, M) sigma = np.sin(np.pi * np.arange(1, M + 1) / M) / (np.pi * np.arange(1, M + 1) / M) sigma = np.insert(sigma, 0, 1) hkB = hkcs * sigma hkA = -hkB hkA[0] = hkA[0] + 1 coef = np.array([hkB, hkA]) return coef
[docs]def lowpass_cosine_filter_coef(Cf, M): """ Compute the lowpass coeficients using the cut frequency Cf """ sig = np.sin(np.pi * np.arange(1, M + 1) * Cf) / (np.pi * np.arange(1, M + 1) * Cf) coef = Cf * np.insert(sig, 0, 1) return coef
[docs]def spectral_window(coef, N): """ Get the spectral window from a series of coefficients """ Ff = np.atleast_2d(np.arange(0, 1 + 1e-9, 2 / N)).T window = coef[0] + 2 * np.sum( np.atleast_2d(coef[1:]) * np.cos(np.atleast_2d(np.arange(1, len(coef))) * np.pi * Ff), axis=-1, ) return window, Ff
[docs]def spectral_filtering(x, window): """ Spectral filtering of series x with the specified windows """ Nx = len(x) Cx = np.fft.fft(x) Cx = Cx[: (math.floor(Nx / 2)) + 1] CxH = Cx * window ext = np.conj(CxH[Nx - len(CxH) + 1 : 0 : -1]) CxH = np.concatenate((CxH, ext)) y = np.real(np.fft.ifft(CxH)) return y, Cx
[docs]def lanczosfilter(X, Cf, dT=1, M=100, kind="low", *args): """ Core function that filters the signal in either low or high pass """ if np.isnan(X).all(): return np.full_like(X, np.nan, dtype=np.float) kind_val = {"high": 1, "low": 0} Nf = 1 / (2 * dT) Cf = Cf / Nf coef = lanczos_filter_coef(Cf, M)[kind_val[kind]] window, Ff = spectral_window(coef, len(X)) Ff = Ff * Nf X = np.nan_to_num(X, np.nanmean(X)) y, Cx = spectral_filtering(X, window) return y