neuropsychology / NeuroKit

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

NeuroKit2 Analysis on Animal ECG Data #978

Open luneo-1 opened 3 months ago

luneo-1 commented 3 months ago

my subjects are mice, and their resting heart rates significantly differ from humans, typically ranging between 500–700 beats per minute (bpm) – a stark contrast to the human resting heart rate of 60–70 bpm. To accommodate this difference,

Firstly, nk.ecg_simulate cannot generate data for heart rates exceeding 200 bpm, which is applicable for humans. However, this does not work for my animal experiments.


import neurokit2 as nk

ecg = nk.ecg_simulate(duration=15, sampling_rate=1000, heart_rate=750)

signals, info = nk.ecg_process(ecg, sampling_rate=1000)

nk.ecg_plot(signals, info)

Subsequently, I used my own data, and I was able to visualize it in the charts.

Screenshots

Screenshot 2024-03-27 at 09 35 32

System Specifications

import neurokit2 as nk
nk.version()
welcome[bot] commented 3 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

Mitchellb16 commented 2 months ago

Hi, I'm also working with animals with higher heart rate. I had some success using the 'martinez2004' method for ecg_process (code below for sequentially testing all the methods with a chunk of my data). For the most part, this helps with peak detection, which I think is the main issue with the other methods.

That being said, I'll hop on the animal-related-problems thread and say there are still some misses that produce crazy high rate values - does anyone have advice on how to handle these? (Image and code pasted below).

# Preprocess the data (filter, find peaks, etc.)
chunk = slice(int(600* sampling_rate), int(604 * sampling_rate))
# try out every method
methods_list = ['neurokit', 'pantompkins1985', 'hamilton2002', 
                'elgendi2010', 'engzeemod2012', 'zong2003', 'martinez2004', 
                'christov2004', 'gamboa2008', 'manikandan2012', 'kalidas2017', 
                'nabian2018', 'rodrigues2021', 'emrich2023', 'promac']
for method in methods_list:
    try:
        print(method)
        processed_data, info = ecg_process(data.ECG.loc[chunk], 
                                           sampling_rate=sampling_rate, 
                                           method=method)
        nk.ecg_plot(processed_data, info)
        plt.show()
    except:
        print('method failed')
# get all indexes where rate is too high
noise_idxs = processed_data[processed_data.ECG_Rate > 380].index
# find beginning of each noisy segment by checking if the index is 1 greater than the previous. 
noise_diff = np.diff(noise_idxs, prepend=[0])
noise_starts = noise_idxs[noise_diff != 1]

# make figure with an axis for each noiseidx
fig, axs = plt.subplots(len(noise_starts))

# plot each of them and the 10s surrounding them
for i, noise_index in enumerate(noise_starts):
    noise_chunk = processed_data.loc[noise_index-(5*sampling_rate): noise_index + (5*sampling_rate)]
    axs[i].plot(noise_chunk.ECG_Clean)

    # scatter the peaks
    peaks = noise_chunk[noise_chunk.ECG_R_Peaks == 1]
    axs[i].scatter(x = peaks.index, y = peaks.ECG_Clean, c = 'red')

Screenshot from 2024-04-30 13-04-51