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

Difficulty getting RR interval artefact handling working #1062

Open
Chris-Spooner999 opened this issue Jan 22, 2025 · 7 comments
Open

Difficulty getting RR interval artefact handling working #1062

Chris-Spooner999 opened this issue Jan 22, 2025 · 7 comments

Comments

@Chris-Spooner999
Copy link

Hi,
I am using the "Kubios" option for artefact handling in NeuroKit 2 signal_fixpeaks( ) function for HRV deartefacting on my project. I am experiencing problem with some of the very basic artefacts with RR interval data coming from a Polar H10 ECG device. The artefacts are not totally removed from the data. I have included graphs from Kubios HRV from before and after the Kubios artefact correction in NeuroKit 2. You can see that a point has been added to the data and that the RR inetrval values of the artfact data has been reduced, but not enough. I have also included the plots provided by the NeuroKit 2 Kubios artefact handling. I also tried using the "NeuroKit" artefact handling option in the signal_fixpeaks( ) function and that doens't change the RR interval data at all.

If I am doing something wrong then that would be great, but it looks to me that the signal_fixpeaks( ) function doesn't work as expected. Let me know if someone who understands the signal_fixpeaks( ) code wants the RR interval text files I have generated for this. Any help would be appreciated.

Image

Image

Image

Thanks!

Copy link

welcome bot commented Jan 22, 2025

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

@DerAndereJohannes
Copy link
Collaborator

Hey, I don't mind taking a look at your situation when I have some extra time. If you are willing to send the data, the code you used and the sampling rate of the original data, then I would take a look at it.

@Chris-Spooner999
Copy link
Author

Chris-Spooner999 commented Jan 27, 2025

Hi @DerAndereJohannes,
thanks for offering some help. I've attached text files for the data before and after the artefact processing. Here is some code that can be used to generate the problem:

import neurokit2 as nk
import numpy as np

data_in = np.loadtxt('before.txt')

data_accum = np.zeros((data_in.size - 1,), dtype=int)
data_accum[0] = data_in[0].item()
for i, x in enumerate(data_in[1:]):
    data_accum[i] = data_accum[i - 1].item() + data_in[i].item()

_, data_accum_fixed = nk.signal_fixpeaks(peaks=data_accum, iterative=False, show=True, 
                                        sampling_rate=1000, method="Kubios", robust=True)

data_out = np.zeros((data_accum_fixed.size - 1,), dtype=int)
for i, x in enumerate(data_accum_fixed[1:]):
    data_out[i] = data_accum_fixed[i] - data_accum_fixed[i - 1]
data_out[0] = data_accum_fixed[0]

np.savetxt('after.txt', data_out)

As you can see, the sampling rate is 1000.
Here is the input and output data:

after.txt
before.txt

Thank you!

@Chris-Spooner999
Copy link
Author

Hi @DerAndereJohannes,
I discovered an alternative implementation of the same Kubios methodology in the Systole package:

https://embodied-computation-group.github.io/systole/generated/correction/systole.correction.correct_rr.html#systole.correction.correct_rr

It works fairly well. Works most of the time, only has problems when there are lots of successive artefacts.

@DerAndereJohannes
Copy link
Collaborator

Hi Chris, sorry for the late response and thanks for all the info and conducting additional research. I think I have found the issue with your problem. It has to do with the artifact correction mechanism that is used on fixing both the long/short beats and the Ectopic beat (NeuroKit seems to handle these identically) specifically on data with subsequent artifacts (all other instances are not affected).

More specifically, the main problem is that there are 2 detected artifacts right after each other in the data (for you peak 58 and 59). Since Neurokit tries to achieve the interpolating by using the data from the previous and next peak (for peak 58 it would try between 57 and 59), it uses artifacted data as in the correction method. This is of course not intended and creates these issues. Of course these errors then propagate further.

In addition, I noticed that the correction mechanisms are applied sequentially, so the order of when an artifact correction is not accounted for and leads to different results depending on what type of error first occurs (especially a problem with subsequent artifacts). This is also a big issue.

Thank you very much for your find, I will try to create a fix tomorrow for the repository if that is alright with you.

@Chris-Spooner999
Copy link
Author

Thanks @DerAndereJohannes, let me know when in has been submitted to Github and I'll give it a test on my test data.

@DerAndereJohannes
Copy link
Collaborator

Hi Chris, I have an written a small and quick update to the interpolation function to let it expand its interpolation window based on whether there are also misaligned peaks next to it. Here are the current changes:

  1. Correct Ectopic and longshort peaks at the same time by combining them and sorting them
  2. Correct these combined peaks iteratively, such that previously uncorrected results don't create new bad peaks
  3. Implement 2 different functions for misalignment correction:

The first being a simple method of using the two previous points for interpolation rather than one before and one after. This prevents misaligned peaks from being in the calculation and the method is inspired by the link you have previously sent.

The second is a bit more "complex", but it basically reuses the old method of using the peak before and after the actual misaligned peak and interpolating between them. But, now it will look for the first peak before and after that were not misaligned and interpolates between them linearly. This one I am also currently not sure how to deal with boundary issues, so for now I have just implemented an easy fix.

Both methods will create a straight line if there are multiple misaligned peaks in a row due to the linear nature of the correction.

I would like your feedback whether this method is suitable for your needs, or if you have a different idea to handle the misaligned data. Feel free to see the changes here: https://github.com/DerAndereJohannes/NeuroKit/tree/signal_fix . The "complex" fix is currently active, but feel free to play around with the code yourself.

Example

Here is an example on your before data, the red spots were the misaligned peaks:

Overall Result

Image

Correction using simple method:

Image

Correction using "complex" method:

Image

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

No branches or pull requests

2 participants