From 86424e71861d4405be49afd54e32d3c83ff89ea1 Mon Sep 17 00:00:00 2001 From: Giovanni Charles Date: Fri, 15 Sep 2023 12:07:26 +0100 Subject: [PATCH] Fix bug with pev min_wait: * Update pev-epi min_wait test to directly check sample population * Update pe-epi min_wait test to check that pev_timestep is being updated on the first dose * Copy pev-epi min_wait test to mass pev * Update pev and epi processes to calculate targets based on time of first dose * Update infection immunity function to calculate pev immunity only after 3rd dose --- DESCRIPTION | 2 +- NEWS.md | 6 +++ R/human_infection.R | 4 +- R/pev.R | 12 ++++++ R/variables.R | 6 ++- tests/testthat/test-pev-epi.R | 32 +++++++++------- tests/testthat/test-pev.R | 69 +++++++++++++++++++++++++++++++++++ 7 files changed, 114 insertions(+), 17 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 3396705b..1d971723 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: malariasimulation Title: An individual based model for malaria -Version: 1.6.0 +Version: 1.6.1 Authors@R: c( person( given = "Giovanni", diff --git a/NEWS.md b/NEWS.md index 826bf0d0..0d75d61d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,9 @@ + +# malariasimulation 1.6.1 (wip) + + * Fix bug with min_wait. Min wait was working off of the final primary dose. It + now works of of the first dose. + # malariasimulation 1.6.0 * Fix MDA bug where undetectable asymptomatics are treated diff --git a/R/human_infection.R b/R/human_infection.R index b623a2d8..331c397d 100644 --- a/R/human_infection.R +++ b/R/human_infection.R @@ -130,8 +130,10 @@ calculate_infections <- function( # calculate vaccine efficacy vaccine_efficacy <- rep(0, length(source_vector)) vaccine_times <- variables$pev_timestep$get_values(source_vector) - vaccinated <- vaccine_times > -1 pev_profile <- variables$pev_profile$get_values(source_vector) + # get vector of individuals who have been vaccinated + # and received their 3rd dose + vaccinated <- pev_profile > -1 pev_profile <- pev_profile[vaccinated] if (length(vaccinated) > 0) { antibodies <- calculate_pev_antibodies( diff --git a/R/pev.R b/R/pev.R index 4c735552..00371097 100644 --- a/R/pev.R +++ b/R/pev.R @@ -48,6 +48,11 @@ create_epi_pev_process <- function( ) ] + # Update the latest vaccination time + variables$pev_timestep$queue_update(timestep, target) + # Reset the pev_profile so that we are not yet efficacious + variables$pev_profile$queue_update(-1, target) + schedule_vaccination( target, events, @@ -99,6 +104,13 @@ create_mass_pev_listener <- function( correlations ) ] + + # Update the latest vaccination time + variables$pev_timestep$queue_update(timestep, target) + # Reset the pev_profile so that we are not yet efficacious + variables$pev_profile$queue_update(-1, target) + + # Schedule future doses schedule_vaccination( target, events, diff --git a/R/variables.R b/R/variables.R index 0931b3f7..d200f279 100644 --- a/R/variables.R +++ b/R/variables.R @@ -20,8 +20,10 @@ #' * zeta_group - Discretised heterogeneity of human individuals #' * pev_timestep - The timestep of the last pev vaccination (-1 if there #' haven't been any) -#' * pev_profile - The index of the profile of the last administered pev vaccine -#' (-1 if there haven't been any) +#' * pev_profile - The index of the profile of the last administered pev +#' vaccine. +#' This is only set on the final primary dose and subsequent booster doses +#' (-1 otherwise) #' * tbv_vaccinated - The timstep of the last tbv vaccination (-1 if there #' haven't been any #' * net_time - The timestep when a net was last put up (-1 if never) diff --git a/tests/testthat/test-pev-epi.R b/tests/testthat/test-pev-epi.R index 4eea8445..1b8d1cf5 100644 --- a/tests/testthat/test-pev-epi.R +++ b/tests/testthat/test-pev-epi.R @@ -89,46 +89,52 @@ test_that('pev epi targets correct age and respects min_wait', { variables$pev_timestep <- mock_integer( c(50, -1, -1, 4*365, -1) ) + variables$pev_profile <- mock_integer( + c(1, -1, -1, 1, -1) + ) - events$pev_epi_doses <- lapply(events$pev_epi_doses, mock_event) - + correlations <- get_correlation_parameters(parameters) process <- create_epi_pev_process( variables, events, parameters, - get_correlation_parameters(parameters), + correlations, parameters$pev_epi_coverages, parameters$pev_epi_timesteps ) + sample_mock <- mockery::mock(c(TRUE, TRUE, FALSE)) mockery::stub( process, 'sample_intervention', - mockery::mock(c(TRUE, TRUE, FALSE)) + sample_mock ) process(timestep) mockery::expect_args( - events$pev_epi_doses[[1]]$schedule, + sample_mock, 1, - c(1, 2), - parameters$pev_doses[[1]] + c(1, 2, 5), + 'pev', + .8, + correlations ) mockery::expect_args( - events$pev_epi_doses[[2]]$schedule, + variables$pev_timestep$queue_update_mock(), 1, - c(1, 2), - parameters$pev_doses[[2]] + timestep, + c(1, 2) ) mockery::expect_args( - events$pev_epi_doses[[3]]$schedule, + variables$pev_profile$queue_update_mock(), 1, - c(1, 2), - parameters$pev_doses[[3]] + -1, + c(1, 2) ) + }) test_that('pev EPI respects min_wait when scheduling seasonal boosters', { diff --git a/tests/testthat/test-pev.R b/tests/testthat/test-pev.R index 5cb09c5d..2e28bbe1 100644 --- a/tests/testthat/test-pev.R +++ b/tests/testthat/test-pev.R @@ -345,6 +345,75 @@ test_that('Mass booster coverages sample subpopulations correctly', { ) }) +test_that('mass pev targets correct age and respects min_wait', { + timestep <- 5*365 + parameters <- get_parameters(list(human_population = 5)) + parameters <- set_mass_pev( + parameters, + profile = rtss_profile, + timesteps = c(4, 5) * 365, + coverages = c(0.8, 0.8), + min_ages = 0, + max_ages = 19 * 365, + min_wait = 2*365, + booster_timestep = c(1, 6) * 30, + booster_coverage = c(.9, .8), + booster_profile = list(rtss_booster_profile, rtss_booster_profile) + ) + events <- create_events(parameters) + variables <- create_variables(parameters) + variables$birth <- individual::IntegerVariable$new( + -c(18, 18, 30, 18, 18) * 365 + timestep + ) + variables$pev_timestep <- mock_integer( + c(50, -1, -1, 4*365, -1) + ) + + variables$pev_profile <- mock_integer( + c(1, -1, -1, 1, -1) + ) + + correlations <- get_correlation_parameters(parameters) + listener <- create_mass_pev_listener( + variables, + events, + parameters, + get_correlation_parameters(parameters) + ) + + sample_mock <- mockery::mock(c(TRUE, TRUE, FALSE)) + mockery::stub( + listener, + 'sample_intervention', + sample_mock + ) + + listener(timestep) + + mockery::expect_args( + sample_mock, + 1, + c(1, 2, 5), + 'pev', + .8, + correlations + ) + + mockery::expect_args( + variables$pev_timestep$queue_update_mock(), + 1, + timestep, + c(1, 2) + ) + + mockery::expect_args( + variables$pev_profile$queue_update_mock(), + 1, + -1, + c(1, 2) + ) +}) + test_that('Mass efficacy listener works correctly', { timestep <- 50 parameters <- get_parameters()