neuropsychology / NeuroKit

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

Compute HRV from Inter-beat intervals (IBI / RRI) #433

Closed marianoalbaladejo closed 3 years ago

marianoalbaladejo commented 3 years ago

Hi,

I have a sensor that returns in a list the inter-beat intervals (distance in milliseconds between peaks) and not the PPG original signal. I want to use the hrv function to get the heart rate metrics, but my problem is that I can not use the hrv function because it requires a peak list. Is there a function to convert the inter-beat intervals to a peak list or another way to get the heart rate measures from the inter-beat intervals?

Thanks for your help.

welcome[bot] commented 3 years 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

DominiqueMakowski commented 3 years ago

Hi @marianoalbaladejo unless there's something I missed, you can retrieve the peaks location by a cumulative sum of the IBI:

import numpy as np

ibi = [500, 400, 700, 500, 300, 800, 500]
peaks = np.cumsum(ibi)
peaks
array([ 500,  900, 1600, 2100, 2400, 3200, 3700], dtype=int32)

Let me know if that helps!

marianoalbaladejo commented 3 years ago

I have seen in the documentation that the nk.hrv input is a dictionary returned by ecg_findpeaks, ecg_peaks, ppg_findpeaks, or ppg_peaks. My problem is that I have the IBI and not the PPG signal. For this reason, I can't use the functions that generate the required dictionary. Is it correct to use the cumulative sum of the IBI as input for the nk.hrv method?

Thanks so much for the help.

zen-juen commented 3 years ago

Hi there @marianoalbaladejo!

Hmm on further inspection, the concept of converting ibi into peaks using np.cumsum only applies if you can assume that the first peak occurs at sample point 0 (and hence using the example @DominiqueMakowski gave, the first IBI and peak will have equivalent values). But otherwise, because IBI values inherently cannot tell you where your first R-peak occurred, it seems unlikely to obtain the peak points accurately.

It's interesting your sensor returns IBI but not the original signal 🤔 Does it return any other information?

@DominiqueMakowski If this is a common occurrence I'm wondering if we can have the function account for direct IBI inputs, since the first step in the hrv functions is to generate IBI from peaks anyway!

DominiqueMakowski commented 3 years ago

into peaks using np.cumsum only applies if you can assume that the first peak occurs at sample point 0

For HRV the actual location doesn't matter much anyway, but you're right that we should append the first peak:

import numpy as np

ibi = [500, 400, 700, 500, 300, 800, 500]
peaks = np.append([0], np.cumsum(ibi))

I have seen in the documentation that the nk.hrv input is a dictionary returned by ecg_findpeaks

You probably can also pass directly the array that you obtained above, it should work

marianoalbaladejo commented 3 years ago

I have done different experiments, and I have got the same results with the first peak (0) and without it. Thanks for the solution!

But finally, I have a little question, what is the sampling rate for an IBI sequence? Because I have an IBI each time that a peak is detected. I understand the concept of sampling rate for signals, but not for the distance between the peaks of a signal because it changes. The BVP sensor measure with a frequency of 64 Hz, but if I use it in the nk.hrv, the results have no sense. I have an IBI for every peak and not with constant frequency. I have made some tests and compared the results with the results obtained by another device, and I get that If the IBI is in milliseconds, the correct sample rate is 1000, and if IBI is in seconds (IBI/1000), the correct sampling rate es 1. Does this conclusion have an explication due to how the nk.hrv function works?

I am very grateful for the received answers and the interest in the problem. Thanks to everyone!

DominiqueMakowski commented 3 years ago

The BVP sensor measure with a frequency of 64 Hz

This is indeed most likely unrelated to how the IBIs are expressed. If it's Human heart rates, you can probably infer the correct "sampling rate" (in this case, the unit of the IBI) by computing the average IBI, and then converting it to BPM and see if the value makes sense.

For instance, say the average IBI is 700. If you assume that these values are milliseconds (i.e., "sampling rate" of1000) then the corresponding BPM is: 1000/700 (=1.4 beat per second) * 60 = 85.6 beats per minute, which is plausible.

marianoalbaladejo commented 3 years ago

Finally, all my questions are resolved, thanks to everyone. The efficiency and short response time has been amazing.