neuropsychology / NeuroKit

NeuroKit2: The Python Toolbox for Neurophysiological Signal Processing
https://neuropsychology.github.io/NeuroKit
MIT License
1.53k stars 410 forks source link

bio_process() and ecg_peaks() giving different HRV results by same "neurokit" method. #921

Closed CosmoLuminous closed 11 months ago

CosmoLuminous commented 11 months ago

Describe the bug When we pass output peaks calculated via bio_process() and ecg_peaks() at two different times in hrv_time() and hrv_nonlinear() functions, then we are getting different results.

To Reproduce Below is the code to help you reproduce it:

data = nk.data("bio_resting_5min_100hz")
ecg = data['ECG']
sr = 100
peaks1, info1 = nk.ecg_peaks(ecg, sampling_rate=sr)
hrv_time1 = nk.hrv_time(peaks1, sampling_rate=sr, show=True)
hrv_nonlinear1 = nk.hrv_nonlinear(peaks1, sampling_rate=sr, show=True)

peaks2, info2 = nk.bio_process(ecg, sampling_rate=sr)
hrv_time2 = nk.hrv_time(peaks2, sampling_rate=sr, show=True)
hrv_nonlinear2 = nk.hrv_nonlinear(peaks2, sampling_rate=sr, show=True)

print("hrv_time results")
for k1, v1, k2, v2 in zip(hrv_time1.iloc[0].index, hrv_time1.iloc[0].values, hrv_time2.iloc[0].index, hrv_time2.iloc[0].values):
    print(k1, v1, "\t", k2, v2)

print("\nhrv_nonlinear results")
for k1, v1, k2, v2 in zip(hrv_nonlinear1.iloc[0].index, hrv_nonlinear1.iloc[0].values, hrv_nonlinear2.iloc[0].index, hrv_nonlinear2.iloc[0].values):
    print(k1, v1, "\t", k2, v2)

Output: Results of both the functions are different.

hrv_time results
HRV_MeanNN 696.3953488372093     HRV_MeanNN 694.7563805104409
HRV_SDNN 62.135891206172104      HRV_SDNN 49.03604322104105
HRV_SDANN1 10.060727541349376    HRV_SDANN1 7.277184736458611
HRV_SDNNI1 60.27503600273103     HRV_SDNNI1 48.83361026572851
HRV_SDANN2 nan   HRV_SDANN2 nan
HRV_SDNNI2 nan   HRV_SDNNI2 nan
HRV_SDANN5 nan   HRV_SDANN5 nan
HRV_SDNNI5 nan   HRV_SDNNI5 nan
HRV_RMSSD 69.69798316887554      HRV_RMSSD 38.83776632381496
HRV_SDSD 69.77910878189152   HRV_SDSD 38.88255930233926
HRV_CVNN 0.08922502327151112     HRV_CVNN 0.0705801984646964
HRV_CVSD 0.10008392974659035     HRV_CVSD 0.05590127332876118
HRV_MedianNN 690.0   HRV_MedianNN 690.0
HRV_MadNN 44.477999999999994     HRV_MadNN 44.477999999999994
HRV_MCVNN 0.06446086956521738    HRV_MCVNN 0.06446086956521738
HRV_IQRNN 60.0   HRV_IQRNN 70.0
HRV_SDRMSSD 0.8915019973478892   HRV_SDRMSSD 1.2625865970817327
HRV_Prc20NN 660.0    HRV_Prc20NN 660.0
HRV_Prc80NN 740.0    HRV_Prc80NN 730.0
HRV_pNN50 14.651162790697676     HRV_pNN50 13.225058004640372
HRV_pNN20 49.30232558139535      HRV_pNN20 49.88399071925754
HRV_MinNN 470.0      HRV_MinNN 520.0
HRV_MaxNN 1420.0     HRV_MaxNN 860.0
HRV_HTI 7.962962962962963    HRV_HTI 8.795918367346939
HRV_TINN 234.375     HRV_TINN 187.5

