## ----include = FALSE----------------------------------------------------------
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)

## ----pulse, out.width = "250px", echo = FALSE, fig.align = "left"-------------
knitr::include_graphics("images/pulse.jpg")

## ----packages-----------------------------------------------------------------
# library(tidyverse)
library(dplyr)
library(stringr)
library(tibble)
library(ggplot2)
library(heartbeatr)

## ----input_header-------------------------------------------------------------
# pulse example allows quick access to test files
fn   <- pulse_example()[1] 
head <- read.csv(fn, nrows = 50, col.names = c("field", "value"))
skip <- max(grep("----------------", head$field))
head[1:skip,]

## ----input_data, results = "hide"---------------------------------------------
read.csv(fn, skip = skip + 1)

## ----input_data_print, echo = FALSE-------------------------------------------
read.csv(fn, skip = skip + 1, nrows = 5)

## ----workflow_read1-----------------------------------------------------------
pulse_data <- pulse_read(
  paths = pulse_example(), 
  msg = FALSE
  )

## ----o------------------------------------------------------------------------
channels <- paste0("c", formatC(1:10, width = 2, flag = "0"))
discard  <- c("c01", "c02", "c05", "c07", "c08", "c09", "c10")
pulse_data$data <- pulse_data$data[, c("time", setdiff(channels, discard))]

pulse_data$data

## ----workflow_split1----------------------------------------------------------
pulse_data_split <- pulse_split(
  pulse_data = pulse_data, 
  window_width_secs = 30, 
  window_shift_secs = 60, 
  msg = FALSE
  )

pulse_data_split

## ----workflow_split2----------------------------------------------------------
pulse_data_split$data[[1]]

## ----workflow_optimize1-------------------------------------------------------
pulse_data_optimized <- pulse_optimize(
  pulse_data_split = pulse_data_split, 
  interpolation_freq = 40,
  bandwidth = 0.75,
  raw_v_smoothed = FALSE,
  multi = TRUE
  )

## ----workflow_optimize2-------------------------------------------------------
pulse_data_split

## ----workflow_optimize3-------------------------------------------------------
pulse_data_optimized

## ----workflow_optimize4, echo = FALSE, fig.height = 1, fig.width = 6----------
x <- bind_rows(
  pulse_data_split$data[[1]] |> tibble::add_column(opt = "raw") |> dplyr::select(t = time, opt, val = c04),
  pulse_data_optimized$data[[1]] |> tibble::add_column(opt = "opt") |> dplyr::select(t = time, opt, val = c04)
) |>
  dplyr::mutate(opt = factor(opt, levels = c("raw", "opt")))

ggplot(x) + 
  geom_line(aes(t, val, col = opt)) + 
  # facet_grid(rows = vars(opt)) + 
  # scale_color_manual(values = c("raw" = "black", "opt" = "red"), guide = "none") + 
  scale_color_manual(values = c("raw" = "grey20", "opt" = "red"), name = NULL) + 
  theme_void()

## ----workflow_heart1----------------------------------------------------------
heart_rates <- pulse_heart(
  pulse_data_split = pulse_data_optimized,
  msg = FALSE
  )

heart_rates

## ----workflow_double1---------------------------------------------------------
heart_rates <- pulse_doublecheck(
  heart_rates = heart_rates
  )

heart_rates

## ----workflow_double3, echo = FALSE, fig.height = 1, fig.width = 6------------
heart_rates_double <- PULSE(
  pulse_example(), window_width_secs = 30, window_shift_secs = 60,
  bandwidth = 0.55, discard_channels = discard, raw_v_smoothed = FALSE, correct = FALSE)
heart_rates_corr <- PULSE(
  pulse_example(), window_width_secs = 30, window_shift_secs = 60, 
  bandwidth = 0.75, discard_channels = discard, raw_v_smoothed = FALSE, correct = TRUE)

x <- bind_rows(
  heart_rates_double |> 
  dplyr::filter(id == "c03", i == 9) |> 
  dplyr::pull(data) |> 
  dplyr::first() |> 
  tibble::add_column(opt = "double peaks"),
  heart_rates_corr |> 
  dplyr::filter(id == "c03", i == 9) |> 
  dplyr::pull(data) |> 
  dplyr::first() |> 
  tibble::add_column(opt = "corrected")
) |> 
  dplyr::mutate(opt = factor(opt, levels = c("double peaks", "corrected")))

pulse_plot_one(x) +
  ggplot2::facet_grid(rows = vars(opt)) +
  ggplot2::theme_void()

