# Teresa updated May 18th 2018
#' @importFrom assertthat assert_that
#' @importFrom magrittr %>% subtract add
#' @importFrom purrr as_vector discard partial reduce
#'
library("assertthat")
library("magrittr")
library("purrr")
library("robfilter")
library("signal")
signal_low_pass <-
function(signal_,
cutoff = 40,
filter_order = 5,
sampling_frequency = 250) {
lower_limit <- cutoff/(sampling_frequency/2)
filter_coefficients <-
signal::butter(filter_order, lower_limit, type = "low")
filtered_signal <-
signal::filtfilt(filter_coefficients, signal_)
}
baseline_wander_removal_median <-
function(signal_, sampling_frequency) {
window_size_ <-
function(fraction_of_frequency) {
round(fraction_of_frequency * sampling_frequency)
}
pluck_median_signal_ <-
function(filtered_signal) {
filtered_signal$level$MED
}
clean_signal_ <-
partial(subtract, signal_)
signal_ %>%
robfilter::med.filter(window_size_(0.2)) %>%
pluck_median_signal_() %>%
robfilter::med.filter(window_size_(0.6)) %>%
pluck_median_signal_() %>%
clean_signal_()
}
convert_unit_to_ms_ <- function(indexes, sampling_frequency = 250) {
indexes / sampling_frequency * 1000
}
convert_unit_to_sample_ <- function(indexes, sampling_frequency = 250) {
indexes / 1000 * sampling_frequency
}
#' Detect the locations of P,Q,R,S,T waves in ECG signals
#' Return a list including 9 vectors of indexes for each wave
#' The list includes:
#' Q_peak, R_peak, S_peak,
#' P_onset, P_wave, Type_of_P, T_onset, T_wave, Type_of_T
#'
#' Unit of indexes: ms (millisecond)
#'
#' Type_of_P corresponds to the types of P wave morphology
#' 1 - normal; 2 - inverse; 3 - biphasic +/-; 4 - biphasic -/+; 0 - no type
#'
#' Type_of_T corresponds to the types of T wave morphology
#' 1 - normal; 2 - inverse; 3 - biphasic +/-; 4 - biphasic -/+;
#' 5 - upwards; 6 - downwards
#'
#' @param ecg_signal_ The original ECG signal of a subject
#' @param fs The sampling frequency of ECG signal
#'
#' @export
#'
wavelet_ECG_annotation <- function(ecg_signal_, fs) {
# preprocessing
ecg <-
ecg_signal_ %>%
baseline_wander_removal_median(fs) %>%
signal_low_pass(sampling_frequency = fs)
# wavelet transform
ecg_list <-
wavelet_preprocessing(ecg, fs)
R_detection <-
wavelet_R_detection(ecg_list$wavelets, ecg_list$thresholds, ecg_list$alignments)
if(length(R_detection) == 0){
return(list(
P_wave = c(),
Q_peak = c(),
R_peak = c(),
S_peak = c(),
T_wave = c()
))
}else{
R_peak <- R_detection[!is.na(R_detection)]
Q_detection <-
wavelet_Q_detection(R_peak, ecg_list$wavelets, ecg_list$alignments)
S_detection <-
wavelet_S_detection(R_peak, ecg_list$wavelets, ecg_list$alignments)
P_detection <-
wavelet_P_detection(R_peak, ecg_list$wavelets, ecg_list$alignments)
T_detection <-
wavelet_T_detection(R_peak, ecg_list$wavelets, ecg_list$alignments)
list(
P_wave = P_detection$P %>%
convert_unit_to_ms_(),
P_onset = P_detection$P_onset %>%
convert_unit_to_ms_(),
type_of_P = P_detection$type_of_P,
Q_peak = Q_detection %>%
convert_unit_to_ms_(),
R_peak = R_peak %>%
convert_unit_to_ms_(),
S_peak = S_detection %>%
convert_unit_to_ms_(),
T_wave = T_detection$T_wave %>%
convert_unit_to_ms_(),
T_onset = T_detection$T_onset %>%
convert_unit_to_ms_(),
type_of_T = T_detection$type_of_T
)
}
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.