hrv_nonlinear results
HRV_SD1 49.34128100482926    HRV_SD1 27.494121352572165
HRV_SD2 72.59743491590363    HRV_SD2 63.48826248280113
HRV_SD1SD2 0.679655983189845     HRV_SD1SD2 0.43305833672830907
HRV_S 11253.343335830747     HRV_S 5483.819601374913
HRV_CSI 1.4713325928606957   HRV_CSI 2.309157716613541
HRV_CVI 4.758251679217147    HRV_CVI 4.446053269533667
HRV_CSI_Modified 427.25988859940844      HRV_CSI_Modified 586.4176449061847
HRV_PIP 0.5581395348837209   HRV_PIP 0.5290023201856149
HRV_IALS 0.5116883116883117      HRV_IALS 0.48593350383631717
HRV_PSS 0.7360406091370558   HRV_PSS 0.7315789473684211
HRV_PAS 0.15     HRV_PAS 0.07633587786259542
HRV_GI 50.26385224274406     HRV_GI 50.30816640986133
HRV_SI 50.23572209987396     HRV_SI 50.348506485427414
HRV_AI 50.28115653739895     HRV_AI 50.26936026944047
HRV_PI 44.675324675324674    HRV_PI 45.26854219948849
HRV_C1d 0.5096928982725528   HRV_C1d 0.4707061362935554
HRV_C1a 0.490307101727447    HRV_C1a 0.5292938637064447
HRV_SD1d 35.22623809701072   HRV_SD1d 18.863390623838168
HRV_SD1a 34.5498420949365    HRV_SD1a 20.002913540695765
HRV_C2d 0.5209717736499618   HRV_C2d 0.5426579897495845
HRV_C2a 0.47902822635003806      HRV_C2a 0.4573420102504156
HRV_SD2d 52.399648405921354      HRV_SD2d 46.76883399047308
HRV_SD2a 50.24603868271298   HRV_SD2a 42.93524939087491
HRV_Cd 0.5174079273534969    HRV_Cd 0.5312949346524004
HRV_Ca 0.482592072646503     HRV_Ca 0.46870506534759954
HRV_SDNNd 44.64645004662446      HRV_SDNNd 35.659159683424505
HRV_SDNNa 43.11818637239822      HRV_SDNNa 33.49292604695187
HRV_DFA_alpha1 0.7413829049877829    HRV_DFA_alpha1 1.0746110702376064
HRV_MFDFA_alpha1_Width 2.373980385964734     HRV_MFDFA_alpha1_Width 1.1792035894808128
HRV_MFDFA_alpha1_Peak 1.2144704708675136     HRV_MFDFA_alpha1_Peak 1.2257886738545878
HRV_MFDFA_alpha1_Mean 0.9125443600194394     HRV_MFDFA_alpha1_Mean 1.6324867787246338
HRV_MFDFA_alpha1_Max -0.3223950875028905     HRV_MFDFA_alpha1_Max -0.5177903563580628
HRV_MFDFA_alpha1_Delta 0.7504596844298366    HRV_MFDFA_alpha1_Delta -1.4543381838513048
HRV_MFDFA_alpha1_Asymmetry -0.6271813839040538   HRV_MFDFA_alpha1_Asymmetry -0.15510781302055773
HRV_MFDFA_alpha1_Fluctuation 0.0022458324357362267   HRV_MFDFA_alpha1_Fluctuation 0.0009639468078931366
HRV_MFDFA_alpha1_Increment 0.34771722892713364   HRV_MFDFA_alpha1_Increment 0.12156741473014816
HRV_DFA_alpha2 0.7101521169948951    HRV_DFA_alpha2 0.74458349456187
HRV_MFDFA_alpha2_Width 0.41284999234860154   HRV_MFDFA_alpha2_Width 0.12025402871845214
HRV_MFDFA_alpha2_Peak 0.6651894948233759     HRV_MFDFA_alpha2_Peak 0.6260707670636863
HRV_MFDFA_alpha2_Mean 0.5283710409471867     HRV_MFDFA_alpha2_Mean 0.6861977814229123
HRV_MFDFA_alpha2_Max 1.0     HRV_MFDFA_alpha2_Max 1.0034826024405368
HRV_MFDFA_alpha2_Delta 1.0750148438698992    HRV_MFDFA_alpha2_Delta -0.09163628837599025
HRV_MFDFA_alpha2_Asymmetry -0.8313999186432409   HRV_MFDFA_alpha2_Asymmetry 0.0
HRV_MFDFA_alpha2_Fluctuation 0.00013685087673774246      HRV_MFDFA_alpha2_Fluctuation 2.6738753815680297e-05
HRV_MFDFA_alpha2_Increment 0.012984350110936458      HRV_MFDFA_alpha2_Increment 0.00185926598974056
HRV_ApEn 1.1836484532861742      HRV_ApEn 0.7965654560617645
HRV_SampEn 1.2599314579739807    HRV_SampEn 1.9786368425578704
HRV_ShanEn 4.282683406115447     HRV_ShanEn 4.256941017033136
HRV_FuzzyEn 1.0635329445370547   HRV_FuzzyEn 1.2686943754499114
HRV_MSEn 1.2668768643889061      HRV_MSEn 1.404137826745609
HRV_CMSEn 1.446925274367955      HRV_CMSEn 1.469801247099329
HRV_RCMSEn 1.630370229631    HRV_RCMSEn 2.572679544052144
HRV_CD 1.2097521306213086    HRV_CD 1.8322942434320704
HRV_HFD 1.8563723883918795   HRV_HFD 1.846506930176673
HRV_KFD 1.913071066440432    HRV_KFD 2.7223482404936066
HRV_LZC 0.8544746504250169   HRV_LZC 0.8731238852455482

