ABP notch localization [ex905.0]ΒΆ

Identifies the notch in the arterial blood pressure (ABP) signal

../../_images/sphx_glr_fig-exercise-detect-abp-all_001.png

Out:

------
Identified QRS peaks at:  [  184   587  1012  1431  1852  2267  2692  3121  3542  3972  4379  4792
  5199  5607  6007  6431  6860  7274  7705  8122  8525  8944  9361  9763
 10191 10632 11095 11548 11981 12406 12849 13303 13743 14145 14545 14977
 15437 15934 16422 16883 17318 17738 18141 18559 18964 19388 19830 20337
 20856 21357 21828 22265 22678 23085 23485 23885 24322 24783 25321 25846
 26343 26825 27294 27716 28126 28528 28943 29382 29850]
/Users/wbr8/homedata/projects/lmlib-branches/reto-doc/lmlib/utils/beta.py:93: RuntimeWarning: invalid value encountered in greater_equal
  loc_msk = (y_loc>=threshold) & msk_merged[ind_start:ind_end]
------
Ejection time:  [0.324 0.326 0.334 0.328 0.326 0.33  0.334 0.328 0.346 0.326 0.336 0.328
 0.328 0.328 0.32  0.326 0.328 0.334 0.334 0.324 0.324 0.33  0.316 0.32
 0.332 0.342 0.324 0.316 0.328 0.334 0.33  0.332 0.312 0.326 0.322 0.322
 0.334 0.32  0.324 0.336 0.322 0.312 0.31  0.316 0.332 0.324 0.318 0.32
 0.32  0.322 0.332 0.32  0.31  0.318 0.328 0.334 0.334 0.33  0.328 0.32
 0.334 0.336 0.338 0.312 0.328 0.32  0.34  0.338]
Delta BP:  [19.89922587 21.34803283 23.47544346 21.19776527 21.20460685 22.59697461
 22.12266134 20.86128269 22.06340839 22.31374858 19.84272359 22.8761991
 21.05583461 20.15517393 21.17787756 22.02530913 22.18065604 19.6240525
 21.94541111 20.49386446 21.1777211  21.53058523 21.87304463 21.05667589
 23.16195593 22.84123198 23.31291203 20.4900421  20.19687565 19.17376003
 21.10340857 20.59836619 18.32594452 17.92090102 18.36222431 19.11515614
 18.88788157 20.2462245  18.74304815 17.98633318 18.64696976 17.45413414
 15.49727448 18.7753513  19.29542273 19.79120142 18.65247953 20.5785541
 19.28935695 19.14594485 18.19389205 17.48958998 16.8374054  19.14684667
 19.09025877 19.79277937 21.83576473 21.97407353 22.38411461 22.36676089
 20.42737944 20.21911724 19.60400167 16.92847949 18.18938677 21.56285163
 20.27613612 20.76282726]
Diastolic BP:  [82.33958731 83.5453305  83.01412552 82.87746517 82.51863629 83.47238031
 81.47478508 81.40515966 81.27467332 80.12663066 81.90485018 82.61131249
 82.858964   83.29652221 84.94531506 83.95020741 81.36918915 83.45997125
 81.19552118 81.21519897 82.97428166 81.21853292 82.03489241 84.46811004
 83.5075053  83.30636313 80.73811515 79.6209857  79.67593434 79.31953851
 77.59709395 74.39380233 75.88035419 77.39050189 78.1964996  76.39587215
 74.2355473  71.82914869 70.71448344 71.36370785 72.90082235 72.98660133
 74.86900914 74.68121778 76.27560846 77.91103581 77.37413338 72.85459763
 70.6730215  69.17791149 69.68299004 70.03045423 71.92732385 74.00637128
 76.90838541 78.67341049 78.04012068 77.74231888 73.53358982 71.8172348
 71.48341853 71.96014158 72.02707703 74.9781508  76.80869503 78.8386745
 79.54027804 80.30204025]
Notch BP:  [102.23881318 104.89336334 106.48956898 104.07523044 103.72324314
 106.06935492 103.59744642 102.26644235 103.33808171 102.44037925
 101.74757377 105.48751158 103.91479861 103.45169614 106.12319262
 105.97551655 103.54984519 103.08402375 103.14093229 101.70906343
 104.15200276 102.74911815 103.90793704 105.52478593 106.66946123
 106.14759511 104.05102718 100.1110278   99.87280998  98.49329854
  98.70050252  94.99216853  94.20629871  95.31140291  96.55872391
  95.5110283   93.12342888  92.0753732   89.45753159  89.35004103
  91.54779211  90.44073547  90.36628361  93.45656908  95.57103119
  97.70223723  96.02661291  93.43315172  89.96237845  88.32385634
  87.87688209  87.52004421  88.76472925  93.15321795  95.99864419
  98.46618987  99.87588542  99.71639241  95.91770443  94.18399569
  91.91079797  92.17925882  91.6310787   91.90663029  94.9980818
 100.40152614  99.81641416 101.06486751]
------
(30000,) [103.85233876 103.76408191 103.64679454 ... 118.43692471 118.26539567
 118.10414856]

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import find_peaks
import csv as csv

import lmlib as lm
from lmlib.utils.generator import gen_slope, gen_wgn
from lmlib.utils.beta import find_max_mask
from lmlib.utils.beta import load_source_csv
from lmlib.utils.beta import diff0
from lmlib.utils.beta import edge_detection
from lmlib.utils.beta import poly_filter






