neuropsychology / NeuroKit

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

ECG delineate DWT method constants. #367

Closed pramod-katti closed 3 years ago

pramod-katti commented 4 years ago

I'm using the ecg_delineate() function for all the fiducial points detection. When I plot the signals after passing through the ecg_clean(), ecg_findpeaks() and ecg_delineate using DWT method, the detected r_onsets and r_offsets are little bit away from the actual r_onsets for my data. Hence, I thought I could modify some part of the source code. But I couldn't make out the constants defined in sub functions such as -

def _dwt_delinate_tp_onsets_offsets(ecg, peaks, dwtmatr, sampling_rate=250, debug=False, duration=0.3, duration_offset=0.3, onset_weight=0.4, offset_weight=0.4, degree_onset=2, degree_offset=2): degree = _dwt_compensate_degree(sampling_rate) srch_bndry = int(0.5 * qrs_width * sampling_rate) Why is 0.5 considered in srch_bndry = int(0.5qrs_widthsampling_rate)? What is the significance of 0.5? The above code snippet is posted to quote it.

  1. I wanted to know why duration_offset = 0.3 or meaning of degree_onset = 2 or other constants in subfunctions.
  2. Why the default sampling rate is different at different places like def _dwt_ecg_delinator(ecg, rpeaks, sampling_rate, analysis_sampling_rate=2000): def _dwt_delinate_tp_onsets_offsets(ecg, peaks, dwtmatr, sampling_rate=250, debug=False, duration=0.3, duration_offset=0.3, onset_weight=0.4, offset_weight=0.4, degree_onset=2, degree_offset=2): degree = _dwt_compensate_degree(sampling_rate)
  3. I'm trying to figure it out by going through code but not able to clearly understand. Can anyone help me out please.

Thanks in advance.

Tam-Pham commented 4 years ago

Hi @pramod-katti,

Happy to answer your questions!

the constants defined in sub functions such as: srch_bndry = int(0.5 * qrs_width * sampling_rate) Why is 0.5 considered? What is the significance of 0.5?

The constants defined in ecg_delineate() functions such as the 0.5 here are used to define thresholds in our searches. These constants are chosen either based on the physiological plausible duration of the QRS segments or because they work the best in our test sets.

I wanted to know why duration_offset = 0.3 or meaning of degree_onset = 2 or other constants in subfunctions

To address this, we will add in documentation for the arguments in sub-functions.

Why the default sampling rate is different at different places like

The sampling_rate is an argument that will be piped into sub-functions once defined at the main function. So whether it's defined (sampling_rate=250) or not doesn't matter that much. In case you might be referring to the difference in sampling_rate and analysis_sampling_rate, they are two different arguments with two different roles.

We understand that you would like to customize the functions to your need and in order to do that, you would like to thoroughly understand the function and sub-functions. We will work on documenting them.

pramod-katti commented 4 years ago

A big thank you, it was a much needed info. I would also like to ask few questions regarding ECG Interval duration calculation. Currently, I calculate the intervals by extracting the points of the dictionary like below.\ signal_dwt = ecg_delineate(ecg_cleansignals,rpeaks,sampling_rate=Fs,method="dwt",show=True,show_type='all')<br/> P_onsets = signal_dwt[1].get('ECG_P_Onsets')<br/> P_Duration = []<br/> for i in range(len(P_onsets)) and range(len(P_offsets)):<br/> P_Duration.append((P_offsets[i] - P_onsets[i]))<br/> print('P Duration',P_Duration)<br/> print('P Duration - ',np.mean(np.array(P_Duration)))\ Once I get the mean value, I multiply according to my sampling period to convert into time. Is it a correct method to follow? However, I have attached a sample ecg data I have. Sampling frequency is 1000. It would be of great help if you could help me out in this intervals calculation for my file and also the method to calculate.

Edit - What is analysis_sampling_rate and why is the signal resampled to analysis_sampling_rate in the subsequent functions? (np.log2(sampling_rate / 250) Why this calculation is made?

Thanks

Tam-Pham commented 4 years ago

Hi @pramod-katti

It's actually quite hard to figure out the code that you pasted but if you are looking at converting from samples to time, please divide your number of samples by your sampling rate. It will give you the time in seconds (assuming the unit of your sampling rate is Hz).

For the analysis_sampling_rate, it's pertaining to the discrete wavelet method that we implemented, based on this paper. The signal has to be resampled to a rate that is in accordance with the wavelet that we use. Other steps/ calculations are also based on the paper above. Hope it helps

stale[bot] commented 3 years ago

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.

stale[bot] commented 3 years ago

This issue has been inactive for a long time. We're closing it (but feel free to reopen it if need be).