From ebe26cd0e90fdef34a7c8446407d1acf6a72b137 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Tue, 25 Aug 2020 15:27:51 +0100 Subject: [PATCH 01/52] autoformat --- R/epinow.R | 390 ++++++++++++++++++++++++++--------------------------- 1 file changed, 195 insertions(+), 195 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index 9bad172ca..76df0e7b7 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -67,211 +67,211 @@ #' epinow <- function(reported_cases, family = "negbin", generation_time, delays, - gp = list(basis_prop = 0.3, boundary_scale = 2, + gp = list(basis_prop = 0.3, boundary_scale = 2, lengthscale_mean = 0, lengthscale_sd = 2), rt_prior = list(mean = 1, sd = 1), model, prior_smoothing_window = 7, cores = 1, chains = 4, - samples = 1000, warmup = 200, adapt_delta = 0.99, max_treedepth = 15, + samples = 1000, warmup = 200, adapt_delta = 0.99, max_treedepth = 15, estimate_rt = TRUE, estimate_week_eff = TRUE, estimate_breakpoints = FALSE, burn_in = 0, stationary = FALSE, fixed = FALSE, fixed_future_rt = FALSE, - return_fit = FALSE, forecast_model, horizon = 7, ensemble_type = "mean", + return_fit = FALSE, forecast_model, horizon = 7, ensemble_type = "mean", return_estimates = TRUE, target_folder, target_date, verbose = TRUE, debug = FALSE) { - if (!return_estimates & missing(target_folder)) { - futile.logger::flog.fatal("Either return estimates or save to a target folder") - stop("Either return estimates or save to a target folder") - } - - # Convert input to DT ----------------------------------------------------- + if (!return_estimates & missing(target_folder)) { + futile.logger::flog.fatal("Either return estimates or save to a target folder") + stop("Either return estimates or save to a target folder") + } + + # Convert input to DT ----------------------------------------------------- suppressMessages(data.table::setDTthreads(threads = 1)) reported_cases <- data.table::setDT(reported_cases) - # Set up folders ---------------------------------------------------------- + # Set up folders ---------------------------------------------------------- if (missing(target_date)) { target_date <- max(reported_cases$date) } - + if (missing(target_folder)) { target_folder <- NULL } - - + + if (!is.null(target_folder)) { latest_folder <- file.path(target_folder, "latest") target_folder <- file.path(target_folder, target_date) - + if (!dir.exists(target_folder)) { dir.create(target_folder, recursive = TRUE) } } -# Make sure the horizon is as specified from the target date -------------- + # Make sure the horizon is as specified from the target date -------------- - if (horizon != 0) { - horizon <- horizon + as.numeric(as.Date(target_date) - max(reported_cases$date)) - } + if (horizon != 0) { + horizon <- horizon + as.numeric(as.Date(target_date) - max(reported_cases$date)) + } -# Save input data --------------------------------------------------------- + # Save input data --------------------------------------------------------- -if (!is.null(target_folder)) { - latest_date <- reported_cases[confirm > 0][date == max(date)]$date - - saveRDS(latest_date, paste0(target_folder, "/latest_date.rds")) - saveRDS(reported_cases, paste0(target_folder, "/reported_cases.rds")) -} + if (!is.null(target_folder)) { + latest_date <- reported_cases[confirm > 0][date == max(date)]$date -# Estimate infections and Reproduction no --------------------------------- + saveRDS(latest_date, paste0(target_folder, "/latest_date.rds")) + saveRDS(reported_cases, paste0(target_folder, "/reported_cases.rds")) + } + + # Estimate infections and Reproduction no --------------------------------- if (missing(model)) { model <- NULL } - - estimates <- estimate_infections(reported_cases = reported_cases, - family = family, - generation_time = generation_time, - delays = delays, - gp = gp, - rt_prior = rt_prior, - adapt_delta = adapt_delta, - max_treedepth = max_treedepth, - model = model, - cores = cores, chains = chains, - samples = samples, - warmup = warmup, - estimate_rt = estimate_rt, - estimate_week_eff = estimate_week_eff, - estimate_breakpoints = estimate_breakpoints, - burn_in = burn_in, stationary = stationary, fixed = fixed, - fixed_future_rt = fixed_future_rt, - horizon = horizon, - verbose = verbose, return_fit = return_fit, - debug = debug) - -# Report estimates -------------------------------------------------------- + + estimates <- estimate_infections(reported_cases = reported_cases, + family = family, + generation_time = generation_time, + delays = delays, + gp = gp, + rt_prior = rt_prior, + adapt_delta = adapt_delta, + max_treedepth = max_treedepth, + model = model, + cores = cores, chains = chains, + samples = samples, + warmup = warmup, + estimate_rt = estimate_rt, + estimate_week_eff = estimate_week_eff, + estimate_breakpoints = estimate_breakpoints, + burn_in = burn_in, stationary = stationary, fixed = fixed, + fixed_future_rt = fixed_future_rt, + horizon = horizon, + verbose = verbose, return_fit = return_fit, + debug = debug) + + # Report estimates -------------------------------------------------------- if (!is.null(target_folder)) { - saveRDS(estimates$samples, paste0(target_folder, "/estimate_samples.rds")) - saveRDS(estimates$summarised, paste0(target_folder, "/summarised_estimates.rds")) - - if (return_fit){ + saveRDS(estimates$samples, paste0(target_folder, "/estimate_samples.rds")) + saveRDS(estimates$summarised, paste0(target_folder, "/summarised_estimates.rds")) + + if (return_fit) { saveRDS(estimates$fit, paste0(target_folder, "/model_fit.rds")) } - } -# Forecast infections and reproduction number ----------------------------- -if (!missing(forecast_model)) { - forecast <- forecast_infections(infections = estimates$summarised[variable == "infections"][type != "forecast"][, type := NULL], - rts = estimates$summarised[variable == "R"][type != "forecast"][, type := NULL], - gt_mean = estimates$summarised[variable == "gt_mean"]$mean, - gt_sd = estimates$summarised[variable == "gt_sd"]$mean, - gt_max = generation_time$max, - forecast_model = forecast_model, - ensemble_type = ensemble_type, - horizon = horizon, - samples = samples) -} -# Report cases ------------------------------------------------------------ -if (!missing(forecast_model) & !is.null(target_folder)) { - saveRDS(forecast$samples, paste0(target_folder, "/forecast_samples.rds")) - saveRDS(forecast$summarised, paste0(target_folder, "/summarised_forecast.rds")) -} -# Report forcasts --------------------------------------------------------- - -if (missing(forecast_model)) { - estimated_reported_cases <- list() - estimated_reported_cases$samples <- estimates$samples[variable == "reported_cases"][, - .(date, sample, cases = value, type = "gp_rt")] - estimated_reported_cases$summarised <- estimates$summarised[variable == "reported_cases"][, - type := "gp_rt"][, variable := NULL][, strat := NULL] -}else{ - report_cases_with_forecast <- function(model) { - reported_cases <- report_cases(case_estimates = estimates$samples[variable == "infections"][type != "forecast"][, - .(date, sample, cases = value)], - case_forecast = forecast$samples[type == "case" & - forecast_type == model][, - .(date, sample, cases = value)], - delays = delays, - type = "sample") - return(reported_cases) } - - reported_cases_rt <- report_cases_with_forecast(model = "rt") - reported_cases_cases <- report_cases_with_forecast(model = "case") - reported_cases_ensemble <- report_cases_with_forecast(model = "ensemble") - - estimated_reported_cases <- list() - - estimated_reported_cases$samples <- data.table::rbindlist(list( - reported_cases_rt$samples[,type := "rt"], - reported_cases_cases$samples[,type := "case"], - reported_cases_ensemble$samples[,type := "ensemble"], - estimates$samples[variable == "reported_cases"][, - .(date, sample, cases = value, type = "gp_rt")] - ), use.names = TRUE) - - estimated_reported_cases$summarised <- data.table::rbindlist(list( - reported_cases_rt$summarised[,type := "rt"], - reported_cases_cases$summarised[,type := "case"], - reported_cases_ensemble$summarised[,type := "ensemble"], - estimates$summarised[variable == "reported_cases"][, type := "gp_rt"][, - variable := NULL][, strat := NULL] - ), use.names = TRUE) -} - -if (!is.null(target_folder)){ - saveRDS(estimated_reported_cases$samples, paste0(target_folder, "/estimated_reported_cases_samples.rds")) - saveRDS(estimated_reported_cases$summarised, paste0(target_folder, "/summarised_estimated_reported_cases.rds")) -} - -# # Report estimates -------------------------------------------------------- - - summary <- report_summary( - summarised_estimates = estimates$summarised[!is.na(date)][type != "forecast"][date == max(date)], - rt_samples = estimates$samples[variable == "R"][type != "forecast"][date == max(date), .(sample, value)]) - - - if(!is.null(target_folder)) { - saveRDS(summary, paste0(target_folder, "/summary.rds")) - } - -# # Plot -------------------------------------------------------------------- - - plots <- report_plots(summarised_estimates = estimates$summarised, - reported = reported_cases, target_folder = target_folder) - - # Copy all results to latest folder --------------------------------------- - if (!is.null(target_folder)) { + # Forecast infections and reproduction number ----------------------------- + if (!missing(forecast_model)) { + forecast <- forecast_infections(infections = estimates$summarised[variable == "infections"][type != "forecast"][, type := NULL], + rts = estimates$summarised[variable == "R"][type != "forecast"][, type := NULL], + gt_mean = estimates$summarised[variable == "gt_mean"]$mean, + gt_sd = estimates$summarised[variable == "gt_sd"]$mean, + gt_max = generation_time$max, + forecast_model = forecast_model, + ensemble_type = ensemble_type, + horizon = horizon, + samples = samples) + } + # Report cases ------------------------------------------------------------ + if (!missing(forecast_model) & !is.null(target_folder)) { + saveRDS(forecast$samples, paste0(target_folder, "/forecast_samples.rds")) + saveRDS(forecast$summarised, paste0(target_folder, "/summarised_forecast.rds")) + } + # Report forcasts --------------------------------------------------------- + + if (missing(forecast_model)) { + estimated_reported_cases <- list() + estimated_reported_cases$samples <- estimates$samples[variable == "reported_cases"][, + .(date, sample, cases = value, type = "gp_rt")] + estimated_reported_cases$summarised <- estimates$summarised[variable == "reported_cases"][, + type := "gp_rt"][, variable := NULL][, strat := NULL] + }else { + report_cases_with_forecast <- function(model) { + reported_cases <- report_cases(case_estimates = estimates$samples[variable == "infections"][type != "forecast"][, + .(date, sample, cases = value)], + case_forecast = forecast$samples[type == "case" & + forecast_type == model][, + .(date, sample, cases = value)], + delays = delays, + type = "sample") + return(reported_cases) + } + + reported_cases_rt <- report_cases_with_forecast(model = "rt") + reported_cases_cases <- report_cases_with_forecast(model = "case") + reported_cases_ensemble <- report_cases_with_forecast(model = "ensemble") + + estimated_reported_cases <- list() + + estimated_reported_cases$samples <- data.table::rbindlist(list( + reported_cases_rt$samples[, type := "rt"], + reported_cases_cases$samples[, type := "case"], + reported_cases_ensemble$samples[, type := "ensemble"], + estimates$samples[variable == "reported_cases"][, + .(date, sample, cases = value, type = "gp_rt")] + ), use.names = TRUE) + + estimated_reported_cases$summarised <- data.table::rbindlist(list( + reported_cases_rt$summarised[, type := "rt"], + reported_cases_cases$summarised[, type := "case"], + reported_cases_ensemble$summarised[, type := "ensemble"], + estimates$summarised[variable == "reported_cases"][, type := "gp_rt"][, + variable := NULL][, strat := NULL] + ), use.names = TRUE) + } + + if (!is.null(target_folder)) { + saveRDS(estimated_reported_cases$samples, paste0(target_folder, "/estimated_reported_cases_samples.rds")) + saveRDS(estimated_reported_cases$summarised, paste0(target_folder, "/summarised_estimated_reported_cases.rds")) + } + + # # Report estimates -------------------------------------------------------- + + summary <- report_summary( + summarised_estimates = estimates$summarised[!is.na(date)][type != "forecast"][date == max(date)], + rt_samples = estimates$samples[variable == "R"][type != "forecast"][date == max(date), .(sample, value)]) + + + if (!is.null(target_folder)) { + saveRDS(summary, paste0(target_folder, "/summary.rds")) + } + + # # Plot -------------------------------------------------------------------- + + plots <- report_plots(summarised_estimates = estimates$summarised, + reported = reported_cases, target_folder = target_folder) + + # Copy all results to latest folder --------------------------------------- + if (!is.null(target_folder)) { ## Save all results to a latest folder as well suppressWarnings( if (dir.exists(latest_folder)) { unlink(latest_folder) }) - + suppressWarnings( dir.create(latest_folder) ) - + suppressWarnings( file.copy(file.path(target_folder, "."), latest_folder, recursive = TRUE) ) } - - if (return_estimates) { - out <- list() - out$estimates <- estimates - - if (!missing(forecast_model)) { - out$forecast <- forecast - } - - out$estimated_reported_cases <- estimated_reported_cases - out$summary <- summary - out$plots <- plots - return(out) - }else{ - return(invisible(NULL)) - } + + if (return_estimates) { + out <- list() + out$estimates <- estimates + + if (!missing(forecast_model)) { + out$forecast <- forecast + } + + out$estimated_reported_cases <- estimated_reported_cases + out$summary <- summary + out$plots <- plots + return(out) + }else { + return(invisible(NULL)) + } } @@ -330,7 +330,7 @@ if (!is.null(target_folder)){ #' samples = 2000, warmup = 200, verbose = TRUE, #' cores = ifelse(interactive(), 4, 1), chains = 4) #'} -regional_epinow <- function(reported_cases, +regional_epinow <- function(reported_cases, target_folder, target_date, non_zero_points = 2, cores = 1, summary = TRUE, @@ -340,92 +340,92 @@ regional_epinow <- function(reported_cases, return_estimates = TRUE, max_plot = 10, ...) { - + ## Set input to data.table reported_cases <- data.table::setDT(reported_cases) - + if (missing(target_date)) { target_date <- as.character(max(reported_cases$date)) } - + if (missing(target_folder)) { target_folder <- NULL } - + futile.logger::flog.info("Reporting estimates using data up to: %s", target_date) - - + + ## Check for regions more than required time points with cases - eval_regions <- data.table::copy(reported_cases)[,.(confirm = confirm > 0), by = c("region", "date")][, - .(confirm = sum(confirm, na.rm = TRUE)), by = "region"][confirm >= non_zero_points]$region - + eval_regions <- data.table::copy(reported_cases)[, .(confirm = confirm > 0), by = c("region", "date")][, + .(confirm = sum(confirm, na.rm = TRUE)), by = "region"][confirm >= non_zero_points]$region + eval_regions <- unique(eval_regions) - + ## Exclude zero regions reported_cases <- reported_cases[!is.na(region)][region %in% eval_regions] - + futile.logger::flog.info("Producing estimates for: %s", - paste(eval_regions, collapse = ", ")) - + paste(eval_regions, collapse = ", ")) + ## regional pipelines regions <- unique(reported_cases$region) - + ## Function to run the pipeline in a region - run_region <- function(target_region, + run_region <- function(target_region, reported_cases, cores = cores, - ...) { + ...) { futile.logger::flog.info("Initialising estimates for: %s", target_region) - + data.table::setDTthreads(threads = 1) if (!is.null(target_folder)) { target_folder <- file.path(target_folder, target_region) } - + regional_cases <- reported_cases[region %in% target_region][, region := NULL] - + out <- EpiNow2::epinow( reported_cases = regional_cases, target_folder = target_folder, - target_date = target_date, + target_date = target_date, return_estimates = TRUE, cores = cores, ...) - - futile.logger::flog.info("Completed estimates for: %s", target_region) - return(out) - } - + futile.logger::flog.info("Completed estimates for: %s", target_region) + + return(out) + } + safe_run_region <- purrr::safely(run_region) - + ## Run regions (make parallel using future::plan) regional_out <- future.apply::future_lapply(regions, safe_run_region, reported_cases = reported_cases, cores = cores, ..., future.scheduling = Inf) - - regional_errors <- purrr::map(regional_out, ~ .$error) + + regional_errors <- purrr::map(regional_out, ~.$error) names(regional_errors) <- regions regional_errors <- purrr::compact(regional_errors) if (length(regional_errors) != 0) { - futile.logger::flog.info("Runtime errors caught: ") - futile.logger::flog.info(regional_errors) - } + futile.logger::flog.info("Runtime errors caught: ") + futile.logger::flog.info(regional_errors) + } - regional_out <- purrr::map(regional_out, ~ .$result) + regional_out <- purrr::map(regional_out, ~.$result) names(regional_out) <- regions - - + + if (summary) { if (missing(summary_dir)) { summary_dir <- NULL } safe_summary <- purrr::safely(regional_summary) - + summary_out <- safe_summary(regional_output = regional_out, summary_dir = summary_dir, reported_cases = reported_cases, @@ -436,21 +436,21 @@ regional_epinow <- function(reported_cases, if (!is.null(summary_out[[2]])) { futile.logger::flog.info("Errors caught whilst generating summary statistics: ") futile.logger::flog.info(summary_out[[2]]) - } + } summary_out <- summary_out[[1]] } - + if (return_estimates) { out <- list() out$regional <- regional_out - + if (summary) { out$summary <- summary_out } - + return(out) - }else{ + }else { return(invisible(NULL)) } } From d7a3bebb12bd83a426feb77ddbd408d1e4d86605 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Tue, 25 Aug 2020 16:52:46 +0100 Subject: [PATCH 02/52] starting to include timings and timeout function --- DESCRIPTION | 1 + R/epinow.R | 43 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index f9a30665a..2025b4ed4 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -61,6 +61,7 @@ Imports: methods, patchwork, purrr, + R.utils (>= 2.0.0), Rcpp (>= 0.12.0), rstan (>= 2.18.1), rstantools (>= 2.0.0), diff --git a/R/epinow.R b/R/epinow.R index 76df0e7b7..08481439f 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -284,6 +284,8 @@ epinow <- function(reported_cases, family = "negbin", #' @param summary Logical, should summary measures be calculated. #' @param all_regions_summary Logical, defaults to `TRUE`. Should summary plots for all regions be returned #' rather than just regions of interest. +#' @param return_timings Logical, defaults to FALSE. Should timing values be returned for each location. +#' @param max_execution_time Integer, defaults to Inf. If set will kill off processing after x seconds. #' @param ... Pass additional arguments to `epinow` #' @inheritParams epinow #' @inheritParams regional_summary @@ -339,6 +341,8 @@ regional_epinow <- function(reported_cases, all_regions_summary = TRUE, return_estimates = TRUE, max_plot = 10, + return_timings = FALSE, + max_execution_time = Inf, ...) { ## Set input to data.table @@ -385,14 +389,35 @@ regional_epinow <- function(reported_cases, regional_cases <- reported_cases[region %in% target_region][, region := NULL] - out <- EpiNow2::epinow( - reported_cases = regional_cases, - target_folder = target_folder, - target_date = target_date, - return_estimates = TRUE, - cores = cores, - ...) - + timing <- system.time( + tryCatch( + out <- withTimeout( + EpiNow2::epinow( + reported_cases = regional_cases, + target_folder = target_folder, + target_date = target_date, + return_estimates = TRUE, + cores = cores, + ...), + timeout = max_execution_time + ), + TimeoutException = function(ex) { + if (return_timings) { + out <- list("timings" = Inf) + } else { + out <- NULL + } + } + ) + ) + if (return_timings) { + if (is.null(out)) { + out <- list() + } + if (!exists("timings", out)) { + out$timings = timing['elapsed'] + } + } futile.logger::flog.info("Completed estimates for: %s", target_region) return(out) @@ -404,6 +429,8 @@ regional_epinow <- function(reported_cases, regional_out <- future.apply::future_lapply(regions, safe_run_region, reported_cases = reported_cases, cores = cores, + return_timings = return_timings, + max_execution_time = max_execution_time, ..., future.scheduling = Inf) From 5ff094d827d0dbe95875368f245132ea66ac4fb9 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 26 Aug 2020 08:29:18 +0100 Subject: [PATCH 03/52] temporary timing setting for testing on server --- R/epinow.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/epinow.R b/R/epinow.R index 08481439f..2e067c07a 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -342,7 +342,7 @@ regional_epinow <- function(reported_cases, return_estimates = TRUE, max_plot = 10, return_timings = FALSE, - max_execution_time = Inf, + max_execution_time = 60, ...) { ## Set input to data.table From 89d0cefcd77656eeeede6772de95a1acb9159955 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 26 Aug 2020 08:41:59 +0100 Subject: [PATCH 04/52] improve logging --- R/epinow.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/R/epinow.R b/R/epinow.R index 2e067c07a..e875ea12a 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -340,7 +340,7 @@ regional_epinow <- function(reported_cases, region_scale = "Region", all_regions_summary = TRUE, return_estimates = TRUE, - max_plot = 10, + max_plot = 10, #todo: revert to Inf return_timings = FALSE, max_execution_time = 60, ...) { @@ -402,6 +402,7 @@ regional_epinow <- function(reported_cases, timeout = max_execution_time ), TimeoutException = function(ex) { + futile.logger::flog.warn("region %s timed out", region) if (return_timings) { out <- list("timings" = Inf) } else { From d8e613ab0dda31457a2f21231cc4b69e3187a9eb Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 26 Aug 2020 08:52:58 +0100 Subject: [PATCH 05/52] include withTimeout --- R/epinow.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/epinow.R b/R/epinow.R index e875ea12a..8fc61f576 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -295,6 +295,7 @@ epinow <- function(reported_cases, family = "negbin", #' @importFrom data.table as.data.table setDT copy setorder #' @importFrom purrr safely map compact #' @importFrom futile.logger flog.info +#' @importFrom R.utils withTimeout #' @examples #' \donttest{ #' ## Construct example distributions From cc951dc81d4e7048461c8db96fa5a53d5be1fe86 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 26 Aug 2020 09:08:41 +0100 Subject: [PATCH 06/52] make it static to try and deal with include shenanigans --- R/epinow.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/epinow.R b/R/epinow.R index 8fc61f576..71869afbe 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -392,7 +392,7 @@ regional_epinow <- function(reported_cases, timing <- system.time( tryCatch( - out <- withTimeout( + out <- R.utils::withTimeout( EpiNow2::epinow( reported_cases = regional_cases, target_folder = target_folder, From 155ab2b6cbf811a3ef4bd6e3d5ba67d4300def9a Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 26 Aug 2020 09:28:03 +0100 Subject: [PATCH 07/52] fix function signature to match params --- R/epinow.R | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index 71869afbe..05bbb2d24 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -341,9 +341,9 @@ regional_epinow <- function(reported_cases, region_scale = "Region", all_regions_summary = TRUE, return_estimates = TRUE, - max_plot = 10, #todo: revert to Inf + max_plot = 10, return_timings = FALSE, - max_execution_time = 60, + max_execution_time = 60, #todo: revert to Inf ...) { ## Set input to data.table @@ -379,6 +379,8 @@ regional_epinow <- function(reported_cases, run_region <- function(target_region, reported_cases, cores = cores, + return_timings = return_timings, + max_execution_time = max_execution_time, ...) { futile.logger::flog.info("Initialising estimates for: %s", target_region) From fd8a6baef34915100e51dc975e40bd99ca381551 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 26 Aug 2020 09:37:44 +0100 Subject: [PATCH 08/52] get the right region --- R/epinow.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/epinow.R b/R/epinow.R index 05bbb2d24..5f24a6f00 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -405,7 +405,7 @@ regional_epinow <- function(reported_cases, timeout = max_execution_time ), TimeoutException = function(ex) { - futile.logger::flog.warn("region %s timed out", region) + futile.logger::flog.warn("region %s timed out", target_region) if (return_timings) { out <- list("timings" = Inf) } else { From 5c970ac70ed8ad84e443e4269809bd97463d9626 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 26 Aug 2020 13:31:43 +0100 Subject: [PATCH 09/52] add more debugging --- R/epinow.R | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index 5f24a6f00..ad9ab640e 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -390,8 +390,10 @@ regional_epinow <- function(reported_cases, target_folder <- file.path(target_folder, target_region) } + futile.logger::flog.trace("filtering data for target region %s", target_region) regional_cases <- reported_cases[region %in% target_region][, region := NULL] + futile.logger::flog.trace("calling epinow2::epinow to process data") timing <- system.time( tryCatch( out <- R.utils::withTimeout( @@ -414,22 +416,23 @@ regional_epinow <- function(reported_cases, } ) ) + futile.logger::flog.trace("epinow returned for region %s", target_region) if (return_timings) { if (is.null(out)) { + futile.logger::flog.trace("region has not returned an out file (completed but not set to output) so create one") out <- list() } - if (!exists("timings", out)) { - out$timings = timing['elapsed'] - } + out$timings = timing['elapsed'] } futile.logger::flog.info("Completed estimates for: %s", target_region) - + saveRDS(out, "subregion_out.rds") return(out) } safe_run_region <- purrr::safely(run_region) ## Run regions (make parallel using future::plan) + futile.logger::flog.trace("calling future apply to process each region through the run_region function") regional_out <- future.apply::future_lapply(regions, safe_run_region, reported_cases = reported_cases, cores = cores, @@ -438,6 +441,8 @@ regional_epinow <- function(reported_cases, ..., future.scheduling = Inf) + saveRDS(regional_out, "subregion_out.rds") + futile.logger::flog.trace("processing errors") regional_errors <- purrr::map(regional_out, ~.$error) names(regional_errors) <- regions regional_errors <- purrr::compact(regional_errors) From 8c1ad6058d84c8e00a33da0fb1462a7e3579f33e Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 26 Aug 2020 13:44:26 +0100 Subject: [PATCH 10/52] debugging --- R/epinow.R | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index ad9ab640e..5b91cf590 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -408,14 +408,11 @@ regional_epinow <- function(reported_cases, ), TimeoutException = function(ex) { futile.logger::flog.warn("region %s timed out", target_region) - if (return_timings) { - out <- list("timings" = Inf) - } else { - out <- NULL - } + out <- ifelse (return_timings, list("timings" = Inf), NULL) } ) ) + saveRDS(out, "subregion_out_a.rds") futile.logger::flog.trace("epinow returned for region %s", target_region) if (return_timings) { if (is.null(out)) { @@ -441,7 +438,7 @@ regional_epinow <- function(reported_cases, ..., future.scheduling = Inf) - saveRDS(regional_out, "subregion_out.rds") + saveRDS(regional_out, "region_out.rds") futile.logger::flog.trace("processing errors") regional_errors <- purrr::map(regional_out, ~.$error) names(regional_errors) <- regions From 4f892d5afdf8a70ca8771cb8c1daf5ca38e3c101 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 26 Aug 2020 16:38:16 +0100 Subject: [PATCH 11/52] changing null return --- R/epinow.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/epinow.R b/R/epinow.R index 5b91cf590..f8e5f5bc0 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -408,7 +408,7 @@ regional_epinow <- function(reported_cases, ), TimeoutException = function(ex) { futile.logger::flog.warn("region %s timed out", target_region) - out <- ifelse (return_timings, list("timings" = Inf), NULL) + out <- ifelse (return_timings, list("timings" = Inf), list("estimates" = NULL)) } ) ) From c875ce7aa8019ccf3252db87d88d8174507d09ac Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 26 Aug 2020 16:54:41 +0100 Subject: [PATCH 12/52] get the return out of the try catch properly --- R/epinow.R | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index f8e5f5bc0..5adb2e9ec 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -342,8 +342,8 @@ regional_epinow <- function(reported_cases, all_regions_summary = TRUE, return_estimates = TRUE, max_plot = 10, - return_timings = FALSE, - max_execution_time = 60, #todo: revert to Inf + return_timings = TRUE, + max_execution_time = 60, #todo: revert to Inf and timings to false ...) { ## Set input to data.table @@ -395,8 +395,8 @@ regional_epinow <- function(reported_cases, futile.logger::flog.trace("calling epinow2::epinow to process data") timing <- system.time( - tryCatch( - out <- R.utils::withTimeout( + out <- tryCatch( + R.utils::withTimeout( EpiNow2::epinow( reported_cases = regional_cases, target_folder = target_folder, @@ -408,7 +408,7 @@ regional_epinow <- function(reported_cases, ), TimeoutException = function(ex) { futile.logger::flog.warn("region %s timed out", target_region) - out <- ifelse (return_timings, list("timings" = Inf), list("estimates" = NULL)) + return(ifelse (return_timings, list("timings" = Inf), NULL)) } ) ) From 448e622d4cb41f0dc32194caf2a5804fdc2aa0e7 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 26 Aug 2020 17:24:09 +0100 Subject: [PATCH 13/52] keep timing away from the timeout --- R/epinow.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/epinow.R b/R/epinow.R index 5adb2e9ec..b7ed44ebd 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -408,7 +408,7 @@ regional_epinow <- function(reported_cases, ), TimeoutException = function(ex) { futile.logger::flog.warn("region %s timed out", target_region) - return(ifelse (return_timings, list("timings" = Inf), NULL)) + return(list()) } ) ) From 91264aea8a8a8bf4984a1ad26c61847b9b19eaf0 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 26 Aug 2020 17:34:50 +0100 Subject: [PATCH 14/52] up the timeout for a bigger test run --- R/epinow.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/epinow.R b/R/epinow.R index b7ed44ebd..015945193 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -343,7 +343,7 @@ regional_epinow <- function(reported_cases, return_estimates = TRUE, max_plot = 10, return_timings = TRUE, - max_execution_time = 60, #todo: revert to Inf and timings to false + max_execution_time = 3600, #todo: revert to Inf and timings to false ...) { ## Set input to data.table From 0c9ba14e022cc561400aa8e3d3eabc98110ccf7d Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Thu, 27 Aug 2020 11:24:44 +0100 Subject: [PATCH 15/52] rework the error processing post-regional run to handle failure + timeout --- R/epinow.R | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index 015945193..afc1d96cd 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -408,17 +408,13 @@ regional_epinow <- function(reported_cases, ), TimeoutException = function(ex) { futile.logger::flog.warn("region %s timed out", target_region) - return(list()) + return(list("timings" = Inf)) } ) ) saveRDS(out, "subregion_out_a.rds") futile.logger::flog.trace("epinow returned for region %s", target_region) - if (return_timings) { - if (is.null(out)) { - futile.logger::flog.trace("region has not returned an out file (completed but not set to output) so create one") - out <- list() - } + if (!exists("timings", out)) { # only exists if it failed and is Inf out$timings = timing['elapsed'] } futile.logger::flog.info("Completed estimates for: %s", target_region) @@ -440,13 +436,17 @@ regional_epinow <- function(reported_cases, saveRDS(regional_out, "region_out.rds") futile.logger::flog.trace("processing errors") - regional_errors <- purrr::map(regional_out, ~.$error) - names(regional_errors) <- regions - regional_errors <- purrr::compact(regional_errors) - - if (length(regional_errors) != 0) { - futile.logger::flog.info("Runtime errors caught: ") - futile.logger::flog.info(regional_errors) + # names on regional_out + names(regional_out) <- regions # ["foo" => a, "bar" => b$error, "baz" => c, "parrot" => d$error] + problems <- purrr::keep(regional_out, function(row) !is.null(row$error) || row$result$timings == Inf) + + for (location in names(problems)) { + # output timeout / error + if (is.null(problems[[location]]$error)) { + futile.logger::flog.warning("Location $s killed due to timeout", location) + }else{ + futile.logger::flog.info("Runtime error in $s : $s - $s", location, problems[[location]]$error$message, problems[[location]]$error$call) + } } regional_out <- purrr::map(regional_out, ~.$result) From 12ee05e09c1edd2a1aa62de9af83be47d8f49cd4 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Thu, 27 Aug 2020 12:11:48 +0100 Subject: [PATCH 16/52] add withcallinghandlers to add where to the warning --- R/epinow.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index afc1d96cd..1b7b87d4b 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -397,13 +397,13 @@ regional_epinow <- function(reported_cases, timing <- system.time( out <- tryCatch( R.utils::withTimeout( - EpiNow2::epinow( + withCallingHandlers(EpiNow2::epinow( reported_cases = regional_cases, target_folder = target_folder, target_date = target_date, return_estimates = TRUE, cores = cores, - ...), + ...), warning = function(w) futile.logger::flog.warn("$s: $s",region, w)), timeout = max_execution_time ), TimeoutException = function(ex) { From 1d288257779e3e6994037bc01353184c988389e2 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Thu, 27 Aug 2020 12:37:59 +0100 Subject: [PATCH 17/52] remove some debugging dumps --- R/epinow.R | 3 --- 1 file changed, 3 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index 1b7b87d4b..cecba4d07 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -412,13 +412,11 @@ regional_epinow <- function(reported_cases, } ) ) - saveRDS(out, "subregion_out_a.rds") futile.logger::flog.trace("epinow returned for region %s", target_region) if (!exists("timings", out)) { # only exists if it failed and is Inf out$timings = timing['elapsed'] } futile.logger::flog.info("Completed estimates for: %s", target_region) - saveRDS(out, "subregion_out.rds") return(out) } @@ -434,7 +432,6 @@ regional_epinow <- function(reported_cases, ..., future.scheduling = Inf) - saveRDS(regional_out, "region_out.rds") futile.logger::flog.trace("processing errors") # names on regional_out names(regional_out) <- regions # ["foo" => a, "bar" => b$error, "baz" => c, "parrot" => d$error] From 3eb608fe3174e0bb912a1607ffb7af25328e1805 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Thu, 27 Aug 2020 12:39:14 +0100 Subject: [PATCH 18/52] 15 mins is sufficient to run canada minus the one slow region --- R/epinow.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/epinow.R b/R/epinow.R index cecba4d07..b616f82c9 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -343,7 +343,7 @@ regional_epinow <- function(reported_cases, return_estimates = TRUE, max_plot = 10, return_timings = TRUE, - max_execution_time = 3600, #todo: revert to Inf and timings to false + max_execution_time = 900, #todo: revert to Inf and timings to false ...) { ## Set input to data.table From 6c7a605e8a5cc56583f3d5bc1f4cf92b24908575 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Thu, 27 Aug 2020 12:56:37 +0100 Subject: [PATCH 19/52] correct flog warning usage --- R/epinow.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index b616f82c9..299d0a601 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -294,7 +294,7 @@ epinow <- function(reported_cases, family = "negbin", #' @importFrom future.apply future_lapply #' @importFrom data.table as.data.table setDT copy setorder #' @importFrom purrr safely map compact -#' @importFrom futile.logger flog.info +#' @importFrom futile.logger flog.info flog.warn flog.trace #' @importFrom R.utils withTimeout #' @examples #' \donttest{ @@ -440,7 +440,7 @@ regional_epinow <- function(reported_cases, for (location in names(problems)) { # output timeout / error if (is.null(problems[[location]]$error)) { - futile.logger::flog.warning("Location $s killed due to timeout", location) + futile.logger::flog.warn("Location $s killed due to timeout", location) }else{ futile.logger::flog.info("Runtime error in $s : $s - $s", location, problems[[location]]$error$message, problems[[location]]$error$call) } From c59deaf2a9c7720b5d3d03dc78dcfa5d27fc1b2e Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Thu, 27 Aug 2020 13:36:17 +0100 Subject: [PATCH 20/52] get your string placeholders right you wally... --- R/epinow.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index 299d0a601..51165fe73 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -440,9 +440,9 @@ regional_epinow <- function(reported_cases, for (location in names(problems)) { # output timeout / error if (is.null(problems[[location]]$error)) { - futile.logger::flog.warn("Location $s killed due to timeout", location) + futile.logger::flog.warn("Location %s killed due to timeout", location) }else{ - futile.logger::flog.info("Runtime error in $s : $s - $s", location, problems[[location]]$error$message, problems[[location]]$error$call) + futile.logger::flog.info("Runtime error in %s : %s - %s", location, problems[[location]]$error$message, problems[[location]]$error$call) } } From e8b00b5030f9aa8a92cc574982093e39f74772a7 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Thu, 27 Aug 2020 14:02:39 +0100 Subject: [PATCH 21/52] protect summary from no result condition --- R/epinow.R | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index 51165fe73..9edaddcd7 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -343,7 +343,7 @@ regional_epinow <- function(reported_cases, return_estimates = TRUE, max_plot = 10, return_timings = TRUE, - max_execution_time = 900, #todo: revert to Inf and timings to false + max_execution_time = 1200, #todo: revert to Inf and timings to false ...) { ## Set input to data.table @@ -449,8 +449,8 @@ regional_epinow <- function(reported_cases, regional_out <- purrr::map(regional_out, ~.$result) names(regional_out) <- regions - - if (summary) { + # only attempt the summary if there are at least some results + if (summary && length(purrr::discard(regional_out, function(row) row$results$timings == Inf)) > 0) { if (missing(summary_dir)) { summary_dir <- NULL } From 8f8d27084aae6131202273c16acb3068443313e9 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Thu, 27 Aug 2020 14:40:13 +0100 Subject: [PATCH 22/52] perhaps a little more realistic --- R/epinow.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/epinow.R b/R/epinow.R index 9edaddcd7..475fce5dd 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -343,7 +343,7 @@ regional_epinow <- function(reported_cases, return_estimates = TRUE, max_plot = 10, return_timings = TRUE, - max_execution_time = 1200, #todo: revert to Inf and timings to false + max_execution_time = 1800, #todo: revert to Inf and timings to false ...) { ## Set input to data.table From f3cba35a58466400c018173ed72e5686c47e9585 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Thu, 27 Aug 2020 14:51:56 +0100 Subject: [PATCH 23/52] change the filtering logic to be the inverse of the error selection & use is.finite / infinite methods --- R/epinow.R | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index 475fce5dd..1f1f9a473 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -403,7 +403,7 @@ regional_epinow <- function(reported_cases, target_date = target_date, return_estimates = TRUE, cores = cores, - ...), warning = function(w) futile.logger::flog.warn("$s: $s",region, w)), + ...), warning = function(w) futile.logger::flog.warn("$s: $s", region, w)), timeout = max_execution_time ), TimeoutException = function(ex) { @@ -435,13 +435,13 @@ regional_epinow <- function(reported_cases, futile.logger::flog.trace("processing errors") # names on regional_out names(regional_out) <- regions # ["foo" => a, "bar" => b$error, "baz" => c, "parrot" => d$error] - problems <- purrr::keep(regional_out, function(row) !is.null(row$error) || row$result$timings == Inf) + problems <- purrr::keep(regional_out, function(row) !is.null(row$error) || is.infinite(row$result$timings)) for (location in names(problems)) { # output timeout / error if (is.null(problems[[location]]$error)) { futile.logger::flog.warn("Location %s killed due to timeout", location) - }else{ + }else { futile.logger::flog.info("Runtime error in %s : %s - %s", location, problems[[location]]$error$message, problems[[location]]$error$call) } } @@ -450,7 +450,7 @@ regional_epinow <- function(reported_cases, names(regional_out) <- regions # only attempt the summary if there are at least some results - if (summary && length(purrr::discard(regional_out, function(row) row$results$timings == Inf)) > 0) { + if (summary && length(purrr::keep(regional_out, function(row) is.null(row$error) && is.finite(row$result$timings))) > 0) { if (missing(summary_dir)) { summary_dir <- NULL } From 00fac1b0d851df639b6f428db38336dd5bdb6dcf Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Thu, 27 Aug 2020 15:39:55 +0100 Subject: [PATCH 24/52] shuffle how the timedout results are excluded --- R/epinow.R | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index 1f1f9a473..cdc209443 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -343,7 +343,7 @@ regional_epinow <- function(reported_cases, return_estimates = TRUE, max_plot = 10, return_timings = TRUE, - max_execution_time = 1800, #todo: revert to Inf and timings to false + max_execution_time = 600, #todo: revert to Inf and timings to false ...) { ## Set input to data.table @@ -448,15 +448,15 @@ regional_epinow <- function(reported_cases, regional_out <- purrr::map(regional_out, ~.$result) names(regional_out) <- regions - + sucessful_regional_out <- purrr::keep(purrr::compact(regional_out), function(row) is.finite(row$timings)) # only attempt the summary if there are at least some results - if (summary && length(purrr::keep(regional_out, function(row) is.null(row$error) && is.finite(row$result$timings))) > 0) { + if (summary && length(sucessful_regional_out) > 0) { if (missing(summary_dir)) { summary_dir <- NULL } safe_summary <- purrr::safely(regional_summary) - summary_out <- safe_summary(regional_output = regional_out, + summary_out <- safe_summary(regional_output = sucessful_regional_out, summary_dir = summary_dir, reported_cases = reported_cases, region_scale = region_scale, From eb48884322dfbd9f28b896054960e8d83d13bb30 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Thu, 27 Aug 2020 17:39:46 +0100 Subject: [PATCH 25/52] extend back to 1/2 hr to try and get mixed success / fail --- R/epinow.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/epinow.R b/R/epinow.R index cdc209443..ca2f27a65 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -343,7 +343,7 @@ regional_epinow <- function(reported_cases, return_estimates = TRUE, max_plot = 10, return_timings = TRUE, - max_execution_time = 600, #todo: revert to Inf and timings to false + max_execution_time = 1800, #todo: revert to Inf and timings to false ...) { ## Set input to data.table From 76f82bc92d87cf359053db7885e2c82dcc8315da Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Thu, 27 Aug 2020 17:41:59 +0100 Subject: [PATCH 26/52] redundant naming (it's done above and copies through the map fn --- R/epinow.R | 1 - 1 file changed, 1 deletion(-) diff --git a/R/epinow.R b/R/epinow.R index ca2f27a65..6624e3491 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -447,7 +447,6 @@ regional_epinow <- function(reported_cases, } regional_out <- purrr::map(regional_out, ~.$result) - names(regional_out) <- regions sucessful_regional_out <- purrr::keep(purrr::compact(regional_out), function(row) is.finite(row$timings)) # only attempt the summary if there are at least some results if (summary && length(sucessful_regional_out) > 0) { From 9f3457c2b70ce3f5d66b91753d7b84821bbb4b7e Mon Sep 17 00:00:00 2001 From: JAllen42 Date: Fri, 28 Aug 2020 15:23:14 +0100 Subject: [PATCH 27/52] Debugging --- R/epinow.R | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index 6624e3491..bffe55b27 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -432,11 +432,14 @@ regional_epinow <- function(reported_cases, ..., future.scheduling = Inf) - futile.logger::flog.trace("processing errors") # names on regional_out names(regional_out) <- regions # ["foo" => a, "bar" => b$error, "baz" => c, "parrot" => d$error] - problems <- purrr::keep(regional_out, function(row) !is.null(row$error) || is.infinite(row$result$timings)) + futile.logger::flog.trace("processing errors") + problems <- purrr::keep(regional_out, ~ !is.null(.$error) || is.infinite(.$result$timings)) + if (length(problems) != 0) { + futile.logger::flog.trace("Runtime errors caught: ") + } for (location in names(problems)) { # output timeout / error if (is.null(problems[[location]]$error)) { From 4c6eb14c84fd5ba0b8369ed755d983b56e1d656e Mon Sep 17 00:00:00 2001 From: JAllen42 Date: Tue, 1 Sep 2020 11:05:15 +0100 Subject: [PATCH 28/52] Debugging --- R/epinow.R | 6 +++--- R/summarise.R | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index bffe55b27..2c1585350 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -437,9 +437,7 @@ regional_epinow <- function(reported_cases, futile.logger::flog.trace("processing errors") problems <- purrr::keep(regional_out, ~ !is.null(.$error) || is.infinite(.$result$timings)) - if (length(problems) != 0) { - futile.logger::flog.trace("Runtime errors caught: ") - } + futile.logger::flog.trace("%s runtime errors caught", length(problems)) for (location in names(problems)) { # output timeout / error if (is.null(problems[[location]]$error)) { @@ -458,6 +456,8 @@ regional_epinow <- function(reported_cases, } safe_summary <- purrr::safely(regional_summary) + futile.logger::flog.trace("Calling regional_summary") + summary_out <- safe_summary(regional_output = sucessful_regional_out, summary_dir = summary_dir, reported_cases = reported_cases, diff --git a/R/summarise.R b/R/summarise.R index 880e7aa49..f4400a5fe 100644 --- a/R/summarise.R +++ b/R/summarise.R @@ -222,7 +222,7 @@ regional_summary <- function(regional_output, regional_output <- purrr::compact(regional_output) } - + futile.logger::flog.trace("Getting regional results") ## Get estimates results <- get_regional_results(regional_output, results_dir = results_dir, @@ -245,7 +245,8 @@ regional_summary <- function(regional_output, }else{ regional_summaries <- NULL } - + + futile.logger::flog.trace("Summarising results") ## Summarise results as a table summarised_results <- summarise_results(regions, summaries = regional_summaries, From 5dd86be6e4c856e3abcd6e16836f63f6caf2a47f Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Tue, 1 Sep 2020 12:26:14 +0100 Subject: [PATCH 29/52] stringify the language object (why it isn't automagically done in the logging I can't fathom) --- R/epinow.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index 2c1585350..a0fc95052 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -435,7 +435,7 @@ regional_epinow <- function(reported_cases, # names on regional_out names(regional_out) <- regions # ["foo" => a, "bar" => b$error, "baz" => c, "parrot" => d$error] futile.logger::flog.trace("processing errors") - problems <- purrr::keep(regional_out, ~ !is.null(.$error) || is.infinite(.$result$timings)) + problems <- purrr::keep(regional_out, ~!is.null(.$error) || is.infinite(.$result$timings)) futile.logger::flog.trace("%s runtime errors caught", length(problems)) for (location in names(problems)) { @@ -443,7 +443,7 @@ regional_epinow <- function(reported_cases, if (is.null(problems[[location]]$error)) { futile.logger::flog.warn("Location %s killed due to timeout", location) }else { - futile.logger::flog.info("Runtime error in %s : %s - %s", location, problems[[location]]$error$message, problems[[location]]$error$call) + futile.logger::flog.info("Runtime error in %s : %s - %s", location, problems[[location]]$error$message, toString(problems[[location]]$error$call)) } } From 8852c8105a5084dd570cd5f10bbd0192a8c8e896 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Tue, 1 Sep 2020 13:07:36 +0100 Subject: [PATCH 30/52] add intellij to git ignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 2eb3cd2ec..dd84d74e1 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ .RData .Ruserdata .cache +.idea src/*.so src/*.dll src/*.o From 813e62156e5b39194c89ee25d0cb05104c2028f1 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Tue, 1 Sep 2020 14:57:01 +0100 Subject: [PATCH 31/52] stringify, stringify, stringify! --- R/epinow.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index d66189f05..c69abc10d 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -409,7 +409,7 @@ regional_epinow <- function(reported_cases, target_date = target_date, return_estimates = TRUE, cores = cores, - ...), warning = function(w) futile.logger::flog.warn("$s: $s", region, w)), + ...), warning = function(w) futile.logger::flog.warn("$s: $s - $s", region, w$message, toString(w$call))), timeout = max_execution_time ), TimeoutException = function(ex) { @@ -473,7 +473,7 @@ regional_epinow <- function(reported_cases, if (!is.null(summary_out[[2]])) { futile.logger::flog.info("Errors caught whilst generating summary statistics: ") - futile.logger::flog.info(summary_out[[2]]) + futile.logger::flog.info(toString(summary_out[[2]])) } summary_out <- summary_out[[1]] From a4c2b6b22efb28ff42dcbc58435155dab9b4756d Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Tue, 1 Sep 2020 16:06:00 +0100 Subject: [PATCH 32/52] use target_region as the region name... --- R/epinow.R | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index c69abc10d..64203bacf 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -399,7 +399,7 @@ regional_epinow <- function(reported_cases, futile.logger::flog.trace("filtering data for target region %s", target_region) regional_cases <- reported_cases[region %in% target_region][, region := NULL] - futile.logger::flog.trace("calling epinow2::epinow to process data") + futile.logger::flog.trace("calling epinow2::epinow to process data for %s", target_region) timing <- system.time( out <- tryCatch( R.utils::withTimeout( @@ -409,7 +409,8 @@ regional_epinow <- function(reported_cases, target_date = target_date, return_estimates = TRUE, cores = cores, - ...), warning = function(w) futile.logger::flog.warn("$s: $s - $s", region, w$message, toString(w$call))), + ...), warning = function(w) futile.logger::flog.warn("$s: $s - $s", target_region, w$message, toString(w$call)) + ), timeout = max_execution_time ), TimeoutException = function(ex) { From ad8d563f3eae5ca181d32f567f89b90a4c90e9aa Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Tue, 1 Sep 2020 16:14:04 +0100 Subject: [PATCH 33/52] right format syntax --- R/epinow.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/epinow.R b/R/epinow.R index 64203bacf..2123cde71 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -409,7 +409,7 @@ regional_epinow <- function(reported_cases, target_date = target_date, return_estimates = TRUE, cores = cores, - ...), warning = function(w) futile.logger::flog.warn("$s: $s - $s", target_region, w$message, toString(w$call)) + ...), warning = function(w) futile.logger::flog.warn("%s: %s - %s", target_region, w$message, toString(w$call)) ), timeout = max_execution_time ), From 62ab50b66f2fec0a8e86ba289a30dcd13881bb1b Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 2 Sep 2020 11:42:13 +0100 Subject: [PATCH 34/52] add rlang (I think it's already a dependency of a dependency) to allow for muffling of warning propagation (remove duplicate messages) --- DESCRIPTION | 1 + R/epinow.R | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index aa99abb1f..15be138b3 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -63,6 +63,7 @@ Imports: purrr, R.utils (>= 2.0.0), Rcpp (>= 0.12.0), + rlang (>= 0.4.7), rstan (>= 2.18.1), rstantools (>= 2.0.0), scales, diff --git a/R/epinow.R b/R/epinow.R index 2123cde71..1f8064825 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -302,6 +302,7 @@ epinow <- function(reported_cases, family = "negbin", #' @importFrom purrr safely map compact #' @importFrom futile.logger flog.info flog.warn flog.trace #' @importFrom R.utils withTimeout +#' @importFrom rlang cnd_muffle #' @examples #' \donttest{ #' ## Construct example distributions @@ -409,7 +410,11 @@ regional_epinow <- function(reported_cases, target_date = target_date, return_estimates = TRUE, cores = cores, - ...), warning = function(w) futile.logger::flog.warn("%s: %s - %s", target_region, w$message, toString(w$call)) + ...), + warning = function(w) { + futile.logger::flog.warn("%s: %s - %s", target_region, w$message, toString(w$call)) + cnd_muffle(w) + } ), timeout = max_execution_time ), From ce1f0cd7ec99b9d52af020384d3211ca4a838279 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 2 Sep 2020 12:41:41 +0100 Subject: [PATCH 35/52] tidy for PR --- R/epinow.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index 1f8064825..70f2db540 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -349,8 +349,8 @@ regional_epinow <- function(reported_cases, all_regions_summary = TRUE, return_estimates = TRUE, max_plot = 10, - return_timings = TRUE, - max_execution_time = 1800, #todo: revert to Inf and timings to false + return_timings = FALSE, + max_execution_time = Inf, ...) { ## Set input to data.table From 0340b3c4e2be5dc53d789c396144fe68a5309564 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 2 Sep 2020 13:53:48 +0100 Subject: [PATCH 36/52] update docblock --- R/epinow.R | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index 70f2db540..0bd1416f1 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -290,8 +290,8 @@ epinow <- function(reported_cases, family = "negbin", #' @param summary Logical, should summary measures be calculated. #' @param all_regions_summary Logical, defaults to `TRUE`. Should summary plots for all regions be returned #' rather than just regions of interest. -#' @param return_timings Logical, defaults to FALSE. Should timing values be returned for each location. -#' @param max_execution_time Integer, defaults to Inf. If set will kill off processing after x seconds. +#' @param return_timings Logical, defaults to FALSE. Should timing values be returned for each region. +#' @param max_execution_time Numeric, defaults to Inf. If set will kill off processing of each region after x seconds. #' @param ... Pass additional arguments to `epinow` #' @inheritParams epinow #' @inheritParams regional_summary @@ -338,7 +338,8 @@ epinow <- function(reported_cases, family = "negbin", #' delays = list(incubation_period, reporting_delay), #' adapt_delta = 0.9, #' samples = 2000, warmup = 200, verbose = TRUE, -#' cores = ifelse(interactive(), 4, 1), chains = 4) +#' cores = ifelse(interactive(), 4, 1), chains = 4, +#' max_execution_time = Inf, return_timings=False) #'} regional_epinow <- function(reported_cases, target_folder, target_date, From 143b16ff67c68791958b7811d2fcc8c7155a40eb Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 2 Sep 2020 13:05:50 +0000 Subject: [PATCH 37/52] regen documentation --- NAMESPACE | 3 +++ man/regional_epinow.Rd | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/NAMESPACE b/NAMESPACE index dc47e7215..10ca2d04e 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -34,6 +34,7 @@ export(theme_map) import(Rcpp) import(methods) importFrom(HDInterval,hdi) +importFrom(R.utils,withTimeout) importFrom(cowplot,get_legend) importFrom(cowplot,panel_border) importFrom(cowplot,theme_cowplot) @@ -57,6 +58,7 @@ importFrom(futile.logger,flog.debug) importFrom(futile.logger,flog.fatal) importFrom(futile.logger,flog.info) importFrom(futile.logger,flog.threshold) +importFrom(futile.logger,flog.trace) importFrom(futile.logger,flog.warn) importFrom(future.apply,future_lapply) importFrom(ggplot2,.data) @@ -99,6 +101,7 @@ importFrom(purrr,partial) importFrom(purrr,safely) importFrom(purrr,transpose) importFrom(purrr,walk) +importFrom(rlang,cnd_muffle) importFrom(rstan,extract) importFrom(rstan,sampling) importFrom(scales,comma) diff --git a/man/regional_epinow.Rd b/man/regional_epinow.Rd index 20da48a84..b41cd22ae 100644 --- a/man/regional_epinow.Rd +++ b/man/regional_epinow.Rd @@ -16,6 +16,8 @@ regional_epinow( all_regions_summary = TRUE, return_estimates = TRUE, max_plot = 10, + return_timings = FALSE, + max_execution_time = Inf, ... ) } @@ -46,6 +48,10 @@ rather than just regions of interest.} \item{max_plot}{Numeric, defaults to 10. A multiplicative upper bound on the number of cases shown on the plot. Based on the maximum number of reported cases.} +\item{return_timings}{Logical, defaults to FALSE. Should timing values be returned for each region.} + +\item{max_execution_time}{Numeric, defaults to Inf. If set will kill off processing of each region after x seconds.} + \item{...}{Pass additional arguments to \code{epinow}} } \value{ @@ -89,6 +95,7 @@ out <- regional_epinow(reported_cases = cases, delays = list(incubation_period, reporting_delay), adapt_delta = 0.9, samples = 2000, warmup = 200, verbose = TRUE, - cores = ifelse(interactive(), 4, 1), chains = 4) + cores = ifelse(interactive(), 4, 1), chains = 4, + max_execution_time = Inf, return_timings=False) } } From dfab043e14acff0adcc9ef5650132864757dc052 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 2 Sep 2020 14:17:36 +0100 Subject: [PATCH 38/52] timings -> timing, add keep to purr import --- R/epinow.R | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index 0bd1416f1..e0cdda711 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -299,7 +299,7 @@ epinow <- function(reported_cases, family = "negbin", #' @export #' @importFrom future.apply future_lapply #' @importFrom data.table as.data.table setDT copy setorder -#' @importFrom purrr safely map compact +#' @importFrom purrr safely map compact keep #' @importFrom futile.logger flog.info flog.warn flog.trace #' @importFrom R.utils withTimeout #' @importFrom rlang cnd_muffle @@ -387,7 +387,7 @@ regional_epinow <- function(reported_cases, run_region <- function(target_region, reported_cases, cores = cores, - return_timings = return_timings, + return_timing = return_timing, max_execution_time = max_execution_time, ...) { futile.logger::flog.info("Initialising estimates for: %s", target_region) @@ -421,13 +421,13 @@ regional_epinow <- function(reported_cases, ), TimeoutException = function(ex) { futile.logger::flog.warn("region %s timed out", target_region) - return(list("timings" = Inf)) + return(list("timing" = Inf)) } ) ) futile.logger::flog.trace("epinow returned for region %s", target_region) - if (!exists("timings", out)) { # only exists if it failed and is Inf - out$timings = timing['elapsed'] + if (!exists("timing", out)) { # only exists if it failed and is Inf + out$timing = timing['elapsed'] } futile.logger::flog.info("Completed estimates for: %s", target_region) return(out) @@ -440,7 +440,7 @@ regional_epinow <- function(reported_cases, regional_out <- future.apply::future_lapply(regions, safe_run_region, reported_cases = reported_cases, cores = cores, - return_timings = return_timings, + return_timing = return_timing, max_execution_time = max_execution_time, ..., future.scheduling = Inf) @@ -448,7 +448,7 @@ regional_epinow <- function(reported_cases, # names on regional_out names(regional_out) <- regions # ["foo" => a, "bar" => b$error, "baz" => c, "parrot" => d$error] futile.logger::flog.trace("processing errors") - problems <- purrr::keep(regional_out, ~!is.null(.$error) || is.infinite(.$result$timings)) + problems <- purrr::keep(regional_out, ~!is.null(.$error) || is.infinite(.$result$timing)) futile.logger::flog.trace("%s runtime errors caught", length(problems)) for (location in names(problems)) { @@ -461,7 +461,7 @@ regional_epinow <- function(reported_cases, } regional_out <- purrr::map(regional_out, ~.$result) - sucessful_regional_out <- purrr::keep(purrr::compact(regional_out), function(row) is.finite(row$timings)) + sucessful_regional_out <- purrr::keep(purrr::compact(regional_out), function(row) is.finite(row$timing)) # only attempt the summary if there are at least some results if (summary && length(sucessful_regional_out) > 0) { if (missing(summary_dir)) { From 796b2fbe6159a0189281be928a0ee69eb9702b05 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 2 Sep 2020 13:28:07 +0000 Subject: [PATCH 39/52] regen documentation --- NAMESPACE | 1 + 1 file changed, 1 insertion(+) diff --git a/NAMESPACE b/NAMESPACE index 10ca2d04e..50d15bc02 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -93,6 +93,7 @@ importFrom(lubridate,days) importFrom(lubridate,wday) importFrom(patchwork,plot_layout) importFrom(purrr,compact) +importFrom(purrr,keep) importFrom(purrr,map) importFrom(purrr,map_chr) importFrom(purrr,map_dbl) From a4249984286aef76859155305efa8afccc22bbec Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 2 Sep 2020 14:41:25 +0100 Subject: [PATCH 40/52] clarify the logging messages --- R/epinow.R | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index e0cdda711..60842f63d 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -421,15 +421,16 @@ regional_epinow <- function(reported_cases, ), TimeoutException = function(ex) { futile.logger::flog.warn("region %s timed out", target_region) - return(list("timing" = Inf)) + return(ifelse(return_timing, list("timing" = Inf), list())) } ) ) - futile.logger::flog.trace("epinow returned for region %s", target_region) - if (!exists("timing", out)) { # only exists if it failed and is Inf + if (return_timing && !exists("timing", out)) { # only exists if it failed and is Inf out$timing = timing['elapsed'] } - futile.logger::flog.info("Completed estimates for: %s", target_region) + if(exists("summary", out)){ # if it failed a warning would have been output above + futile.logger::flog.info("Completed estimates for: %s", target_region) + } return(out) } From 17b284871abd8f64ddef2e33457601b11e540b2b Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 2 Sep 2020 14:47:25 +0100 Subject: [PATCH 41/52] clarify the logging messages --- R/epinow.R | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index 60842f63d..8e9bc28df 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -449,16 +449,12 @@ regional_epinow <- function(reported_cases, # names on regional_out names(regional_out) <- regions # ["foo" => a, "bar" => b$error, "baz" => c, "parrot" => d$error] futile.logger::flog.trace("processing errors") - problems <- purrr::keep(regional_out, ~!is.null(.$error) || is.infinite(.$result$timing)) + problems <- purrr::keep(regional_out, ~!is.null(.$error) ) futile.logger::flog.trace("%s runtime errors caught", length(problems)) for (location in names(problems)) { # output timeout / error - if (is.null(problems[[location]]$error)) { - futile.logger::flog.warn("Location %s killed due to timeout", location) - }else { futile.logger::flog.info("Runtime error in %s : %s - %s", location, problems[[location]]$error$message, toString(problems[[location]]$error$call)) - } } regional_out <- purrr::map(regional_out, ~.$result) From efd2af71ec7ebf1a428491e074ed60d1997bf9e0 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 2 Sep 2020 14:48:29 +0100 Subject: [PATCH 42/52] adding a temporary value to trigger timeout for testing --- R/epinow.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/epinow.R b/R/epinow.R index 8e9bc28df..9e37d8821 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -351,7 +351,7 @@ regional_epinow <- function(reported_cases, return_estimates = TRUE, max_plot = 10, return_timings = FALSE, - max_execution_time = Inf, + max_execution_time = 1800, #TODO revert to Inf ...) { ## Set input to data.table From 67373bc30b524c22e961aa1fd1bb96d471443b36 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 2 Sep 2020 14:54:46 +0100 Subject: [PATCH 43/52] missed from the rename --- R/epinow.R | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index 9e37d8821..295038992 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -290,7 +290,7 @@ epinow <- function(reported_cases, family = "negbin", #' @param summary Logical, should summary measures be calculated. #' @param all_regions_summary Logical, defaults to `TRUE`. Should summary plots for all regions be returned #' rather than just regions of interest. -#' @param return_timings Logical, defaults to FALSE. Should timing values be returned for each region. +#' @param return_timing Logical, defaults to FALSE. Should timing values be returned for each region. #' @param max_execution_time Numeric, defaults to Inf. If set will kill off processing of each region after x seconds. #' @param ... Pass additional arguments to `epinow` #' @inheritParams epinow @@ -339,7 +339,7 @@ epinow <- function(reported_cases, family = "negbin", #' adapt_delta = 0.9, #' samples = 2000, warmup = 200, verbose = TRUE, #' cores = ifelse(interactive(), 4, 1), chains = 4, -#' max_execution_time = Inf, return_timings=False) +#' max_execution_time = Inf, return_timing=False) #'} regional_epinow <- function(reported_cases, target_folder, target_date, @@ -350,7 +350,7 @@ regional_epinow <- function(reported_cases, all_regions_summary = TRUE, return_estimates = TRUE, max_plot = 10, - return_timings = FALSE, + return_timing = FALSE, max_execution_time = 1800, #TODO revert to Inf ...) { From b630ce33a7931b950373be6db27b519911a5a823 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 2 Sep 2020 15:28:17 +0100 Subject: [PATCH 44/52] include rlang:: --- R/epinow.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/epinow.R b/R/epinow.R index 295038992..ccd7ec914 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -414,7 +414,7 @@ regional_epinow <- function(reported_cases, ...), warning = function(w) { futile.logger::flog.warn("%s: %s - %s", target_region, w$message, toString(w$call)) - cnd_muffle(w) + rlang::cnd_muffle(w) } ), timeout = max_execution_time From 1cb0e72497dc96742f18628eb76a9bc37a4e4d47 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 2 Sep 2020 15:38:27 +0100 Subject: [PATCH 45/52] release notes --- DESCRIPTION | 2 +- NEWS.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 15be138b3..961d2318e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: EpiNow2 Type: Package Title: Estimate Real-Time Case Counts and Time-Varying Epidemiological Parameters -Version: 1.1.0 +Version: 1.2.0 Authors@R: c( person(given = "Sam Abbott", role = c("aut", "cre"), diff --git a/NEWS.md b/NEWS.md index 59ed7f3de..8494c0999 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,7 @@ +# EpiNow2 1.2.0 +* Added timeout and timing option to `regional_epinow` +* Improved logging of warnings in `regional_epinow` + # EpiNow2 1.1.0 * Implemented reporting templates From 8c9785b898764573d4b995621ae64124f8de22a0 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 2 Sep 2020 15:40:08 +0100 Subject: [PATCH 46/52] backout test setting on default --- R/epinow.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/epinow.R b/R/epinow.R index ccd7ec914..a728d7deb 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -351,7 +351,7 @@ regional_epinow <- function(reported_cases, return_estimates = TRUE, max_plot = 10, return_timing = FALSE, - max_execution_time = 1800, #TODO revert to Inf + max_execution_time = Inf, ...) { ## Set input to data.table From b3543fdfb36ec99149a23b4f35d5871870a107a8 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 2 Sep 2020 15:00:22 +0000 Subject: [PATCH 47/52] updating docs --- man/regional_epinow.Rd | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/man/regional_epinow.Rd b/man/regional_epinow.Rd index b41cd22ae..7b2fc3477 100644 --- a/man/regional_epinow.Rd +++ b/man/regional_epinow.Rd @@ -16,7 +16,7 @@ regional_epinow( all_regions_summary = TRUE, return_estimates = TRUE, max_plot = 10, - return_timings = FALSE, + return_timing = FALSE, max_execution_time = Inf, ... ) @@ -48,7 +48,7 @@ rather than just regions of interest.} \item{max_plot}{Numeric, defaults to 10. A multiplicative upper bound on the number of cases shown on the plot. Based on the maximum number of reported cases.} -\item{return_timings}{Logical, defaults to FALSE. Should timing values be returned for each region.} +\item{return_timing}{Logical, defaults to FALSE. Should timing values be returned for each region.} \item{max_execution_time}{Numeric, defaults to Inf. If set will kill off processing of each region after x seconds.} @@ -96,6 +96,6 @@ out <- regional_epinow(reported_cases = cases, adapt_delta = 0.9, samples = 2000, warmup = 200, verbose = TRUE, cores = ifelse(interactive(), 4, 1), chains = 4, - max_execution_time = Inf, return_timings=False) + max_execution_time = Inf, return_timing=False) } } From 39247630acfe596b5f19f6a09dec763040b6743b Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Wed, 2 Sep 2020 19:07:41 +0100 Subject: [PATCH 48/52] reintroduce test setting, remove another redundant debug line --- R/epinow.R | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index a728d7deb..d7190f19e 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -351,7 +351,7 @@ regional_epinow <- function(reported_cases, return_estimates = TRUE, max_plot = 10, return_timing = FALSE, - max_execution_time = Inf, + max_execution_time = 1800, ...) { ## Set input to data.table @@ -448,7 +448,6 @@ regional_epinow <- function(reported_cases, # names on regional_out names(regional_out) <- regions # ["foo" => a, "bar" => b$error, "baz" => c, "parrot" => d$error] - futile.logger::flog.trace("processing errors") problems <- purrr::keep(regional_out, ~!is.null(.$error) ) futile.logger::flog.trace("%s runtime errors caught", length(problems)) From d1970a7c18fd0cc7672b7ccc1781f954761a543a Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Thu, 3 Sep 2020 09:49:09 +0100 Subject: [PATCH 49/52] change timing return flag handling to always return timings from the inner. Fix filtering logic. --- R/epinow.R | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index d7190f19e..52734ec69 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -290,7 +290,7 @@ epinow <- function(reported_cases, family = "negbin", #' @param summary Logical, should summary measures be calculated. #' @param all_regions_summary Logical, defaults to `TRUE`. Should summary plots for all regions be returned #' rather than just regions of interest. -#' @param return_timing Logical, defaults to FALSE. Should timing values be returned for each region. +#' @param return_timings Logical, defaults to FALSE. If not returning estimates can be used to request timing data is returned. #' @param max_execution_time Numeric, defaults to Inf. If set will kill off processing of each region after x seconds. #' @param ... Pass additional arguments to `epinow` #' @inheritParams epinow @@ -339,7 +339,7 @@ epinow <- function(reported_cases, family = "negbin", #' adapt_delta = 0.9, #' samples = 2000, warmup = 200, verbose = TRUE, #' cores = ifelse(interactive(), 4, 1), chains = 4, -#' max_execution_time = Inf, return_timing=False) +#' max_execution_time = Inf, return_timings=False) #'} regional_epinow <- function(reported_cases, target_folder, target_date, @@ -350,7 +350,7 @@ regional_epinow <- function(reported_cases, all_regions_summary = TRUE, return_estimates = TRUE, max_plot = 10, - return_timing = FALSE, + return_timings = FALSE, max_execution_time = 1800, ...) { @@ -387,7 +387,6 @@ regional_epinow <- function(reported_cases, run_region <- function(target_region, reported_cases, cores = cores, - return_timing = return_timing, max_execution_time = max_execution_time, ...) { futile.logger::flog.info("Initialising estimates for: %s", target_region) @@ -421,14 +420,14 @@ regional_epinow <- function(reported_cases, ), TimeoutException = function(ex) { futile.logger::flog.warn("region %s timed out", target_region) - return(ifelse(return_timing, list("timing" = Inf), list())) + return(list("timing" = Inf)) } ) ) - if (return_timing && !exists("timing", out)) { # only exists if it failed and is Inf + if (!exists("timing", out)) { # only exists if it failed and is Inf out$timing = timing['elapsed'] } - if(exists("summary", out)){ # if it failed a warning would have been output above + if (exists("summary", out)) { # if it failed a warning would have been output above futile.logger::flog.info("Completed estimates for: %s", target_region) } return(out) @@ -441,14 +440,13 @@ regional_epinow <- function(reported_cases, regional_out <- future.apply::future_lapply(regions, safe_run_region, reported_cases = reported_cases, cores = cores, - return_timing = return_timing, max_execution_time = max_execution_time, ..., future.scheduling = Inf) # names on regional_out names(regional_out) <- regions # ["foo" => a, "bar" => b$error, "baz" => c, "parrot" => d$error] - problems <- purrr::keep(regional_out, ~!is.null(.$error) ) + problems <- purrr::keep(regional_out, ~!is.null(.$error)) futile.logger::flog.trace("%s runtime errors caught", length(problems)) for (location in names(problems)) { @@ -457,7 +455,7 @@ regional_epinow <- function(reported_cases, } regional_out <- purrr::map(regional_out, ~.$result) - sucessful_regional_out <- purrr::keep(purrr::compact(regional_out), function(row) is.finite(row$timing)) + sucessful_regional_out <- purrr::keep(purrr::compact(regional_out), ~is.finite(.$timing)) # only attempt the summary if there are at least some results if (summary && length(sucessful_regional_out) > 0) { if (missing(summary_dir)) { @@ -490,6 +488,9 @@ regional_epinow <- function(reported_cases, out$summary <- summary_out } + return(out) + }else if (return_timings) { + out <- purrr::map(regional_out, ~.$timing) return(out) }else { return(invisible(NULL)) From e8671e5eee61d7d6b70d745329387c9183569d9c Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Thu, 3 Sep 2020 10:01:03 +0100 Subject: [PATCH 50/52] steal the pipeline from devtools for building documentation and reformatting automatically as part of a PR --- .github/workflows/pr-commands.yaml | 55 ++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 .github/workflows/pr-commands.yaml diff --git a/.github/workflows/pr-commands.yaml b/.github/workflows/pr-commands.yaml new file mode 100644 index 000000000..db0312247 --- /dev/null +++ b/.github/workflows/pr-commands.yaml @@ -0,0 +1,55 @@ +on: + issue_comment: + types: [created] +name: Commands +jobs: + document: + if: startsWith(github.event.comment.body, '/document') + name: document + runs-on: macOS-latest + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@v2 + - uses: r-lib/actions/pr-fetch@master + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + - uses: r-lib/actions/setup-r@master + - name: Install dependencies + run: Rscript -e 'install.packages(c("remotes", "roxygen2"))' -e 'remotes::install_deps(dependencies = TRUE)' + - name: Document + run: Rscript -e 'roxygen2::roxygenise()' + - name: commit + run: | + git config --local user.email "actions@github.com" + git config --local user.name "GitHub Actions" + git add man/\* NAMESPACE + git commit -m 'Document' + - uses: r-lib/actions/pr-push@master + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + style: + if: startsWith(github.event.comment.body, '/style') + name: style + runs-on: macOS-latest + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@v2 + - uses: r-lib/actions/pr-fetch@master + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + - uses: r-lib/actions/setup-r@master + - name: Install dependencies + run: Rscript -e 'install.packages("styler")' + - name: Style + run: Rscript -e 'styler::style_pkg()' + - name: commit + run: | + git config --local user.email "actions@github.com" + git config --local user.name "GitHub Actions" + git add \*.R + git commit -m 'Style' + - uses: r-lib/actions/pr-push@master + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file From 4fb075c2b8934d252fbadf52308338d00d71796e Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Thu, 3 Sep 2020 10:32:31 +0100 Subject: [PATCH 51/52] reset default ready for merge --- R/epinow.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/epinow.R b/R/epinow.R index 52734ec69..fb36cee2f 100644 --- a/R/epinow.R +++ b/R/epinow.R @@ -351,7 +351,7 @@ regional_epinow <- function(reported_cases, return_estimates = TRUE, max_plot = 10, return_timings = FALSE, - max_execution_time = 1800, + max_execution_time = Inf, ...) { ## Set input to data.table @@ -463,7 +463,7 @@ regional_epinow <- function(reported_cases, } safe_summary <- purrr::safely(regional_summary) - futile.logger::flog.trace("Calling regional_summary") + futile.logger::flog.info("Producing summary") summary_out <- safe_summary(regional_output = sucessful_regional_out, summary_dir = summary_dir, From 9e71ab0a6cee7979991c7e04b9a9a767cd83d410 Mon Sep 17 00:00:00 2001 From: Joe Hickson Date: Thu, 3 Sep 2020 09:33:44 +0000 Subject: [PATCH 52/52] documentation --- man/regional_epinow.Rd | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/man/regional_epinow.Rd b/man/regional_epinow.Rd index 7b2fc3477..12167ce26 100644 --- a/man/regional_epinow.Rd +++ b/man/regional_epinow.Rd @@ -16,7 +16,7 @@ regional_epinow( all_regions_summary = TRUE, return_estimates = TRUE, max_plot = 10, - return_timing = FALSE, + return_timings = FALSE, max_execution_time = Inf, ... ) @@ -48,7 +48,7 @@ rather than just regions of interest.} \item{max_plot}{Numeric, defaults to 10. A multiplicative upper bound on the number of cases shown on the plot. Based on the maximum number of reported cases.} -\item{return_timing}{Logical, defaults to FALSE. Should timing values be returned for each region.} +\item{return_timings}{Logical, defaults to FALSE. If not returning estimates can be used to request timing data is returned.} \item{max_execution_time}{Numeric, defaults to Inf. If set will kill off processing of each region after x seconds.} @@ -96,6 +96,6 @@ out <- regional_epinow(reported_cases = cases, adapt_delta = 0.9, samples = 2000, warmup = 200, verbose = TRUE, cores = ifelse(interactive(), 4, 1), chains = 4, - max_execution_time = Inf, return_timing=False) + max_execution_time = Inf, return_timings=False) } }