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

ValueError: cannot convert float NaN to integer #1006

Open
Khaled-Mohammed-Abdelgaber opened this issue Jul 9, 2024 · 8 comments
Open

ValueError: cannot convert float NaN to integer #1006

Khaled-Mohammed-Abdelgaber opened this issue Jul 9, 2024 · 8 comments
Assignees

Comments

@Khaled-Mohammed-Abdelgaber

i am trying to get the peak of ecg signals. and for some signals i get the following error:
Cell In[7], line 42
39 Beat_loc = correctPeaks(Beat_loc, signal, 30)
41 if sign_name == 'ecg':
---> 42 minLoc = nk.ecg_process(signal , sampling_rate = 125, method='neurokit')[1]['ECG_R_Peaks']
43 Beat_loc = minLoc[1:-1]
44 Beat_loc = correctPeaks(Beat_loc, signal, 30)

File c:\Users\Khalid\anaconda3\envs\tf_gpu\lib\site-packages\neurokit2\ecg\ecg_process.py:111, in ecg_process(ecg_signal, sampling_rate, method)
106 rate = signal_rate(
107 info, sampling_rate=sampling_rate, desired_length=len(ecg_cleaned)
108 )
110 # Assess signal quality
--> 111 quality = ecg_quality(
112 ecg_cleaned, rpeaks=info["ECG_R_Peaks"], sampling_rate=sampling_rate
113 )
115 # Merge signals in a DataFrame
116 signals = pd.DataFrame(
117 {
118 "ECG_Raw": ecg_signal,
(...)
122 }
123 )

File c:\Users\Khalid\anaconda3\envs\tf_gpu\lib\site-packages\neurokit2\ecg\ecg_quality.py:105, in ecg_quality(ecg_cleaned, rpeaks, sampling_rate, method, approach)
103 # Run peak detection algorithm
104 if method in ["averageqrs"]:
--> 105 quality = _ecg_quality_averageQRS(
106 ecg_cleaned, rpeaks=rpeaks, sampling_rate=sampling_rate
107 )
108 elif method in ["zhao2018", "zhao", "SQI"]:
109 if approach is None:

File c:\Users\Khalid\anaconda3\envs\tf_gpu\lib\site-packages\neurokit2\ecg\ecg_quality.py:136, in _ecg_quality_averageQRS(ecg_cleaned, rpeaks, sampling_rate)
133 rpeaks = rpeaks["ECG_R_Peaks"]
135 # Get heartbeats
--> 136 heartbeats = ecg_segment(ecg_cleaned, rpeaks, sampling_rate)
137 data = epochs_to_df(heartbeats).pivot(
138 index="Label", columns="Time", values="Signal"
139 )
140 data.index = data.index.astype(int)

File c:\Users\Khalid\anaconda3\envs\tf_gpu\lib\site-packages\neurokit2\ecg\ecg_segment.py:64, in ecg_segment(ecg_cleaned, rpeaks, sampling_rate, show, **kwargs)
59 raise ValueError("The data length is too small to be segmented.")
61 epochs_start, epochs_end, average_hr = _ecg_segment_window(
62 rpeaks=rpeaks, sampling_rate=sampling_rate, desired_length=len(ecg_cleaned)
63 )
---> 64 heartbeats = epochs_create(
65 ecg_cleaned,
66 rpeaks,
67 sampling_rate=sampling_rate,
68 epochs_start=epochs_start,
69 epochs_end=epochs_end,
70 )
72 # Pad last heartbeats with nan so that segments are equal length
73 last_heartbeat_key = str(np.max(np.array(list(heartbeats.keys()), dtype=int)))

File c:\Users\Khalid\anaconda3\envs\tf_gpu\lib\site-packages\neurokit2\epochs\epochs_create.py:164, in epochs_create(data, events, sampling_rate, epochs_start, epochs_end, event_labels, event_conditions, baseline_correction)
162 # Find the maximum numbers of samples in an epoch
163 parameters["duration"] = list(np.array(parameters["end"]) - np.array(parameters["start"]))
--> 164 epoch_max_duration = int(max((i * sampling_rate for i in parameters["duration"])))
166 # Extend data by the max samples in epochs * NaN (to prevent non-complete data)
167 length_buffer = epoch_max_duration

ValueError: cannot convert float NaN to integer

Copy link

welcome bot commented Jul 9, 2024

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
Contributor

Are you sure that your input signal itself does not contain any NaN values? Assuming your input variable signal is a pd.Series, You can check by doing something like: print(signal.isna().sum()) to see if there are any.

@geniusturtle6174
Copy link

I got the same error, and after some experiments, I guess that the error occurs when the length of the signal is too short (less than three periods).

@DerAndereJohannes
Copy link
Contributor

FWIW here is a minimal example:

import neurokit2 as nk

SAMPLE_RATE=125

ecg = nk.ecg_simulate(duration=10, sampling_rate=SAMPLE_RATE, heart_rate=10)

nk.ecg_process(ecg, sampling_rate=SAMPLE_RATE)

@debaratipaul4
Copy link

I am getting the same error. My ECG sample length is 96. My code goes like below:-
_, rpeaks = nk2.ecg_peaks(ecg_signal, sampling_rate=96)
print(rpeaks['ECG_R_Peaks']) // it is getting printed as [108]
signals, waves = nk2.ecg_delineate(ecg_signal, rpeaks, sampling_rate = 24)

after this getting error
File ~/Lava_workspace/.venv/lib/python3.10/site-packages/neurokit2/epochs/epochs_create.py:164, in epochs_create(data, events, sampling_rate, epochs_start, epochs_end, event_labels, event_conditions, baseline_correction)
162 # Find the maximum numbers of samples in an epoch
163 parameters["duration"] = list(np.array(parameters["end"]) - np.array(parameters["start"]))
--> 164 epoch_max_duration = int(max((i * sampling_rate for i in parameters["duration"])))
166 # Extend data by the max samples in epochs * NaN (to prevent non-complete data)
167 length_buffer = epoch_max_duration

ValueError: cannot convert float NaN to integer

@DominiqueMakowski
Copy link
Member

@DerAndereJohannes do you have some idea of the cause of this error?

@DerAndereJohannes
Copy link
Contributor

I will take a look at it

@DerAndereJohannes
Copy link
Contributor

DerAndereJohannes commented Nov 15, 2024

I looked a bit into this and can give the following information:

I assume that everyone getting these NaN errors are working with signals that contain 3 or less periods. This is close to what @geniusturtle6174 mentioned.

The problem comes from the signal rate calculation (using signal_rate), which returns NaN values as it uses signal_period which just returns a vector of NaNs if it sees less than 4 periods. This occurs too when using ecg_delineate so it is not surprise that the error occurs there too. Signal rate is computed in many different functions, so it might make sense to find a solution to low period counts.

Using the ecg_process function was a problem too for my minimal sample as the minimal sample produced a single QRS complex. In the process function, we also use standardizing functions which seemingly return NaN if there is only a single sample (e.g., numpy nanstd).

I also found a potential bug in ecg_segment ~ line 74 when trying to pad the last segment in case the segment goes beyond the actual signal. It seems as if the angle bracket should be reversed as in my single complex it just set my entire signal to NaN.

I have not had enough time to look into a solution yet. I would also be interested in how you think the best next step would be? I would guess that we should start by finding an alternative signal_period behavior when dealing with shorter ecg segments. Do let me know.

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

6 participants