Expected behaviour Since we are using same 'neurokit' method in both the scenarios, we should be getting the same output parameters.

System Specifications

welcome[bot] commented 11 months ago

Hi 👋 Thanks for reaching out and opening your first issue here! We'll try to come back to you as soon as possible. ❤️ kenobi

CosmoLuminous commented 11 months ago

In addition to it bio_analyze() and hrv() are giving different results for the same ecg signal as follows:

Code to replicate

data = nk.data("bio_resting_5min_100hz")
ecg = data['ECG']
sr = 100
peaks1, info1 = nk.ecg_peaks(ecg, sampling_rate=sr)
hrv = nk.hrv(peaks1, sampling_rate=sr, show=False)

peaks2, info2 = nk.bio_process(ecg, sampling_rate=sr)
bio = nk.bio_analyze(peaks2, sampling_rate=sr)

for idx in list(hrv.iloc[0].index):
    print(idx, hrv.iloc[0][idx], bio.iloc[0][idx])

Output

HRV_MeanNN 696.3953488372093 [[694.75638051]]
HRV_SDNN 62.135891206172104 [[49.03604322]]
HRV_SDANN1 10.060727541349376 [[7.27718474]]
HRV_SDNNI1 60.27503600273103 [[48.83361027]]
HRV_SDANN2 nan [[nan]]
HRV_SDNNI2 nan [[nan]]
HRV_SDANN5 nan [[nan]]
HRV_SDNNI5 nan [[nan]]
HRV_RMSSD 69.69798316887554 [[38.83776632]]
HRV_SDSD 69.77910878189152 [[38.8825593]]
HRV_CVNN 0.08922502327151112 [[0.0705802]]
HRV_CVSD 0.10008392974659035 [[0.05590127]]
HRV_MedianNN 690.0 [[690.]]
HRV_MadNN 44.477999999999994 [[44.478]]
HRV_MCVNN 0.06446086956521738 [[0.06446087]]
HRV_IQRNN 60.0 [[70.]]
HRV_SDRMSSD 0.8915019973478892 [[1.2625866]]
HRV_Prc20NN 660.0 [[660.]]
HRV_Prc80NN 740.0 [[730.]]
HRV_pNN50 14.651162790697676 [[13.225058]]
HRV_pNN20 49.30232558139535 [[49.88399072]]
HRV_MinNN 470.0 [[520.]]
HRV_MaxNN 1420.0 [[860.]]
HRV_HTI 7.962962962962963 [[8.79591837]]
HRV_TINN 234.375 [[187.5]]
HRV_ULF nan [[nan]]
HRV_VLF 0.017310077265848153 [[0.01283397]]
HRV_LF 0.04802607886179408 [[0.03135665]]
HRV_HF 0.0602318686518902 [[0.03045333]]
HRV_VHF 0.011185774793627326 [[0.0015541]]
HRV_TP 0.13675379957315975 [[0.07619804]]
HRV_LFHF 0.7973532938079769 [[1.02966256]]
HRV_LFn 0.3511864314680439 [[0.41151515]]
HRV_HFn 0.44044018403794116 [[0.39966021]]
HRV_LnHF -2.809553687139805 [[-3.49156008]]
HRV_SD1 49.34128100482926 [[27.49412135]]
HRV_SD2 72.59743491590363 [[63.48826248]]
HRV_SD1SD2 0.679655983189845 [[0.43305834]]
HRV_S 11253.343335830747 [[5483.81960137]]
HRV_CSI 1.4713325928606957 [[2.30915772]]
HRV_CVI 4.758251679217147 [[4.44605327]]
HRV_CSI_Modified 427.25988859940844 [[586.41764491]]
HRV_PIP 0.5581395348837209 [[0.52900232]]
HRV_IALS 0.5116883116883117 [[0.4859335]]
HRV_PSS 0.7360406091370558 [[0.73157895]]
HRV_PAS 0.15 [[0.07633588]]
HRV_GI 50.26385224274406 [[50.30816641]]
HRV_SI 50.23572209987396 [[50.34850649]]
HRV_AI 50.28115653739895 [[50.26936027]]
HRV_PI 44.675324675324674 [[45.2685422]]
HRV_C1d 0.5096928982725528 [[0.47070614]]
HRV_C1a 0.490307101727447 [[0.52929386]]
HRV_SD1d 35.22623809701072 [[18.86339062]]
HRV_SD1a 34.5498420949365 [[20.00291354]]
HRV_C2d 0.5209717736499618 [[0.54265799]]
HRV_C2a 0.47902822635003806 [[0.45734201]]
HRV_SD2d 52.399648405921354 [[46.76883399]]
HRV_SD2a 50.24603868271298 [[42.93524939]]
HRV_Cd 0.5174079273534969 [[0.53129493]]
HRV_Ca 0.482592072646503 [[0.46870507]]
HRV_SDNNd 44.64645004662446 [[35.65915968]]
HRV_SDNNa 43.11818637239822 [[33.49292605]]
HRV_DFA_alpha1 0.7413829049877829 [[1.07461107]]
HRV_MFDFA_alpha1_Width 2.373980385964734 [[1.17920359]]
HRV_MFDFA_alpha1_Peak 1.2144704708675136 [[1.22578867]]
HRV_MFDFA_alpha1_Mean 0.9125443600194394 [[1.63248678]]
HRV_MFDFA_alpha1_Max -0.3223950875028905 [[-0.51779036]]
HRV_MFDFA_alpha1_Delta 0.7504596844298366 [[-1.45433818]]
HRV_MFDFA_alpha1_Asymmetry -0.6271813839040538 [[-0.15510781]]
HRV_MFDFA_alpha1_Fluctuation 0.0022458324357362267 [[0.00096395]]
HRV_MFDFA_alpha1_Increment 0.34771722892713364 [[0.12156741]]
HRV_DFA_alpha2 0.7101521169948951 [[0.74458349]]
HRV_MFDFA_alpha2_Width 0.41284999234860154 [[0.12025403]]
HRV_MFDFA_alpha2_Peak 0.6651894948233759 [[0.62607077]]
HRV_MFDFA_alpha2_Mean 0.5283710409471867 [[0.68619778]]
HRV_MFDFA_alpha2_Max 1.0 [[1.0034826]]
HRV_MFDFA_alpha2_Delta 1.0750148438698992 [[-0.09163629]]
HRV_MFDFA_alpha2_Asymmetry -0.8313999186432409 [[0.]]
HRV_MFDFA_alpha2_Fluctuation 0.00013685087673774246 [[2.67387538e-05]]
HRV_MFDFA_alpha2_Increment 0.012984350110936458 [[0.00185927]]
HRV_ApEn 1.1836484532861742 [[0.79656546]]
HRV_SampEn 1.2599314579739807 [[1.97863684]]
HRV_ShanEn 4.282683406115447 [[4.25694102]]
HRV_FuzzyEn 1.0635329445370547 [[1.26869438]]
HRV_MSEn 1.2668768643889061 [[1.40413783]]
HRV_CMSEn 1.446925274367955 [[1.46980125]]
HRV_RCMSEn 1.630370229631 [[2.57267954]]
HRV_CD 1.2097521306213086 [[1.83229424]]
HRV_HFD 1.8563723883918795 [[1.84650693]]
HRV_KFD 1.913071066440432 [[2.72234824]]
HRV_LZC 0.8544746504250169 [[0.87312389]]

