NeuroKit
NeuroKit copied to clipboard
'No R-peak detected' is not handled in ecg_quality
Description of the bug
Using ecg.ecg_quality, the function ecg.ecg_findpeaks
is used. It works well for all signals but for a really noisy signal (hand-crafted signal using ecg.ecg_simulate, with artificial powerline noise on top of it - see image and data provided), it turns out that no peaks are detected, which leads to an empty list that is not handled properly in the rest of the code leading to all sorts of errors (IndexError
, ValueError
, ZeroDivisionError
, ... errors obtained while modifying the code to handling the error).
Error obtained on original code:
NeuroKit/neurokit2/ecg/ecg_findpeaks.py", line 260, in _ecg_findpeaks_neurokit
end_qrs = end_qrs[end_qrs > beg_qrs[0]]
IndexError: index 0 is out of bounds for axis 0 with size 0
To Reproduce
- Get the provided data (
data.csv
) in Material section: clean data obtained usingnk.ecg_simulate()
with heart rate of 110Hz and PowerlineNoise added on top of it (sinusoid of amplitude 50Hz, energy ratio of 977% of the initial clean signal) - Use
nk.ecg_quality()
withsampling_rate=256
- See error
Expected behaviour
At least: I would expect the empty list to be handled so that the reported heart rate is 0 and quality is set to bad.
At best: However, seeing the shape of the signal, I would expect the function ecg_findpeaks
to spot the peaks but the quality algorithm to still be able to determine that the signal is noisy, based on its other SQIs.
Screenshots and material on the signal used for the bug
Shape of the signal on which the bug occurs
Data to us to reproduce the bug (data used for plot above) data.csv
System Specifications
-
OS: Darwin ( 64bit)
-
Python: 3.9.7
-
NeuroKit2: 0.1.4.1
-
NumPy: 1.21.2
-
Pandas: 1.3.1
-
SciPy: 1.6.2
-
sklearn: 1.0.1
-
matplotlib: 3.4.2
Hi 👋 Thanks for reaching out and opening your first issue here! We'll try to come back to you as soon as possible. ❤️
Hi @CeliaBenquet
Is your data.csv file the simulated signal? What was the method that you used with ecg_quality
?
I might be missing something here but using your instructions, I managed to run the pipeline quite smoothly without errors
ecg = pd.read_csv('data.csv')['ecg']
cleaned = nk.ecg_clean(ecg, sampling_rate=256)
quality = nk.ecg_quality(cleaned, sampling_rate=256, method='averageQRS')
nk.signal_plot([ecg, cleaned, quality], labels=['Original', 'Cleaned', 'Quality'])
and for method='zhao2018'
, running nk.ecg_quality(cleaned, sampling_rate=256, method='zhao2018')
returns 'Unacceptable'
Hi @zen-juen,
I used method='zhao2018'
.
I didn't have this line: cleaned = nk.ecg_clean(ecg, sampling_rate=256)
. I would like to evaluate the quality of the original signal and not the corresponding cleaned signal. When I run your snippet of code using ecg
rather than cleaned
with ecg_quality()
, I also get the error described above.
I see, thanks for clarifying! You're right in that the error is due to ecg_findpeaks
rather than ecg_quality
which requires the former to work in order to compute quality indices that vary based on heart rate (See zhao et al.). For ecg_findpeaks
, the default method is 'neurokit' which identifies peaks by QRS complexes, which doesn't work because of the noisy signal. You can specify another method such as 'pantompkins' and pass the resultant rpeaks into ecg_quality
to circumvent this issue:
ecg = pd.read_csv('data.csv')['ecg']
rpeaks = nk.ecg_findpeaks(ecg, method='pantompkins')
quality = nk.ecg_quality(ecg, sampling_rate=256, rpeaks=rpeaks, method='zhao2018')
quality
'Barely acceptable'
Hope this helps!
This issue has been automatically marked as inactive because it has not had recent activity. It will eventually be closed if no further activity occurs.
Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.