Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix phase inversion of odd order high pass filters #693

Merged
merged 1 commit into from
Jan 7, 2024

Conversation

myd7349
Copy link
Contributor

@myd7349 myd7349 commented Jan 7, 2024

This is a known issue with DSPFilters:
vinniefalco/DSPFilters#29
and has been fixed in iir1 and iirj:
berndporr/iir1@379d697
berndporr/iirj#27

Test script:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from importlib.metadata import version

from brainflow.data_filter import DataFilter, FilterTypes
import matplotlib.pyplot as plt
import numpy as np
from scipy import signal


def scipy_butter_hp(data, order, cutoff, fs):
    sos = signal.butter(order, cutoff, 'hp', fs=fs, output='sos')
    return signal.sosfilt(sos, data)


def brainflow_butter_hp(data, order, cutoff, fs):
    data_copy = np.array(data, dtype=np.float64)

    DataFilter.perform_highpass(
        data_copy,
        fs,
        cutoff,
        order,
        FilterTypes.BUTTERWORTH,
        0)

    return data_copy


def main():
    print('brainflow version:', version('brainflow'))

    data = (
        -105, -86, -66, -46, -28, -27, -44, -63,
        -83, -102, -114, -115, -115, -116, -116, -116,
        -116, -116, -116, -116, -111, -95, -76, -56,
        -37, -24, -34, -54, -73, -92, -109, -114,
    )
    
    plt.figure(
        'Butterworth high pass filter test',
        figsize=(10, 8))
    
    max_order = 5

    plt.subplot(max_order+1, 2, 1)
    plt.plot(data)
    plt.title('Input data')
    
    plt.subplot(max_order+1, 2, 2)
    plt.plot(data)
    plt.title('Input data')

    for order in range(1, max_order+1):
        print(f'-------------------- order = {order} --------------------')

        plt.subplot(max_order+1, 2, order*2+1)
        filtered = scipy_butter_hp(data, order, 0.16, 512)
        print(f'scipy: {filtered}')
        plt.plot(filtered)
        plt.title(f'SciPy butter, order = {order}')

        plt.subplot(max_order+1, 2, order*2+2)
        filtered = brainflow_butter_hp(data, order, 0.16, 512)
        print(f'brainflow: {filtered}')
        plt.plot(filtered)
        plt.title(f'BrainFlow butter, order = {order}')

    plt.tight_layout()
    plt.savefig('butter_hp.png')


if __name__ == '__main__':
    main()


# References:
# https://github.com/berndporr/iir1/commit/379d697de7719110465240301531c53845021edf
# https://github.com/vinniefalco/DSPFilters/issues/29
# https://github.com/berndporr/iirj/issues/27
# [Matplotlib subplots_adjust hspace so titles and xlabels don't overlap?](https://stackoverflow.com/questions/2418125/matplotlib-subplots-adjust-hspace-so-titles-and-xlabels-dont-overlap)
# https://peps.python.org/pep-0396/

Output:

butter_hp

brainflow version: 5.10.2
-------------------- order = 1 --------------------
scipy: [-104.89701756  -85.70988961  -65.56137934  -45.45239179  -27.38088786
  -26.32815911  -43.25984123  -62.15634909  -82.01480934 -100.83529661
 -112.62573167 -113.4038276  -113.18137802 -113.95838401 -113.73484663
 -113.51174774 -113.28908647 -113.06686196 -112.84507337 -112.62371983
 -107.40770441  -91.21270922  -72.05242399  -51.9307038   -32.847473
  -19.79579058  -29.74715189  -49.66918506  -68.55312055  -87.40001386
 -104.21189925 -109.00257636]
brainflow: [104.89701757  85.7098896   65.56137935  45.45239178  27.38088787
  26.3281591   43.25984124  62.15634908  82.01480935 100.8352966
 112.62573168 113.40382759 113.18137803 113.958384   113.73484664
 113.51174773 113.28908648 113.06686195 112.84507338 112.62371982
 107.40770442  91.21270921  72.052424    51.93070379  32.84747301
  19.79579057  29.7471519   49.66918505  68.55312056  87.40001385
 104.21189926 109.00257635]
-------------------- order = 2 --------------------
scipy: [-104.85431906  -85.58952089  -65.37920097  -45.22467155  -27.12308065
  -26.04799369  -42.95081373  -61.80382287  -81.60292817 -100.3482048
 -112.05082745 -112.73582973 -112.41988594 -113.102998   -112.78516781
 -112.46778474 -112.15084875 -111.83435984 -111.51831797 -111.20272313
 -105.89451248  -89.61587536  -70.38619537  -50.21095479  -31.09007839
  -18.0137789   -27.94175893  -47.82822721  -66.66075461  -85.44080371
 -102.1712226  -106.87150477]
