mrc-ide / leapfrog

Multistate population projection model for demographic estimation.
Other
2 stars 5 forks source link

Leapfrog requirements #13

Open r-ash opened 2 years ago

r-ash commented 2 years ago

Leapfrog is an extensible implementation of HIV EPP-ASM model which will act as a common code base for R, Spectrum and any other applications which want to use the model

Requirements

Qs

  1. What type of model is it? (A compartmental model?)
  2. Can it be implemented in odin - if not why not?
  3. What ways do we want to extend it?
r-ash commented 2 years ago
  1. Yes -- compartmental. The model is a consolidated version of Spectrum / EPP-ASM / Shiny90
  2. I don't think so; I think (1) too many janky things happening, (2) need for templated code to interface with TMB, (3) one of the requirements is to be able to step in and out of the simulation (e.g. do some of the steps in leapfrog, then some steps in different code, then back into leapfrog)
  3. Similar to how we extended EPP-ASM to create Shiny90. (I'm not sure if this is a helpful analogy for you or not; but that's basically it) The extension are all essentially adding more compartments. how to best modularise the code is to be worked out. Ideally it would be different functions that could be called sequentially (similar to the stepping in and out), but I'm not sure that will be possible. it might be more loops / if statements

This package has the proposed pattern for interfacing with TMB: https://github.com/mrc-ide/ccmpp.tmb It also has an attempt at a class-structured simulation model.

r-ash commented 2 years ago

Idea for this is to have templated C++ code packages as a header only library. The templating means we can use it with TMB. It will be class structured and have methods for each step of the model like

model_fit
+ demography_projection
+ adult_art
+ mortality
+ births

etc. and then each time step will run each of these functions (demography_projection, adult_art, etc.).

Avenir will want to extend this to e.g. include TB values in the model, they will do this by calling the functions that they want to run and then running some additional code they write themselves to simulate the rest of the model they want to add. They will then loop over this for however number of time steps.

For researchers to extend this they will fork the code, make additions and then we can integrate them into the code as a PR. The base model will need to still be runnable without any extensions so we need feature switches. We could manage this by having a runner which defines different types of model run. Where each one calls different functions from the class. e.g. a

base_model <- function() {
  fit = new model_fit()
  for each time step {
    fit$demography()
    fit$adult_art()
    fit$mortality()
    ...
  }
}
paediatric_model <- function() {
  fit = new model_fit()
  for each time step {
    fit$demography()
    fit$adult_art()
    fit$child_art()
    fit$mortality()
    ...
  }
}

We could alternatively have switches. run_model(include_paediatric = TRUE) but might get complicated with a large amount of switches.

The R wrapper will use Rcpp or cpp11.

Jeff is keen that we modify the memory in place. So the model will take pointers to the data, the model fit will modify that data in place and then Avenir's extensions will also modify the data in place.

r-ash commented 2 years ago

Different models and steps

MVP

EPPASM Adds

shiny90 Adds

CSAVR

Spectrum/AIM (will be implemented by Spectrum)

r-ash commented 1 year ago

Avenir also want to be able to run 1 year and then see the output. They will run 1 year, run some further process on the data. Then run next year in the projection and run some other process etc.

Avenir will want the model as is with Maggie's fertility work

Would be helpful if we can make a diagram of what the model does

r-ash commented 1 year ago

Avenir requirements

Avenir will write their own C++ wrapper which will do the mapping from python types in C++. They want to be able to run it like

// ...initialize inputs and outputs…
calc_baseyear_events(); // calculate births and deaths in the first year of the projection
for year in years:
      project_pop_one_year(year);         // do demographic calculations for one year
      project_hiv_one_year(year);         // do HIV dynamics calculations for one year
      calc_net_migration(year, has_aim);  // do end-year net migration calculations. “has_aim” flag is used to toggle use of HIV+ net migrant inputs
      adjust_population(year);            // apply population adjustment file if used
      postyear_hiv_calcs(year);           // tally results (this currently calculates the ultimate need for ART in children and adults