## ----workflow_keep1-----------------------------------------------------------
heart_rates <- pulse_choose_keep(
  heart_rates = heart_rates
  )

heart_rates

## ----workflow_keep2-----------------------------------------------------------
dplyr::filter(heart_rates, keep)

## ----simple1------------------------------------------------------------------
# the code below takes approximately 30 seconds   
#  to run on a machine with the following specs:
# - MacBook Air 2022
# - chip:   Apple M2
# - memory: 16 GB RAM
# - macOS:  Sequoia 15.3.1 
heart_rates_PULSE <- PULSE(
  paths = pulse_example(),
  window_width_secs = 30,
  window_shift_secs = 60,
  bandwidth         = 0.75,
  raw_v_smoothed    = FALSE,
  discard_channels  = discard
  )

heart_rates_PULSE

## ----simple2------------------------------------------------------------------
identical(heart_rates_PULSE, heart_rates)

## ----plot_all1, fig.height = 4, fig.width = 6---------------------------------
pulse_plot(heart_rates)

## ----plot_all1b, fig.height = 4, fig.width = 6--------------------------------
pulse_plot(dplyr::filter(heart_rates, keep))

## ----plot_all2, fig.height = 3, fig.width = 6---------------------------------
pulse_plot(
  dplyr::filter(heart_rates, keep), 
  facets = FALSE, 
  bpm    = TRUE, 
  smooth = FALSE, 
  points = FALSE
  )

## ----plot_all3, fig.height = 4, fig.width = 6---------------------------------
pulse_plot(filter(heart_rates, keep)) +
  ggplot2::geom_vline(ggplot2::aes(xintercept = mean(heart_rates$time))) +
  ggplot2::theme_bw() +
  ggplot2::ggtitle("example")

## ----plot_all4, fig.height = 3, fig.width = 6---------------------------------
pulse_plot(dplyr::filter(heart_rates, keep), ID = "c03")

## ----plot_raw1----------------------------------------------------------------
dplyr::filter(heart_rates, id == "c03")

## ----plot_raw2, fig.height = 3, fig.width = 6---------------------------------
pulse_plot_raw(heart_rates, ID = "c03", target_i = 7)

## ----plot_raw3, fig.height = 3, fig.width = 6---------------------------------
pulse_plot_raw(heart_rates, ID = "c03", target_time = "2024-10-01 10:58")

## ----plot_raw4, fig.height = 6, fig.width = 6---------------------------------
pulse_plot_raw(heart_rates, ID = "c03", target_time = "2024-10-01 10:58", range = 2)

## ----bw1----------------------------------------------------------------------
x_02 <- PULSE(
  paths = pulse_example(), bandwidth = 0.2,
  raw_v_smoothed = FALSE, discard_channels = paste0("c0", 1:9), 
  subset = 10, subset_seed = 1, subset_reindex = TRUE, show_progress = FALSE)
x_15 <- PULSE(
  paths = pulse_example(), bandwidth = 1.5,
  raw_v_smoothed = FALSE, discard_channels = paste0("c0", 1:9), 
  subset = 10, subset_seed = 1, subset_reindex = TRUE, show_progress = FALSE)

## ----bw2, fig.height = 2, fig.width = 6---------------------------------------
# when bandwith = 0.2, too many peaks are identified
pulse_plot_raw(x_02, ID = "c10", target_i = 1)
# when bandwith = 0.5, only one peak is identified in each heartbeat, as it should
pulse_plot_raw(x_15, ID = "c10", target_i = 1)

## ----plot_norm1---------------------------------------------------------------
heart_rates_norm <- pulse_normalize(
  dplyr::filter(heart_rates, keep), 
  t0 = "2024-10-01 10:52", 
  span_mins = 5
  )

heart_rates_norm

## ----plot_norm2, fig.height = 3, fig.width = 6--------------------------------
pulse_plot(heart_rates_norm, normalized = FALSE, facets = FALSE)
pulse_plot(heart_rates_norm, normalized = TRUE,  facets = FALSE)

## ----plot_sum1----------------------------------------------------------------
heart_rates_sum <- pulse_summarise(
  heart_rates_norm, 
  FUN = mean, 
  span_mins = 5, 
  min_data_points = 0)

heart_rates_sum

## ----plot_sum2, fig.height = 3, fig.width = 6---------------------------------
pulse_plot(heart_rates_sum, normalized = FALSE, facets = FALSE)

