filter_bandpass

selfeeg.augmentation.functional.filter_bandpass(x: ArrayLike, Fs: float, Wp: list[float] = [8, 35], Ws: list[float] = [1, 50], rp: float = np.float64(0.9151498112135024), rs: float = np.float64(16.478174818886377), filter_type: str = 'butter', order: int = None, Wn: float = None, a: ndarray | float = None, b: ndarray | float = None, eeg_band: str = None, return_filter_coeff: bool = False) tuple[ArrayLike, tuple[ArrayLike, ArrayLike] | None][source]

applies a bandpass filter on the last dimension of the ArrayLike.

If a and b coefficient are not given, internally calls get_filter_coeff with the other arguments to get them. The filter design follows this hierarchical order:

(Wp,Ws,rp,rs) –> (Wn, order) –> (a,b)

Therefore the arguments closer to a and b in the scheme are used to get the filter coefficient.

If eeg_band is given, (Wp,Ws,rp,rs) are ignored and instantiated according to the EEG band specified. The priority order remains. So, if (Wn, order) or (a,b) are given, the filter will be created according to such argument.

Parameters:
  • x (ArrayLike) – the input Tensor or Array. The last two dimensions must refer to the EEG recording (Channels x Samples).

  • Fs (float) – the sampling frequency in Hz.

  • Wp (ArrayLike, optional) –

    Passband edges in Hz. It must be a length 2 scalar vector.

    Default = None

  • Ws (ArrayLike, optional) –

    Stopband edges in Hz. It must be a length 2 scalar vector.

    Default = None

  • rp (float, optional) –

    Ripple at bandpass in dB.

    Default = -20*log10(0.95)

  • rs (float, optional) –

    Ripple at stopband in dB.

    Default = -20*log10(0.15)

  • filter_type (str, optional) –

    Which filter design. Accepted values are ‘butter’, ‘ellip’, ‘cheby1’, ‘cheby2’

    Default = “butter”

  • order (int, optional) –

    The order of the filter.

    Default = None

  • Wn (ArrayLike, optional) –

    The critical frequency or frequencies.

    Default = None

  • a (ArrayLike, optional) –

    The denominator coefficients of the filter

    Default = None

  • b (ArrayLike, optional) –

    The numerator coefficients of the filer

    Default = None

  • eeg_band (str, optional) –

    Any of the possible EEG bands. Accepted values are “delta”, “theta”, “alpha”, “beta”, “gamma”, “gamma_low”, “gamma_high”. Note that eeg_band bypass any (Wp, Ws, rp, rs) if given.

    Default = None

  • return_filter_coeff (bool, optional) – whether to return the filter coefficient or not Default: False

Returns:
  • x (ArrayLike) – The augmented version of the input Tensor or Array.

  • b (ArrayLike, optional) – Array with the numerator coefficients of rational transfer function.

  • a (ArrayLike, optional) – Array with the denominator coefficients of rational transfer function.

Note

Many parameters are those used in scipy’s implementation of Matlab-style filters, except for Wp and Ws, which must be specified directly in Hz. The normalization to [0,1] with respect to half-cycles/sample (i.e., Nyquist frequency) is done directly inside the get_filter_coeff function.

Note

Pytorch filtfilt works differently on edges and is pretty unstable with high order filters, so avoid restrictive conditions that can increase the order of the filter.

Example

>>> import torch
>>> import numpy as np
>>> from scipy.signal import periodogram
>>> import selfeeg.augmentation as aug
>>> x = torch.zeros(16,32,1024) + torch.sin(torch.linspace(0, 8*torch.pi,1024))
>>> x += torch.sin(torch.linspace(0, 48*2*torch.pi,1024))
>>> x += torch.sin(torch.linspace(0, 256*2*torch.pi,1024))
>>> f, per1 = periodogram(x[0,0], 128)
>>> xaug = aug.filter_bandpass(x, 128, [13,22], [5,27])
>>> f, per2 = periodogram(xaug[0,0], 128)
>>> print(np.isclose(np.max(per2[f<5]), 0, rtol=1e-04, atol=1e-04))# should return True
>>> print(np.isclose(np.max(per2[f>27]), 0, rtol=1e-04, atol=1e-04))# should return True