def get_peaks_ecg(subject, inputs, outputs, recompute, logpath): """Detect R-peaks in ECG. 1. Detect R-peaks 2. autocorrect artifacts in R-peaks detection. """ save_path = Path( individualize_path(outputs["save_path"], subject, expand_name=True)) if save_path.exists() and not recompute: # only recompute if requested print(f"Not re-computing {save_path}") return physio_path = next( Path(".").glob(individualize_path(inputs["physio_path"], subject))) ecg = np.ravel(pd.read_csv(physio_path, sep="\t", header=None)) # Detect R-peaks. peaks = ecg_peaks(ecg, ECG_SFREQ_DECIMATED) # Correct artifacts in peak detection. peaks_corrected = correct_peaks(peaks, ECG_SFREQ_DECIMATED, iterative=True) # Save peaks as samples. pd.Series(peaks_corrected).to_csv(save_path, sep="\t", header=False, index=False, float_format="%.4f") if not logpath: return fig, ax = plt.subplots(nrows=1, ncols=1) sec = np.linspace(0, len(ecg) / ECG_SFREQ_DECIMATED, len(ecg)) ax.plot(sec, ecg) ax.scatter(sec[peaks], ecg[peaks], zorder=3, c="r", marker="+", s=300, label="uncorrected R-peaks") ax.scatter(sec[peaks_corrected], ecg[peaks_corrected], zorder=4, c="g", marker="x", s=300, label="corrected R-peaks") ax.set_xlabel("seconds") ax.legend(loc="upper right") fig.savefig(logpath, dpi=200) plt.close(fig)
for record, annotation in zip(records, annotations): try: ecg = np.ravel(pd.read_csv(record, sep=" ", usecols=[1], header=None)) except FileNotFoundError: print(f"no ECG available for {record}") continue try: manupeaks = np.ravel(pd.read_csv(annotation, header=None)) except FileNotFoundError: print(f"no annotations available for {annotation}") continue algopeaks = ecg_peaks(ecg, sfreq) if algopeaks.size > 1: comparitor = compare_annotations(manupeaks, algopeaks, tolerance) tp = comparitor.tp fp = comparitor.fp fn = comparitor.fn # plt.figure() # plt.plot(ecg) # plt.scatter(manupeaks, ecg[manupeaks], c="m") # plt.scatter(algopeaks, ecg[algopeaks], c='g', marker='X', s=150) sensitivity.append(float(tp) / (tp + fn)) precision.append(float(tp) / (tp + fp))
import matplotlib.pyplot as plt import numpy as np import pandas as pd from biopeaks import heart from matplotlib.patches import FancyArrowPatch from matplotlib import rc # make all text bold rc('font', weight='bold') sfreq = 100 signal = np.ravel(pd.read_csv("ecg_snippet.tsv", sep="\t")) peaks = heart.ecg_peaks(signal, sfreq) period, _ = heart.heart_period(peaks, sfreq, signal.size) minsignal = min(signal) maxsignal = max(signal) fig, (ax0, ax1) = plt.subplots(nrows=2, ncols=1, figsize=(7.2, 4.45)) fig.subplots_adjust(hspace=.05) ax0td = ax0.transData ax1td = ax1.transData figtf = fig.transFigure figtf_inv = figtf.inverted()
def test_ecg_peaks(ecg_data): test_extrema = ecg_peaks(ecg_data["signal"], ecg_data["sfreq"]) assert np.allclose(np.sum(test_extrema), 202504458, atol=5)