PLEASE NOTE These results will differ even more in case of ecg samples with more noise.

-Aman

DominiqueMakowski commented 11 months ago

Could you help me by isolating which indices are different, and if there are any non-deterministic processes in them?

CosmoLuminous commented 11 months ago

Could you help me by isolating which indices are different, and if there are any non-deterministic processes in them?

Hi @DominiqueMakowski

I have tried with two different ECG Samples, and the matched and mismatched indices are different in both the cases: Below are the indices which match and mismatch for HRV RESULTS

'''SIGNAL1'''
MISMATCH_INDICES:  ['HRV_MeanNN', 'HRV_SDNN', 'HRV_SDANN1', 'HRV_SDNNI1', 'HRV_SDANN2', 'HRV_SDNNI2', 'HRV_SDANN5', 'HRV_SDNNI5', 'HRV_RMSSD', 'HRV_SDSD', 'HRV_CVNN', 'HRV_CVSD', 'HRV_IQRNN', 'HRV_SDRMSSD', 'HRV_Prc80NN', 'HRV_pNN50', 'HRV_pNN20', 'HRV_MinNN', 'HRV_MaxNN', 'HRV_HTI', 'HRV_TINN', 'HRV_ULF', 'HRV_VLF', 'HRV_LF', 'HRV_HF', 'HRV_VHF', 'HRV_TP', 'HRV_LFHF', 'HRV_LFn', 'HRV_HFn', 'HRV_LnHF', 'HRV_SD1', 'HRV_SD2', 'HRV_SD1SD2', 'HRV_S', 'HRV_CSI', 'HRV_CVI', 'HRV_CSI_Modified', 'HRV_PIP', 'HRV_IALS', 'HRV_PSS', 'HRV_PAS', 'HRV_GI', 'HRV_SI', 'HRV_AI', 'HRV_PI', 'HRV_C1d', 'HRV_C1a', 'HRV_SD1d', 'HRV_SD1a', 'HRV_C2d', 'HRV_C2a', 'HRV_SD2d', 'HRV_SD2a', 'HRV_Cd', 'HRV_Ca', 'HRV_SDNNd', 'HRV_SDNNa', 'HRV_DFA_alpha1', 'HRV_MFDFA_alpha1_Width', 'HRV_MFDFA_alpha1_Peak', 'HRV_MFDFA_alpha1_Mean', 'HRV_MFDFA_alpha1_Max', 'HRV_MFDFA_alpha1_Delta', 'HRV_MFDFA_alpha1_Asymmetry', 'HRV_MFDFA_alpha1_Fluctuation', 'HRV_MFDFA_alpha1_Increment', 'HRV_DFA_alpha2', 'HRV_MFDFA_alpha2_Width', 'HRV_MFDFA_alpha2_Peak', 'HRV_MFDFA_alpha2_Mean', 'HRV_MFDFA_alpha2_Max', 'HRV_MFDFA_alpha2_Delta', 'HRV_MFDFA_alpha2_Asymmetry', 'HRV_MFDFA_alpha2_Increment', 'HRV_ApEn', 'HRV_SampEn', 'HRV_ShanEn', 'HRV_FuzzyEn', 'HRV_MSEn', 'HRV_CMSEn', 'HRV_RCMSEn', 'HRV_CD', 'HRV_HFD', 'HRV_KFD', 'HRV_LZC']
MATCH_INDICES:  ['HRV_MedianNN', 'HRV_MadNN', 'HRV_MCVNN', 'HRV_Prc20NN', 'HRV_MFDFA_alpha2_Fluctuation']

