Skip to content

Commit

Permalink
Merge pull request #889 from neuropsychology/ppg_fixpeaks
Browse files Browse the repository at this point in the history
[Breaking] for *_plot() and ecg_fixpeaks(method="neurokit")
  • Loading branch information
DominiqueMakowski authored Aug 23, 2023
2 parents 6493c6e + b47335f commit 4bf8071
Show file tree
Hide file tree
Showing 37 changed files with 1,059 additions and 624 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: "3.10"
python-version: "3.11"

- name: Install dependencies
run: |
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/releasePR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: "3.7"
python-version: "3.11"

- name: Install dependencies
run: |
Expand Down Expand Up @@ -50,7 +50,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.x"
python-version: "3.11"

- name: Install pep517
run: >-
Expand Down
41 changes: 21 additions & 20 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ Electrodermal Activity (EDA/GSR)
signals, info = nk.eda_process(eda, sampling_rate=250)
# Visualise the processing
nk.eda_plot(signals, sampling_rate=250)
nk.eda_plot(signals, info)
.. image:: https://raw.github.com/neuropsychology/NeuroKit/master/docs/readme/README_eda.png
:target: https://neuropsychology.github.io/NeuroKit/examples/eda_peaks/eda_peaks.html
Expand All @@ -266,7 +266,7 @@ Cardiac activity (ECG)
signals, info = nk.ecg_process(ecg, sampling_rate=250)
# Visualise the processing
nk.ecg_plot(signals, sampling_rate=250)
nk.ecg_plot(signals, info)
.. image:: https://raw.github.com/neuropsychology/NeuroKit/master/docs/readme/README_ecg.png
Expand All @@ -285,47 +285,48 @@ Respiration (RSP)
signals, info = nk.rsp_process(rsp, sampling_rate=250)
# Visualise the processing
nk.rsp_plot(signals, sampling_rate=250)
nk.rsp_plot(signals, info)
.. image:: https://raw.github.com/neuropsychology/NeuroKit/master/docs/readme/README_rsp.png
:target: https://neuropsychology.github.io/NeuroKit/examples/rsp_rrv/rsp_rrv.html


Electromyography (EMG)
^^^^^^^^^^^^^^^^^^^^^^^
Photoplethysmography (PPG/BVP)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. code-block:: python
# Generate 10 seconds of EMG signal (recorded at 250 samples/second)
emg = nk.emg_simulate(duration=10, sampling_rate=250, burst_number=3)
# Generate 15 seconds of PPG signal (recorded at 250 samples/second)
ppg = nk.ppg_simulate(duration=15, sampling_rate=250, heart_rate=70)
# Process it
signals, info = nk.emg_process(emg, sampling_rate=250)
signals, info = nk.ppg_process(ppg, sampling_rate=250)
# Visualise the processing
nk.emg_plot(signals, sampling_rate=250)
# Visualize the processing
nk.ppg_plot(signals, info)
.. image:: https://raw.github.com/neuropsychology/NeuroKit/master/docs/readme/README_emg.png
.. image:: https://raw.github.com/neuropsychology/NeuroKit/master/docs/readme/README_ppg.png


Photoplethysmography (PPG/BVP)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Electromyography (EMG)
^^^^^^^^^^^^^^^^^^^^^^^

.. code-block:: python
# Generate 15 seconds of PPG signal (recorded at 250 samples/second)
ppg = nk.ppg_simulate(duration=15, sampling_rate=250, heart_rate=70)
# Generate 10 seconds of EMG signal (recorded at 250 samples/second)
emg = nk.emg_simulate(duration=10, sampling_rate=250, burst_number=3)
# Process it
signals, info = nk.ppg_process(ppg, sampling_rate=250)
signals, info = nk.emg_process(emg, sampling_rate=250)
# Visualize the processing
nk.ppg_plot(signals, sampling_rate=250)
# Visualise the processing
nk.emg_plot(signals, info)
.. image:: https://raw.github.com/neuropsychology/NeuroKit/master/docs/readme/README_ppg.png
.. image:: https://raw.github.com/neuropsychology/NeuroKit/master/docs/readme/README_emg.png



Electrooculography (EOG)
Expand All @@ -340,7 +341,7 @@ Electrooculography (EOG)
signals, info = nk.eog_process(eog_signal, sampling_rate=100)
# Plot
nk.eog_plot(signals, info, sampling_rate=100)
nk.eog_plot(signals, info)
.. image:: https://raw.github.com/neuropsychology/NeuroKit/master/docs/readme/README_eog.png
Expand Down
Binary file modified docs/readme/README_ecg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/readme/README_eda.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/readme/README_emg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/readme/README_eog.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
103 changes: 58 additions & 45 deletions docs/readme/README_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

