NeuroKit icon indicating copy to clipboard operation
NeuroKit copied to clipboard

ecg_delineate returns ValueError when using dwt method, but not peaks or cwt

Open lindaruetz opened this issue 2 years ago • 5 comments

Here is the code that I used:

ecgs_two = pd.read_csv("LeadTwo.csv")
ecg_signal_two = ecgs_two['II']
signals_two, info_two = nk.ecg_process(ecg_signal_two, sampling_rate=2000)
rpeaks_two = info_two["ECG_R_Peaks"]
cleaned_ecg_two = signals_two["ECG_Clean"]
_, waves_peak_two_dwt = nk.ecg_delineate(cleaned_ecg_two, rpeaks_two, sampling_rate=2000,
method='dwt',show=True,show_type='peaks')

Describe the bug ecg_delineate does not display results but instead returns ValueError when method 'dwt' is used. If 'peaks' or 'cwt' are used, it runs fine.

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File ~\Anaconda3\envs\neurokit2\lib\site-packages\pandas\core\indexes\range.py:385, in RangeIndex.get_loc(self, key, method, tolerance)
    384 try:
--> 385     return self._range.index(new_key)
    386 except ValueError as err:

ValueError: 295 is not in range

The above exception was the direct cause of the following exception:

KeyError                                  Traceback (most recent call last)
Input In [161], in <cell line: 7>()
      5 rpeaks_two = info_two["ECG_R_Peaks"]
      6 cleaned_ecg_two = signals_two["ECG_Clean"]
----> 7 _, waves_peak_two_dwt = nk.ecg_delineate(cleaned_ecg_two, rpeaks_two, sampling_rate=2000, method='dwt',show=True,show_type='peaks')

File ~\Anaconda3\envs\neurokit2\lib\site-packages\neurokit2\ecg\ecg_delineate.py:137, in ecg_delineate(ecg_cleaned, rpeaks, sampling_rate, method, show, show_type, check)
    135     waves = _ecg_delineator_cwt(ecg_cleaned, rpeaks=rpeaks, sampling_rate=sampling_rate)
    136 elif method in ["dwt", "discrete wavelet transform"]:
--> 137     waves = _dwt_ecg_delineator(ecg_cleaned, rpeaks, sampling_rate=sampling_rate)
    139 else:
    140     raise ValueError(
    141         "NeuroKit error: ecg_delineate(): 'method' should be one of 'peak'," "'cwt' or 'dwt'."
    142     )

File ~\Anaconda3\envs\neurokit2\lib\site-packages\neurokit2\ecg\ecg_delineate.py:239, in _dwt_ecg_delineator(ecg, rpeaks, sampling_rate, analysis_sampling_rate)
    230 # # only for debugging
    231 # for idx in [0, 1, 2, 3]:
    232 #     plt.plot(dwtmatr[idx + 3], label=f'W[{idx}]')
   (...)
    235 # plt.grid(True)
    236 # plt.show()
    237 rpeaks_resampled = _dwt_resample_points(rpeaks, sampling_rate, analysis_sampling_rate)
--> 239 tpeaks, ppeaks = _dwt_delineate_tp_peaks(
    240     ecg, rpeaks_resampled, dwtmatr, sampling_rate=analysis_sampling_rate
    241 )
    242 qrs_onsets, qrs_offsets = _dwt_delineate_qrs_bounds(
    243     rpeaks_resampled, dwtmatr, ppeaks, tpeaks, sampling_rate=analysis_sampling_rate
    244 )
    245 ponsets, poffsets = _dwt_delineate_tp_onsets_offsets(
    246     ppeaks, rpeaks_resampled, dwtmatr, sampling_rate=analysis_sampling_rate
    247 )

File ~\Anaconda3\envs\neurokit2\lib\site-packages\neurokit2\ecg\ecg_delineate.py:384, in _dwt_delineate_tp_peaks(ecg, rpeaks, dwtmatr, sampling_rate, qrs_width, p2r_duration, rt_duration, degree_tpeak, degree_ppeak, epsilon_T_weight, epsilon_P_weight)
    379 idx_zero = (
    380     signal_zerocrossings(dwt_local[idx_peak : idx_peak_nxt + 1])[0] + idx_peak
    381 )
    382 # This is the score assigned to each peak. The peak with the highest score will be
    383 # selected.
--> 384 score = ecg_local[idx_zero] - (
    385     float(idx_zero) / sampling_rate - (rt_duration - 0.5 * qrs_width)
    386 )
    387 candidate_peaks.append(idx_zero)
    388 candidate_peaks_scores.append(score)

File ~\Anaconda3\envs\neurokit2\lib\site-packages\pandas\core\series.py:958, in Series.__getitem__(self, key)
    955     return self._values[key]
    957 elif key_is_scalar:
--> 958     return self._get_value(key)
    960 if is_hashable(key):
    961     # Otherwise index.get_value will raise InvalidIndexError
    962     try:
    963         # For labels that don't resolve as scalars like tuples and frozensets

File ~\Anaconda3\envs\neurokit2\lib\site-packages\pandas\core\series.py:1069, in Series._get_value(self, label, takeable)
   1066     return self._values[label]
   1068 # Similar to Index.get_value, but we do not fall back to positional
-> 1069 loc = self.index.get_loc(label)
   1070 return self.index._get_values_for_loc(self, loc, label)

File ~\Anaconda3\envs\neurokit2\lib\site-packages\pandas\core\indexes\range.py:387, in RangeIndex.get_loc(self, key, method, tolerance)
    385         return self._range.index(new_key)
    386     except ValueError as err:
--> 387         raise KeyError(key) from err
    388 self._check_indexing_error(key)
    389 raise KeyError(key)

KeyError: 295

I attached CSV file 'LeadTwo.csv'

System Specifications

It's important that you give us some information about the system you are using. For that you can run:

nk Version '0.1.7' on Windows10 LeadTwo.csv

lindaruetz avatar May 03 '22 19:05 lindaruetz

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

welcome[bot] avatar May 03 '22 19:05 welcome[bot]

I think it is a problem with ecg_process. If I instead do ecg_clean, then ecg_peaks, it works fine with dwt method.

lindaruetz avatar May 03 '22 19:05 lindaruetz

@Tam-Pham sorry to bother you but we have this weird issue:

signal = nk.ecg_simulate(duration = 20, sampling_rate= 2000)

df, info = nk.ecg_process(signal, sampling_rate=2000)
rpeaks = info["ECG_R_Peaks"]

So if I extract the signal from df as an array (.values), then it works no probs:

out = nk.ecg_delineate(df["ECG_Clean"].values, info["ECG_R_Peaks"], sampling_rate=2000, method='dwt',show=True,show_type='peaks')

But if I pass it as a pd.Series, then it fails:

out = nk.ecg_delineate(df["ECG_Clean"], info["ECG_R_Peaks"], sampling_rate=2000, method='dwt',show=True,show_type='peaks')

But the weirdest thing, is that it works if the sampling rate is not 2000:

out = nk.ecg_delineate(df["ECG_Clean"], info["ECG_R_Peaks"], sampling_rate=2001, method='dwt',show=True,show_type='peaks')

Any hunch?

DominiqueMakowski avatar May 09 '22 07:05 DominiqueMakowski

@DominiqueMakowski that sounds strange!

Imma look at them this weekend, latest!

Tam-Pham avatar May 09 '22 09:05 Tam-Pham

@Tam-Pham bump

DominiqueMakowski avatar May 31 '22 12:05 DominiqueMakowski