diff --git a/DESCRIPTION b/DESCRIPTION index 72ada1b..f82a26c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: stoner Title: Support for Building VIMC Montagu Touchstones, using Dettl -Version: 0.1.21 +Version: 0.1.22 Authors@R: c(person("Wes", "Hinsley",role = c("aut", "cre", "cst", "dnc", "elg", "itr", "sng", "ard"), email = "w.hinsley@imperial.ac.uk"), diff --git a/NAMESPACE b/NAMESPACE index 0fa8961..50b8f44 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -8,6 +8,7 @@ export(stone_load) export(stone_stochastic_central) export(stone_stochastic_cert_verify) export(stone_stochastic_graph) +export(stone_stochastic_make_meta) export(stone_stochastic_process) export(stone_stochastic_standardise) export(stone_stochastic_upload) diff --git a/R/stochastic_files.R b/R/stochastic_files.R index 70cd9bd..b27e578 100644 --- a/R/stochastic_files.R +++ b/R/stochastic_files.R @@ -150,10 +150,19 @@ stone_stochastic_standardise <- function( } } + # Note that for MenA, we want to keep the _cwyx outcomes. + if (missing_run_id_fix) { if ((!"run_id" %in% names(d)) && (length(index) == 200)) d$run_id <- j } + # Remove columns "X" and "X.1" that have crept in with some of the + # inputs saved with row.names + + d[["X"]] <- NULL + d[["X.1"]] <- NULL + + # Round to integer, as per guidance. (Not using as.integer, as that # has limits on how large numbers can be, so we are just truncating @@ -257,3 +266,70 @@ stone_stochastic_central <- function(base, touchstone, disease, group, outfile <- sprintf("%s_%s_central.pq", group, scenario) arrow::write_parquet(central, file.path(path, outfile)) } + + + +##' Create a `meta.csv` file in the root of the standardised +##' stochastics. The columns contain scalars of `touchstone`, +##' `disease`, `group`, `scenario` - and for each row, a +##' semi-colon-separated lists for `countries` and `outcomes`. +##' This is useful for making the stochastic explorer faster +##' on startup (otherwise it has to sample all of the files +##' each time you run it) - and also it is a good general +##' record of all the stochastic data we have. +##' +##' This does mean that we should re-create the meta data +##' each time we make changes to the standardised stochastic +##' data though. +##' +##' @export +##' @title Produce `meta.csv` summary of the structure and +##' content of a standardised stochastic data folder. +##' @importFrom data.table rbindlist +##' @importFrom utils write.csv +##' @param path The root folder of the stochastic data. + +stone_stochastic_make_meta <- function(path) { + + explore_files <- function(touchstone, folder, disease, group) { + files <- list.files(file.path(path, touchstone, folder)) + first <- file.path(path, touchstone, folder, files[1]) + ds <- arrow::open_dataset(first) + outcomes <- ds$schema$names + outcomes <- outcomes[!outcomes %in% c("run_id", "disease", "year", "age", + "country", "cohort_size")] + outcomes <- sort(unique(tolower(outcomes))) + + files <- strsplit(list.files(file.path(path, touchstone, folder)), "_") + + scenarios <- unique(unlist(lapply(files, `[[`, 2))) + df <- data.frame() + for (scenario in scenarios) { + matches <- files[unlist(lapply(files, `[[`, 2)) == scenario] + countries <- unique(unlist(lapply(matches, `[[`, 3))) + countries <- gsub(".pq", "", countries) + df <- rbind(df, data.frame( + touchstone = touchstone, + disease = disease, + group = group, + scenario = scenario, + countries = paste0(countries, collapse = ";"), + outcomes = paste0(outcomes, collapse = ";") + )) + } + df + } + + touchstone_meta <- function(touchstone) { + entries <- list.files(file.path(path, touchstone)) + data.table::rbindlist(lapply(entries, function(x) { + xs <- strsplit(x, "_")[[1]] + explore_files(touchstone, x, xs[1], xs[2]) + })) + } + + touchstones <- basename(list.dirs(paste0(path, "/"), recursive = FALSE)) + res <- data.table::rbindlist(lapply(touchstones, touchstone_meta)) + write.csv(res, file.path(path, "meta.csv"), + row.names = FALSE, quote = FALSE) +} diff --git a/R/stochastic_graphs.R b/R/stochastic_graphs.R index 172369f..7a2d7b8 100644 --- a/R/stochastic_graphs.R +++ b/R/stochastic_graphs.R @@ -1,13 +1,25 @@ -age_string <- function(ages) { - if (is.null(ages)) { - "all ages" - } else if (identical(unique(sort(ages)), as.numeric(min(ages):max(ages)))) { - sprintf("age %d..%d", min(ages), max(ages)) - } else "selected ages" +filter_string <- function(s, units) { + if (is.null(s)) return(sprintf("all %s", units)) + s <- as.numeric(s) + if (identical(unique(sort(s)), as.numeric(min(s):max(s)))) { + sprintf("%s %d..%d", units, min(s), max(s)) + } else sprintf("selected %s", units) } -##' Draw a stochastic plot showing all the different runs, with the mean, -##' median, 5% and 95% quantiles shown. +##' A feature-rich-ish graph plotting function, which can show the stochastic +##' line for an outcome for different runs, the mean, median and quantiles. +##' If two scenarios are specified, then the burden difference between +##' scenarios is plotted. Additionally, if multiple groups or multiple +##' touchstones are specified, then separate graphs with the same scaling are +##' plotted to allow comparison. +##' +##' Graphs can have calendar year or birth cohort on the y-axis for +##' time-series plots, in which case age is aggregated and the ages to be +##' included can be specified. Alternatively, the x-axis can be age aggregated +##' over time, where the calendar years to be aggregated can be specified. +##' +##' Finally, it can also include a central estimate provided as a file within +##' a packit, from the montagu reporting portal. ##' ##' @export ##' @title Stochastic plot @@ -17,145 +29,292 @@ age_string <- function(ages) { ##' @importFrom graphics lines par ##' @importFrom stats quantile median ##' @importFrom grDevices recordPlot -##' @param base The folder in which the standardised stochastic files are found. -##' @param touchstone The touchstone name (for the graph title) -##' @param disease The disease, used for building the filename and graph title. -##' @param group The modelling group, used in the filename and graph title. +##' @param base The root folder in which the standardised stochastic files are +##' found. Within it should be folders with touchstone names. +##' @param touchstones A touchstone to plot, or a pair of touchstones to +##' compare. If a pair, then only one modelling group can be specified below. +##' @param disease The disease to display. +##' @param groups The modelling group to plot, or a pair of modelling +##' groups to be compared, in which case, only one touchstone can be specified. ##' @param country The country to plot. -##' @param scenario The scenario to plot. -##' @param outcome The outcome to plot, for example `deaths`, `cases`, `dalys` or -##' since 2023, `yll`. -##' @param ages A vector of one or more ages to be selected and aggregated, or -##' if left as NULL, then all ages are used and aggregated. +##' @param scenarios A scenario to plot data for, or a pair of scenarios in +##' which case we plot the outcome for the first scenario, subtract the second. +##' @param outcome The outcome to plot, for example `deaths`, `cases`, `dalys` +##' or since 2023, `yll`. +##' @param xaxis The default is "time", meaning the x-axis is either calendar +##' year, or birth cohort, depending on the `by_cohort` parameter. This means +##' and age gets filtered by the `filter` parameter, and then aggregated. +##' Alternatively, if set to "age", then age will be on the x-axis, and the +##' `filter` parameter specifies either the years, or the birth cohorts to +##' select (depending on the `by_cohort` parameter), before aggregation. +##' @param filter Filter either ages, years, or birth cohort years to a range - +##' see the comments above on the `xaxis` parametern. The filter is a vector +##' of ages, or years, or can be NULL to do no filtering. ##' @param by_cohort If TRUE, then age is subtracted from year to convert it to -##' year of birth before aggregating. +##' year of birth before aggregating. See the `xaxis` and `filter` parameters. ##' @param log If TRUE, then use a logged y-axis. ##' @param packit_id If set, then read central burden estimates from a file ##' within a packit on the Montagu packit server. ##' @param packit_file Used with packit_id to specify the filename of an RDS ##' file providing burden estimates. We expect to find scenario, year, age, ##' country, burden_outcome and value fields in the table. +##' @param include_stochastics Default TRUE, select whether to draw the +##' individual stochastic lines. ##' @param include_quantiles Default TRUE, select whether to plot the ##' 5% and 95% quantile lines. ##' @param include_mean Default TRUE, select whether to plot the mean. ##' @param include_median Default TRUE, select whether to plot the median. -##' @param scenario2 Default NULL; if set, then the burdens from this -##' scenario will be subtracted from those in `scenario` - ie, this plots -##' an impact graph of applying the second scenario. For many graphs that -##' use this, the result will be positive numbers, representing cases -##' or deaths averted. - -stone_stochastic_graph <- function(base, touchstone, disease, group, country, - scenario, outcome, ages = NULL, + +stone_stochastic_graph <- function(base, + touchstones, disease, groups, country, + scenarios, outcome, + xaxis = "time", + filter = NULL, by_cohort = FALSE, log = FALSE, packit_id = NULL, packit_file = NULL, + include_stochastics = TRUE, include_quantiles = TRUE, include_mean = TRUE, - include_median = TRUE, - scenario2 = NULL) { + include_median = TRUE) { - d <- prepare_graph_data(base, touchstone, disease, group, country, - scenario, outcome, ages, by_cohort) - age <- age_string(ages) + # Forbid multi-touchstone AND multi-group for now - which means we will + # only produce 2 graphs. We could do more - for example, 3 groups that + # model a disease, but for now, we'll stick with two. - title <- sprintf("%s, %s, %s, %s\n%s, %s\n", touchstone, disease, group, age, - scenario, country) - outcome_ylab <- outcome + if (!length(touchstones) %in% 1:2) { + cli::cli_abort("Only specify one or two touchstones.") + } - if (!is.null(scenario2)) { - d2 <- prepare_graph_data(base, touchstone, disease, group, country, - scenario2, outcome, ages, by_cohort) - title <- sprintf("%s, %s, %s, %s\n%s, %s\n", touchstone, disease, group, age, - sprintf("Impact of %s ->\n%s", scenario, scenario2), country) - d <- d[order(d$year, d$run_id), ] - d2 <- d2[order(d2$year, d2$run_id), ] - d[[outcome]] <- d[[outcome]] - d2[[outcome]] - outcome_ylab <- paste(outcome_ylab, "averted") + if (!length(groups) %in% 1:2) { + cli::cli_abort("Only specify one or two modelling groups.") + } + + if (!length(scenarios) %in% 1:2) { + cli::cli_abort("Only specify one or two scenarios.") + } + + if ((length(touchstones) == 2) && (length(groups) ==2)) { + cli::cli_abort("Only one of `touchstones` or `groups` can be plural.") } - runs <- max(d$run_id) - miny <- max(1, min(d[[outcome]])) - maxy <- max(d[[outcome]]) - log <- if (log) "y" else "" + if (!isTRUE(tolower(xaxis) %in% c("time", "age"))) { + cli::cli_abort("`xaxis` must be either `time` or `age`.") + } + + xaxis <- tolower(xaxis) + outcome <- tolower(outcome) + + miny <- Inf + maxy <- -Inf + minx <- Inf + maxx <- -Inf + + # Fetch the packit data if wanted if (!is.null(packit_id)) { - central <- prepare_central_data(packit_id, packit_file, - country, scenario, outcome, ages, by_cohort) - # To be continued... + central <- get_packit_data(packit_id, packit_file, + country, scenarios, outcome, by_cohort) + if (xaxis == "age") { + central <- aggregate_by_age(central, outcome, filter) + minx <- 0 + maxx <- 100 + } else { + central <- aggregate_by_year(central, outcome, filter) + miny <- min(central[[outcome]]) + maxy <- max(central[[outcome]]) + minx <- min(central$year) + maxx <- max(central$year) + } } - par(mar = c(5, 4, 5, 2)) - plot(ylab = outcome_ylab, xlab = if (by_cohort) "Birth Cohort" else "year", - x = d$year[d$run_id == 1], y = d[[outcome]][d$run_id == 1], type="l", - col = "#b0b0b0", ylim = c(miny, maxy), main = title, log = log) - for (i in 2:runs) { - lines(x = d$year[d$run_id == i], y = d[[outcome]][d$run_id == i], - col = "#b0b0b0") + # Fetch the data from the files. We may end up with 1 or 2 graphs here. + + data <- list() + n_graphs <- 0 + for (touchstone in touchstones) { + for (group in groups) { + n_graphs <- n_graphs + 1 + data[[n_graphs]] <- get_graph_data(base, touchstone, disease, group, + country, scenarios, outcome, by_cohort) + } } - avgs <- d %>% group_by(.data$year) %>% - summarise( - mean = mean(.data[[outcome]]), - median = median(.data[[outcome]]), - q05 = quantile(.data[[outcome]], 0.05), - q95 = quantile(.data[[outcome]], 0.95), - .groups = "drop" - ) - if (include_mean) { - lines(x = avgs$year, y = avgs$mean, col = "#ff4040", lwd = 2) - } - if (include_median) { - lines(x = avgs$year, y = avgs$median, col = "#00ff00", lwd = 2) - } - if (include_quantiles) { - lines(x = avgs$year, y = avgs$q05, col = "#202020", lwd = 2) - lines(x = avgs$year, y = avgs$q95, col = "#202020", lwd = 2) - } - recordPlot() + # Filter and aggregate the data, finding bounds + + for (i in 1:n_graphs) { + if (xaxis == "age") { + data[[i]] <- aggregate_by_age(data[[i]], outcome, filter) + minx <- 0 + maxx <- 100 + } else { + data[[i]] <- aggregate_by_year(data[[i]], outcome, filter) + minx <- min(minx, data[[i]]$year) + maxx <- max(maxx, data[[i]]$year) + } + miny <- min(miny, data[[i]][[outcome]]) + maxy <- max(maxy, data[[i]][[outcome]]) + } + + # Sort out titles and labels common to both graphs + units <- if (xaxis == "time") "ages" else if (by_cohort) "cohorts" else "years" + filter_title <- filter_string(filter, units) + outcome_ylab <- outcome + scenario_title <- scenarios[1] + + if (log) { + log <- "y" + miny <- max(1, miny) + } else { + log <- "" + } + + if (length(scenarios) == 2) { + outcome_ylab <- paste(outcome_ylab, "averted") + scenario_title <- sprintf("Difference of %s ->\n%s", scenarios[1], + scenarios[2]) + } + + + # Plot the one or two graphs + + res <- list() + for (i in 1:n_graphs) { + touchstone_title <- touchstones[min(i, length(touchstones))] + group_title <- groups[min(i, length(groups))] + title <- sprintf("%s, %s, %s, %s\n%s, %s\n", + touchstone_title, disease, group_title, + filter_title, + scenario_title, country) + + + if (xaxis == "age") { + xlabel <- "Age" + xfield <- "age" + } else { + xlabel <- if (by_cohort) "Birth Cohort" else "Year" + xfield <- "year" + } + + + runs <- max(data[[i]]$run_id) + par(mar = c(5, 4, 5, 2)) + plot(ylab = outcome_ylab, xlab = xlabel, + x = NULL, y = NULL, + col = "#b0b0b0", xlim = c(minx, maxx), ylim = c(miny, maxy), + main = title, log = log) + + if (include_stochastics) { + for (j in seq_len(runs)) { + lines(x = data[[i]][[xfield]][data[[i]]$run_id == j], + y = data[[i]][[outcome]][data[[i]]$run_id == j], + col = "#b0b0b0") + } + } + + if (include_mean | include_median | include_quantiles) { + avgs <- data[[i]] %>% group_by(.data[[xfield]]) %>% + summarise( + mean = mean(.data[[outcome]]), + median = median(.data[[outcome]]), + q05 = quantile(.data[[outcome]], 0.05), + q95 = quantile(.data[[outcome]], 0.95), + .groups = "drop" + ) + if (include_mean) { + lines(x = avgs[[xfield]], y = avgs$mean, col = "#ff4040", lwd = 2) + } + if (include_median) { + lines(x = avgs[[xfield]], y = avgs$median, col = "#00ff00", lwd = 2) + } + if (include_quantiles) { + lines(x = avgs[[xfield]], y = avgs$q05, col = "#202020", lwd = 2) + lines(x = avgs[[xfield]], y = avgs$q95, col = "#202020", lwd = 2) + } + } + + if (!is.null(packit_id)) { + lines(x = central[[xfield]], y = central[[outcome]], + col = "#2020ff", lwd = 2) + } + + res[[i]] <- recordPlot() + } + res } +get_burden_difference <- function(data, outcome) { + if (length(data) == 2) { + data[[1]][[outcome]] <- data[[1]][[outcome]] - data[[2]][[outcome]] + } + data[[1]] +} -prepare_graph_data <- function(base, touchstone, disease, group, country, - scenario, outcome, ages, by_cohort) { +# Here we'll fetch the data for one graph. `scenarios` might be length 1 +# (which is easy) or 2 - in which case we'll subtract the outcome values of +# the second from the first. We can also do the by_cohort calculation in here - pq <- sprintf("%s/%s/%s_%s/%s_%s_%s.pq", base, touchstone, disease, - group, group, scenario, country) +get_graph_data <- function(base, touchstone, disease, group, country, + scenarios, outcome, by_cohort) { + + data <- list() + for (s in seq_along(scenarios)) { + pq <- sprintf("%s/%s/%s_%s/%s_%s_%s.pq", base, touchstone, disease, + group, group, scenarios[s], country) + + if (!file.exists(pq)) { + cli::cli_abort("Couldn't find file {pq} - check files or parameters") + } + d <- arrow::read_parquet(pq) + if (by_cohort) { + d$year <- d$year - d$age + } + d <- d[order(d$year ,d$age, d$run_id), ] + data[[s]] <- d[, c("run_id", "year", "age", outcome)] + } + get_burden_difference(data, outcome) +} - d <- arrow::read_parquet(pq) +aggregate_by_year <- function(d, outcome, ages = NULL) { if (!is.null(ages)) { d <- d[d$age %in% ages, ] } - if (by_cohort) { - d$year <- d$year - d$age + d %>% group_by(.data$run_id, .data$year) %>% + summarise( + !!outcome := sum(.data[[outcome]], na.rm = TRUE), + .groups = "drop") +} + +aggregate_by_age <- function(d, outcome, years = NULL) { + if (!is.null(years)) { + d <- d[d$year %in% years, ] } - d <- d[, c("run_id", "year", "age", outcome)] - d <- d %>% group_by(.data$run_id, .data$year) %>% + d %>% group_by(.data$run_id, .data$age) %>% summarise( !!outcome := sum(.data[[outcome]], na.rm = TRUE), .groups = "drop") - d } -prepare_central_data <- function(packit_id, packit_file, - country, scenario, outcome, ages, by_cohort) { +get_packit_data <- function(packit_id, packit_file, + country, scenarios, outcome, by_cohort) { central <- readRDS(fetch_packit(packit_id, packit_file)) central <- central[central$country == country, ] - central <- central[central$scenario == scenario, ] central <- central[central$burden_outcome == outcome, ] - if (!is.null(ages)) { - central <- central[central$age %in% ages, ] - } - if (by_cohort) { - central$year <- central$year - central$age + + data <- list() + for (s in seq_along(scenarios)) { + d <- central[central$scenario == scenarios[s], ] + if (by_cohort) { + d$year <- d$year - d$age + } + names(d)[names(d) == "value"] <- outcome + d <- d[order(d$year, d$age), ] + data[[s]] <- d } - names(central)[names(central) == "value"] <- outcome - central <- central %>% group_by(.data$year) %>% - summarise( - !!outcome := sum(.data[[outcome]], na.rm = TRUE), - .groups = "drop") - central$run_id <- 0 - central + d <- get_burden_difference(data, outcome) + d <- as.data.frame(d[, c("year", "age", outcome)]) + d$run_id <- 1 + d } ##' Launch a Shiny app to allow interactive plotting of diff --git a/inst/app/app.R b/inst/app/app.R index bef6258..03a5242 100644 --- a/inst/app/app.R +++ b/inst/app/app.R @@ -47,15 +47,15 @@ app_ui <- function() { sidebar <- append(sidebar, scenarios) sidebar <- append(sidebar, list( selectInput(sprintf("%s_country", prefix), "Country:", choices = c0), + selectInput(sprintf("%s_xaxis", prefix), "X-Axis:", choices = + c("Time (Calendar)", "Time (Birth Cohort)", + "Age (Calendar)", "Age (Birth Cohort)")), selectInput(sprintf("%s_outcome", prefix), "Y-Axis:", choices = c0), - radioButtons(sprintf("%s_year", prefix), "X-Axis:", inline = TRUE, - choices = c("Calendar", "Cohort")), - radioButtons(sprintf("%s_ages", prefix), "Age:", inline = TRUE, - choices = c("All", "Under 5")), + textInput(sprintf("%s_filter", prefix), "Filter Ages", value = "All"), checkboxGroupInput( sprintf("%s_options", prefix), "Plot Options:", - choices = c("Quantiles", "Median", "Mean", "Log-Y"), - selected = c("Quantiles", "Median", "Mean", "Log-Y"), + choices = c("Stochastics", "Quantiles", "Median", "Mean", "Log-Y"), + selected = c("Stochastics", "Quantiles", "Median", "Mean", "Log-Y"), inline = TRUE), actionButton(sprintf("%s_plot_btn", prefix), "Plot") )) @@ -112,9 +112,9 @@ app_ui <- function() { make_panel("Burden", "b", 1, 1, 1), make_panel("Burden/TS", "bts", 2, 1, 1), make_panel("Burden/MG", "bmg", 1, 1, 2), - make_panel("Impact", "i", 1, 2, 1), - make_panel("Impact/TS", "its", 2, 2, 1), - make_panel("Impact/MG", "img", 1, 2, 2) + make_panel("Burden Diff", "i", 1, 2, 1), + make_panel("Burden Diff/TS", "its", 2, 2, 1), + make_panel("Burden Diff/MG", "img", 1, 2, 2) ) ) } @@ -253,6 +253,17 @@ app_server <- function(input, output, session) { input, prefix)}) + filter <- sprintf("%s_filter", prefix) + xaxis <- sprintf("%s_xaxis", prefix) + + observeEvent(input[[xaxis]], { + xaxis_val <- input[[xaxis]] + if (grepl("Time", xaxis_val)) lab <- "Filter age: (eg. All, or 0-4)" + else if (grepl("Calendar", xaxis_val)) lab <- "Filter years: (eg. All, or 2000-2010)" + else lab <- "Filter cohorts: (eg. All, or 2000-2010)" + updateTextInput(session, filter, label = lab) + }) + n_graphs <- 1 + ((n_touchstone * n_group) > 1) if (n_graphs == 1) { graphs <- sprintf("%s_main_plot", prefix) @@ -262,11 +273,6 @@ app_server <- function(input, output, session) { button <- sprintf("%s_plot_btn", prefix) plot_reactive <- eventReactive(input[[button]], { - ages <- NULL - if (input[[sprintf("%s_ages", prefix)]] == "Under 5") { - ages <- 0:4 - } - check <- function(pre, x1, x2, type) { if (is.null(x2)) return(TRUE) if ((grepl(pre, prefix)) && (input[[x1]] == input[[x2]])) { @@ -286,7 +292,7 @@ app_server <- function(input, output, session) { if (!check("i", is1, is2, "scenario")) return(NULL) list( - ages = ages, + filter = input[[sprintf("%s_filter", prefix)]], opts = input[[sprintf("%s_options", prefix)]], touchstone = c(input[[it1]], if (!is.null(it2)) input[[it2]] else NULL), @@ -296,37 +302,41 @@ app_server <- function(input, output, session) { disease = input[[id]], country = input[[ic]], outcome = input[[sprintf("%s_outcome", prefix)]], - year = input[[sprintf("%s_year", prefix)]] + xaxis = input[[sprintf("%s_xaxis", prefix)]] + ) + }) + + res_reactive <- reactive({ + pr <- plot_reactive() + req(pr) + filter_vec <- parse_filter(pr$filter) + + stoner::stone_stochastic_graph( + base = data_dir, + touchstones = pr$touchstone, + disease = pr$disease, + groups = pr$group, + country = pr$country, + scenarios = pr$scenario, + outcome = pr$outcome, + xaxis = if (grepl("Time", pr$xaxis)) "time" else "age", + filter = filter_vec, + by_cohort = grepl("Birth Cohort", pr$xaxis), + log = "Log-Y" %in% pr$opts, + include_median = "Median" %in% pr$opts, + include_quantiles = "Quantiles" %in% pr$opts, + include_mean = "Mean" %in% pr$opts, + include_stochastics = "Stochastics" %in% pr$opts ) }) for (g in seq_along(graphs)) { local({ gg <- g - output[[graphs[gg]]] <- renderPlot({ - pr <- plot_reactive() - req(pr) - - it <- pr$touchstone[min(gg, length(pr$touchstone))] - ig <- pr$group[min(gg, length(pr$group))] - - stoner::stone_stochastic_graph( - base = data_dir, - touchstone = it, - disease = pr$disease, - group = ig, - country = pr$country, - scenario = pr$scenario[1], - scenario2 = if (length(pr$scenario) > 1) pr$scenario[2] else NULL, - outcome = pr$outcome, - by_cohort = pr$year == "Cohort", - ages = pr$ages, - log = "Log-Y" %in% pr$opts, - include_median = "Median" %in% pr$opts, - include_quantiles = "Quantiles" %in% pr$opts, - include_mean = "Mean" %in% pr$opts - ) + res <- res_reactive() + req(res) + replayPlot(res[[gg]]) }) }) } diff --git a/inst/app/utils.R b/inst/app/utils.R index daaa9cc..f3a6ad6 100644 --- a/inst/app/utils.R +++ b/inst/app/utils.R @@ -7,42 +7,35 @@ # Functions ending in _mg will find things common # between to modelling groups, for comparisons. +meta <- read.csv(file.path(data_dir, "meta.csv")) + get_touchstones <- function() { - sort(unique(basename(list.dirs(data_dir, recursive = FALSE)))) + sort(unique(meta$touchstone), decreasing = TRUE) } -get_diseases <- function(touchstone1, touchstone2) { - lookup <- function(touchstone, res = NULL) { - if (is.null(touchstone)) return(res) - path <- file.path(data_dir, touchstone) - dirs <- basename(list.dirs(path, recursive = FALSE)) - unique(unlist(lapply(strsplit(dirs, "_"), `[[`, 1))) +get_diseases <- function(touchstone1, touchstone2 = NULL) { + res <- meta$disease[meta$touchstone %in% touchstone1] + if (!is.null(touchstone2)) { + res <- intersect(res, meta$disease[meta$touchstone %in% touchstone2]) } - res <- lookup(touchstone1) - sort(unique(res[res %in% lookup(touchstone2, res)])) + sort(unique(res)) } get_groups <- function(touchstone1, touchstone2, disease) { - lookup <- function(touchstone, disease, res = NULL) { - if (is.null(touchstone)) return(res) - path <- file.path(data_dir, touchstone) - dirs <- basename(list.dirs(path, recursive = FALSE)) - dirs <- dirs[substr(dirs, 1, nchar(disease) + 1) == paste0(disease, "_")] - unique(substring(dirs, nchar(disease) + 2)) + m <- meta[meta$disease %in% disease, ] + res <- m$group[m$touchstone %in% touchstone1] + if (!is.null(touchstone2)) { + res <- intersect(res, m$group[m$touchstone %in% touchstone2]) } - res <- lookup(touchstone1, disease) - sort(unique(res[res %in% lookup(touchstone2, disease, res)])) + sort(unique(res)) } get_scenarios <- function(touchstone1, touchstone2, disease, group1, group2) { lookup <- function(touchstone, disease, group, res = NULL) { if ((is.null(touchstone)) || (is.null(group))) return(res) - path <- file.path(data_dir, touchstone, paste(disease, group, sep = "_")) - files <- basename(list.files(path, recursive = FALSE)) - files <- gsub(".pq", "", files) - files <- substring(files, nchar(group) + 2) - ends <- unlist(lapply(gregexpr("_", files), `[[`, 1)) - 1 - unique(substring(files, 1, ends)) + sort(unique(meta$scenario[(meta$touchstone %in% touchstone) & + (meta$disease %in% disease) & + (meta$group %in% group)])) } res <- lookup(touchstone1, disease, group1) @@ -57,14 +50,11 @@ get_countries <- function(touchstone1, touchstone2, disease, group1, group2, if ((is.null(touchstone)) || (is.null(group)) || (is.null(scenario))) { return(res) } - - path <- file.path(data_dir, touchstone, paste(disease, group, sep = "_")) - files <- basename(list.files(path, recursive = FALSE)) - files <- gsub(".pq", "", files) - files <- substring(files, nchar(group) + 2) - files <- files[substring(files, 1, nchar(scenario) + 1) == paste0(scenario, "_")] - ends <- unlist(lapply(gregexpr("_", files), `[[`, 1)) + 1 - unique(substring(files, ends)) + cts <- meta$countries[(meta$touchstone %in% touchstone) & + (meta$disease %in% disease) & + (meta$group %in% group) & + (meta$scenario %in% scenario)] + sort(unique(strsplit(cts, ";")[[1]])) } res <- lookup(touchstone1, disease, group1, scenario1) res <- res[res %in% lookup(touchstone2, disease, group1, scenario1, res)] @@ -78,17 +68,18 @@ get_countries <- function(touchstone1, touchstone2, disease, group1, group2, get_outcomes <- function(touchstone1, touchstone2, disease, group1, group2, scenario1, scenario2, country) { + lookup <- function(touchstone, disease, group, scenario, country, res = NULL) { if ((is.null(touchstone)) || (is.null(group)) || (is.null(scenario))) { return(res) } - path <- file.path(data_dir, touchstone, paste(disease, group, sep = "_")) - thefile <- sprintf("%s_%s_%s.pq", group, scenario, country) - tbl <- arrow::read_parquet(file.path(path, thefile), col_select = NULL) - cols <- names(tbl) - sort(cols[!cols %in% c("disease", "run_id", "year", "age", - "country", "cohort_size")]) + outs <- meta$outcomes[(meta$touchstone %in% touchstone) & + (meta$disease %in% disease) & + (meta$group %in% group) & + (meta$scenario %in% scenario)] + sort(unique(strsplit(outs, ";")[[1]])) } + res <- lookup(touchstone1, disease, group1, scenario1, country) res <- res[res %in% lookup(touchstone2, disease, group1, scenario1, country, res)] res <- res[res %in% lookup(touchstone1, disease, group2, scenario1, country, res)] @@ -96,7 +87,8 @@ get_outcomes <- function(touchstone1, touchstone2, disease, group1, group2, res <- res[res %in% lookup(touchstone1, disease, group1, scenario2, country, res)] res <- res[res %in% lookup(touchstone2, disease, group1, scenario2, country, res)] res <- res[res %in% lookup(touchstone1, disease, group2, scenario2, country, res)] - sort(unique(res[res %in% lookup(touchstone2, disease, group2, scenario2, country, res)])) + res <- sort(unique(res[res %in% lookup(touchstone2, disease, group2, scenario2, country, res)])) + res } # GUI helpers. @@ -178,3 +170,19 @@ update_country <- function(session, ts1, ts2, disease, g1, g2, s1, s2, country, outcomes <- get_outcomes(ts1, ts2, disease, g1, g2, s1, s2, country) update_dropdown_keep(session, o, outcomes, input[[o]]) } + +parse_filter <- function(s) { + if (tolower(s) == "all") return(NULL) + s <- gsub(" ", "", s) + s <- strsplit(s, ",")[[1]] + sel <- integer(0) + for (bit in s) { + if (!grepl("-", bit)) { + sel <- c(sel, as.integer(bit)) + } else { + from_to <- strsplit(bit, "-")[[1]] + sel <- c(sel, from_to[1]:from_to[2]) + } + } + sort(unique(sel)) +} diff --git a/man/stone_stochastic_graph.Rd b/man/stone_stochastic_graph.Rd index 5e40693..59451ec 100644 --- a/man/stone_stochastic_graph.Rd +++ b/man/stone_stochastic_graph.Rd @@ -6,44 +6,57 @@ \usage{ stone_stochastic_graph( base, - touchstone, + touchstones, disease, - group, + groups, country, - scenario, + scenarios, outcome, - ages = NULL, + xaxis = "time", + filter = NULL, by_cohort = FALSE, log = FALSE, packit_id = NULL, packit_file = NULL, + include_stochastics = TRUE, include_quantiles = TRUE, include_mean = TRUE, - include_median = TRUE, - scenario2 = NULL + include_median = TRUE ) } \arguments{ -\item{base}{The folder in which the standardised stochastic files are found.} +\item{base}{The root folder in which the standardised stochastic files are +found. Within it should be folders with touchstone names.} -\item{touchstone}{The touchstone name (for the graph title)} +\item{touchstones}{A touchstone to plot, or a pair of touchstones to +compare. If a pair, then only one modelling group can be specified below.} -\item{disease}{The disease, used for building the filename and graph title.} +\item{disease}{The disease to display.} -\item{group}{The modelling group, used in the filename and graph title.} +\item{groups}{The modelling group to plot, or a pair of modelling +groups to be compared, in which case, only one touchstone can be specified.} \item{country}{The country to plot.} -\item{scenario}{The scenario to plot.} +\item{scenarios}{A scenario to plot data for, or a pair of scenarios in +which case we plot the outcome for the first scenario, subtract the second.} -\item{outcome}{The outcome to plot, for example \code{deaths}, \code{cases}, \code{dalys} or -since 2023, \code{yll}.} +\item{outcome}{The outcome to plot, for example \code{deaths}, \code{cases}, \code{dalys} +or since 2023, \code{yll}.} -\item{ages}{A vector of one or more ages to be selected and aggregated, or -if left as NULL, then all ages are used and aggregated.} +\item{xaxis}{The default is "time", meaning the x-axis is either calendar +year, or birth cohort, depending on the \code{by_cohort} parameter. This means +and age gets filtered by the \code{filter} parameter, and then aggregated. +Alternatively, if set to "age", then age will be on the x-axis, and the +\code{filter} parameter specifies either the years, or the birth cohorts to +select (depending on the \code{by_cohort} parameter), before aggregation.} + +\item{filter}{Filter either ages, years, or birth cohort years to a range - +see the comments above on the \code{xaxis} parametern. The filter is a vector +of ages, or years, or can be NULL to do no filtering.} \item{by_cohort}{If TRUE, then age is subtracted from year to convert it to -year of birth before aggregating.} +year of birth before aggregating. See the \code{xaxis} and \code{filter} parameters.} \item{log}{If TRUE, then use a logged y-axis.} @@ -54,20 +67,30 @@ within a packit on the Montagu packit server.} file providing burden estimates. We expect to find scenario, year, age, country, burden_outcome and value fields in the table.} +\item{include_stochastics}{Default TRUE, select whether to draw the +individual stochastic lines.} + \item{include_quantiles}{Default TRUE, select whether to plot the 5\% and 95\% quantile lines.} \item{include_mean}{Default TRUE, select whether to plot the mean.} \item{include_median}{Default TRUE, select whether to plot the median.} - -\item{scenario2}{Default NULL; if set, then the burdens from this -scenario will be subtracted from those in \code{scenario} - ie, this plots -an impact graph of applying the second scenario. For many graphs that -use this, the result will be positive numbers, representing cases -or deaths averted.} } \description{ -Draw a stochastic plot showing all the different runs, with the mean, -median, 5\% and 95\% quantiles shown. +A feature-rich-ish graph plotting function, which can show the stochastic +line for an outcome for different runs, the mean, median and quantiles. +If two scenarios are specified, then the burden difference between +scenarios is plotted. Additionally, if multiple groups or multiple +touchstones are specified, then separate graphs with the same scaling are +plotted to allow comparison. +} +\details{ +Graphs can have calendar year or birth cohort on the y-axis for +time-series plots, in which case age is aggregated and the ages to be +included can be specified. Alternatively, the x-axis can be age aggregated +over time, where the calendar years to be aggregated can be specified. + +Finally, it can also include a central estimate provided as a file within +a packit, from the montagu reporting portal. } diff --git a/man/stone_stochastic_make_meta.Rd b/man/stone_stochastic_make_meta.Rd new file mode 100644 index 0000000..6a4b797 --- /dev/null +++ b/man/stone_stochastic_make_meta.Rd @@ -0,0 +1,27 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/stochastic_files.R +\name{stone_stochastic_make_meta} +\alias{stone_stochastic_make_meta} +\title{Produce \code{meta.csv} summary of the structure and +content of a standardised stochastic data folder.} +\usage{ +stone_stochastic_make_meta(path) +} +\arguments{ +\item{path}{The root folder of the stochastic data.} +} +\description{ +Create a \code{meta.csv} file in the root of the standardised +stochastics. The columns contain scalars of \code{touchstone}, +\code{disease}, \code{group}, \code{scenario} - and for each row, a +semi-colon-separated lists for \code{countries} and \code{outcomes}. +This is useful for making the stochastic explorer faster +on startup (otherwise it has to sample all of the files +each time you run it) - and also it is a good general +record of all the stochastic data we have. +} +\details{ +This does mean that we should re-create the meta data +each time we make changes to the standardised stochastic +data though. +} diff --git a/scripts/imports.R b/scripts/imports.R new file mode 100644 index 0000000..89472c8 --- /dev/null +++ b/scripts/imports.R @@ -0,0 +1,1498 @@ +get_con <- function() { + vault <- vaultr::vault_client(login = "github") + password <- vault$read("/secret/vimc/database/production/users/readonly")$password + DBI::dbConnect(RPostgres::Postgres(), + dbname = "montagu", + host = "montagu.vaccineimpact.org", + port = 5432, password = password, + user = "readonly") +} + +get_annex <- function() { + vault <- vaultr::vault_client(login = "github") + password <- vault$read("/secret/vimc/annex/users/vimc")$password + DBI::dbConnect(RPostgres::Postgres(), + dbname = "montagu", + host = "annex.montagu.dide.ic.ac.uk", + port = 15432, + password = password, + user = "vimc") + +} + + +upload4 <- function(out_path, modelling_group, disease, touchstone, + con, annex) { + stub <- file.path(out_path, sprintf("%s_%s_", modelling_group, disease)) + + stoner::stone_stochastic_upload( + paste0(stub, "calendar.qs"), + con, annex, modelling_group, disease, touchstone, + is_cohort = FALSE, is_under5 = FALSE) + + stoner::stone_stochastic_upload( + paste0(stub, "calendar_u5.qs"), + con, annex, modelling_group, disease, touchstone, + is_cohort = FALSE, is_under5 = TRUE) + + stoner::stone_stochastic_upload( + paste0(stub, "cohort.qs"), + con, annex, modelling_group, disease, touchstone, + is_cohort = TRUE, is_under5 = FALSE) + + stoner::stone_stochastic_upload( + paste0(stub, "cohort_u5.qs"), + con, annex, modelling_group, disease, touchstone, + is_cohort = TRUE, is_under5 = TRUE) +} + +do_stochastics_2024 <- function() { + con <- get_con() + annex <- get_annex() + in_path <- "D:/Dropbox (SPH Imperial College)/File requests/latest/202409malaria-1/" + out_path <- "D:/stochastic_2024/" + + # UAC-Kakai + + stoner::stone_stochastic_process(con, "UAC-Glele_Kakai", "Malaria", "202409malaria-1", + c("malaria-no-vaccination", + "malaria-r3-r4-default", "malaria-rts3-rts4-default"), + file.path(in_path, "Malaria-UAC-Kakai"), + c("Stochastic_Burden_Estimates_Glele_Kakai_No_Vaccine_:index.csv.xz", + "Stochastic_Burden_Estimates_Glele_Kakai_Default_r34_:index.csv.xz", + "Stochastic_Burden_Estimates_Glele_Kakai_Default_rts34_:index.csv.xz"), + "", 1, 200, out_path, bypass_cert_check = TRUE) + + upload4(out_path, "UAC-Glele_Kakai", "Malaria", "202409malaria-1", con, annex) + + # IC-Okell + in_path <- "D:/Dropbox (SPH Imperial College)/File requests/latest/202409malaria-1/Malaria-IC-Okell/" + out_path <- "D:/stochastic_2024/" + stoner::stone_stochastic_process(con, + "IC-Okell", "Malaria", "202409malaria-1", + c("malaria-no-vaccination", + "malaria-r3-r4-default", "malaria-rts3-rts4-default"), + in_path, + c("stochastic-burden-est-no-vaccination_:index Lydia Haile.csv.xz", + "stochastic-burden-est-malaria-r3-r4-default_:index Lydia Haile.csv.xz", + "stochastic-burden-est-malaria-rts3-rts4-default_:index Lydia Haile.csv.xz"), + "", 1, 200, out_path, bypass_cert_check = TRUE) + + upload4(out_path, "IC-Okell", "Malaria", "202409malaria-1", con, annex) + + # TKI-Penny + + in_path <- "D:/Dropbox (SPH Imperial College)/File requests/latest/202409malaria-1/Malaria-TKI-Penny/" + + stoner::stone_stochastic_process(con, + "TKI-Penny", "Malaria", "202409malaria-1", + c("malaria-no-vaccination", + "malaria-r3-r4-default", + "malaria-rts3-rts4-default"), + in_path, + c("stochastic_burden_est_malaria_:index_novaccine Josephine Malinga.csv.xz", + "stochastic_burden_est_malaria_:index_r21_d4_default Josephine Maasd linga.csv.xz", + "stochastic_burden_est_malaria_:index_rtss_d4_default Josephine asd fgMalinga.csv.xz"), + "", 1, 31, out_path, bypass_cert_check = TRUE) + + upload4(out_path, "TKI-Penny", "Malaria", "202409malaria-1", con, annex) + +} + + +do_stochastics_2023 <- function() { + con <- get_con() + annex <- get_annex() + in_path <- "D:/Dropbox (SPH Imperial College)/File requests/latest/202310gavi/" + out_path <- "D:/stochastic_2023/" + + ###################### HepB ######################################### + + stoner::stone_stochastic_process(con, "Li", "HepB", "202310gavi-4", + c( "hepb-hepb3-bd-bluesky", + "hepb-hepb3-bd-default", + "hepb-hepb3-bd-ia2030", + "hepb-hepb3-bluesky", + "hepb-hepb3-default", + "hepb-hepb3-ia2030", + "hepb-no-vaccination" + ), + file.path(in_path, "HepB-Li"), + paste0(":scenario:index.csv.xz"), + "cert156", 1, 200, out_path, NULL, + "deaths", "cases", "dalys") + + upload4(out_path, "Li", "HepB", "202310gavi-4", con, annex) + + stoner::stone_stochastic_process( + con, "IC-Hallett", "HepB", "202310gavi-4", + c( "hepb-hepb3-bd-bluesky", + "hepb-hepb3-bd-default", + "hepb-hepb3-bd-ia2030", + "hepb-hepb3-bluesky", + "hepb-hepb3-default", + "hepb-hepb3-ia2030", + "hepb-no-vaccination"), + file.path(in_path, "HepB-IC-Hallett"), + c("stochastic_burden_est_HepB-IC-Hallett_hepb_hepb3_bd_bluesky_:index.csv.xz", + "stochastic_burden_est_HepB-IC-Hallett_hepb_hepb3_bd_default_:index.csv.xz", + "stochastic_burden_est_HepB-IC-Hallett_hepb_hepb3_bd_ia2030_:index.csv.xz", + "stochastic_burden_est_HepB-IC-Hallett_hepb_hepb3_bluesky_:index.csv.xz", + "stochastic_burden_est_HepB-IC-Hallett_hepb_hepb3_default_:index.csv.xz", + "stochastic_burden_est_HepB-IC-Hallett_hepb_hepb3_ia2030_:index.csv.xz", + "stochastic_burden_est_HepB-IC-Hallett_hepb_no_vaccination_:index.csv.xz"), + "", 1, 200, out_path, NULL, + "deaths", "cases", "dalys", bypass_cert_check = TRUE ) + + upload4(out_path, "IC-Hallett", "HepB", "202310gavi-4", con, annex) + + + stoner::stone_stochastic_process( + con, "IC-Hallett", "HepB", "202310gavi-4", + c( "hepb-hepb3-bd-bluesky", + "hepb-hepb3-bd-default", + "hepb-hepb3-bd-ia2030", + "hepb-hepb3-bluesky", + "hepb-hepb3-default", + "hepb-hepb3-ia2030", + "hepb-no-vaccination"), + file.path(in_path, "HepB-IC-Hallett"), + c("stochastic_burden_est_HepB-IC-Hallett_hepb_hepb3_bd_bluesky_:index.csv.xz", + "stochastic_burden_est_HepB-IC-Hallett_hepb_hepb3_bd_default_:index.csv.xz", + "stochastic_burden_est_HepB-IC-Hallett_hepb_hepb3_bd_ia2030_:index.csv.xz", + "stochastic_burden_est_HepB-IC-Hallett_hepb_hepb3_bluesky_:index.csv.xz", + "stochastic_burden_est_HepB-IC-Hallett_hepb_hepb3_default_:index.csv.xz", + "stochastic_burden_est_HepB-IC-Hallett_hepb_hepb3_ia2030_:index.csv.xz", + "stochastic_burden_est_HepB-IC-Hallett_hepb_no_vaccination_:index.csv.xz"), + "", 1, 200, out_path, NULL, + "deaths", "cases", "dalys", bypass_cert_check = TRUE ) + + upload4(out_path, "IC-Hallett", "HepB", "202310gavi-4", con, annex) + + + + ###################### YF ######################################### + + in_path <- "//fi--didenas1-app/Test/YF" + out_path <- in_path + + stoner::stone_stochastic_process( + con, "IC-Garske", "YF", "202310gavi-4", + c("yf-no-vaccination", + "yf-routine-bluesky", + "yf-routine-campaign-bluesky", + "yf-routine-campaign-default", + "yf-routine-campaign-ia2030", + "yf-routine-default", + "yf-routine-ia2030"), + in_path, + "burden_results_stochastic_202310gavi-3_:scenario Keith Fraser.csv.xz", + "", NA, NA, out_path, outcomes = list(cases = "cases", deaths = "deaths", + dalys = "dalys", yll = "yll"), bypass_cert_check = TRUE ) + + upload4(out_path, "IC-Garske", "YF", "202310gavi-4", con, annex) + + + stoner::stone_stochastic_process( + con, "UND-Perkins", "YF", "202310gavi-7", + c("yf-no-vaccination", + "yf-routine-bluesky", + "yf-routine-campaign-bluesky", + "yf-routine-campaign-default", + "yf-routine-campaign-ia2030", + "yf-routine-default", + "yf-routine-ia2030"), + file.path(in_path, "YF-UND-Perkins"), + c("stochastic_burden_est_YF_UND-Perkins_yf-no_vaccination_:index.csv.xz", + "stochastic_burden_est_YF_UND-Perkins_yf-routine_bluesky_:index.csv.xz", + "stochastic_burden_est_YF_UND-Perkins_yf-routine_campaign_bluesky_:index.csv.xz", + "stochastic_burden_est_YF_UND-Perkins_yf-routine_campaign_default_:index.csv.xz", + "stochastic_burden_est_YF_UND-Perkins_yf-routine_campaign_ia2030_:index.csv.xz", + "stochastic_burden_est_YF_UND-Perkins_yf-routine_default_:index.csv.xz", + "stochastic_burden_est_YF_UND-Perkins_yf-routine_ia2030_:index.csv.xz"), + + "", 1, 200, out_path, outcomes = list(cases = "cases", deaths = "deaths", + dalys = "dalys", yll = "yll"), bypass_cert_check = TRUE ) + + upload4(out_path, "UND-Perkins", "YF", "202310gavi-7", con, annex) + + + + ###################### HPV ######################################### + + stoner::stone_stochastic_process( + con, "Harvard-Sweet", "HPV", "202310gavi-4", + c("hpv-no-vaccination", + "hpv-campaign-default", + "hpv-campaign-bluesky", + "hpv-campaign-routine-bluesky", + "hpv-campaign-routine-default", + "hpv-campaign-default_transition_hpv_1d", + "hpv-campaign-routine-default_transition_hpv_1d", + "hpv-campaign-ia2030", + "hpv-campaign-routine-ia2030"), + file.path(in_path, ""), + c("stochastic-burden-est.coverage_202310gavi-4_:scenario_run_:index Allison Portnoy.csv.xz"), + "", 1, 200, out_path, NULL, + "deaths", "cases", "dalys", "yll", bypass_cert_check = TRUE ) + + upload4(out_path, "Harvard-Sweet", "HPV", "202310gavi-4", con, annex) + + in_path <- "//fi--didenas1-app/Test/hpv-jit" + stoner::stone_stochastic_process( + con, "LSHTM-Jit", "HPV", "202310gavi-7", + c("hpv-no-vaccination", + "hpv-campaign-default", + "hpv-campaign-bluesky", + "hpv-campaign-routine-bluesky", + "hpv-campaign-routine-default", + "hpv-campaign-default_transition_hpv_1d", + "hpv-campaign-routine-default_transition_hpv_1d", + "hpv-campaign-ia2030", + "hpv-campaign-routine-ia2030"), + file.path(in_path, ""), + c("stochastic-burden-novaccination_all_202310gavi-7_hpv-no-vaccination Kaja Abbas.csv.xz", + "stochastic-burden-vaccination_all_202310gavi-7_hpv-campaign-default Kaja Abbas.csv.xz", + "stochastic-burden-vaccination_all_202310gavi-7_hpv-campaign-bluesky Kaja Abbas.csv.xz", + "stochastic-burden-vaccination_all_202310gavi-7_hpv-campaign-routine-bluesky Kaja Abbas.csv.xz", + "stochastic-burden-vaccination_all_202310gavi-7_hpv-campaign-routine-default Kaja Abbas.csv.xz", + "stochastic-burden-vaccination_all_202310gavi-7_hpv-campaign-default_transition_hpv_1d Kaja Abbas.csv.xz", + "stochastic-burden-vaccination_all_202310gavi-7_hpv-campaign-routine-default_transition_hpv_1d Kaja Abbas.csv.xz", + "stochastic-burden-vaccination_all_202310gavi-7_hpv-campaign-ia2030 Kaja Abbas.csv.xz", + "stochastic-burden-vaccination_all_202310gavi-7_hpv-campaign-routine-ia2030 Kaja Abbas.csv.xz"), + "", NA, NA, in_path, NULL, + "deaths", "cases", "dalys", "yll", bypass_cert_check = TRUE ) + + upload4(in_path, "LSHTM-Jit", "HPV", "202310gavi-7", con, annex) + + + ###################### Cholera ######################################### + + in_path <- "D:/Dropbox (SPH Imperial College)/File requests/latest/202310gavi/Cholera-IVI-Kim" + out_path <- "D:/stochastic_2023/" + stoner::stone_stochastic_process(con, + "IVI-Kim", "Cholera", "202310gavi-7", + c("cholera-no-vaccination", "cholera-ocv1-default", "cholera-ocv1-ocv2-default"), + file.path(in_path), + c("stoch_Cholera_novacc_20250704T130601 Jong-Hoon Kim.csv.xz", + "stoch_Cholera_campaign_default_ocv1_20250704T130601 Jong-Hoon Kim.csv.xz", + "stoch_Cholera_campaign_default_ocv12_20250704T130601 Jong-Hoon Kim.csv.xz"), + + "", NA, NA, out_path, NULL, bypass_cert_check = TRUE ) + upload4(out_path, "IVI-Kim", "Cholera", "202310gavi-7", con, annex) + + + in_path <- "K:/jhu-chol" + stoner::stone_stochastic_process(con, + "JHU-Lee", "Cholera", "202310gavi-7", + c("cholera-no-vaccination", "cholera-ocv1-default", "cholera-ocv1-ocv2-default"), + file.path(in_path), + c("stochastic-burden-template.202310gavi-4.Cholera_standard_template.529.no-vaccination Christina Alam.csv.xz", + "stochastic-burden-template.202310gavi-4.Cholera_standard_template.529.ocv1-default_one Christina Alam.csv.xz", + "stochastic-burden-template.202310gavi-4.Cholera_standard_template.529.ocv1-ocv2-default_two Christina Alam.csv.xz"), + "cert172 Christina Alam", NA, NA, out_path, NULL, + "deaths", "cases", "dalys", "yll", bypass_cert_check = TRUE ) + upload4(out_path, "JHU-Lee", "Cholera", "202310gavi-4", con, annex) + + + ###################### COVID ######################################### + + in_path <- "//fi--didenas1-app/Test/covid-liu" + stoner::stone_stochastic_process(con, + "LSHTM-Liu", "COVID", "202310gavi-7", + c("covid-no-vaccination", + "covid-no-vaccination_severe", + "covid-primary-bluesky", + "covid-primary-bluesky_severe", + "covid-primary-booster-bluesky", + "covid-primary-booster-bluesky_severe", + "covid-primary-booster-default", + "covid-primary-booster-default_severe", + "covid-primary-default", + "covid-primary-default_severe"), + in_path, + c("stochastic_burden_est_covid-LSHTM-Liu_covid-no-vaccination Yang Liu.csv.xz", + "stochastic_burden_est_covid-LSHTM-Liu_covid-no-vaccination_severe Yang Liu.csv.xz", + "stochastic_burden_est_covid-LSHTM-Liu_covid-primary-bluesky Yang Liu.csv.xz", + "stochastic_burden_est_covid-LSHTM-Liu_covid-primary-bluesky_severe Yang Liu.csv.xz", + "stochastic_burden_est_covid-LSHTM-Liu_covid-primary-booster-bluesky Yang Liu.csv.xz", + "stochastic_burden_est_covid-LSHTM-Liu_covid-primary-booster-bluesky_severe Yang Liu.csv.xz", + "stochastic_burden_est_covid-LSHTM-Liu_covid-primary-booster-default Yang Liu.csv.xz", + "stochastic_burden_est_covid-LSHTM-Liu_covid-primary-booster-default_severe Yang Liu.csv.xz", + "stochastic_burden_est_covid-LSHTM-Liu_covid-primary-default Yang Liu.csv.xz", + "stochastic_burden_est_covid-LSHTM-Liu_covid-primary-default_severe Yang Liu.csv.xz"), + "", NA, NA, in_path, NULL, "deaths", "cases", "dalys", "yll", bypass_cert_check = TRUE) + upload4(in_path, "LSHTM-Liu", "COVID", "202310gavi-7", con, annex) + + + in_path <- "//fi--didenas1-app/Test/cov" + stoner::stone_stochastic_process(con, + "IC-Ghani", "COVID", "202310gavi-7", + c("covid-no-vaccination", + "covid-no-vaccination_severe", + "covid-primary-bluesky", + "covid-primary-bluesky_severe", + "covid-primary-booster-bluesky", + "covid-primary-booster-bluesky_severe", + "covid-primary-booster-default", + "covid-primary-booster-default_severe", + "covid-primary-default", + "covid-primary-default_severe"), + in_path, + c("covid-no-vaccination Gemma Gilani_:index.csv.xz", + "covid-no-vaccination_severe Gemma Gilani_:index.csv.xz", + "covid-primary-bluesky Daniela Olivera_:index.csv.xz", + "covid-primary-bluesky_severe Daniela Olivera_:index.csv.xz", + "covid-primary-booster-bluesky Daniela Olivera_:index.csv.xz", + "covid-primary-booster-bluesky_severe Daniela Olivera_:index.csv.xz", + "covid-primary-booster-default Gemma Gilani_:index.csv.xz", + "covid-primary-booster-default_severe Gemma Gilani_:index.csv.xz", + "covid-primary-default Gemma Gilani_:index.csv.xz", + "covid-primary-default_severe Gemma Gilani_:index.csv.xz"), + "", 1, 200, in_path, NULL, "deaths", "cases", "dalys", "yll", bypass_cert_check = TRUE) + upload4(in_path, "IC-Ghani", "COVID", "202310gavi-7", con, annex) + + + + + ###################### Measles ######################################### + + # Updated June 2025 + + stoner::stone_stochastic_process( + con, + "PSU-Ferrari", "Measles", "202310gavi-7", + c("measles-no-vaccination", + "measles-mcv1-bluesky", + "measles-mcv1-default", + "measles-mcv1-ia2030", + "measles-mcv1-mcv2-bluesky", + "measles-mcv1-mcv2-campaign-bluesky", + "measles-mcv1-mcv2-campaign-default", + "measles-mcv1-mcv2-campaign-default_under5sia", + "measles-mcv1-mcv2-campaign-default_update", + "measles-mcv1-mcv2-campaign-ia2030", + "measles-mcv1-mcv2-default", + "measles-mcv1-mcv2-ia2030"), + file.path(in_path), + c("no-vaccination.202310gavi-6.Measles_PSU-Ferrari_standard.csv.xz", + "mcv1-bluesky.202310gavi-6.Measles_PSU-Ferrari_standard.csv.xz", + "mcv1-default.202310gavi-6.Measles_PSU-Ferrari_standard.csv.xz", + "mcv1-ia2030.202310gavi-6.Measles_PSU-Ferrari_standard.csv.xz", + "mcv1-mcv2-bluesky.202310gavi-6.Measles_PSU-Ferrari_standard.csv.xz", + "mcv1-mcv2-campaign-bluesky.202310gavi-6.Measles_PSU-Ferrari_standard.csv.xz", + "mcv1-mcv2-campaign-default.202310gavi-6.Measles_PSU-Ferrari_standard.csv.xz", + "measles-mcv1-mcv2-campaign-default_under5sia_PSU_Ferrari_Stochastic_Runs_Revised_05102025.csv.xz", + "measles-mcv1-mcv2-campaign-default_update_PSU_Ferrari_Stochastic_Runs_Revised_05102025.csv.xz", + "mcv1-mcv2-campaign-ia2030.202310gavi-6.Measles_PSU-Ferrari_standard.csv.xz", + "mcv1-mcv2-default.202310gavi-6.Measles_PSU-Ferrari_standard.csv.xz", + "mcv1-mcv2-ia2030.202310gavi-6.Measles_PSU-Ferrari_standard.csv.xz"), + "", NA, NA, out_path, bypass_cert_check = TRUE) + + upload4(out_path, "PSU-Ferrari", "Measles", "202310gavi-7", con, annex) + + + stoner::stone_stochastic_process( + con, + "LSHTM-Jit", "Measles", "202310gavi-7", + c("measles-no-vaccination", + "measles-mcv1-bluesky", + "measles-mcv1-default", + "measles-mcv1-ia2030", + "measles-mcv1-mcv2-bluesky", + "measles-mcv1-mcv2-campaign-bluesky", + "measles-mcv1-mcv2-campaign-default", + "measles-mcv1-mcv2-campaign-default_under5sia", + "measles-mcv1-mcv2-campaign-default_update", + "measles-mcv1-mcv2-campaign-ia2030", + "measles-mcv1-mcv2-default", + "measles-mcv1-mcv2-ia2030"), + in_path, + c("stochastic_burden_estimate_measles-LSHTM-Jit-no-vaccination Han Fu.csv.xz", + "stochastic_burden_estimate_measles-LSHTM-Jit-mcv1-bluesky Han Fu.csv.xz", + "stochastic_burden_estimate_measles-LSHTM-Jit-mcv1-default Han Fu.csv.xz", + "stochastic_burden_estimate_measles-LSHTM-Jit-mcv1-ia2030 Han Fu.csv.xz", + "stochastic_burden_estimate_measles-LSHTM-Jit-mcv1-mcv2-bluesky Han Fu.csv.xz", + "stochastic_burden_estimate_measles-LSHTM-Jit-mcv1-mcv2-campaign-bluesky Han Fu.csv.xz", + "stochastic_burden_estimate_measles-LSHTM-Jit-mcv1-mcv2-campaign-default.csv.xz", + "stochastic_burden_estimate_measles-LSHTM-Jit-mcv1-mcv2-campaign-default_under5sia.csv.xz", + "stochastic_burden_estimate_measles-LSHTM-Jit-mcv1-mcv2-campaign-default_update.csv.xz", + "stochastic_burden_estimate_measles-LSHTM-Jit-mcv1-mcv2-campaign-ia2030 Han Fu.csv.xz", + "stochastic_burden_estimate_measles-LSHTM-Jit-mcv1-mcv2-default Han Fu.csv.xz", + "stochastic_burden_estimate_measles-LSHTM-Jit-mcv1-mcv2-ia2030 Han Fu.csv.xz"), + "", NA, NA, out_path, bypass_cert_check = TRUE) + upload4(out_path, "LSHTM-Jit", "Measles", "202310gavi-7", con, annex) + + + ###################### Rubella ######################################### + + in_path <- "//fi--didenas1-app/Test/rub-uga" + stoner::stone_stochastic_process(con, + "JHU-Lessler", "Rubella", "202310gavi-7", + c("rubella-no-vaccination", + "rubella-campaign-default", + "rubella-campaign-bluesky", + "rubella-campaign-rcv1-rcv2-bluesky", + "rubella-campaign-rcv1-bluesky", + "rubella-campaign-rcv1-rcv2-default", + "rubella-campaign-rcv1-default", + "rubella-campaign-ia2030", + "rubella-campaign-rcv1-rcv2-ia2030", + "rubella-campaign-rcv1-ia2030"), + in_path, + c("stochastic_burden_est-rubella-no-vaccination_:index Amy Winter.csv.xz", + "stochastic_burden_est-rubella-campaign-default_:index Amy Winter.csv.xz", + "stochastic_burden_est-rubella-campaign-bluesky_:index Amy Winter.csv.xz", + "stochastic_burden_est-rubella-campaign-rcv1-rcv2-bluesky_:index Amy Winter.csv.xz", + "stochastic_burden_est-rubella-campaign-rcv1-bluesky_:index Amy Winter.csv.xz", + "stochastic_burden_est-rubella-campaign-rcv1-rcv2-default_:index Amy Winter.csv.xz", + "stochastic_burden_est-rubella-campaign-rcv1-default_:index Amy Winter.csv.xz", + "stochastic_burden_est-rubella-campaign-ia2030_:index Amy Winter.csv.xz", + "stochastic_burden_est-rubella-campaign-rcv1-rcv2-ia2030_:index Amy Winter.csv.xz", + "stochastic_burden_est-rubella-campaign-rcv1-ia2030_:index Amy Winter.csv.xz"), + "", 1, 12, in_path, NULL, + "rubella_deaths_congenital", + "rubella_cases_congenital", "dalys", "yll", bypass_cert_check = TRUE) + upload4(in_path, "JHU-Lessler", "Rubella", "202310gavi-7", con, annex) + + in_path <- "//fi--didenas1-app/Test/rub-ukhsa" + stoner::stone_stochastic_process(con, + "PHE-Vynnycky", "Rubella", "202310gavi-7", + c("rubella-no-vaccination", + "rubella-campaign-default", + "rubella-campaign-bluesky", + "rubella-campaign-rcv1-rcv2-bluesky", + "rubella-campaign-rcv1-bluesky", + "rubella-campaign-rcv1-rcv2-default", + "rubella-campaign-rcv1-default", + "rubella-campaign-ia2030", + "rubella-campaign-rcv1-rcv2-ia2030", + "rubella-campaign-rcv1-ia2030"), + in_path, + c("imp.c:indexs401.csv.xz", + "stochastic_burden_est_rubella_Vynnycky_rubella-campaign-default_:index.csv.xz", + "stochastic_burden_est_rubella_Vynnycky_rubella-campaign-bluesky_:index.csv.xz", + "Vynnycky-camp-rcv1-rcv2-bluesky_country:index.csv.xz", + "Vynnycky-camp-rcv1-bluesky_country:index.csv.xz", + "stochastic_burden_est_rubella_Vynnycky_rubella-campaign-rcv1-rcv2-default_:index.csv.xz", + "stochastic_burden_est_rubella_Vynnycky_rubella-campaign-rcv1-default_:index.csv.xz", + "stochastic_burden_est_rubella_Vynnycky_rubella-campaign-ia2030_:index.csv.xz", + "Vynnycky-camp-rcv1-rcv2-ia2030_country:index.csv.xz", + "Vynnycky-camp-rcv1-ia2030_country:index.csv.xz"), + "", 1, 117, in_path, NULL, + "rubella_deaths_congenital", + "rubella_cases_congenital", "dalys", "yll", bypass_cert_check = TRUE) + upload4(in_path, "PHE-Vynnycky", "Rubella", "202310gavi-7", con, annex) + + + + ###################### Typhoid ######################################### + + in_path <- "//fi--didenas1-app/Test/ivi-typhoid" + stoner::stone_stochastic_process(con, "IVI-Kim", "Typhoid", "202310gavi-7", + c("typhoid-no-vaccination", + "typhoid-campaign-default", "typhoid-campaign-routine-default", + "typhoid-campaign-bluesky", "typhoid-campaign-routine-bluesky"), + in_path, + c("stoch_Typhoid_novacc_20240314T233526 Jong-Hoon Kim.csv.xz", + "stoch_Typhoid_campaign_default_20240314T233526 Jong-Hoon Kim.csv.xz", + "stoch_Typhoid_campaign_routine_default_20240314T233526 Jong-Hoon Kim.csv.xz", + "stoch_Typhoid_campaign_bluesky_20240314T233526 Jong-Hoon Kim.csv.xz", + "stoch_Typhoid_campaign_routine_bluesky_20240314T233526 Jong-Hoon Kim.csv.xz"), + "", NA, NA, in_path, bypass_cert_check = TRUE) + upload4(in_path, "IVI-Kim", "Typhoid", "202310gavi-7", con, annex) + + + ###################### Malaria R2 ######################################### + + in_path <- "//fi--didenas1-app/Test/uac-malaria" + stoner::stone_stochastic_process(con, "UAC-Glele_Kakai", "Malaria", "202310gavi-7", + c("malaria-no-vaccination", + "malaria-rts3-default", "malaria-rts3-rts4-default", + "malaria-rts3-bluesky", "malaria-rts3-rts4-bluesky" + ), + in_path, + c("Stochastic_Burden_Estimates_Glele_Kakai_No_Vaccine_:index.csv.xz", + "Stochastic_Burden_Estimates_Glele_Kakai_Default_rts3_:index.csv.xz", + "Stochastic_Burden_Estimates_Glele_Kakai_Default_rts3_4_:index.csv.xz", + "stochastic_Burden_Estimates_Glele_Kakai_Blue_Sky_rts3_:index.csv.xz", + "Stochastic_Burden_Estimates_Glele_Kakai_Blue_Sky_rts34_:index.csv.xz"), + "", 1, 200, in_path, bypass_cert_check = TRUE) + + upload4(in_path, "UAC-Glele_Kakai", "Malaria", "202310gavi-7", con, annex) + + in_path <- "//fi--didenas1-app/Test/mal" + stoner::stone_stochastic_process(con, "IC-Okell", "Malaria", "202310gavi-7", + c("malaria-no-vaccination", + "malaria-rts3-default", "malaria-rts3-rts4-default", + "malaria-rts3-bluesky", "malaria-rts3-rts4-bluesky" + ), + in_path, + c("stochastic-burden-est.202310gavi-7.Malaria_IC-Okell_no-vaccination_draw_:index Lydia Haile.csv.xz", + "stochastic-burden-est.202310gavi-7.Malaria_IC-Okell_malaria-rts3-default_draw_:index Lydia Haile.csv.xz", + "stochastic-burden-est.202310gavi-7.Malaria_IC-Okell_malaria-rts3-rts4-default_draw_:index Lydia Haile.csv.xz", + "stochastic-burden-est.202310gavi-7.Malaria_IC-Okell_malaria-rts3-bluesky_draw_:index Lydia Haile.csv.xz", + "stochastic-burden-est.202310gavi-7.Malaria_IC-Okell_malaria-rts3-rts4-bluesky_draw_:index Lydia Haile.csv.xz" + ), + "", 1, 200, in_path, bypass_cert_check = TRUE) + upload4(in_path, "IC-Okell", "Malaria", "202310gavi-7", con, annex) + + + + in_path <- "//fi--didenas1-app/Test/tki" + stoner::stone_stochastic_process(con, "TKI-Penny", "Malaria", "202310gavi-7", + c("malaria-no-vaccination", + "malaria-rts3-default", "malaria-rts3-rts4-default", + "malaria-rts3-bluesky", "malaria-rts3-rts4-bluesky" + ), + in_path, + c("stochastic_burden_est_malaria_:index_novaccine Josephine Malinga.csv.xz", + "stochastic_burden_est_malaria_:index_rtss_d3_default Josephine Malinga.csv.xz", + "stochastic_burden_est_malaria_:index_rtss_d4_default Josephine Malinga.csv.xz", + "stochastic_burden_est_malaria_:index_rtss_d3_bluesky Josephine Malinga.csv.xz", + "stochastic_burden_est_malaria_:index_rtss_d4_bluesky Josephine Malinga.csv.xz"), + "", 1, 31, in_path, bypass_cert_check = TRUE) + upload4(in_path, "TKI-Penny", "Malaria", "202310gavi-7", con, annex) + + + ################################################################ + # MENA + # NB - mena-campaign-default and mena-campaign-ia2030 are identical, + # so same file used below. + + in_path <- "//fi--didenas1-app/Test/MenA" + out_path <- in_path + + + stub <- "stochastic-burden-template202310gavi-7MenA_Cambridge-Trotter_mena-" + stoner::stone_stochastic_process(con, + "Cambridge-Trotter", "MenA", "202310gavi-7", + c("mena-no-vaccination", "mena-campaign-default", "mena-campaign-routine-default", + "mena-campaign-bluesky", "mena-campaign-routine-bluesky", + "mena-campaign-ia2030", "mena-campaign-routine-ia2030"), + in_path, + c(paste0(stub, "novaccination (:index) Andromachi Karachaliou.csv"), + paste0(stub, "campaign-default (:index) Andromachi Karachaliou.csv"), + paste0(stub, "routine-default (:index) Andromachi Karachaliou.csv"), + paste0(stub, "campaign-bluesky (:index) Andromachi Karachaliou.csv"), + paste0(stub, "routine-bluesky (:index) Andromachi Karachaliou.csv"), + paste0(stub, "campaign-default (:index) Andromachi Karachaliou.csv"), + paste0(stub, "routine-ia2030 (:index) Andromachi Karachaliou.csv")), + "", 1, 26, out_path, outcomes = list(cases = "cases", deaths = "deaths", + dalys = "dalys", yll = "yll", cases_cwyx = "cases_cwyx", + deaths_cwyx = "deaths_cwyx", dalys_cwyx = "dalys_cwyx", yll_cwyx = "yll_cwyx"), + bypass_cert_check = TRUE) + upload4(in_path, "Cambridge-Trotter", "MenA", "202310gavi-7", con, annex) + +} + +do_stochastics_2021 <- function(con) { + out_path <- "E:/stochastic_2023/" + in_path <- "E:/Dropbox (SPH Imperial College)/File requests/latest/202110gavi/" + + + stub <- "Andromachi Karachaliou - stochastic-burden.202110gavi-2.MenA_Cambridge-Trotter_" + stone_stochastic_process(con, + "Cambridge-Trotter", "MenA", "202110gavi-3", + c("mena-no-vaccination", "mena-campaign-default", "mena-routine-default", + "mena-booster-default", "mena-campaign-ia2030_target", + "mena-routine-ia2030_target"), + file.path(in_path, "Cambridge-Trotter"), + c(paste0(stub, "no_vaccination_:index.csv.xz"), + paste0(stub, "campaign_default_:index.csv.xz"), + paste0(stub, "routine_default_:index.csv.xz"), + paste0(stub, "booster_:index.csv.xz"), + paste0(stub, "campaign-ia2030_target_:index.csv.xz"), + paste0(stub, "routine-ia2030_target_:index.csv.xz")), + "", 1, 26, out_path, bypass_cert_check = TRUE) + + ############################################################################# + + stub <- "Aniruddha Deshpande - stochastic_burden_est_lopman_" + stone_stochastic_process(con, + "Emory-Lopman", "Rota", "202110gavi-3", + c("rota-no-vaccination", + "rota-routine-default", + "rota-routine-ia2030_target"), + file.path(in_path, "Emory-Lopman"), + c(paste0(stub, "no_vaccination_2022_01_31.csv.xz"), + paste0(stub, "routine_2022_01_31.csv.xz"), + paste0(stub, "ia2030_target_2022_01_31.csv.xz")), + "", NA, NA, out_path, allow_missing_disease = TRUE, bypass_cert_check = TRUE) + + ############################################################################# + + stub <- "Allison Portnoy - stochastic-burden-est." + stone_stochastic_process(con, + "Harvard-Sweet", "HPV", "202110gavi-3", + c("hpv-no-vaccination", + "hpv-campaign-default", + "hpv-campaign-ia2030_target", + "hpv-routine-default", + "hpv-routine-ia2030_target"), + in_path, + c(paste0(stub, "novacc_run_:index.csv.xz"), + paste0(stub, "coverage_202110gavi-3_hpv-campaign-default_run_:index.csv.xz"), + paste0(stub, "coverage_202110gavi-3_hpv-campaign-ia2030_target_run_:index.csv.xz"), + paste0(stub, "coverage_202110gavi-3_hpv-routine-default_run_:index.csv.xz"), + paste0(stub, "coverage_202110gavi-3_hpv-routine-ia2030_target_run_:index.csv.xz")), + "", 1, 200, out_path, + runid_from_file = TRUE, bypass_cert_check = TRUE) + + ############################################################################# + + stub <- "Keith Fraser - stochastic-burden-estimates.202110gavi-3_YF_IC-Garske_" + stoner::stone_stochastic_process(con, + "IC-Garske", "YF", "202110gavi-3", + c("yf-no-vaccination", + "yf-preventive-default", + "yf-preventive-ia2030_target", + "yf-routine-default", + "yf-routine-ia2030_target"), + file.path(in_path, "IC-Garske-YF"), + paste0(stub, ":scenario_:index.csv.xz"), + "", 1, 200, out_path, bypass_cert_check = TRUE) + + ############################################################################# + + stone_stochastic_process(con, "IVI-Kim", "Typhoid", "202110gavi-3", + c("typhoid-no-vaccination", + "typhoid-campaign-default", "typhoid-campaign-ia2030_target", + "typhoid-routine-default", "typhoid-routine-ia2030_target"), + in_path, + c("Jong-Hoon Kim - stoch_Typhoid_novacc_20211217T1.csv.xz", + "Jong-Hoon Kim - stoch_Typhoid_campaign-default_20211217T1.csv.xz", + "Jong-Hoon Kim - stoch_Typhoid_campaign-ia2030_20211217T1.csv.xz", + "Jong-Hoon Kim - stoch_Typhoid_routine-default_20211217T1.csv.xz", + "Jong-Hoon Kim - stoch_Typhoid_routine-ia2030_20211217T1.csv.xz"), + "", NA, NA, out_path, bypass_cert_check = TRUE) + + ##################################################### + + stub <- "stochastic_burden_est_HepB-IC-Hallett_" + stone_stochastic_process(con, + "IC-Hallett", "HepB", "202110gavi-3", + c("hepb-bd-default-hepb-routine-default", + "hepb-bd-routine-default", + "hepb-bd-routine-ia2030_target-hepb-routine-ia2030_target", + "hepb-bd-routine-ia2030_target", + "hepb-hepb-routine-default", + "hepb-hepb-routine-ia2030_target", + "hepb-no-vaccination"), + in_path, + paste0(stub, ":scenario_:index.csv.xz"), + "Margaret de Villiers - cert115", 1, 200, out_path, + "deaths", c("hepb_cases_acute_severe","hepb_cases_comp_cirrh", + "hepb_cases_hcc_no_cirrh"), "dalys") + + ############################################################################# + + stoner::stone_stochastic_process(con, + "IVI-Kim", "Cholera", "202110gavi-3", + c("cholera-no-vaccination", "cholera-campaign-default"), + file.path(in_path, "IVI-Kim-Cholera"), + c("Jong-Hoon Kim - stoch_Cholera_novacc_20211221T00.csv.xz", + "Jong-Hoon Kim - stoch_Cholera_campaign_20211222T212131.csv.xz"), + "", NA, NA, out_path, bypass_cert_check = TRUE) + + ############################################################################# + + stone_stochastic_process(con, + "JHU-Lee", "Cholera", "202110gavi-3", + c("cholera-no-vaccination", "cholera-campaign-default"), + file.path(in_path, "JHU-Lee-Cholera"), + c("Kaiyue Zou - no-vaccination.csv.xz", + "Kaiyue Zou - campaign-default.csv.xz"), + "", NA, NA, out_path, bypass_cert_check = TRUE) + + ############################################################################# + + + stub <- "Amy Winter - stochastic_burden_est-rubella-" + stone_stochastic_process(con, + "JHU-Lessler", "Rubella", "202110gavi-3", + c("rubella-routine-no-vaccination", + "rubella-campaign-default", + "rubella-rcv1-default", + "rubella-rcv2-default", + "rubella-rcv1-rcv2-default", + "rubella-campaign-ia2030_target", + "rubella-rcv1-ia2030_target", + "rubella-rcv2-ia2030_target", + "rubella-rcv1-rcv2-ia2030_target"), + in_path, + c(paste0(stub, "routine-no-vaccination_:index.csv.xz"), + paste0(stub, "campaign-default_:index.csv.xz"), + paste0(stub, "rcv1-default_:index.csv.xz"), + paste0(stub, "rcv2-default_:index.csv.xz"), + paste0(stub, "rcv1-rcv2-default_:index.csv.xz"), + paste0(stub, "campaign-ia2030_target_:index.csv.xz"), + paste0(stub, "rcv1-ia2030_target_:index.csv.xz"), + paste0(stub, "rcv2-ia2030_target_:index.csv.xz"), + paste0(stub, "rcv1-rcv2-ia2030_target_:index.csv.xz")), + "", 1, 11, out_path, + "rubella_deaths_congenital", + "rubella_cases_congenital", "dalys", bypass_cert_check = TRUE) + + ############################################################################# + + list_params_hib_pcv <- data.frame( + outcome = c("cases_men", "cases_men", "cases_men", "cases_men", "cases_men", + "cases_pneumo", "cases_pneumo", "deaths_men", "deaths_pneumo"), + proportion = c(1, 0.014, 0.045, 0.021, 0.017, 1, 0.06, 1, 1), + average_duration = c(0.04,1000,1000,1000,1000,0.02,1000,1000,1000), + disability_weight = c(0.133, 0.043, 0.027, 0.552, 0.61, 0.051, 0.019, 1, 1) + ) + + hib_scenarios <- c("hib-no-vaccination-LiST", + "hib-routine-default-LiST", + "hib-routine-ia2030_target-LiST") + + stone_stochastic_process(con, + "JHU-Tam", "Hib", "202110gavi-3", + hib_scenarios, + file.path(in_path, "JHU-Tam-Carter-Hib"), ":scenario.csv.xz", + "", NA, NA, out_path, + outcomes <- list(deaths = c("deaths_men", "deaths_pneumo"), + cases = c("cases_men", "cases_pneumo"), + dalys = list_params_hib_pcv), + bypass_cert_check = TRUE) + + # And to sort out DALYs on the centrals: + + for (hib_scenario in hib_scenarios) { + stoner::stoner_dalys_for_db(con, list_params_hib_pcv, "JHU-Tam", + "Hib", "202110gavi-3", hib_scenario, + output_file = file.path(out_path, sprintf("%s_central_dalys.csv", + hib_scenario))) + } + + pcv_scenarios <- c("pcv-no-vaccination-LiST", + "pcv-routine-default-LiST", + "pcv-routine-ia2030_target-LiST") + + stone_stochastic_process(con, + "JHU-Tam", "PCV", "202110gavi-3", + pcv_scenarios, + file.path(in_path, "JHU-Tam-Carter-PCV"), ":scenario.csv.xz", + "", NA, NA, out_path, + deaths = c("deaths_men", "deaths_pneumo"), + cases = c("cases_men", "cases_pneumo"), + dalys = list_params_hib_pcv, + bypass_cert_check = TRUE) + + # And to sort out DALYs on the centrals: + + for (pcv_scenario in pcv_scenarios) { + stoner::stoner_dalys_for_db(con, list_params_hib_pcv, "JHU-Tam", + "PCV", "202110gavi-3", pcv_scenario, + output_file = file.path(out_path, sprintf("%s_central_dalys.csv", + pcv_scenario))) + } + + + list_params_rota <- data.frame( + outcome = c("cases", "deaths"), + proportion = c(1, 1), + average_duration = c(0.01, 1000), + disability_weight = c(0.247, 1) + ) + + rota_scenarios <- c("rota-no-vaccination-LiST", + "rota-routine-default-LiST", + "rota-routine-ia2030_target-LiST") + + stone_stochastic_process(con, + "JHU-Tam", "Rota", "202110gavi-3", + rota_scenarios, + file.path(in_path, "JHU-Tam-Carter-Rota"), ":scenario.csv.xz", + "", NA, NA, out_path, + dalys = list_params_rota, + bypass_cert_check = TRUE) + + + # And to sort out DALYs on the centrals: + + for (rota_scenario in rota_scenarios) { + stoner::stoner_dalys_for_db(con, list_params_rota, "JHU-Tam", + "Rota", "202110gavi-3", rota_scenario, + output_file = file.path(out_path, sprintf("%s_central_dalys.csv", + rota_scenario))) + } + + #################################################################################### + + stub <- "Eric Johnson - " + stone_stochastic_process(con, + "KPW-Jackson", "MenA", "202110gavi-3", + c("mena-booster-default", + "mena-campaign-default", + "mena-campaign-ia2030_target", + "mena-no-vaccination", + "mena-routine-default", + "mena-routine-ia2030_target"), + file.path(in_path, "KPW-Jackson-MenA"), + paste0(stub, ":scenario-202111gavi-2.MenA_KPW-Johnson.csv.xz"), + "", NA, NA, out_path, bypass_cert_check = TRUE) + + ############################################################################# + + stoner::stone_stochastic_process(con, + "Li", "HepB", "202110gavi-2", + c( "hepb-bd-default-hepb-routine-default", + "hepb-bd-routine-default", + "hepb-bd-routine-ia2030_target-hepb-routine-ia2030_target", + "hepb-bd-routine-ia2030_target", + "hepb-hepb-routine-default", + "hepb-hepb-routine-ia2030_target", + "hepb-no-vaccination" + + ), + file.path(in_path, "Li"), + paste0(":scenario:index.csv"), + "cert105", 1, 200, out_path, + c("hepb_deaths_acute", "hepb_deaths_total_cirrh", "hepb_deaths_hcc"), + c("hepb_cases_acute_symp", "hepb_cases_fulminant", + "hepb_cases_chronic", "hepb_chronic_symptomatic_in_acute_phase"), + "dalys" + ) + + ############################################################################# + + stub <- "Kaja Abbas - PSA_202110gavi-3_" + stone_stochastic_process(con, + "LSHTM-Clark", "Hib", "202110gavi-3", + c("hib-no-vaccination","hib-routine-default","hib-routine-ia2030_target"), + file.path(in_path, "LSHTM-Clark_Hib"), + c(paste0(stub, ":scenario.csv.xz")), + "Kaja Abbas - hib_cert116", NA, NA, out_path) + + ############################################################################# + + + stub <- "Kaja Abbas - PSA_202110gavi-3_" + stone_stochastic_process(con, + "LSHTM-Clark", "Rota", "202110gavi-3", + c("rota-no-vaccination","rota-routine-default","rota-routine-ia2030_target"), + file.path(in_path, "LSHTM-Clark_Rota"), + c(paste0(stub, ":scenario.csv.xz")), + "Kaja Abbas - rota_cert117", NA, NA, out_path) + + ############################################################################# + + + stub <- "stochastic-burden-" + stoner::stone_stochastic_process(con, + "LSHTM-Jit", "HPV", "202110gavi-3", + c("hpv-no-vaccination", + "hpv-campaign-default", + "hpv-routine-default", + "hpv-campaign-ia2030_target", + "hpv-routine-ia2030_target"), + "E:/Dropbox (SPH Imperial College)/File requests/latest/202110gavi/LSHTM-Jit_HPV", + c(paste0(stub, "novaccination_all_202110gavi-3_hpv-no-vaccination.csv.xz"), + paste0(stub, "vaccination_all_202110gavi-3_hpv-campaign-default.csv.xz"), + paste0(stub, "vaccination_all_202110gavi-3_hpv-routine-default.csv.xz"), + paste0(stub, "vaccination_all_202110gavi-3_hpv-campaign-ia2030_target.csv.xz"), + paste0(stub, "vaccination_all_202110gavi-3_hpv-routine-ia2030_target.csv.xz")), + "cert104", NA, NA, out_path, bypass_cert_check = TRUE) + + ############################################################################# + + stub <- "Han Fu - stochastic_burden_estimate_measles-LSHTM-Jit-" + stone_stochastic_process(con, "LSHTM-Jit", "Measles", "202110gavi-2", + c("measles-no-vaccination", + "measles-campaign-default", + "measles-campaign-only-default", + "measles-mcv1-default", + "measles-mcv2-default", + "measles-campaign-ia2030_target", + "measles-campaign-only-ia2030_target", + "measles-mcv1-ia2030_target", + "measles-mcv2-ia2030_target"), + file.path(in_path, "LSHTM-Jit_Measles"), + c(paste0(stub, "no-vaccination.csv.xz"), + paste0(stub, "campaign-default.csv.xz"), + paste0(stub, "campaign-only-default.csv.xz"), + paste0(stub, "mcv1-default.csv.xz"), + paste0(stub, "mcv2-default.csv.xz"), + paste0(stub, "campaign-ia2030_target.csv.xz"), + paste0(stub, "campaign-only-ia2030_target.csv.xz"), + paste0(stub, "mcv1-ia2030_target.csv.xz"), + paste0(stub, "mcv2-ia2030_target.csv.xz")), + "Han Fu - cert107", NA, NA, out_path) + + ############################################################################# + + stub <- "stochastic_burden_est_" + stone_stochastic_process(con, + "NUS-Chen", "PCV", "202110gavi-3", + c("pcv-no-vaccination","pcv-routine-default","pcv-routine-ia2030_target"), + file.path(in_path, "LSHTM-NUS-Chen_PCV"), + paste0(stub, ":scenario.csv.xz"), + "Jemima Koh - cert121", NA, NA, "E:/Stochastic_2021") + + + + stoner::stone_stochastic_process(con, + "PHE-Vynnycky", "Rubella", "202110gavi-3", + c("rubella-routine-no-vaccination", + "rubella-campaign-default", + "rubella-rcv1-default", + "rubella-rcv2-default", + "rubella-rcv1-rcv2-default", + "rubella-campaign-ia2030_target", + "rubella-rcv1-ia2030_target", + "rubella-rcv2-ia2030_target", + "rubella-rcv1-rcv2-ia2030_target"), + file.path(in_path, "PHE-Vynnycky_Rubella"), + c("VIMC_NV_RCV1RCV2Camp_country:index.csv.xz", + "VIMC_DF_Camp_country:index.csv.xz", + "VIMC_DF_RCV1Camp_country:index.csv.xz", + "VIMC_DF_RCV1RCV2Camp_country:index.csv.xz", + "VIMC_DF_RCV1RCV2_country:index.csv.xz", + "VIMC_IA_Camp_country:index.csv.xz", + "VIMC_IA_RCV1Camp_country:index.csv.xz", + "VIMC_IA_RCV1RCV2Camp_country:index.csv.xz", + "VIMC_IA_RCV1RCV2_country:index.csv.xz"), + "", 1, 112, out_path, + "rubella_deaths_congenital", + "rubella_cases_congenital", "dalys", bypass_cert_check = TRUE) + + ############################################################################# + + stub <- "Sean Moore - stochastic_burden_est_JE_UND-Moore_" + stone_stochastic_process(con, + "UND-Moore", "JE", "202110gavi-2", + c("je-routine-no-vaccination", + "je-campaign-default", + "je-routine-default", + "je-campaign-ia2030_target", + "je-routine-ia2030_target" + ), + file.path(in_path, "UND-Moore-JE"), + paste0(stub, ":scenario.csv.xz"), + "Sean Moore - cert108", NA, NA, out_path) + + stub <- "stochastic_burden_est_YF_UND-Perkins_" + stoner::stone_stochastic_process(con, + "UND-Perkins", "YF", "202110gavi-3", + c("yf-no-vaccination", + "yf-preventive-default", + "yf-preventive-ia2030_target", + "yf-routine-default", + "yf-routine-ia2030_target"), + file.path(in_path, "UND-Perkins-YF"), + paste0(stub, ":scenario_:index.csv.xz"), + "", 1, 200, out_path, bypass_cert_check = TRUE) + + stub <- "Holly Burrows - stochastic_burden_est_TF-Yale-Burrows" + stone_stochastic_process(con, + "Yale-Pitzer", "Typhoid", "202110gavi-3", + c("typhoid-no-vaccination", + "typhoid-campaign-default", "typhoid-campaign-ia2030_target", + "typhoid-routine-default", "typhoid-routine-ia2030_target"), + file.path(in_path, "Yale-Pitzer-Typhoid"), + c(paste0(stub, "-novacc_202110.csv.xz"), + paste0(stub, "_campaign-default_202110.csv.xz"), + paste0(stub, "_campaign-IA2030_202110.csv.xz"), + paste0(stub, "_routine-default_202110.csv.xz"), + paste0(stub, "_routine-IA2030_202110.csv.xz")), + "", NA, NA, out_path, bypass_cert_check = TRUE) + + + upload4(out_path, "Cambridge-Trotter", "MenA", "202110gavi-3", con, annex) + upload4(out_path, "Emory-Lopman", "Rota", "202110gavi-3", con, annex) + upload4(out_path, "IC-Garske", "YF", "202110gavi-3", con, annex) + upload4(out_path, "IC-Hallett", "HepB", "202110gavi-3", con, annex) + upload4(out_path, "IVI-Kim", "Cholera", "202110gavi-3", con, annex) + upload4(out_path, "IVI-Kim", "Typhoid", "202110gavi-3", con, annex) + upload4(out_path, "JHU-Lee", "Cholera", "202110gavi-3", con, annex) + upload4(out_path, "JHU-Lessler", "Rubella", "202110gavi-3", con, annex) + upload4(out_path, "JHU-Tam", "Hib", "202110gavi-3", con, annex) + upload4(out_path, "JHU-Tam", "PCV", "202110gavi-3", con, annex) + upload4(out_path, "JHU-Tam", "Rota", "202110gavi-3", con, annex) + upload4(out_path, "Li", "HepB", "202110gavi-2", con, annex) + upload4(out_path, "LSHTM-Clark", "Hib", "202110gavi-3", con, annex) + upload4(out_path, "LSHTM-Clark", "Rota", "202110gavi-3", con, annex) + upload4(out_path, "LSHTM-Jit", "HPV", "202110gavi-3", con, annex) + upload4(out_path, "LSHTM-Jit", "Measles", "202110gavi-2", con, annex) + upload4(out_path, "NUS-Chen", "PCV", "202110gavi-3", con, annex) + upload4(out_path, "PHE-Vynnycky", "Rubella", "202110gavi-2", con, annex) + upload4(out_path, "UND-Moore", "JE", "202110gavi-3", con, annex) + upload4(out_path, "UND-Perkins", "YF", "202110gavi-3", con, annex) + upload4(out_path, "Yale-Pitzer", "Typhoid", "202110gavi-3", con, annex) + + + +} + +do_stochastics_2019 <- function() { + in_path <- "E:/Dropbox (SPH Imperial College)/File requests/latest/201910gavi" + out_path <- "E:/Stocastic_2019" + + ############################################################################# + + stub <- "Andromachi Karachaliou - stochastic-burden.201910gavi-4.MenA_Cambridge-Trotter_" + stone_stochastic_process(con, + "Cambridge-Trotter", "MenA", "201910gavi-5", + c("mena-campaign-bestcase", "mena-campaign-default", "mena-no-vaccination", + "mena-routine-bestcase", "mena-routine-default"), + file.path(in_path, "Cambridge-Trotter"), + c(paste0(stub, "campaign-bestcase_:index.csv.xz"), + paste0(stub, "campaign-default_:index.csv.xz"), + paste0(stub, "no-vaccination_:index.csv.xz"), + paste0(stub, "routine-bestcase_:index.csv.xz"), + paste0(stub, "routine-default_:index.csv.xz")), + "cert60", 1, 52, out_path) + + ############################################################################# + + stub <- "Ivane Gamkrelidze - stochastic-burden-template.201910gavi-4.HepB_CDA-Razavi_" + stone_stochastic_process(con, + "CDA-Razavi", "HepB", "201910gavi-5", + c("hepb-bd-default-hepb-routine-default", + "hepb-bd-routine-bestcase-hepb-routine-bestcase", + "hepb-no-vaccination", + "hepb-stop", + "hepb-bd-routine-bestcase", + "hepb-bd-routine-default", + "hepb-hepb-routine-bestcase", + "hepb-hepb-routine-default" + ), + file.path(in_path, "CDA-Razavi"), + c(paste0(stub, "all_:scenario.csv.xz"), + paste0(stub, "all_:scenario.csv.xz"), + paste0(stub, "all_:scenario.csv.xz"), + paste0(stub, "all_:scenario.csv.xz"), + paste0(stub, "bd_:scenario.csv.xz"), + paste0(stub, "bd_:scenario.csv.xz"), + paste0(stub, "non_bd_:scenario.csv.xz"), + paste0(stub, "non_bd_:scenario.csv.xz")), + "Ivane Gamkrelidze - cert68", NA, NA, out_path, + c("hepb_deaths_acute","hepb_deaths_dec_cirrh","hepb_deaths_hcc"), + c("hepb_cases_acute_severe","hepb_cases_dec_cirrh","hepb_cases_hcc"), + "dalys" + ) + + ############################################################################# + + stub <- "Molly Steele - stochastic-burden.201910gavi-4.Rota_Emory-Lopman_" + stone_stochastic_process(con, + "Emory-Lopman", "Rota", "201910gavi-5", + c("rota-no-vaccination", + "rota-routine-bestcase", + "rota-routine-default"), + file.path(in_path, "Emory-Lopman"), + paste0(stub, ":scenario.csv.xz"), + "Molly Steele - cert66", NA, NA, out_path, + allow_missing_disease = TRUE) + + ############################################################################# + + stub <- "stochastic-burden-est.201910gavi-5.HPV_Harvard-Sweet_" + stone_stochastic_process(con, + "Harvard-Sweet", "HPV", "201910gavi-5", + c("hpv-campaign-bestcase", + "hpv-campaign-default", + "hpv-no-vaccination", + "hpv-routine-bestcase", + "hpv-routine-default"), + file.path(in_path, "Harvard-Sweet"), + c(paste0(stub, "campaign-bestcase_run_:index.csv.xz"), + paste0(stub, "campaign-default_run_:index.csv.xz"), + paste0(stub, "novacc_run_:index.csv.xz"), + paste0(stub, "routine-bestcase_run_:index.csv.xz"), + paste0(stub, "routine-default_run_:index.csv.xz")), + "", 1, 200, out_path, + runid_from_file = TRUE, bypass_cert_check = TRUE) + + ############################################################################# + + stub <- "stochastic-burden-estimates.201910gavi-4_YF_IC-Garske_" + stone_stochastic_process(con, + "IC-Garske", "YF", "201910gavi-5", + c("yf-no-vaccination", + "yf-preventive-bestcase", + "yf-preventive-default", + "yf-routine-bestcase", + "yf-routine-default", + "yf-stop"), + file.path(in_path, "IC-Garske2"), + paste0(stub, ":scenario_:index.csv.xz"), + "Katy Gaythorpe - cert62", 1, 200, out_path) + + ############################################################################# + + stub <- "stochastic_burden_est_HepB-IC-Hallett_" + stone_stochastic_process(con, + "IC-Hallett", "HepB", "201910gavi-5", + c("hepb-bd-default-hepb-routine-default", + "hepb-bd-routine-bestcase-hepb-routine-bestcase", + "hepb-no-vaccination", + "hepb-stop", + "hepb-bd-routine-bestcase", + "hepb-bd-routine-default", + "hepb-hepb-routine-bestcase", + "hepb-hepb-routine-default"), + file.path(in_path, "IC-Hallett"), + paste0(stub, ":scenario_:index.csv.xz"), + "Margaret de Villiers - cert73", 1, 200, out_path, + "deaths", c("hepb_cases_acute_severe","hepb_cases_comp_cirrh", + "hepb_cases_hcc_no_cirrh"), "dalys") + + ############################################################################# + + stone_stochastic_process(con, + "IVI-Kim", "Cholera", "201910gavi-5", + c("cholera-no-vaccination", "cholera-campaign-default"), + file.path(in_path, "IVI-Kim-Cholera"), + c("Jong-Hoon Kim - stoch_output_Cholera_novacc_20210902.csv.xz", + "Jong-Hoon Kim - stoch_output_Cholera_campaign_20210902.csv.xz"), + "Jong-Hoon Kim - cert89", NA, NA, out_path) + + ############################################################################# + + stone_stochastic_process(con, + "IVI-Kim", "Typhoid", "201910gavi-5", + c("typhoid-no-vaccination", "typhoid-campaign-default", "typhoid-routine-default"), + file.path(in_path, "IVI-Kim-Typhoid"), + c("Jong-Hoon Kim - stoch_Typhoid_novacc.csv.xz", + "Jong-Hoon Kim - stoch_Typhoid_campaign.csv.xz", + "Jong-Hoon Kim - stoch_Typhoid_routine.csv.xz"), + "Jong-Hoon Kim - cert90", NA, NA, out_path) + + ############################################################################# + + stub <- "Amy Winter - stochastic_burden_est-" + stone_stochastic_process(con, + "JHU-Lessler", "Rubella", "201910gavi-5", + c("rubella-campaign-bestcase", + "rubella-campaign-default", + "rubella-routine-no-vaccination", + "rubella-rcv1-bestcase", + "rubella-rcv1-default", + "rubella-rcv1-rcv2-bestcase", + "rubella-rcv1-rcv2-default", + "rubella-rcv2-bestcase", + "rubella-rcv2-default", + "rubella-stop"), + file.path(in_path, "JHU-Lessler"), + c(rep(paste0(stub, ":scenario_:index.csv.xz"), 2), + paste0(stub, "rubella-no-vaccination_:index.csv.xz"), + rep(paste0(stub, ":scenario_:index.csv.xz"), 7)), + "Amy Winter - cert70", 1, 12, out_path, + "rubella_deaths_congenital", + "rubella_cases_congenital", "dalys") + + ############################################################################# + + stub <- "Michael Jackson - stochastic_burden_est_MenA_KPWA_" + stone_stochastic_process(con, + "KPW-Jackson", "MenA", "201910gavi-5", + c("mena-routine-bestcase", + "mena-routine-default", + "mena-campaign-bestcase", + "mena-campaign-default", + "mena-no-vaccination"), + file.path(in_path, "KPW-Jackson"), + c(paste0(stub, "both_bestcase_:index.csv.xz"), + paste0(stub, "both_default_:index.csv.xz"), + paste0(stub, "campaign_bestcase_:index.csv.xz"), + paste0(stub, "campaign_default_:index.csv.xz"), + paste0(stub, "none_default_:index.csv.xz")), + "cert61", 1, 26, out_path) + + ############################################################################# + + stone_stochastic_process(con, + "JHU-Lee", "Cholera", "201910gavi-5", + c("cholera-no-vaccination", "cholera-campaign-default"), + file.path(in_path, "JHU-Lee"), + c("Kaiyue Zou - stochastic-burden-template.201910gavi-5.Cholera_no-vaccination.csv.xz", + "Kaiyue Zou - stochastic-burden-template.201910gavi-5.Cholera_campaign-default.csv.xz"), + "", NA, NA, out_path, bypass_cert_check = TRUE) + + ############################################################################# + + list_params_hib_pcv <- data_frame( + outcome = c("cases_men", "cases_men", "cases_men", "cases_men", "cases_men", + "cases_pneumo", "cases_pneumo", "deaths_men", "deaths_pneumo"), + proportion = c(1, 0.014, 0.045, 0.021, 0.017, 1, 0.06, 1, 1), + average_duration = c(0.04,1000,1000,1000,1000,0.02,1000,1000,1000), + disability_weight = c(0.133, 0.043, 0.027, 0.552, 0.61, 0.051, 0.019, 1, 1) + ) + + stone_stochastic_process(con, + "JHU-Tam", "Hib", "201910gavi-5", + c("hib-no-vaccination-LiST", "hib-routine-default-LiST", "hib-routine-bestcase-LiST"), + file.path(in_path, "JHU-Tam-Hib"), + c("novac:index.csv.xz", "default:index.csv.xz", "best:index.csv.xz"), + "", 1, 14, out_path, + deaths = c("deaths_men", "deaths_pneumo"), + cases = c("cases_men", "cases_pneumo"), + dalys = list_params_hib_pcv, + bypass_cert_check = TRUE) + + # And to add DALYs to the existing + + stone_stochastic_process(con, + "JHU-Tam", "PCV", "201910gavi-5", + c("pcv-no-vaccination-LiST", "pcv-routine-default-LiST", "pcv-routine-bestcase-LiST"), + file.path(in_path, "JHU-Tam-PCV"), + c("novac:index.csv.xz", "default:index.csv.xz", "best:index.csv.xz"), + "", 1, 14, out_path, + deaths = c("deaths_men", "deaths_pneumo"), + cases = c("cases_men", "cases_pneumo"), + dalys = list_params_hib_pcv, + bypass_cert_check = TRUE) + + list_params_rota <- data_frame( + outcome = c("cases", "deaths"), + proportion = c(1, 1), + average_duration = c(0.01, 1000), + disability_weight = c(0.247, 1) + ) + + stone_stochastic_process(con, + "JHU-Tam", "Rota", "201910gavi-5", + c("rota-no-vaccination-LiST", "rota-routine-default-LiST", "rota-routine-bestcase-LiST"), + file.path(in_path, "JHU-Tam-Rota"), + c("novac:index.csv.xz", "default:index.csv.xz", "best:index.csv.xz"), + "", 1, 14, out_path, + dalys = list_params_rota, + bypass_cert_check = TRUE) + + ############################################################################# + + stone_stochastic_process(con, + "Li", "HepB", "201910gavi-5", + c("hepb-bd-default-hepb-routine-default", + "hepb-bd-routine-bestcase-hepb-routine-bestcase", + "hepb-no-vaccination", + "hepb-stop", + "hepb-bd-routine-bestcase", + "hepb-bd-routine-default", + "hepb-hepb-routine-bestcase", + "hepb-hepb-routine-default" + ), + file.path(in_path, "Li"), + paste0(":scenario:index.csv.xz"), + "cert74", 1, 200, out_path, + c("hepb_deaths_acute", "hepb_deaths_total_cirrh", "hepb_deaths_hcc"), + c("hepb_cases_acute_symp", "hepb_cases_fulminant", + "hepb_cases_chronic", "hepb_chronic_symptomatic_in_acute_phase"), + "dalys" + ) + + ############################################################################# + + stub <- "VIMC_Hib_PSA_" + stone_stochastic_process(con, + "LSHTM-Clark", "Hib", "201910gavi-5", + c("hib-no-vaccination","hib-routine-bestcase","hib-routine-default"), + file.path(in_path, "LSHTM-Clark_Hib"), + c(paste0(stub, "NoVax.csv.xz"), + paste0(stub, "Best.csv.xz"), + paste0(stub, "Default.csv.xz")), + "cert81", NA, NA, out_path) + + stub <- "VIMC_Sp_PSA_" + stone_stochastic_process(con, + "LSHTM-Clark", "PCV", "201910gavi-5", + c("pcv-no-vaccination","pcv-routine-bestcase","pcv-routine-default"), + file.path(in_path, "LSHTM-Clark_PCV"), + c(paste0(stub, "NoVax.csv.xz"), + paste0(stub, "Best.csv.xz"), + paste0(stub, "Default.csv.xz")), + "cert82", NA, NA, "E:/Stochastic_2019") + + stub <- "Hira Tanvir - VIMC_Rota_PSA_" + stone_stochastic_process(con, + "LSHTM-Clark", "Rota", "201910gavi-5", + c("rota-no-vaccination","rota-routine-bestcase","rota-routine-default"), + file.path(in_path, "LSHTM-Clark_Rota"), + c(paste0(stub, "NoVax.csv.xz"), + paste0(stub, "Best.csv.xz"), + paste0(stub, "Default.csv.xz")), + "", NA, NA, "E:/Stochastic_2019") + + ############################################################################# + + stub <- "stochastic-burden-" + stone_stochastic_process(con, + "LSHTM-Jit", "HPV", "201910gavi-5", + c("hpv-campaign-bestcase", + "hpv-campaign-default", + "hpv-no-vaccination", + "hpv-routine-bestcase", + "hpv-routine-default"), + file.path(in_path, "LSHTM-Jit_HPV"), + c(paste0(stub, "vaccination_201910gavi-4_hpv-campaign-bestcase.csv.xz"), + paste0(stub, "vaccination_201910gavi-4_hpv-campaign-default.csv.xz"), + paste0(stub, "novaccination_201910gavi-4_hpv-no-vaccination.csv.xz"), + paste0(stub, "vaccination_201910gavi-4_hpv-routine-bestcase.csv.xz"), + paste0(stub, "vaccination_201910gavi-4_hpv-routine-default.csv.xz")), + "Kaja Abbas - stochastic_parameters_certificate_HPV_LSHTM-Jit_201910gavi-4", + NA, NA, out_path, bypass_cert_check = TRUE) + + ############################################################################# + + stub <- "stochastic_burden_estimate_measles-LSHTM-Jit-" + stone_stochastic_process(con, "LSHTM-Jit", "Measles", "201910gavi-5", + c("measles-no-vaccination", + "measles-campaign-default","measles-campaign-bestcase", + "measles-campaign-only-default","measles-campaign-only-bestcase", + "measles-mcv1-default","measles-mcv1-bestcase", + "measles-mcv2-default","measles-mcv2-bestcase", + "measles-stop"), + file.path(in_path, "LSHTM-Jit_Measles"), + c(paste0(stub, "no-vaccination_Portnoy.csv.xz"), + paste0(stub, "campaign-default_Portnoy.csv.xz"), paste0(stub, "campaign-bestcase_Portnoy.csv.xz"), + paste0(stub, "campaign-only-default_Portnoy.csv.xz"), paste0(stub, "campaign-only-bestcase_Portnoy.csv.xz"), + paste0(stub, "mcv1-default_Portnoy.csv.xz"), paste0(stub, "mcv1-bestcase_Portnoy.csv.xz"), + paste0(stub, "mcv2-default_Portnoy.csv.xz"), paste0(stub, "mcv2-bestcase_Portnoy.csv.xz"), + paste0(stub, "stop_Portnoy.csv.xz")), + "cert83", NA, NA, out_path) + + ############################################################################# + + stub <- "Template_Stochastic_" + stone_stochastic_process(con, + "OUCRU-Clapham", "JE", "201910gavi-5", + c("je-campaign-bestcase", + "je-campaign-default", + "je-routine-no-vaccination", + "je-routine-bestcase", + "je-routine-default"), + file.path(in_path, "OUCRU-Clapham"), + c(paste0(stub, "Campaign_Best4_correcting_:index.csv.xz"), + paste0(stub, "Campaign_Default4_correcting_:index.csv.xz"), + paste0(stub, "Naive4_correcting_:index.csv.xz"), + paste0(stub, "Routine_Best4_correcting_:index.csv.xz"), + paste0(stub, "Routine_Default4_correcting_:index.csv.xz")), + "cert76", 1, 200, out_path) + + ############################################################################# + + stub <- "stochastic_burden_est_" + stone_stochastic_process(con, + "PHE-Vynnycky", "Rubella", "201910gavi-5", + c("rubella-campaign-bestcase", + "rubella-campaign-default", + "rubella-routine-no-vaccination", + "rubella-rcv1-bestcase", + "rubella-rcv1-default", + "rubella-rcv1-rcv2-bestcase", + "rubella-rcv1-rcv2-default", + "rubella-rcv2-bestcase", + "rubella-rcv2-default", + "rubella-stop"), + file.path(in_path, "PHE-Vynnycky"), + paste0(stub, ":scenario_country:index.csv.xz"), + "", 1, 112, out_path, + "rubella_deaths_congenital", + "rubella_cases_congenital", "dalys") + + ############################################################################# + + stub <- "Heather Santos - " + stone_stochastic_process(con, + "PSU-Ferrari", "Measles", "201910gavi-5", + c("measles-no-vaccination", + "measles-mcv1-bestcase", + "measles-mcv2-bestcase", + "measles-campaign-bestcase", + "measles-mcv1-default", + "measles-mcv2-default", + "measles-campaign-default", + "measles-stop", + "measles-campaign-only-bestcase", + "measles-campaign-only-default"), + file.path(in_path, "PSU-Ferrari"), + c(paste0(stub, "novax_stochastic:index_burden_Measles-PSU-Ferrari.csv.xz"), + paste0(stub, "bestcase_mcv1_stochastic:index_burden_Measles-PSU-Ferrari.csv.xz"), + paste0(stub, "bestcase_mcv2_stochastic:index_burden_Measles-PSU-Ferrari.csv.xz"), + "stochastic:index_burden_Measles-PSU-Ferrari.csv.xz", + paste0(stub, "default_mcv1_stochastic:index_burden_Measles-PSU-Ferrari.csv.xz"), + paste0(stub, "default_mcv2_stochastic:index_burden_Measles-PSU-Ferrari.csv.xz"), + paste0(stub, "default_campaign_stochastic:index_burden_Measles-PSU-Ferrari.csv.xz"), + paste0(stub, "stop_stochastic:index_burden_Measles-PSU-Ferrari.csv.xz"), + paste0(stub, "bestcase_campaign_only_stochastic:index_burden_Measles-PSU-Ferrari.csv.xz"), + paste0(stub, "default_campaign_only_stochastic:index_burden_Measles-PSU-Ferrari.csv.xz")), + "Heather Santos - cert80", 1, 8, out_path) + + ############################################################################# + + stub <- "Sean Moore - stochastic_burden_est_JE_UND-Moore_" + stone_stochastic_process(con, + "UND-Moore", "JE", "201910gavi-5", + c("je-campaign-bestcase", + "je-campaign-default", + "je-routine-no-vaccination", + "je-routine-bestcase", + "je-routine-default"), + file.path(in_path, "UND-Moore"), + c(paste0(stub, ":scenario.csv.xz"), + paste0(stub, ":scenario.csv.xz"), + paste0(stub, "je-no-vaccination.csv.xz"), + paste0(stub, ":scenario.csv.xz"), + paste0(stub, ":scenario.csv.xz")), + "Sean Moore - cert58", NA, NA, out_path) + + ############################################################################# + + stub <- "stochastic_burden_est_YF_UND-Perkins_" + stone_stochastic_process(con, + "UND-Perkins", "YF", "201910gavi-5", + c("yf-no-vaccination", + "yf-preventive-bestcase", + "yf-preventive-default", + "yf-routine-bestcase", + "yf-routine-default", + "yf-stop"), + file.path(in_path, "UND-Perkins"), + paste0(stub, ":scenario_:index.csv.xz"), + "John Huber - cert85", 1, 200, out_path) + + ############################################################################# + + stone_stochastic_process(con, + "Yale-Pitzer", "Typhoid", "201910gavi-5", + c("typhoid-no-vaccination", "typhoid-campaign-default", "typhoid-routine-default"), + file.path(in_path, "Yale-Pitzer"), + c("Virginia Pitzer - 2021-02-18 17.00.26 - stochastic_output_TF-Yale-Pitzer_novacc.csv.xz", + "Virginia Pitzer - 2021-02-18 16.58.03 - stochastic_output_TF-Yale-Pitzer_campaign.csv.xz", + "Virginia Pitzer - 2021-02-18 16.59.14 - stochastic_output_TF-Yale-Pitzer_camproutine.csv.xz"), + "Virginia Pitzer - cert88", NA, NA, out_path) + + ############################################################################# + + upload4(out_path, "Cambridge-Trotter", "MenA", "201910gavi-5", con, annex) + upload4(out_path, "CDA-Razavi", "HepB", "201910gavi-5", con, annex) + upload4(out_path, "Emory-Lopman", "Rota", "201910gavi-5", con, annex) + upload4(out_path, "Harvard-Sweet", "HPV", "201910gavi-5", con, annex) + upload4(out_path, "IC-Garske", "YF", "201910gavi-5", con, annex) + upload4(out_path, "IC-Hallett", "HepB", "201910gavi-5", con, annex) + upload4(out_path, "IVI-Kim", "Cholera", "201910gavi-5", con, annex) + upload4(out_path, "IVI-Kim", "Typhoid", "201910gavi-5", con, annex) + upload4(out_path, "KPW-Jackson", "MenA", "201910gavi-5", con, annex) + upload4(out_path, "JHU-Lee", "Cholera", "201910gavi-5", con, annex) + upload4(out_path, "JHU-Tam", "Hib", "201910gavi-5", con, annex) + upload4(out_path, "JHU-Tam", "PCV", "201910gavi-5", con, annex) + upload4(out_path, "JHU-Tam", "Rota", "201910gavi-5", con, annex) + upload4(out_path, "JHU-Lessler", "Rubella", "201910gavi-5", con, annex) + upload4(out_path, "Li", "HepB", "201910gavi-5", con, annex) + upload4(out_path, "LSHTM-Clark", "Hib", "201910gavi-5", con, annex) + upload4(out_path, "LSHTM-Clark", "PCV", "201910gavi-5", con, annex) + upload4(out_path, "LSHTM-Clark", "Rota", "201910gavi-5", con, annex) + upload4(out_path, "LSHTM-Jit", "HPV", "201910gavi-5", con, annex) + upload4(out_path, "LSHTM-Jit", "Measles", "201910gavi-5", con, annex) + upload4(out_path, "OUCRU-Clapham", "JE", "201910gavi-5", con, annex) + upload4(out_path, "PHE-Vynnycky", "Rubella", "201910gavi-5", con, annex) + upload4(out_path, "PSU-Ferrari", "Measles", "201910gavi-5", con, annex) + upload4(out_path, "UND-Moore", "JE", "201910gavi-5", con, annex) + upload4(out_path, "UND-Perkins", "YF", "201910gavi-5", con, annex) + upload4(out_path, "Yale-Pitzer", "Typhoid", "201910gavi-5", con, annex) + +} diff --git a/scripts/process_stoch_201710gavi.R b/scripts/process_stoch_201710gavi.R index bcb89f4..3c2534d 100644 --- a/scripts/process_stoch_201710gavi.R +++ b/scripts/process_stoch_201710gavi.R @@ -22,7 +22,7 @@ fetch_scenarios <- function(disease, touchstone='201710gavi-5') { # Let's unleash the cow setwd("Q:/testcow") -writeLines("vimc/stoner@VIMC-9230", "pkgdepends.txt") +writeLines("vimc/stoner", "pkgdepends.txt") hipercow::hipercow_init(driver = "dide-windows") hipercow::hipercow_provision() # Network/memory might be too much for more than a job per node. @@ -296,3 +296,5 @@ stoner::stone_stochastic_standardise( "John Huber - stochastic_burden_est_YF_UND-Perkins_yf-preventive-gavi_:index.csv.xz", "John Huber - stochastic_burden_est_YF_UND-Perkins_yf-routine-gavi_:index.csv.xz"), index = 1:200)) + +stoner::stone_stochastic_make_meta(base_out_path) diff --git a/scripts/process_stoch_201910gavi.R b/scripts/process_stoch_201910gavi.R index 1ed1318..48e2019 100644 --- a/scripts/process_stoch_201910gavi.R +++ b/scripts/process_stoch_201910gavi.R @@ -22,7 +22,7 @@ fetch_scenarios <- function(disease) { # Let's unleash the cow setwd("Q:/testcow") -writeLines("vimc/stoner@VIMC-9230", "pkgdepends.txt") +writeLines("vimc/stoner", "pkgdepends.txt") hipercow::hipercow_init(driver = "dide-windows") hipercow::hipercow_provision() # Network/memory might be too much for more than a job per node. @@ -417,3 +417,5 @@ stoner::stone_stochastic_standardise( scenarios = scenarios, files = "stochastic_burden_est_YF_UND-Perkins_:scenario_:index.csv.xz", index = 1:200)) + +stoner::stone_stochastic_make_meta(base_out_path) diff --git a/scripts/process_stoch_202110gavi.R b/scripts/process_stoch_202110gavi.R index 210d016..1abb596 100644 --- a/scripts/process_stoch_202110gavi.R +++ b/scripts/process_stoch_202110gavi.R @@ -20,7 +20,7 @@ fetch_scenarios <- function(disease) { # Let's unleash the cow setwd("Q:/testcow") -writeLines("vimc/stoner@VIMC-9230", "pkgdepends.txt") +writeLines("vimc/stoner", "pkgdepends.txt") hipercow::hipercow_init(driver = "dide-windows") hipercow::hipercow_provision() # Network/memory might be too much for more than a job per node. @@ -226,7 +226,6 @@ stoner::stone_stochastic_standardise( sprintf("%s_booster_:index.csv.xz", stub)), index = 1:26)) -hipercow::task_create_expr(resources = hres, expr = stoner::stone_stochastic_standardise( group = "KPW-Jackson", in_path = file.path(base_in_path, "KPW-Jackson-MenA"), @@ -238,7 +237,7 @@ stoner::stone_stochastic_standardise( "stochastic_burden_est_MenA_KPWA_routine_default_:index.csv.xz", "stochastic_burden_est_MenA_KPWA_routine_ia2030_target_:index.csv.xz", "stochastic_burden_est_MenA_KPWA_booster_default_:index.csv.xz"), - index = 1:26)) + index = 1:26) ############### # PCV @@ -377,10 +376,13 @@ stoner::stone_stochastic_standardise( files = sprintf("%s_:scenario_:index.csv.xz", stub), index = 1:200) -stoner::stone_stochastic_standardise( +hipercow::task_create_expr(resources = hres, expr = + stoner::stone_stochastic_standardise( group = "UND-Perkins", in_path = file.path(base_in_path, "UND-Perkins-YF"), out_path = file.path(base_out_path, "YF_UND-Perkins"), scenarios = scenarios, files = "stochastic_burden_est_YF_UND-Perkins_:scenario_:index.csv.xz", - index = 1:200) + index = 1:200)) + +stoner::stone_stochastic_make_meta(base_out_path) diff --git a/scripts/process_stoch_202310gavi.R b/scripts/process_stoch_202310gavi.R index b2eaaef..ad320b7 100644 --- a/scripts/process_stoch_202310gavi.R +++ b/scripts/process_stoch_202310gavi.R @@ -323,7 +323,7 @@ stoner::stone_stochastic_standardise( scenarios = c("malaria-no-vaccination", "malaria-rts3-default", "malaria-rts3-rts4-default", - "malaria-rts3-bluesky", "malaria-rts3-rts4-bluesky"), + "malaria-rts3-bluesky", "malaria-rts3-rts4-bluesky") stoner::stone_stochastic_standardise( group = "UAC-Kakai", @@ -360,3 +360,5 @@ stoner::stone_stochastic_standardise( "stochastic_burden_est_malaria_:index_rtss_d3_bluesky Josephine Malinga.csv.xz", "stochastic_burden_est_malaria_:index_rtss_d4_bluesky Josephine Malinga.csv.xz"), index = 1:31) + +stoner::stone_stochastic_make_meta(base_out_path) diff --git a/scripts/process_stoch_202409malaria.R b/scripts/process_stoch_202409malaria.R index c150f99..b17d724 100644 --- a/scripts/process_stoch_202409malaria.R +++ b/scripts/process_stoch_202409malaria.R @@ -35,3 +35,5 @@ stoner::stone_stochastic_standardise( "stochastic_burden_est_malaria_:index_rtss_d4_default Josephine Malinga.csv.xz"), index = 1:31 ) + +stoner::stone_stochastic_make_meta(base_out_path) diff --git a/scripts/process_stoch_202602yf.R b/scripts/process_stoch_202602yf.R new file mode 100644 index 0000000..5e18778 --- /dev/null +++ b/scripts/process_stoch_202602yf.R @@ -0,0 +1,28 @@ +base_in_path <- "//wpia-hn2.hpc.dide.ic.ac.uk/vimc_stochastics_dropbox/latest/202602yf" +base_out_path <- "//wpia-hn2.hpc.dide.ic.ac.uk/vimc_stochastics/2026202yf" + +############### +# YF + +scenarios = c("yf-no-vaccination", "yf-routine-default", + "yf-routine-campaign-default") + +stoner::stone_stochastic_standardise( + group = "IC-Gaythorpe", + in_path = file.path(base_in_path, "YF-IC-Gaythorpe"), + out_path = file.path(base_out_path, "YF_IC-Gaythorpe"), + scenarios = scenarios, + files = c("burden_results_stochastic_2026_updates_01_novacc_:index.csv.xz", + "burden_results_stochastic_2026_updates_02_default_routine_:index.csv.xz", + "burden_results_stochastic_2026_updates_03_default_routine_campaign_:index.csv.xz"), + index = 1:200) + +stoner::stone_stochastic_standardise( + group = "UND-Perkins", + in_path = file.path(base_in_path, "YF-UND-Perkins"), + out_path = file.path(base_out_path, "YF_UND-Perkins"), + scenarios = "yf-routine-campaign-default", + files = c("stochastic_burden_est_YF_UND-Perkins_yf-scenario-1-default-Routine_and_Campaign_:index.csv.xz"), + index = 1:200) + +stoner::stone_stochastic_make_meta(base_out_path) diff --git a/tests/testthat/test_stochastic_files.R b/tests/testthat/test_stochastic_files.R index ac19da8..c7b92a2 100644 --- a/tests/testthat/test_stochastic_files.R +++ b/tests/testthat/test_stochastic_files.R @@ -330,3 +330,35 @@ test_that("Different file count per scenario is handled", { expect_true("north_pole_lurgy_fatalistic_NOR.pq" %in% files) expect_true("north_pole_lurgy_fatalistic_LAP.pq" %in% files) }) + +test_that("Can produce metadata", { + tmpout <- file.path(tempdir(), "base") + d <- fake_data() + dir.create(file.path(tmpout, "T1", "elf-piles_G1"), recursive = TRUE) + dir.create(file.path(tmpout, "T2", "elf-piles_G2"), recursive = TRUE) + arrow::write_parquet(d, file.path(tmpout, "T1", "elf-piles_G1", "G1_S1_LAP.pq")) + d$country <- "NPL" + arrow::write_parquet(d, file.path(tmpout, "T1", "elf-piles_G1", "G1_S1_NPL.pq")) + d$yll <- NULL + d$potatoes <- sample(nrow(d)) + arrow::write_parquet(d, file.path(tmpout, "T2", "elf-piles_G2", "G1_S1_ZAP.pq")) + arrow::write_parquet(d, file.path(tmpout, "T2", "elf-piles_G2", "G1_S1_ZIP.pq")) + stone_stochastic_make_meta(tmpout) + + expect_true(file.exists(file.path(tmpout, "meta.csv"))) + meta <- read.csv(file.path(tmpout, "meta.csv")) + expect_equal(nrow(meta), 2) + expect_true("T1" %in% meta$touchstone) + t1 <- meta[meta$touchstone %in% "T1", ] + expect_equal(t1$group, "G1") + expect_equal(t1$scenario, "S1") + expect_equal(t1$countries, "LAP;NPL") + expect_equal(t1$outcomes, "cases;dalys;deaths;yll") + expect_true("T2" %in% meta$touchstone) + t2 <- meta[meta$touchstone %in% "T2", ] + expect_equal(t2$group, "G2") + expect_equal(t2$scenario, "S1") + expect_equal(t2$countries, "ZAP;ZIP") + expect_equal(t2$outcomes, "cases;dalys;deaths;potatoes") +}) + diff --git a/tests/testthat/test_stochastic_graphs.R b/tests/testthat/test_stochastic_graphs.R index 58a2735..4ab224e 100644 --- a/tests/testthat/test_stochastic_graphs.R +++ b/tests/testthat/test_stochastic_graphs.R @@ -29,34 +29,57 @@ test_that("stochastic_graph data transforms", { if (file.exists(f)) file.remove(f) arrow::write_parquet(data, file.path(folder, filename)) - # Aggregate all ages, not by cohort. Should have 1 point per year. + # Expecting unaggregated data - res <- prepare_graph_data(base, touchstone, disease, group, country, - scenario, "deaths", NULL, FALSE) + res <- get_graph_data(base, touchstone, disease, group, country, + scenario, "deaths", FALSE) - expect_equal(nrow(res), 25) # 5 runs, 5 years - expect_equal(res$deaths[res$run_id == 1 & res$year == 2002], + expect_equal(nrow(res), 125) # 5 runs, 5 years, 5 ages + + # Aggregate by year + + res2 <- aggregate_by_year(res, "deaths") + expect_equal(nrow(res2), 25) # 5 runs, 5 years, all age + + expect_equal(res2$deaths[res2$run_id == 1 & res2$year == 2002], sum(data$deaths[data$year == 2002 & data$run_id == 1])) # Select ages - res <- prepare_graph_data(base, touchstone, disease, group, country, - scenario, "deaths", c(10, 12, 14), FALSE) + res2 <- aggregate_by_year(res, "deaths", c(10, 12, 14)) - expect_equal(nrow(res), 25) # 5 runs, 5 years - expect_equal(res$deaths[res$run_id == 1 & res$year == 2003], + expect_equal(nrow(res2), 25) # 5 runs, 5 years + expect_equal(res2$deaths[res2$run_id == 1 & res2$year == 2003], sum(data$deaths[data$year == 2003 & data$run_id == 1 & data$age %in% c(10, 12, 14)])) # By cohort - res <- prepare_graph_data(base, touchstone, disease, group, country, - scenario, "deaths", c(10, 12, 14), TRUE) + res <- get_graph_data(base, touchstone, disease, group, country, + scenario, "deaths", TRUE) + + res2 <- aggregate_by_year(res, "deaths", c(10, 12, 14)) + + expect_equal(min(res2$year), min(data$year) - max(data$age)) + expect_equal(max(res2$year), max(data$year) - min(data$age)) + + # Aggregate by age, for all years + + res2 <- aggregate_by_age(data, "deaths", NULL) + expect_equal(nrow(res2), 25) + expect_equal(res2$deaths[res2$run_id == 2 & res2$age == 10], + sum(data$deaths[data$age == 10 & data$run_id == 2])) + + # Aggregate by age, for some years - expect_equal(min(res$year), min(data$year) - max(data$age)) - expect_equal(max(res$year), max(data$year) - min(data$age)) + res2 <- aggregate_by_age(data, "deaths", c(2002, 2003)) + expect_equal(nrow(res2), 25) + expect_equal(res2$deaths[res2$run_id == 2 & res2$age == 10], + sum(data$deaths[data$age == 10 & data$run_id == 2 & + data$year %in% c(2002, 2003)])) - # Test graph - we can't really, but just check it doesn't crash. + # Test graph - we can't really, but just check it doesn't crash; we've + # already tested the functions being called. expect_no_error(stone_stochastic_graph( base, touchstone, disease, group, country, @@ -68,12 +91,13 @@ test_that("stochastic_graph data transforms", { expect_no_error(stone_stochastic_graph( base, touchstone, disease, group, country, - scenario, "deaths", scenario2 = scenario)) + c(scenario, scenario), "deaths")) # Packit gets called if needed - fake_result <- mockery::mock("fake_result") - mockery::stub(stone_stochastic_graph, "prepare_central_data", fake_result) + fake_data <- data.frame(year = 2000, age = 10, deaths = 25, run_id = 1) + fake_result <- mockery::mock(fake_data, cycle = TRUE) + mockery::stub(stone_stochastic_graph, "get_packit_data", fake_result) expect_no_error(stone_stochastic_graph( base, touchstone, disease, group, country, @@ -82,10 +106,22 @@ test_that("stochastic_graph data transforms", { mockery::expect_called(fake_result, 1) mockery::expect_args(fake_result, 1, "123", "file.csv", country, - scenario, "deaths", NULL, FALSE) + scenario, "deaths", FALSE) + + expect_no_error(stone_stochastic_graph( + base, touchstone, disease, group, country, + scenario, "deaths", xaxis = "age")) + + expect_no_error(stone_stochastic_graph( + base, touchstone, disease, group, country, + scenario, "deaths", xaxis = "age", + packit_id = "123", + packit_file = "file.csv")) + }) + test_that("stochastic_explorer data_dir handling", { expect_error(stochastic_explorer(file.path(tempdir(), "potato", "salad")), "Cannot access the path/mount") @@ -116,42 +152,85 @@ test_that("Can launch shiny app", { }) }) -test_that("Age formats are reasonable", { - expect_equal(age_string(NULL), "all ages") - expect_equal(age_string(c(5,4,3,2,1,5,4,3,2,1)), "age 1..5") - expect_equal(age_string(c(2,4,6,8)), "selected ages") +test_that("Filter formats are reasonable", { + expect_equal(filter_string(NULL, "ages"), "all ages") + expect_equal(filter_string(c(5,4,3,2,1,5,4,3,2,1), "ages"), "ages 1..5") + expect_equal(filter_string(c(2,4,6,8), "potatoes"), "selected potatoes") +}) + +test_that("Arguments are tested", { + + expect_error(stone_stochastic_graph( + "b", c("T1", "T2", "T3"), "d", "g", "c", "s", "o"), + "Only specify one or two touchstones") + + expect_error(stone_stochastic_graph( + "b", NULL, "d", "g", "c", "s", "o"), + "Only specify one or two touchstones") + + expect_error(stone_stochastic_graph( + "b", "t", "d", NULL, "c", "s", "o"), + "Only specify one or two modelling groups") + + expect_error(stone_stochastic_graph( + "b", "t", "d", c("g1", "g2", "g3"), "c", "s", "o"), + "Only specify one or two modelling groups") + + expect_error(stone_stochastic_graph( + "b", "t", "d", "g", "c", NULL, "o"), + "Only specify one or two scenarios") + + expect_error(stone_stochastic_graph( + "b", "t", "d", "g", "c", c("s1", "s2", "s3"), "o"), + "Only specify one or two scenarios") + + expect_error(stone_stochastic_graph( + "b", c("T1", "T2"), "d", c("g1", "g2"), "c", "s", "o"), + "Only one of `touchstones` or `groups` can be plural") + + expect_error(stone_stochastic_graph( + "b", c("T1", "T2"), "d", c("g1", "g2"), "c", c("s1", "s2"), "o"), + "Only one of `touchstones` or `groups` can be plural") + + expect_error(stone_stochastic_graph( + "b", c("T1", "T2"), "d", "g", "c", c("s1", "s2"), "o", xaxis = "potato"), + "`xaxis` must be either `time` or `age`") + + expect_error(stone_stochastic_graph( + "b", c("T1", "T2"), "d", "g", "c", c("s1", "s2"), "o", xaxis = "age"), + "Couldn't find file") }) -test_that("Parsing central from packit works", { - # Packit gets called if needed +test_that("Packit data is arranged correctly", { fake <- data.frame( scenario_type = "RSV-rout", scenario = "RSV-rout", year = c(rep(2000, 4), rep(2001, 4), rep(2000, 4), rep(2001, 4)), - age = c(rep(0, 8), rep(1, 8)), + age = c(rep(6, 8), rep(7, 8)), country = "RFP", burden_outcome = rep(c("cases", "dalys", "deaths", "yll"), 2), value = 1:16) + fake2 <- fake + fake2$country <- "POT" + fake2$scenario <- "XYZ-rout" + fake <- rbind(fake, fake2) rds <- tempfile(fileext = ".rds") saveRDS(fake, rds) fetch_fake <- function(id, file) rds - mockery::stub(prepare_central_data, "fetch_packit", fetch_fake) - - res <- prepare_central_data("123", "file.csv", - "RFP", "RSV-rout", "deaths", 0:5, TRUE) - - # Data in for death is: (year, age, deaths) - # 2000, 0, 3 - # 2000, 1, 11 - # 2001, 0, 7 - # 2001, 1, 15 - # For cohort - this should become... - # 1999, 11 (2000 year 1, were born in 1999) - # 2000, 18 (2000 year 0, and 2001 year 1 born in 2000) - # 2001, 7 (2001 year 0) - - expect_true(all.equal(res$year, c(1999, 2000, 2001))) - expect_true(all.equal(res$deaths, c(11, 18, 7))) + mockery::stub(get_packit_data, "fetch_packit", fetch_fake) + + res <- get_packit_data("", "", "RFP", "RSV-rout", "cases", TRUE) + expect_true(unique(res$run_id) == 1) + fake$year <- fake$year - fake$age + fake <- fake[fake$country == "RFP", ] + fake <- fake[fake$scenario == "RSV-rout", ] + fake <- fake[fake$burden_outcome == "cases", ] + fake <- fake[order(fake$year, fake$age), ] + res <- res[order(res$year, res$age), ] + expect_equal(nrow(fake), nrow(res)) + expect_all_true(fake$year ==res$year) + expect_all_true(fake$age == res$age) + expect_all_true(fake$value == res$cases) }) diff --git a/vignettes/Stochastics.Rmd b/vignettes/Stochastics.Rmd index 9be11c9..e9b63ec 100644 --- a/vignettes/Stochastics.Rmd +++ b/vignettes/Stochastics.Rmd @@ -5,8 +5,11 @@ date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Stochastics} - %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} + %\VignetteEngine{knitr::rmarkdown} +editor_options: + markdown: + wrap: 80 --- ```{r setup, include = FALSE} @@ -19,59 +22,65 @@ data_frame <- function(...) { data.frame(stringsAsFactors = FALSE, ...) } ``` -## Stochastics -VIMC modelling groups produce stochastic data for us, which is currently -200 runs of their models varying key parameters, to express uncertainty. -These files get uploaded to Box, and the groups are provided with -guidance to produce files that we can process easily. +## Stochastics -Stoner can process these stochastic files into a standard format to -make the files more predictable to work with. For a good compromise -between ease-of-use, performance and compression, we have used the -`Parquet` format and the `arrow` package. This vignette covers -how to process the data, how to create a central from a set of -stochastics, and how to see a graph of the stochastics for quick -diagnosis. +VIMC modelling groups produce stochastic data for us, which is currently 200 +runs of their models varying key parameters, to express uncertainty. These files +get uploaded to Box, and the groups are provided with guidance to produce files +that we can process easily. +Stoner can process these stochastic files into a standard format to make the +files more predictable to work with. For a good compromise between ease-of-use, +performance and compression, we have used the `Parquet` format and the `arrow` +package. This vignette covers how to process the data, how to create a central +from a set of stochastics, how to produce some graphs of the stochastics for +quick diagnosis, and also how to use the stochastic explorer, a local shiny app +for exploring and comparing stochastic datasets. ### Creating standard stochastic files -This has superceded `stoner_stochastic_process`, which will be -removed and undocumented soon. - -Here, we are mostly likely working with two folders or network shares, -one of which contains the stochastics that groups have uploaded, and the -other is a destination where we want to write our standardised files. These -I'll call `in_path` and `out_path`. The `out_path` folders I am assuming -will be only written to by stoner; paths and filenames will adhere to the -following format:- - -* Within the root of the share we will have the **touchstone**, without -a version. At time of writing, we have `202310gavi` and `202409malaria`. -I am not anticipating having separate stochastics for separate versions -of the stochastics at this point. - -* Within those touchstone folders, we have more folders in the form -`Disease_Modelling-Group` - such as `COVID_IC-Ghani` or `YF_IC-Garske`. -The groups and diseases set up here copy the historic contents of the -Montagu database. - -* Within each of these folders, we will be writing a file per -country per scenario, containing all run_ids, named in the format -`Modelling-Group_scenario_country.pq` - for example, -`IC-Garske_yf-routine-ia2030_KEN.pq`. If we also create a -average (central) of the stochastics (see later), that will be called -`IC-Garske_yf-routine-ia2030_central.pq`, containing all the countries, -and no run_id. +This has superseded `stoner_stochastic_process`, which will be removed and +undocumented soon. + +Here, we are mostly likely working with two folders or network shares, one of +which contains the stochastics that groups have uploaded, and the other is a +destination where we want to write our standardised files. These I'll call +`in_path` and `out_path`. The `out_path` folders I am assuming will be only +written to by stoner; paths and filenames will adhere to the following format:- + +- Within the root of the share we will have the **touchstone**, without a + version. At time of writing, we have `202310gavi` and `202409malaria`. I am + not anticipating having separate stochastics for separate versions of the + stochastics at this point. + +- Within those touchstone folders, we have more folders in the form + `Disease_Modelling-Group` - such as `COVID_IC-Ghani` or `YF_IC-Garske`. The + groups and diseases set up here copy the historic contents of the Montagu + database. + +- Within each of these folders, we will be writing a file per country per + scenario, containing all run_ids, named in the format + `Modelling-Group_scenario_country.pq` - for example, + `IC-Garske_yf-routine-ia2030_KEN.pq`. If we also create a average (central) + of the stochastics (see later), that will be called + `IC-Garske_yf-routine-ia2030_central.pq`, containing all the countries, and + no run_id. + +- Finally, in the root of the standardised folder, we'll keep a file + `meta.csv` to describe in one file the range of stochastic data we have by + touchstone, disease, group and scenario, and for each the outcomes and + countries provided. This is useful for speeding up the stochastic explorer + shiny app, but also may be a useful quick reference of our inventory in + general. #### Example Usage - One file per scenario -Examples used so far are in the `scripts` folder in the root of the -stoner repo - files such as `process_stoch_202310gavi.R`. Here is an -example of the Yellow Fever standardisation:- +Examples used so far are in the `scripts` folder in the root of the stoner +repo - files such as `process_stoch_202310gavi.R`. Here is an example of the +Yellow Fever standardisation:- -``` +``` scenarios = c("yf-no-vaccination", "yf-routine-bluesky", "yf-routine-campaign-bluesky", "yf-routine-campaign-default", "yf-routine-campaign-ia2030", "yf-routine-default", @@ -86,27 +95,30 @@ stoner::stone_stochastic_standardise( ``` `base_in_path` and `base_out_path` are defined elsewhere, and are my drive -mappings to the incoming, and destination network shares. We provide the -group name, the paths to the uploaded files (note the original dropbox path -was a little incorrect with its dashes instead of underscores!) - and the -destination path in the format described above. +mappings to the incoming, and destination network shares. We'll briefly talk +about those later. + +We provide the group name, the paths to the uploaded files and the destination +we want to write files to. Note that the `in_path` is not managed, and might be +arbitrary - here it has dashes instead of underscores; but the `out_path`, we +need to be careful to get right, in the format `disease` then underscore then +the modelling group. We then provide the vector of scenarios, and because this group follow the -guidance very well, they have included the exact scenario in the filenames. -We can therefore use the `:scenario` glob in the `files` argument, and -stoner will handle each of the seven scenarios in the right order. +guidance very well, they have included the exact scenario in the filenames. We +can therefore use the `:scenario` glob in the `files` argument, and stoner will +handle each of the seven scenarios in the right order. #### Example Usage - One file per run -Other groups provide a file per run, which is also fine. Here, we can -specify an additional `index` parameter, usually `1:200`, and use the glob -`:index` in the files argument. Here is an example of that - but note for -this group, they didn't _quite_ include the scenarios exactly in the -filenames, so we have to explicitly name the files, rather than using -the `:scenario` glob. This is still yellow fever, so using the same -`scenarios` vector as before. +Other groups provide a file per run, which is also fine. Here, we can specify an +additional `index` parameter, usually `1:200`, and use the glob `:index` in the +files argument. Here is an example of that - but note for this group, they +didn't *quite* include the scenarios exactly in the filenames, so we have to +explicitly name the files, rather than using the `:scenario` glob. This is still +yellow fever, so using the same `scenarios` vector as before. -``` +``` stoner::stone_stochastic_standardise( group = "UND-Perkins", in_path = file.path(base_in_path, "YF-UND-Perkins"), @@ -122,103 +134,338 @@ stoner::stone_stochastic_standardise( index = 1:200) ``` -The subtle difference is that the group used underscores instead of dashes in the scenario -names. So here, I have to be careful and ensure the order of `files` matches the order of -`scenarios` manually. After that, the `:index` glob, and the `index` argument deal with -the fact we have 200 files per scenario. +The subtle difference is that the group used underscores instead of dashes in +the scenario names. So here, I have to be careful and ensure the order of +`files` matches the order of `scenarios` manually. After that, the `:index` +glob, and the `index` argument deal with the fact we have 200 files per +scenario. #### Example Usage - One file per country -If groups want to supply a file per country, then at present, we need them to do so -including the country in their uploads as normal, but number their files using the -`index` method above, rather than having country names or ISO codes in the filename. -We could do better if this proves to be a popular method. +If groups want to supply a file per country, then at present, we need them to do +so including the country in their uploads as normal, but number their files +using the `index` method above, rather than having country names or ISO codes in +the filename. We could do better if this proves to be a popular method. + +### Updating the meta-data + +Having run `stone_stochastic_standardise` and made changes to the structure, to +enable the stochastic explorer shiny app to use the data (and to keep a useful +file up-to-date), we need to run a command to update the metadata. + +``` +stoner::stone_stochastic_make_meta(out_path) +``` + +which will run for a few seconds, recreating the entire file. The columns are +touchstone, disease, group, scenario, countries and outcomes; the first four +will be single elements, whereas countries and outcomes will be semi-colon +separated lists. ### Advanced Usage -You shouldn't have to worry about these things, but this is just so that you know -they are there. We have some historic fixes that have made it possible for us to -process some groups' stochastics with some formatting issues, rather than asking -them to resubmit. These fixes are enabled by default; they won't do anything bad -for groups where the fixes are not relevant, and are strictly required for the -groups where they are relevant. +You shouldn't have to worry about these things, but this is just so that you +know they are there. We have some historic fixes that have made it possible for +us to process some groups' stochastics with some formatting issues, rather than +asking them to resubmit. These fixes are enabled by default; they won't do +anything bad for groups where the fixes are not relevant, and are strictly +required for the groups where they are relevant. #### The Rubella Fix An argument `rubella_fix`, by default `TRUE`, deals with the fact that rubella -groups have traditionally uploaded with different outcome names. Instead of `deaths`, -`rubella_deaths_congenital`, and instead of `cases`, `rubella_cases_congenital`. -Some groups additionally supplied the `rubella_infections` outcome. +groups have traditionally uploaded with different outcome names. Instead of +`deaths`, `rubella_deaths_congenital`, and instead of `cases`, +`rubella_cases_congenital`. Some groups additionally supplied the +`rubella_infections` outcome. -The `rubella_fix` argument causes stoner to omit `rubella_infections`, and rename -the others to `deaths` and `cases` respectively, standardising them against the -other diseases. +The `rubella_fix` argument causes stoner to omit `rubella_infections`, and +rename the others to `deaths` and `cases` respectively, standardising them +against the other diseases. #### The Missing Run Id fix One group also is in the habit of sending us one file per run_id, but omitting -the `run_id` field from their uploads. The argument `missing_run_id_fix`, default -`TRUE` lets Stoner spot this, and specifically if `index` is `1:200` (ie, we are -expecting 200 uploads), it will transplant the index into the file to allow -processing to be done normally. +the `run_id` field from their uploads. The argument `missing_run_id_fix`, +default `TRUE` lets Stoner spot this, and specifically if `index` is `1:200` +(ie, we are expecting 200 uploads), it will transplant the index into the file +to allow processing to be done normally. ### Other Considerations: -* Stoner rounds of all the outcomes, (deaths, cases, dalys, yll and -cohort_size) to be integer-like, which can create some confusion with small -countries with a very small number of cases, but we expect those confusions. -Some groups still provide us with 16 decimal places, which creates some -problems, and the integer-like rounding is in the guidance. +- Stoner rounds of all the outcomes, (deaths, cases, dalys, yll and + cohort_size) to be integer-like, which can create some confusion with small + countries with a very small number of cases, but we expect those confusions. + Some groups still provide us with 16 decimal places, which creates some + problems, and the integer-like rounding is in the guidance. + +- Note that for some groups with very large files (especially those with 16 + decimal places), the processing takes **a lot of memory** - towards 128Gb. + So run these on a large machine or perhaps a cluster node. + +### More about the paths + +If at all possible, you should perform Stoner tasks on a computer within DIDE, +connected with a cable. Stochastic processing involves large volumes of data, +and ZScaler from outside, or even WiFi from inside may not copy that well with +these tasks. -* Note that for some groups with very large files (especially those with -16 decimal places), the processing takes **a lot of memory** - towards -128Gb. So run these on a large machine or perhaps a cluster node. +On a DIDE Windows machine, `in_path` and `out_path` can be fully-qualified paths +to DIDE network shares, which only members of the VIMC team have access to. This +is probably the easiest case. + +On Linux or Mac, you have to mount the DIDE network shares, providing your DIDE +details, and it is up to you what you call your local mountpoints. On linux, +they may start with `/mnt/` and on Mac `/Volume/`. Talk to IT, if you need help +setting up those mounts. + +And lastly, if you're on a windows machine but for some reason need to work +externally, then use ZScaler, map drive letters to the network shares, and pass +those in, but as we said, this is not recommended as it's not particularly +stable. If at all possible, use an internal machine to do the heavy data work, +and remote desktop into that if you need to be external. ## Creating a central estimate -For many groups, their central estimates are the average of their -stochastic runs. Historically groups have provided their centrals before -their stochastics, as a means of early review and detection of problems. -Having standardised a group's stochastic files, we can then generate -an averaged central for a single touchstone, disease, group and scenario, -with the following call:- +For many groups, their central estimates are the average of their stochastic +runs. Historically groups have provided their centrals before their stochastics, +as a means of early review and detection of problems. Having standardised a +group's stochastic files, we can then generate an averaged central for a single +touchstone, disease, group and scenario, with the following call:- -``` +``` stone_stochastic_central(base, "202310gavi", "YF", "IC-Garske", "yf-routine-campaign-ia2030") ``` -`base` here is the root of the share where our standardised stochastic -outputs have been put, and since those were created by stoner, it knows -how to build the paths correctly. +`base` here is the root of the share where our standardised stochastic outputs +have been put, and since those were created by stoner, it knows how to build the +paths correctly. -The result will be a new file in the form `group_scenario_central.pq` so -in this case `IC-Garske_yf-routine-campaign-ia2030_central.pq` which -matches the other standardised filenames, except for the country; this -one central file will contain all countries. +The result will be a new file in the form `group_scenario_central.pq` so in this +case `IC-Garske_yf-routine-campaign-ia2030_central.pq` which matches the other +standardised filenames, except for the country; this one central file will +contain all countries. -The default averaging function is `mean` - if we really want the `median` -of the stochastics, then add the argument `avg_method = mean` to the -function call. +The default averaging function is `mean` - if we really want the `median` of the +stochastics, then add the argument `avg_method = mean` to the function call. +Note the lack of quotes - we are sending a function, not the name of a function. ## Creating stochastic graphs -It can be useful to quickly dig out a graph showing all the stochastic -lines together, to see what sort of spread they have. Again, with -`base` set to the root of the share where we are putting our -standardised outputs, here is an example function call, and -the graph that it produces. +The `stone_stochastuc_graph` function can dig out a range of different graphs. +If you want to explore the stochastics interactively, then try the shiny app +(below) - but for programmatic plotting, read on. -``` +### Basic burdens. + +With `base` set to the root of the share where we are putting our standardised +outputs, here is an example function call, and the graph that it produces. + +``` stone_stochastic_graph(base, "202310gavi", "YF", "IC-Garske", - "KEN", "yf-routine-campaign-ia2030", + "KEN", "yf-no-vaccination", "deaths") ``` -![Stochastic graph of IC-Garske, YF, Kenya, 202310gavi deaths.](figures/stoch_example_1.png) +![](figures/stoch_example_1.png) + +The grey lines are each and every stochastic run. Red is the mean, and green is +the median of the stochastics. The thicker black lines are the 5% and 95% +quantiles. We can toggle the presence of each of those line types with the +optional arguments `include_stochastics`, `include_quantiles`, `include_mean` +and `include_median`, which can be set to `FALSE`, or left as the default +`TRUE`. + +### Burden Differences + +If we specify two scenarios instead of one, then the plot will be the burden of +the first scenario, subtract the burden of the second - i.e., the difference +made by applying a scenario. Below is an example - I'll also add the +`log = TRUE` argument to get a logged y-axis. + +``` +stone_stochastic_graph(base, "202310gavi", "YF", "IC-Garske", + "KEN", c("yf-no-vaccination", "yf-routine-campaign-ia2030"), + "deaths", log = TRUE) +``` + +![](figures/stoch_burden_diff.png) + +The y-axis now reads "deaths averted" instead of just deaths. + +### Comparing touchstones + +You may have noticed that `stone_stochastic_graph` when you run it causes a plot +to appear, but is actually returning you a list of plots - one so far. If we +specify two touchstones, then stoner will instead return us a list of two +graphs - assuming that the same disease, group and scenarios are present in both +touchstones. The y-axis will be matched between the two, so we can see the pair +of graphs for comparison. + +Below is an example returning to just a single scenario, although you can +provide two and compare burden differences across two touchstones too. Here I am +collecting both resulting graphs, and then plotting them one by one. + +``` +res <- stone_stochastic_graph(base, c("202110gavi", "202310gavi"), "YF", "IC-Garske", + "ETH", "yf-no-vaccination", + "deaths", log = TRUE) +res[[1]] +res[[2]] +``` + +::: {style="display: flex; gap: 10px;"} + + +::: + +### Comparing modelling groups + +Similarly, within the same touchstone, we can compare two modelling groups, with +either a single scenario, or pair of scenarios. The disease, scenarios and +outcomes must be compatible between the two groups. Here's a comparison of +burden difference: + +``` +res <- stone_stochastic_graph(base, "202310gavi", "YF", + c("IC-Garske", "UND-Perkins"), + "UGA", + c("yf-no-vaccination", "yf-routine-default"), + "cases") +res[[1]] +res[[2]] +``` + +::: {style="display: flex; gap: 10px;"} + + +::: + +### Filtering by age + +The stochastic data contains both years and ages. Our plots so far have been +using time on the x-axis, and all the ages have been summed together for each +calendar year. We can also filter by age before plotting. The example below +filters to ages between 0 and 4 inclusive (ie, under 5 year-olds). + +``` +res <- stone_stochastic_graph(base, "202310gavi", "YF", "IC-Garske", "UGA", +"yf-no-vaccination", "deaths", filter = 0:4) +``` + +![](figures/stoch_u5.png) + +### Plotting by birth cohort + +The `by_cohort` parameter lets us subtract age from year before plotting, so we +can see burden specific to people who were born in a certain year, rather than +the previous plots, which have all treated the x-axis as calendar year. + +``` +res <- stone_stochastic_graph(base, "202310gavi", "YF", "IC-Garske", "UGA", + "yf-no-vaccination", "deaths", by_cohort = TRUE) +``` + +![](figures/stoch_cohort.png) + +### Age on the x-axis + +If instead we want to see how burden affects people of different ages throughout +the time series, we can set `xaxis` to `age` (its default is `time`). + +``` +res <- stone_stochastic_graph(base, "202602yf", "YF", "IC-Gaythorpe", "UGA", + "yf-no-vaccination", "deaths", xaxis = "age") +``` + +![](figures/stoch_byage.png) + +This sums over the entire range of years. If `xaxis` is age, then the `filter` +argument will let you select which years are to be included. This example shows +the burden by age in the years 2040-2050. + +``` +res <- stone_stochastic_graph(base, "202602yf", "YF", "IC-Gaythorpe", "UGA", + "yf-no-vaccination", "deaths", xaxis = "age", + filter = 2040:2050) +``` + +![](figures/stoch_byage_filter.png) + +And if we additionally set the `by_cohort` flag, then we are asking for the +burden breakdown by age, for people who were born within the filtered range, +rather than selecting a calendar year range. + +``` +res <- stone_stochastic_graph(base, "202602yf", "YF", "IC-Gaythorpe", "UGA", + "yf-no-vaccination", "deaths", xaxis = "age", + filter = 2040:2050, by_cohort = TRUE) +``` + +![](figures/stoch_byage_filter_cohort.png) The graph has this shape because the +stochastics here only continue until 2100, hence the last 60-year olds will be +born in 2040. + +### Including data from packit. + +Lastly, if a central burden estimate has been included in a packit in Montagu's +reporting portal, we can include that on a graph by specifying the id, and the +name of the file within that packit. For example, this graph shows both the +stochastics from the file share, and the central from a packit, which is drawn +in blue. + +``` +res <- stone_stochastic_graph(base, "202602yf", "YF", "IC-Gaythorpe", "UGA", + "yf-no-vaccination", "deaths", + packit_id = "20260421-090519-e4a90228", + packit_file = "burden-estimates-disaggregated.rds") + +Visit and enter code DNLH-NMRL + +✔ Waiting for response from server [10.6s] +``` + +![](figures/stoch_packit.png) + +And here's an example of a burden difference graph, showing how much difference +the `yf-routine-default` scenario makes in both the stochastics, and the central +from packit. + +``` +res <- stone_stochastic_graph(base, "202602yf", "YF", "IC-Gaythorpe", "UGA", + c("yf-no-vaccination", "yf-routine-default"), "deaths", + packit_id = "20260421-090519-e4a90228", + packit_file = "burden-estimates-disaggregated.rds") + +Visit and enter code MBWV-NBBC +✔ Waiting for response from server [10.9s] +``` + +![](figures/stoch_packit_diff.png) \## The stochastic explorer shiny app + +All of the graphs above (except currently the packit graphs) can be visualised +interactively using a shiny app that is part of stoner. We call it providing the +path to the root of the standardised stochastic data, where the `meta.csv` file +should also be found. + +``` +stoner::stochastic_explorer(path) +``` -Red is the mean, and green is the median of the stochastics, and the -thicker black lines are the 5% and 95% quantiles. Other useful arguments for -graphs are `by_cohort` which plots a graph with birth cohort on the x-axis instead -of calendar year, `log` which causes the y-axis to be log-scale, and `ages` can be -a vector of ages to filter to, for example `0:4` to plot stochastics of under 5s. +![](figures/stoch_explorer.png) + +The features in the GUI closely map onto the parameters for `stochastic_graph` +in the following ways: + +- The tabs along the top let you choose a single graph, a comparison by + touchstone, or a comparison by modelling group, firstly for simply burdens, + and secondly for differences between scenarios. Different tabs therefore + cause different components in the sidebar to be available. +- One or two touchstones, groups, or scenarios will be available depending on + the tab. +- Whether the x-axis is time or age, and whether by cohort, are all selected + in the x-axis dropdown. +- The filter text, whether for time or for age, is a comma-separated list of + numbers or dash-separated ranges. So in a contrived example, `0-5,50,95-100` + would select the very young, very old, and exactly 50-year olds. diff --git a/vignettes/figures/stoch_burden_diff.png b/vignettes/figures/stoch_burden_diff.png new file mode 100644 index 0000000..8be0700 Binary files /dev/null and b/vignettes/figures/stoch_burden_diff.png differ diff --git a/vignettes/figures/stoch_byage.png b/vignettes/figures/stoch_byage.png new file mode 100644 index 0000000..4b4afe8 Binary files /dev/null and b/vignettes/figures/stoch_byage.png differ diff --git a/vignettes/figures/stoch_byage_filter.png b/vignettes/figures/stoch_byage_filter.png new file mode 100644 index 0000000..d14adf6 Binary files /dev/null and b/vignettes/figures/stoch_byage_filter.png differ diff --git a/vignettes/figures/stoch_byage_filter_cohort.png b/vignettes/figures/stoch_byage_filter_cohort.png new file mode 100644 index 0000000..432c306 Binary files /dev/null and b/vignettes/figures/stoch_byage_filter_cohort.png differ diff --git a/vignettes/figures/stoch_cohort.png b/vignettes/figures/stoch_cohort.png new file mode 100644 index 0000000..1b25b62 Binary files /dev/null and b/vignettes/figures/stoch_cohort.png differ diff --git a/vignettes/figures/stoch_compare_mg_1.png b/vignettes/figures/stoch_compare_mg_1.png new file mode 100644 index 0000000..5e5b16c Binary files /dev/null and b/vignettes/figures/stoch_compare_mg_1.png differ diff --git a/vignettes/figures/stoch_compare_mg_2.png b/vignettes/figures/stoch_compare_mg_2.png new file mode 100644 index 0000000..fdf14cc Binary files /dev/null and b/vignettes/figures/stoch_compare_mg_2.png differ diff --git a/vignettes/figures/stoch_compare_ts_1.png b/vignettes/figures/stoch_compare_ts_1.png new file mode 100644 index 0000000..51de321 Binary files /dev/null and b/vignettes/figures/stoch_compare_ts_1.png differ diff --git a/vignettes/figures/stoch_compare_ts_2.png b/vignettes/figures/stoch_compare_ts_2.png new file mode 100644 index 0000000..ae92b38 Binary files /dev/null and b/vignettes/figures/stoch_compare_ts_2.png differ diff --git a/vignettes/figures/stoch_example_1.png b/vignettes/figures/stoch_example_1.png index a963933..2a62687 100644 Binary files a/vignettes/figures/stoch_example_1.png and b/vignettes/figures/stoch_example_1.png differ diff --git a/vignettes/figures/stoch_explorer.png b/vignettes/figures/stoch_explorer.png new file mode 100644 index 0000000..d39d287 Binary files /dev/null and b/vignettes/figures/stoch_explorer.png differ diff --git a/vignettes/figures/stoch_packit.png b/vignettes/figures/stoch_packit.png new file mode 100644 index 0000000..bb93985 Binary files /dev/null and b/vignettes/figures/stoch_packit.png differ diff --git a/vignettes/figures/stoch_packit_diff.png b/vignettes/figures/stoch_packit_diff.png new file mode 100644 index 0000000..85fa481 Binary files /dev/null and b/vignettes/figures/stoch_packit_diff.png differ diff --git a/vignettes/figures/stoch_u5.png b/vignettes/figures/stoch_u5.png new file mode 100644 index 0000000..b8b8e17 Binary files /dev/null and b/vignettes/figures/stoch_u5.png differ