# Setup matplotlib with Agg to run on server
matplotlib.use("Agg")
plt.rcParams["figure.figsize"] = (10, 6.5)
plt.rcParams["figure.figsize"] = (2**0.5 * 10, 10)
plt.rcParams["savefig.facecolor"] = "white"

# =============================================================================
Expand Down Expand Up @@ -55,13 +55,15 @@
}
)
plot = data.plot(
subplots=True, layout=(5, 1), color=["#f44336", "#E91E63", "#2196F3", "#9C27B0", "#FF9800"]
subplots=True,
layout=(5, 1),
color=["#f44336", "#E91E63", "#2196F3", "#9C27B0", "#FF9800"],
)
fig = plt.gcf()
fig.set_size_inches(10, 6, forward=True)
[ax.legend(loc=1) for ax in plt.gcf().axes]
plt.tight_layout()
fig.savefig("README_simulation.png", dpi=300)
fig.savefig("README_simulation.png", dpi=150)

# =============================================================================
# Electrodermal Activity (EDA) processing
Expand All @@ -73,13 +75,10 @@
# Process it
signals, info = nk.eda_process(eda, sampling_rate=250)

# Visualise the processing
nk.eda_plot(signals, sampling_rate=None)

# Save it
nk.eda_plot(signals, sampling_rate=None)
nk.eda_plot(signals, info)
plt.tight_layout()
plt.savefig("README_eda.png", dpi=300)
plt.savefig("README_eda.png", dpi=150)

# =============================================================================
# Cardiac activity (ECG) processing
Expand All @@ -91,13 +90,10 @@
# Process it
signals, info = nk.ecg_process(ecg, sampling_rate=250)

# Visualise the processing
nk.ecg_plot(signals, sampling_rate=250)

# Save it
nk.ecg_plot(signals, sampling_rate=250)
nk.ecg_plot(signals, info)
plt.tight_layout()
plt.savefig("README_ecg.png", dpi=300)
plt.savefig("README_ecg.png", dpi=150)

# =============================================================================
# Respiration (RSP) processing
Expand All @@ -109,51 +105,43 @@
# Process it
signals, info = nk.rsp_process(rsp, sampling_rate=250)

# Visualise the processing
nk.rsp_plot(signals, sampling_rate=250)

# Save it
nk.rsp_plot(signals, sampling_rate=250)
nk.rsp_plot(signals, info)
fig = plt.gcf()
fig.set_size_inches(10, 12, forward=True)
plt.tight_layout()
plt.savefig("README_rsp.png", dpi=300)
plt.savefig("README_rsp.png", dpi=150)

# =============================================================================
# Electromyography (EMG) processing
# Photoplethysmography (PPG/BVP)
# =============================================================================

# Generate 10 seconds of EMG signal (recorded at 250 samples / second)
emg = nk.emg_simulate(duration=10, sampling_rate=250, burst_number=3)
# Generate 15 seconds of PPG signal (recorded at 250 samples / second)
ppg = nk.ppg_simulate(duration=15, sampling_rate=250, heart_rate=70, random_state=333)

# Process it
signals, info = nk.emg_process(emg, sampling_rate=250)

# Visualise the processing
nk.emg_plot(signals, sampling_rate=250)
signals, info = nk.ppg_process(ppg, sampling_rate=250)

# Save it
nk.emg_plot(signals, sampling_rate=250)
nk.ppg_plot(signals, info)
plt.tight_layout()
plt.savefig("README_emg.png", dpi=300)
plt.savefig("README_ppg.png", dpi=150)

# =============================================================================
# Photoplethysmography (PPG/BVP)
# Electromyography (EMG) processing
# =============================================================================

# Generate 15 seconds of PPG signal (recorded at 250 samples / second)
ppg = nk.ppg_simulate(duration=15, sampling_rate=250, heart_rate=70, random_state=333)
# Generate 10 seconds of EMG signal (recorded at 250 samples / second)
emg = nk.emg_simulate(duration=10, sampling_rate=250, burst_number=3)

# Process it
signals, info = nk.ppg_process(ppg, sampling_rate=250)

# Visualize the processing
nk.ppg_plot(signals, sampling_rate=250)
signals, info = nk.emg_process(emg, sampling_rate=250)