brainflow: [-104.85431907  -85.58952088  -65.37920098  -45.22467154  -27.12308066
  -26.04799368  -42.95081374  -61.80382286  -81.60292818 -100.34820479
 -112.05082746 -112.73582972 -112.41988595 -113.10299799 -112.78516782
 -112.46778473 -112.15084876 -111.83435983 -111.51831798 -111.20272312
 -105.89451249  -89.61587535  -70.38619538  -50.21095478  -31.0900784
  -18.01377889  -27.94175894  -47.8282272   -66.66075462  -85.4408037
 -102.17122261 -106.87150476]
-------------------- order = 3 --------------------
scipy: [-104.79403522  -85.41977989  -65.12276101  -44.90478921  -26.76178673
  -25.65633695  -42.5197115   -61.31274041  -81.02967735  -99.67067212
 -111.25156695 -111.80778877 -111.36292568 -111.91698064 -111.46995666
 -111.02381826 -110.57856458 -110.13419473 -109.69070784 -109.24810303
 -103.81618727  -87.42632553  -68.10589804  -47.86261549  -28.69632704
  -15.59315097  -25.49607819  -45.34036511  -64.10847295  -82.80251314
  -99.42655471 -104.00819765]
brainflow: [104.79403523  85.41977988  65.12276102  44.9047892   26.76178674
  25.65633694  42.51971151  61.3127404   81.02967736  99.67067211
 111.25156696 111.80778876 111.36292569 111.91698063 111.46995667
 111.02381825 110.57856459 110.13419472 109.69070785 109.24810302
 103.81618728  87.42632552  68.10589805  47.86261548  28.69632705
  15.59315096  25.4960782   45.3403651   64.10847296  82.80251313
  99.42655472 104.00819764]
-------------------- order = 4 --------------------
scipy: [-104.73097499  -85.2422957   -64.85479411  -44.57077419  -26.3848473
  -25.24808189  -42.07067738  -60.8014955   -80.43308573  -98.96570328
 -110.42010016 -110.84259684 -110.26402235 -110.684381   -110.1036771
 -109.5244771  -108.94677872 -108.37057969 -107.79587774 -107.22267059
 -101.66376669  -85.1601252   -65.7474759   -45.43583536  -26.22494562
  -13.09661412  -22.97632753  -42.77951486  -61.48331342  -80.0905408
  -96.6065698  -101.0675054 ]
brainflow: [-104.730975    -85.24229569  -64.85479412  -44.57077418  -26.38484731
  -25.24808188  -42.07067739  -60.80149549  -80.43308574  -98.96570327
 -110.42010017 -110.84259683 -110.26402236 -110.68438099 -110.10367711
 -109.52447709 -108.94677873 -108.37057968 -107.79587775 -107.22267058
 -101.6637667   -85.16012519  -65.74747591  -45.43583535  -26.22494563
  -13.09661411  -22.97632754  -42.77951485  -61.48331343  -80.09054079
  -96.60656981 -101.06750539]
-------------------- order = 5 --------------------
scipy: [-104.66694403  -85.06215709  -64.58299862  -44.23224394  -26.00314318
  -24.83504409  -41.61673514  -60.28493722  -79.83049569  -98.25380133
 -109.58061984 -109.86835516 -109.15519755 -109.44115258 -108.72622582
 -108.01359478 -107.30325491 -106.59520169 -105.88943059 -105.18593708
  -99.50057645  -82.88404522  -63.38053489  -43.00237675  -23.74917464
  -10.59832945  -20.4575302   -40.22207083  -58.86370485  -77.38599546
  -93.79566697  -98.13748634]
brainflow: [104.66694404  85.06215708  64.58299863  44.23224393  26.00314319
  24.83504408  41.61673515  60.28493721  79.8304957   98.25380132
 109.58061985 109.86835515 109.15519756 109.44115257 108.72622583
 108.01359477 107.30325492 106.59520168 105.8894306  105.18593707
  99.50057646  82.88404521  63.3805349   43.00237674  23.74917465
  10.59832944  20.45753021  40.22207082  58.86370486  77.38599545
  93.79566698  98.13748633]

This is a known issue with DSPFilters:
vinniefalco/DSPFilters#29
and has been fixed in iir1 and iirj:
berndporr/iir1@379d697
berndporr/iirj#27
@Andrey1994
Copy link
Member

wow, I am surprised it was not found before. Thanks a lot for the fix!

@Andrey1994 Andrey1994 merged commit 4b494e2 into brainflow-dev:master Jan 7, 2024
11 checks passed
@myd7349 myd7349 deleted the fix-odd-order-hp branch January 7, 2024 12:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants