Skip to content

Commit

Permalink
ecg_process: improve documentation and readability
Browse files Browse the repository at this point in the history
  • Loading branch information
jchromik committed Jul 25, 2023
1 parent a802b57 commit 0bd4ccf
Showing 1 changed file with 43 additions and 42 deletions.
85 changes: 43 additions & 42 deletions neurokit2/ecg/ecg_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,27 @@
def ecg_process(ecg_signal, sampling_rate=1000, method="neurokit"):
"""**Automated pipeline for preprocessing an ECG signal**
This function runs different preprocessing steps. **Help us improve the documentation of
this function by making it more tidy and useful!**
This function runs different preprocessing steps: Cleaning (using ``ecg_clean()``),
peak detection (using ``ecg_peaks()``), heart rate calculation (using ``signal_rate()``),
signal quality assessment (using ``ecg_quality()``),
QRS complex delineation (using ``ecg_delineate()``),
and cardiac phase determination (using ``ecg_phase()``).
**Help us improve the documentation of this function by making it more tidy and useful!**
Parameters
----------
ecg_signal : Union[list, np.array, pd.Series]
The raw ECG channel.
The raw single-channel ECG signal.
sampling_rate : int
The sampling frequency of ``ecg_signal`` (in Hz, i.e., samples/second). Defaults to 1000.
method : str
The processing pipeline to apply. Defaults to ``"neurokit"``. We aim at improving this
aspect to make the available methods more transparent, and be able to generate specific
reports. Please get in touch if you are interested in helping out with this.
The processing method used for signal cleaning (using ``ecg_clean()``) and peak detection
(using ``ecg_peaks()``). Defaults to ``'neurokit'``. Available methods are ``'neurokit'``,
``'pantompkins1985'``, ``'hamilton2002'``, ``'elgendi2010'``, ``'engzeemod2012'``.
We aim at improving this aspect to make the available methods more transparent, and be able
to generate specific reports. Please get in touch if you are interested in helping out with
this.
Returns
-------
Expand All @@ -33,38 +41,34 @@ def ecg_process(ecg_signal, sampling_rate=1000, method="neurokit"):
* ``"ECG_Raw"``: the raw signal.
* ``"ECG_Clean"``: the cleaned signal.
* ``"ECG_R_Peaks"``: the R-peaks marked as "1" in a list of zeros.
* ``"ECG_Rate"``: heart rate interpolated between R-peaks.
* ``"ECG_Quality"``: the quality of the cleaned signal
* ``"ECG_R_Peaks"``: the R-peaks marked as "1" in a list of zeros.
* ``"ECG_P_Peaks"``: the P-peaks marked as "1" in a list of zeros
* ``"ECG_P_Onsets"``: the P-onsets marked as "1" in a list of zeros.
* ``"ECG_P_Offsets"``: the P-offsets marked as "1" in a list of zeros.
* ``"ECG_Q_Peaks"``: the Q-peaks marked as "1" in a list of zeros .
* ``"ECG_R_Onsets"``: the R-onsets marked as "1" in a list of zeros.
* ``"ECG_R_Offsets"``: the R-offsets marked as "1" in a list of zeros.
* ``"ECG_S_Peaks"``: the S-peaks marked as "1" in a list of zeros.
* ``"ECG_T_Peaks"``: the T-peaks marked as "1" in a list of zeros.
* ``"ECG_P_Onsets"``: the P-onsets marked as "1" in a list of zeros.
* ``"ECG_P_Offsets"``: the P-offsets marked as "1" in a list of zeros (only when method in
``ecg_delineate()`` is wavelet).
* ``"ECG_T_Onsets"``: the T-onsets marked as "1" in a list of zeros (only when method in
``ecg_delineate()`` is wavelet).
* ``"ECG_T_Onsets"``: the T-onsets marked as "1" in a list of zeros.
* ``"ECG_T_Offsets"``: the T-offsets marked as "1" in a list of zeros.
* ``"ECG_R_Onsets"``: the R-onsets marked as "1" in a list of zeros (only when method in
``ecg_delineate()`` is wavelet).
* ``"ECG_R_Offsets"``: the R-offsets marked as "1" in a list of zeros (only when method in
``ecg_delineate()`` is wavelet).
* ``"ECG_Phase_Atrial"``: cardiac phase, marked by "1" for systole and "0" for diastole.
* ``"ECG_Phase_Completion_Atrial"``: cardiac phase (atrial) completion, expressed in
percentage (from 0 to 1), representing the stage of the current cardiac phase.
* ``"ECG_Phase_Ventricular"``: cardiac phase, marked by "1" for systole and "0" for
diastole.
* ``"ECG_Atrial_PhaseCompletion"``: cardiac phase (atrial) completion, expressed in
percentage
(from 0 to 1), representing the stage of the current cardiac phase.
* ``"ECG_Ventricular_PhaseCompletion"``: cardiac phase (ventricular) completion, expressed
* ``"ECG_Phase_Completion_Ventricular"``: cardiac phase (ventricular) completion, expressed
in percentage (from 0 to 1), representing the stage of the current cardiac phase.
* **This list is not up-to-date. Help us improve the documentation!**
info : dict
rpeaks : dict
A dictionary containing the samples at which the R-peaks occur, accessible with the key
``"ECG_R_Peaks"``, as well as the signals' sampling rate.
See Also
--------
ecg_clean, ecg_peaks, ecg_delineate, ecg_phase, ecg_plot, .signal_rate
ecg_clean, ecg_peaks, ecg_quality, ecg_delineate, ecg_phase, ecg_plot, .signal_rate
Examples
--------
Expand All @@ -85,34 +89,31 @@ def ecg_process(ecg_signal, sampling_rate=1000, method="neurokit"):
plt.close()
"""
# Sanitize input
ecg_signal = signal_sanitize(ecg_signal)