# Save it
nk.ppg_plot(signals, sampling_rate=250)
nk.emg_plot(signals, info)
plt.tight_layout()
plt.savefig("README_ppg.png", dpi=300)
plt.savefig("README_emg.png", dpi=150)


# =============================================================================
# Electrooculography (EOG)
Expand All @@ -166,9 +154,9 @@
signals, info = nk.eog_process(eog_signal, sampling_rate=100)

# Plot
nk.eog_plot(signals, peaks=info, sampling_rate=100)
nk.eog_plot(signals, info)
plt.tight_layout()
plt.savefig("README_eog.png", dpi=300)
plt.savefig("README_eog.png", dpi=150)

# =============================================================================
# Signal Processing
Expand Down Expand Up @@ -280,7 +268,9 @@
signal = nk.signal_simulate(duration=10, frequency=1) # High freq
signal += 3 * nk.signal_simulate(duration=10, frequency=3) # Higher freq
signal += 3 * np.linspace(0, 2, len(signal)) # Add baseline and linear trend
signal += 2 * nk.signal_simulate(duration=10, frequency=0.1, noise=0) # Non-linear trend
signal += 2 * nk.signal_simulate(
duration=10, frequency=0.1, noise=0
) # Non-linear trend
signal += np.random.normal(0, 0.02, len(signal)) # Add noise

# Decompose signal using Empirical Mode Decomposition (EMD)
Expand Down Expand Up @@ -323,10 +313,16 @@
)

# Get the PSD using different methods
welch = nk.signal_psd(signal, method="welch", min_frequency=1, max_frequency=20, show=True)
welch = nk.signal_psd(
signal, method="welch", min_frequency=1, max_frequency=20, show=True
)
multitaper = nk.signal_psd(signal, method="multitapers", max_frequency=20, show=True)
lomb = nk.signal_psd(signal, method="lomb", min_frequency=1, max_frequency=20, show=True)
burg = nk.signal_psd(signal, method="burg", min_frequency=1, max_frequency=20, order=10, show=True)
lomb = nk.signal_psd(
signal, method="lomb", min_frequency=1, max_frequency=20, show=True
)
burg = nk.signal_psd(
signal, method="burg", min_frequency=1, max_frequency=20, order=10, show=True
)


# Visualize the different methods together
Expand All @@ -337,7 +333,12 @@
axes[0].set_xlabel("Time (s)")

axes[1].plot(
welch["Frequency"], welch["Power"], label="Welch", color="#E91E63", linewidth=2, zorder=1
welch["Frequency"],
welch["Power"],
label="Welch",
color="#E91E63",
linewidth=2,
zorder=1,
)
axes[1].plot(
multitaper["Frequency"],
Expand All @@ -347,9 +348,21 @@
linewidth=2,
zorder=2,
)
axes[1].plot(burg["Frequency"], burg["Power"], label="Burg", color="#4CAF50", linewidth=2, zorder=3)
axes[1].plot(
lomb["Frequency"], lomb["Power"], label="Lomb", color="#FFC107", linewidth=0.5, zorder=4
burg["Frequency"],
burg["Power"],
label="Burg",
color="#4CAF50",
linewidth=2,
zorder=3,
)
axes[1].plot(
lomb["Frequency"],
lomb["Power"],
label="Lomb",
color="#FFC107",
linewidth=0.5,
zorder=4,
)

axes[1].set_title("Power Spectrum Density (PSD)")
Expand Down
Binary file modified docs/readme/README_ppg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/readme/README_rsp.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/readme/README_simulation.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 4 additions & 2 deletions neurokit2/ecg/ecg_clean.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import scipy.signal

from ..misc import NeuroKitWarning, as_vector
from ..signal import signal_filter, signal_resample
from ..signal import signal_filter


def ecg_clean(ecg_signal, sampling_rate=1000, method="neurokit", **kwargs):
Expand Down Expand Up @@ -335,7 +335,9 @@ def _ecg_clean_templateconvolution(ecg_signal, sampling_rate=1000):
"""Filter and Convolve ECG signal with QRS complex template.
Totally exploratory method by Dominique Makowski, use at your own risks.
The idea is to use a QRS template to convolve the signal with, in order to magnify the QRS features. However, it doens't work well and creates a lot of artifacts. If you have ideas for improvement please let me know!
The idea is to use a QRS template to convolve the signal with, in order to magnify the QRS
features. However, it doens't work well and creates a lot of artifacts. If you have ideas for
improvement please let me know!
"""

window_size = int(np.round(sampling_rate / 4))
Expand Down
Loading

0 comments on commit 4bf8071

Please sign in to comment.