# y_raw = load_source_csv('../../python/cerebral-vasoreg-diabetes-heaad-up-tilt_day1-s0030DA-noheader.csv') # for direct start
y_raw = load_source_csv('./csv-data/cerebral-vasoreg-diabetes-heaad-up-tilt_day1-s0030DA-noheader.csv', time_format = "H:M:S") # for script start




# Signal
fs = 500
k0 = 2000
K = 30000 # 30000
k = range(K)
y_n = gen_wgn(K, sigma=.5, seed=431412)
y_ecg = y_raw[k0:k0+K, 2]
y = y_raw[k0:k0+K, 3]  + y_n


# Reference from QRS
(peaks_ecg_ind, _) = find_peaks(y_ecg, distance=fs*0.6)
print("------")
print("Identified QRS peaks at: ", peaks_ecg_ind)


(y_avg, _) = poly_filter(y, (5,5), (10,10), poly_degree=0)
peaks_bd = find_max_mask(y_avg, () , locs=peaks_ecg_ind, range_start=int(fs*0.1), range_end=int(fs*0.4), skip_invalid=False)

# find dicrotic notch (=end of ventricular ejection phase)
(lcr, y_hat_notch, a0, a1) = edge_detection(y, (30, 30) , (50, 50))
peaks_notch = find_max_mask(lcr, (a0<a1) , locs=peaks_ecg_ind, range_start=int(fs*0.2), range_end=int(fs*0.6), skip_invalid=False)

# find arterial valve opening edge(=begin of ventricular ejection phase)
(lcr, y_hat_ejection, a0, a1) = edge_detection(y, (50, 20) , (80, 50))
peaks_ejection = find_max_mask(lcr, (a0<a1) , locs=peaks_ecg_ind, range_start=int(fs*0.0), range_end=int(fs*0.3), skip_invalid=False)

# remove invalid samples ...
msk = (peaks_notch>=0) & (peaks_ejection>=0) & (peaks_bd >= 0) # only evaluate when all data valid

peaks_bd = peaks_bd[msk]
peaks_ecg_ind = peaks_ecg_ind[msk]
peaks_notch = peaks_notch[msk]
peaks_ejection = peaks_ejection[msk]


# ... and do some statistics
beat_time = diff0(peaks_ecg_ind)/fs
ejection_time = (peaks_notch - peaks_ejection)/fs  # ejection time
delta_pb = y_hat_notch[peaks_notch] - y_hat_ejection[peaks_ejection] # blood pressure amplitude
pd_dia = y_hat_ejection[peaks_ejection] # diastolic blood pressure
pd_sys = y_avg[peaks_bd] # systolic blood pressure
pd_notch = y_hat_notch[peaks_notch] # blood pressure at valve closure (=notch)





print("------")
print("Ejection time: ", ejection_time)
print("Delta BP: ", delta_pb)
print("Diastolic BP: ", pd_dia)
print("Notch BP: ", pd_notch)
print("------")



# Plot
_, axs = plt.subplots(4, 1, sharex='all', figsize=(6, 4))
print(y.shape, y_avg)
axs[0].plot(k, y, lw=0.5, c='tab:gray', label='')
axs[0].plot(k, y_avg, lw=0.5, ls='--', c='tab:red', label='')
axs[0].scatter(peaks_bd, y_avg[peaks_bd], s=30, marker=7,  c='k', label='sys', zorder=20)
axs[0].scatter(peaks_notch, y_hat_notch[peaks_notch], s=30, marker='x',  c='k', label='notch', zorder=20)
axs[0].scatter(peaks_ejection, y_hat_ejection[peaks_ejection], s=30, marker=6,  c='k', label='dia', zorder=20)

axs[0].set_title('Arterial blood pressure (ABP) -- Pressure Parameters')
axs[0].legend(loc=4)


axs[1].plot(peaks_ecg_ind, beat_time, c='black', ls='-', marker='.', lw=1.0, markersize=3, label='$t_{beat}$')
axs[1].plot(peaks_ecg_ind, ejection_time, c='blue', ls='-',  marker='.', lw=1.0, markersize=3, label='$t_{eject}$')
axs[1].set_ylim([0, 1.2])
axs[1].legend(loc=4)
axs[1].grid(True)

axs[2].plot(peaks_ecg_ind, pd_notch, c='black', ls='--', marker='x', markersize=5, lw=1.0, label='$BP_{notch}$')
axs[2].plot(peaks_ecg_ind, pd_sys, c='black', ls='-', marker=7, markersize=5, lw=1.0, label='$BP_{sys}$')
axs[2].plot(peaks_ecg_ind, pd_dia, c='black', ls='-', marker=6, markersize=5, lw=1.0, label='$BP_{dia}$')
axs[2].plot(peaks_ecg_ind, delta_pb, c='black', ls='-', marker='x', markersize=5, lw=1.0, label='$\Delta BP$')
axs[2].legend(loc=4)
axs[2].grid(True)


axs[3].plot(k, y_ecg, c='tab:gray', label='ECG')
axs[3].scatter(peaks_ecg_ind, y_ecg[peaks_ecg_ind], s=20, marker=7,  c='k', label='peaks', zorder=20)
axs[3].legend(loc=4)

axs[3].set(xlabel='k', ylabel=r'$y_k$')


plt.show()

Total running time of the script: ( 0 minutes 11.707 seconds)

Gallery generated by Sphinx-Gallery