Skip to content

Commit

Permalink
Implement simplified pev booster interface:
Browse files Browse the repository at this point in the history
 * rename booster_timesteps -> booster_spacing
 * make booster_coverage a matrix (timestep x booster doses)
 * update validation
 * update implementation of attach_booster_listener
 * fix regression tests
 * update documentation
 * update vignettes
  • Loading branch information
giovannic committed Jan 4, 2024
1 parent d49c8dd commit d13e23e
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 245 deletions.
12 changes: 5 additions & 7 deletions R/events.R
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ create_events <- function(parameters) {
function(.) individual::TargetedEvent$new(parameters$human_population)
)
mass_pev_boosters <- lapply(
seq_along(parameters$mass_pev_booster_timestep),
seq_along(parameters$mass_pev_booster_spacing),
function(.) individual::TargetedEvent$new(parameters$human_population)
)
events$mass_pev <- individual::Event$new()
Expand Down Expand Up @@ -129,12 +129,11 @@ attach_event_listeners <- function(
attach_pev_dose_listeners(
variables,
parameters,
parameters$mass_pev_timesteps,
events$mass_pev_doses,
events$mass_pev_boosters,
parameters$mass_pev_booster_timestep,
parameters$mass_pev_booster_spacing,
parameters$mass_pev_booster_coverage,
parameters$mass_pev_timed_booster_coverage,
parameters$mass_pev_timed_booster_coverage_timestep,
parameters$mass_pev_profile_indices,
'mass',
renderer
Expand All @@ -145,12 +144,11 @@ attach_event_listeners <- function(
attach_pev_dose_listeners(
variables,
parameters,
parameters$pev_epi_timesteps,
events$pev_epi_doses,
events$pev_epi_boosters,
parameters$pev_epi_booster_timestep,
parameters$pev_epi_booster_spacing,
parameters$pev_epi_booster_coverage,
parameters$pev_epi_timed_booster_coverage,
parameters$pev_epi_timed_booster_coverage_timestep,
parameters$pev_epi_profile_indices,
'epi',
renderer
Expand Down
27 changes: 9 additions & 18 deletions R/pev.R
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,7 @@ create_pev_efficacy_listener <- function(variables, pev_profile_index) {
create_pev_booster_listener <- function(
variables,
coverage,
timed_coverage = NULL,
timed_coverage_timestep = NULL,
pev_distribution_timesteps,
booster_number,
pev_profile_index,
next_booster_event,
Expand All @@ -194,17 +193,11 @@ create_pev_booster_listener <- function(
force(next_booster_delay)
force(coverage)
function(timestep, target) {
if (is.null(timed_coverage)) {
t_coverage <- 1
} else {
t_coverage <- timed_coverage[
match_timestep(timed_coverage_timestep, timestep)
]
}
target <- sample_bitset(
target,
coverage * t_coverage
)
cov_t <- coverage[
match_timestep(pev_distribution_timesteps, timestep),
booster_number
]
target <- sample_bitset(target, cov_t)
variables$last_pev_timestep$queue_update(timestep, target)
variables$last_eff_pev_timestep$queue_update(timestep, target)
variables$pev_profile$queue_update(pev_profile_index, target)
Expand Down Expand Up @@ -248,12 +241,11 @@ create_dosage_renderer <- function(renderer, strategy, dose) {
attach_pev_dose_listeners <- function(
variables,
parameters,
pev_distribution_timesteps,
dose_events,
booster_events,
booster_delays,
booster_coverages,
booster_timed_coverage,
booster_timed_coverage_timestep,
pev_profile_indices,
strategy,
renderer
Expand Down Expand Up @@ -316,9 +308,8 @@ attach_pev_dose_listeners <- function(
booster_events[[b]]$add_listener(
create_pev_booster_listener(
variables = variables,
coverage = booster_coverages[[b]],
timed_coverage = booster_timed_coverage,
timed_coverage_timestep = booster_timed_coverage_timestep,
coverage = booster_coverages,
pev_distribution_timesteps = pev_distribution_timesteps,
booster_number = b,
pev_profile_index = pev_profile_indices[[b + 1]],
next_booster_event = next_booster_event,
Expand Down
69 changes: 29 additions & 40 deletions R/pev_parameters.R
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ rtss_booster_profile <- create_pev_profile(
#' age. Efficacy will take effect after the last dose
#'
#' @param parameters a list of parameters to modify
#' @param profile primary vaccine profile of type PEVProfile
#' @param profile a list of details for the vaccine profile, create with `create_pev_profile`
#' @param coverages a vector of coverages for the primary doses
#' @param timesteps a vector of timesteps associated with coverages
#' @param age the age when an individual will receive the first dose of the
Expand All @@ -72,14 +72,11 @@ rtss_booster_profile <- create_pev_profile(
#' between an individual receiving the final dose and the first booster. When using
#' both set_mass_pev and set_pev_epi, this represents the minimum time between
#' an individual being vaccinated under one scheme and vaccinated under another.
#' @param booster_timestep the timesteps (following the final dose) at which booster vaccinations are administered
#' @param booster_coverage the proportion of the vaccinated population relative to the last vaccination (whether a previous booster or the primary series)
#' @param booster_timed_coverage a time varying proportion of the vaccinated population relative to the last vaccination (whether a previous booster or the primary series), set in time with `booster_coverage_timestep`
#' @param booster_timed_coverage_timestep a vector of timesteps to change the time varying coverage specified in `booster_timed_coverage`
#' @param booster_profile list of booster vaccine profiles, of type
#' PEVProfile, for each timestep in booster_timeteps
#' @param booster_spacing the timesteps (following the final primary dose) at which booster vaccinations are administered
#' @param booster_coverage a matrix of coverages (timesteps x boosters) specifying the proportion the previously vaccinated population to continue receiving booster doses. The rows of the matrix must be the same size as `timesteps`. The columns of the matrix must be the same size as `booster_spacing`.
#' @param booster_profile list of lists representing each booster profile, the outer list must be the same length as `booster_spacing`. Create vaccine profiles with `create_pev_profile`
#' @param seasonal_boosters logical, if TRUE the first booster timestep is
#' relative to the start of the year, otherwise they are relative to the last dose
#' relative to the start of the year, otherwise they are relative to the last primary dose
#' @export
set_pev_epi <- function(
parameters,
Expand All @@ -88,14 +85,13 @@ set_pev_epi <- function(
timesteps,
age,
min_wait,
booster_timestep,
booster_spacing,
booster_coverage,
booster_timed_coverage = NULL,
booster_timed_coverage_timestep = NULL,
booster_profile,
seasonal_boosters = FALSE
) {
stopifnot(all(coverages >= 0) && all(coverages <= 1))
stopifnot(is.matrix(booster_coverage))

# Check that the primary timing parameters make sense
if(length(coverages) != length(timesteps)){
Expand All @@ -107,19 +103,20 @@ set_pev_epi <- function(
stopifnot(age >= 0)
stopifnot(is.logical(seasonal_boosters))
if (seasonal_boosters) {
if(booster_timestep[[1]] < 0) {
booster_timestep <- booster_timestep + 365
if(booster_spacing[[1]] < 0) {
booster_spacing <- booster_spacing + 365
}
}

# Check that the booster timing parameters make sense
stopifnot((length(booster_timestep) == 0) || all(booster_timestep > 0))
stopifnot((length(booster_spacing) == 0) || all(booster_spacing > 0))
stopifnot((length(booster_coverage)) == 0 || all(booster_coverage >= 0 & booster_coverage <= 1))
if (!all(c(length(booster_coverage), length(booster_timestep), length(booster_profile)) == length(booster_timestep))) {
stop('booster_timestep and booster_coverage and booster_profile does not align')
if (!all(c(ncol(booster_coverage), length(booster_profile)) == length(booster_spacing))) {
stop('booster_spacing, booster_coverage and booster_profile do not align')
}
if (length(booster_timed_coverage) != length(booster_timed_coverage_timestep)) {
stop("booster_coverage_timestep must be the same length as booster_coverage")
# Check that booster_coverage and timesteps align
if (nrow(booster_coverage) != length(timesteps)) {
stop('booster_coverage and timesteps do not align')
}

# Index the new vaccine profiles
Expand All @@ -132,12 +129,9 @@ set_pev_epi <- function(
parameters$pev_epi_coverages <- coverages
parameters$pev_epi_timesteps <- timesteps
parameters$pev_epi_age <- age
parameters$pev_epi_booster_timestep <- booster_timestep
parameters$pev_epi_booster_spacing <- booster_spacing
parameters$pev_epi_min_wait <- min_wait
parameters$pev_epi_booster_coverage <- booster_coverage
parameters$pev_epi_timed_booster_coverage <- booster_timed_coverage
parameters$pev_epi_timed_booster_coverage_timestep <- booster_timed_coverage_timestep
parameters$pev_epi_booster_coverage <- booster_coverage
parameters$pev_epi_profile_indices <- profile_indices
parameters$pev_epi_seasonal_boosters <- seasonal_boosters
parameters
Expand All @@ -149,20 +143,17 @@ set_pev_epi <- function(
#' Efficacy will take effect after the last dose
#'
#' @param parameters a list of parameters to modify
#' @param profile primary vaccine profile of type PEVProfile
#' @param profile a list of details for the vaccine profile, create with `create_pev_profile`
#' @param timesteps a vector of timesteps for each round of vaccinations
#' @param coverages the coverage for each round of vaccinations
#' @param min_wait the minimum acceptable time since the last vaccination (in timesteps);
#' When using both set_mass_pev and set_pev_epi, this represents the minimum
#' time between an individual being vaccinated under one scheme and vaccinated under another.
#' @param min_ages for the target population, inclusive (in timesteps)
#' @param max_ages for the target population, inclusive (in timesteps)
#' @param booster_timestep the timesteps (following the initial vaccination) at which booster vaccinations are administered
#' @param booster_coverage the proportion of the vaccinated population relative to the last vaccination (whether a previous booster or the primary series)
#' @param booster_timed_coverage a time varying proportion of the vaccinated population relative to the last vaccination (whether a previous booster or the primary series), set in time with `booster_coverage_timestep`
#' @param booster_timed_coverage_timestep a vector of timesteps to change the time varying coverage specified in `booster_timed_coverage`
#' @param booster_profile list of booster vaccine profiles, of type
#' PEVProfile, for each timestep in booster_timeteps
#' @param booster_spacing the timesteps (following the final primary dose) at which booster vaccinations are administered
#' @param booster_coverage a matrix of coverages (timesteps x boosters) specifying the proportion the previously vaccinated population to continue receiving booster doses. The rows of the matrix must be the same size as `timesteps`. The columns of the matrix must be the same size as `booster_spacing`.
#' @param booster_profile list of lists representing each booster profile, the outer list must be the same length as `booster_spacing`. Create vaccine profiles with `create_pev_profile`
#' @export
set_mass_pev <- function(
parameters,
Expand All @@ -172,26 +163,26 @@ set_mass_pev <- function(
min_ages,
max_ages,
min_wait,
booster_timestep,
booster_spacing,
booster_coverage,
booster_timed_coverage = NULL,
booster_timed_coverage_timestep = NULL,
booster_profile
) {
stopifnot(all(timesteps >= 1))
stopifnot(min_wait >= 0)
stopifnot(all(coverages >= 0) && all(coverages <= 1))
stopifnot(all(min_ages >= 0 & max_ages >= 0))
stopifnot(all(booster_timestep > 0))
stopifnot(all(booster_spacing > 0))
stopifnot(all(booster_coverage >= 0 & booster_coverage <= 1))
if (length(min_ages) != length(max_ages)) {
stop('min and max ages do not align')
}
if (!all(c(length(booster_coverage), length(booster_timestep), length(booster_profile)) == length(booster_timestep))) {
stop('booster_timestep, booster_coverage and booster_profile does not align')
stopifnot((length(booster_coverage)) == 0 || all(booster_coverage >= 0 & booster_coverage <= 1))
if (!all(c(ncol(booster_coverage), length(booster_profile)) == length(booster_spacing))) {
stop('booster_spacing, booster_coverage and booster_profile do not align')
}
if (length(booster_timed_coverage) != length(booster_timed_coverage_timestep)) {
stop("booster_coverage_timestep must be the same length as booster_coverage")
# Check that booster_coverage and timesteps align
if (nrow(booster_coverage) != length(timesteps)) {
stop('booster_coverage and timesteps do not align')
}

# Index the new vaccine profiles
Expand All @@ -206,10 +197,8 @@ set_mass_pev <- function(
parameters$mass_pev_min_ages <- min_ages
parameters$mass_pev_max_ages <- max_ages
parameters$mass_pev_min_wait <- min_wait
parameters$mass_pev_booster_timestep <- booster_timestep
parameters$mass_pev_booster_spacing <- booster_spacing
parameters$mass_pev_booster_coverage <- booster_coverage
parameters$mass_pev_booster_timed_coverage <- booster_timed_coverage
parameters$mass_pev_booster_timed_coverage_timestep <- booster_timed_coverage_timestep
parameters$mass_pev_profile_indices <- profile_indices
parameters
}
Expand Down
17 changes: 5 additions & 12 deletions man/set_mass_pev.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 6 additions & 13 deletions man/set_pev_epi.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions tests/testthat/test-infection-integration.R
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ test_that('calculate_infections works various combinations of drug and vaccinati
min_ages = 0,
max_ages = 100 * 365,
min_wait = 0,
booster_timestep = 365,
booster_coverage = 1,
booster_spacing = 365,
booster_coverage = matrix(1),
booster_profile = list(rtss_booster_profile)
)

Expand Down
Loading

0 comments on commit d13e23e

Please sign in to comment.