'''SIGNAL2:'''
MISMATCH_INDICES:  ['HRV_SDNN', 'HRV_SDANN1', 'HRV_SDNNI1', 'HRV_SDANN2', 'HRV_SDNNI2', 'HRV_SDANN5', 'HRV_SDNNI5', 'HRV_RMSSD', 'HRV_SDSD', 'HRV_CVNN', 'HRV_CVSD', 'HRV_MadNN', 'HRV_MCVNN', 'HRV_IQRNN', 'HRV_SDRMSSD', 'HRV_Prc20NN', 'HRV_Prc80NN', 'HRV_pNN50', 'HRV_pNN20', 'HRV_MinNN', 'HRV_MaxNN', 'HRV_HTI', 'HRV_TINN', 'HRV_ULF', 'HRV_VLF', 'HRV_LF', 'HRV_HF', 'HRV_VHF', 'HRV_LFHF', 'HRV_LFn', 'HRV_HFn', 'HRV_LnHF', 'HRV_SD1', 'HRV_SD2', 'HRV_SD1SD2', 'HRV_S', 'HRV_CSI', 'HRV_CVI', 'HRV_CSI_Modified', 'HRV_PIP', 'HRV_IALS', 'HRV_PSS', 'HRV_PAS', 'HRV_GI', 'HRV_SI', 'HRV_AI', 'HRV_PI', 'HRV_C1d', 'HRV_C1a', 'HRV_SD1d', 'HRV_SD1a', 'HRV_C2d', 'HRV_C2a', 'HRV_SD2d', 'HRV_SD2a', 'HRV_Cd', 'HRV_Ca', 'HRV_SDNNd', 'HRV_SDNNa', 'HRV_DFA_alpha1', 'HRV_MFDFA_alpha1_Width', 'HRV_MFDFA_alpha1_Peak', 'HRV_MFDFA_alpha1_Mean', 'HRV_MFDFA_alpha1_Max', 'HRV_MFDFA_alpha1_Delta', 'HRV_MFDFA_alpha1_Asymmetry', 'HRV_MFDFA_alpha1_Fluctuation', 'HRV_MFDFA_alpha1_Increment', 'HRV_ApEn', 'HRV_SampEn', 'HRV_ShanEn', 'HRV_FuzzyEn', 'HRV_MSEn', 'HRV_CMSEn', 'HRV_RCMSEn', 'HRV_CD', 'HRV_HFD', 'HRV_KFD', 'HRV_LZC']
MATCH_INDICES:  ['HRV_MeanNN', 'HRV_MedianNN', 'HRV_TP']

OBSERVATION: There seems to be no consistency between the results of the two signals.

CosmoLuminous commented 11 months ago

@DominiqueMakowski,

Did you or someone from your team get a chance to look into this issue? Ideally both the functions should give the same results but apparently they are not. Please try to rectify it, as this one seems to be a major bug raising a question over the reliability of the neurokit2 tool.

Regards Aman

DominiqueMakowski commented 11 months ago

I don't think it's a bug, it's likely just that bio_process does some additional steps like signal cleaning etc. You should try adding the same steps and check again

CosmoLuminous commented 11 months ago

I don't think it's a bug, it's likely just that bio_process does some additional steps like signal cleaning etc. You should try adding the same steps and check again

@DominiqueMakowski ,

Alright. Thanks for the clarification. Just one more query, which of the two methods would you recommend for calculating the HRV parameters from realtime ECG Signals?

DominiqueMakowski commented 11 months ago

bio_process is fine (though the discrepancies should be small in general so it doesn't matter that much)