# Sanitize and clean input
ecg_signal = signal_sanitize(ecg_signal)
ecg_cleaned = ecg_clean(ecg_signal, sampling_rate=sampling_rate, method=method)
# R-peaks
(instant_peaks, rpeaks,) = ecg_peaks(
ecg_cleaned=ecg_cleaned, sampling_rate=sampling_rate, method=method, correct_artifacts=True
)

# Detect R-peaks
instant_peaks, rpeaks = ecg_peaks(ecg_cleaned, sampling_rate, method, correct_artifacts=True)

# Calculate heart rate
rate = signal_rate(rpeaks, sampling_rate=sampling_rate, desired_length=len(ecg_cleaned))

# Assess signal quality
quality = ecg_quality(ecg_cleaned, rpeaks=rpeaks["ECG_R_Peaks"], sampling_rate=sampling_rate)

signals = pd.DataFrame(
{"ECG_Raw": ecg_signal, "ECG_Clean": ecg_cleaned, "ECG_Rate": rate, "ECG_Quality": quality}
)
# Merge signals in a DataFrame
signals = pd.DataFrame({"ECG_Raw": ecg_signal, "ECG_Clean": ecg_cleaned, "ECG_Rate": rate, "ECG_Quality": quality})

# Additional info of the ecg signal
delineate_signal, delineate_info = ecg_delineate(
ecg_cleaned=ecg_cleaned, rpeaks=rpeaks, sampling_rate=sampling_rate
)
# Delineate QRS complex
delineate_signal, delineate_info = ecg_delineate(ecg_cleaned, rpeaks, sampling_rate)

cardiac_phase = ecg_phase(ecg_cleaned=ecg_cleaned, rpeaks=rpeaks, delineate_info=delineate_info)
# Determine cardiac phases
cardiac_phase = ecg_phase(ecg_cleaned, rpeaks, delineate_info)

# Add additional information to signals DataFrame
signals = pd.concat([signals, instant_peaks, delineate_signal, cardiac_phase], axis=1)

# Rpeaks location and sampling rate in dict info
info = rpeaks
info["sampling_rate"] = sampling_rate

return signals, info
# return signals DataFrame and R-peak locations
return signals, rpeaks

0 comments on commit 0bd4ccf

Please sign in to comment.