mrc-ide / malariasimulation

The malaria model
https://mrc-ide.github.io/malariasimulation
Other
16 stars 14 forks source link

Intervention coverage checks to help avoid ambiguous run failures #195

Closed pwinskill closed 1 year ago

pwinskill commented 2 years ago

Currently, there are no checks that input intervention coverages are in [0, 1]. Running the model with coverages outside of this range can lead to ambiguous errors on failure, such as: Error in bitset_insert(self$.bitset, v) : Insert out of range To avoid this, we could add a simple range check on the coverage arguments for any set_intervention() helpers?

giovannic commented 2 years ago

Do you have a full traceback? it's not yet clear to me how an invalid intervention coverage leads to the bitset_insert.

But it would be nice regardless to validate intervention coverages at parameterisation time. We should cover:

pwinskill commented 2 years ago

Sorry yes, so to use a modified vignette example:

library(malariasimulation)

simparams <- get_parameters(
  list(
    human_population = 1000,
    model_seasonality = TRUE,
    g0 = 0.28605,
    g = c(0.20636, -0.0740318, -0.0009293),
    h = c(0.173743, -0.0730962, -0.116019)
  )
)
simparams <- set_equilibrium(simparams, init_EIR = 20)
simparams <- set_drugs(simparams, list(SP_AQ_params))

smcparams <- simparams
peak <- peak_season_offset(smcparams)
smc_events = data.frame(
  timestep = c(1, 2) * 365 + peak - 30
)
smcparams <- set_smc(
  smcparams,
  drug = 1,
  timesteps = smc_events$timestep,
  coverages = c(0.1, 11),
  min_ages = rep(2 * 365 - 1, length(smc_events$timestep)),
  max_ages = rep(11 * 365, length(smc_events$timestep))
)

output <- run_simulation(10*365, smcparams)

Gives the following error:

Error in bitset_insert(self$.bitset, v) : Insert out of range
In addition: Warning message:
In qnorm(p, 0) :
 Error in bitset_insert(self$.bitset, v) : Insert out of range

With the following traceback

8. stop(structure(list(message = "Insert out of range", call = bitset_insert(self$.bitset, 
v), cppstack = NULL), class = c("Rcpp::exception", "C++Error", 
"error", "condition")))
7. bitset_insert(self$.bitset, v)
6. to_move$insert(target[successful_treatments]) at mda_processes.R#44
5. listener(event_get_timestep(self$.event))
4. self$.process_listener(listener)
3. event$.process()
2. individual::simulation_loop(processes = create_processes(renderer, 
variables, events, parameters, vector_models, solvers, correlations, 
list(create_lagged_eir(variables, solvers, parameters)), 
list(create_lagged_infectivity(variables, parameters))), ... at model.R#107
1. run_simulation(10 * 365, smcparams)
pwinskill commented 2 years ago

Not super obvious to me where it is failing. I wonder if the qnorm(p, 0) call, which I think only pops up in the correlations, is the culprit?

giovannic commented 2 years ago

sounds right. qnorm(11) gives NaN and a warning message. I'd guess when that's cast to a size_t for bitset_insert it becomes a really big number, hence out of range.

Great catch!