{"id":18399720,"url":"https://github.com/mrc-ide/frogger","last_synced_at":"2025-04-12T16:23:34.991Z","repository":{"id":37087180,"uuid":"501190497","full_name":"mrc-ide/frogger","owner":"mrc-ide","description":null,"archived":false,"fork":false,"pushed_at":"2025-04-09T16:46:14.000Z","size":294771,"stargazers_count":0,"open_issues_count":49,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-09T17:47:36.671Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://mrc-ide.github.io/frogger/","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mrc-ide.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2022-06-08T09:50:30.000Z","updated_at":"2025-04-07T08:47:46.000Z","dependencies_parsed_at":"2023-09-28T16:34:27.957Z","dependency_job_id":"368e02e1-9339-480c-8f5e-373317bc3525","html_url":"https://github.com/mrc-ide/frogger","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrc-ide%2Ffrogger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrc-ide%2Ffrogger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrc-ide%2Ffrogger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrc-ide%2Ffrogger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mrc-ide","download_url":"https://codeload.github.com/mrc-ide/frogger/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248594359,"owners_count":21130354,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T02:28:18.846Z","updated_at":"2025-04-12T16:23:34.952Z","avatar_url":"https://github.com/mrc-ide.png","language":"C++","readme":"\n\u003c!-- README.md is generated from README.Rmd. Please edit that file --\u003e\n\n# frogger\n\n\u003c!-- badges: start --\u003e\n\n[![Project Status: Concept – Minimal or no implementation has been done\nyet, or the repository is only intended to be a limited example, demo,\nor\nproof-of-concept.](https://www.repostatus.org/badges/latest/concept.svg)](https://www.repostatus.org/#concept)\n[![R build\nstatus](https://github.com/mrc-ide/frogger/workflows/R-CMD-check/badge.svg)](https://github.com/mrc-ide/frogger/actions)\n[![codecov.io](https://codecov.io/github/mrc-ide/frogger/coverage.svg?branch=main)](https://codecov.io/github/mrc-ide/frogger?branch=main)\n\u003c!-- badges: end --\u003e\n\nLeapfrog is a multistate population projection model for demographic and\nHIV epidemic estimation.\n\nThe name *leapfrog* is in honor of\n[Professor](https://iussp.org/en/basia-zaba-1949-2018) Basia\n[Zaba](https://translate.google.co.uk/?sl=pl\u0026tl=en\u0026text=Zaba\u0026op=translate).\n\n## Installation\n\nYou can install the development version of frogger from\n[GitHub](https://github.com/) with:\n\n``` r\n# install.packages(\"remotes\")\nremotes::install_github(\"mrc-ide/frogger\")\n```\n\n## Simulation model\n\nThe simulation model is implemented in a header-only C++ library located\nin [`inst/include/frogger.hpp`](inst/include/frogger.hpp). This location\nallows the C++ code to be imported in other R packages via specifying\n`LinkingTo: leapfrog` in the `DESCRIPTION` file.\n\n\u003e [!IMPORTANT]\n\u003e We use C++20 for this package. Please make sure you have a compiler that is compatible.\n\nThe simulation model is callable in R via a wrapper function\n`run_model()` created with [Rcpp](https://www.rcpp.org).\n\nYou can control how the simulation model is run with the following\narguments:\n\n- `run_hiv_simulation` which is `TRUE` by default. Set to `FALSE` to\n  turn off the HIV simulation and run only the demographic projection.\n- `hiv_age_stratification` which must be “coarse” or “full”. Coarse is\n  run with 5-year age groups and full with single year ages.\n- `run_child_model` which is `FALSE` by default. Set to `TRUE` to run\n  the child portion of the model.\n\n## Example\n\nThe file `pjnz/bwa_aim-adult-art-no-special-elig_v6.13_2022-04-18.PJNZ`\ncontains an example Spectrum file constructed from default country data\nfor Botswana with Spectrum (April 2022).\n\nPrepare model inputs.\n\n``` r\nlibrary(frogger)\n\npjnz \u003c- system.file(\"pjnz/bwa_aim-adult-art-no-special-elig_v6.13_2022-04-18.PJNZ\",\n                    package = \"frogger\", mustWork = TRUE)\n\ndemp \u003c- prepare_leapfrog_demp(pjnz)\nhivp \u003c- prepare_leapfrog_projp(pjnz)\n```\n\nSimulate adult ‘full’ age group (single-year age) and ‘coarse’ age group\n(collapsed age groups) models from 1970 to 2030 with 10 HIV time steps\nper year.\n\n``` r\nlsimF \u003c- run_model(demp, hivp, 1970:2030, 10L,\n                   hiv_age_stratification = \"full\", run_child_model = FALSE)\nlsimC \u003c- run_model(demp, hivp, 1970:2030, 10L,\n                   hiv_age_stratification = \"coarse\", run_child_model = FALSE)\n```\n\nCompare the HIV prevalence age 15-49 years and AIDS deaths 50+ years.\nDeaths 50+ years are to show some noticeable divergence between the\n`\"full\"` and `\"coarse\"` age group simulations.\n\n``` r\nprevF \u003c- colSums(lsimF$p_hiv_pop[16:50,,],,2) / colSums(lsimF$p_total_pop[16:50,,],,2)\nprevC \u003c- colSums(lsimC$p_hiv_pop[16:50,,],,2) / colSums(lsimC$p_total_pop[16:50,,],,2)\n\ndeathsF \u003c- colSums(lsimF$p_hiv_deaths[51:81,,],,2)\ndeathsC \u003c- colSums(lsimC$p_hiv_deaths[51:81,,],,2)\n\nplot(1970:2030, prevF, type = \"l\", main = \"Prevalence 15-49\")\nlines(1970:2030, prevC, col = 2)\n```\n\n\u003cimg src=\"man/figures/README-sim_prev-1.png\" width=\"100%\" /\u003e\n\n``` r\n\nplot(1970:2030, deathsF, type = \"l\", main = \"AIDS Deaths 50+ years\")\nlines(1970:2030, deathsC, col = 2)\n```\n\n\u003cimg src=\"man/figures/README-sim_prev-2.png\" width=\"100%\" /\u003e\n\n## Benchmarking\n\nInstall the package and then run the benchmarking script\n`./scripts/benchmark`\n\n## lint\n\nLint R code with `lintr`\n\n``` r\nlintr::lint_package()\n```\n\nLint C++ code with [cpplint](https://github.com/cpplint/cpplint)\n\n``` console\ncpplint inst/include/*\n```\n\n## Code design\n\n### Simulation model\n\nThe simulation model is implemented as templated C++ code in\n`inst/include/frogger.hpp`. This is so the simulation model may be\ndeveloped as a standalone C++ library that can be called by other\nsoftware without requiring R-specific code features. The code uses\nheader-only open source libraries to maximize portability.\n\n### Code generation\n\nTo change what parameters can be passed in from `R` or the structure\nof `Intermediate`, `State` or `OutputState`, please modify json files\n[here](./cpp_generation/modelSchemas/).\n\nThen to run code generation follow [cpp_generation/README.md](./cpp_generation/README.md)\n\n### R functions\n\nThe file `src/frogger.cpp` contains R wrapper functions for the model\nsimulation via [Rcpp](http://dirk.eddelbuettel.com/code/rcpp.html) and\n[RcppEigen](http://dirk.eddelbuettel.com/code/rcpp.eigen.html).\n\n## Development notes\n\n### Testing\n\nThere is some pre-prepared test data available to make tests run faster.\nThis is generated and saved `./scripts/create_test_data.R`.\n\nWe also have some separate data written out in a generic format which\ncan be read to test the model directly from C++. This is in\n`inst/standalone_model/data` in zipped files.\n\nIf this is your first time running you will need to unzip the standalone\ntest data\n\n    ./inst/standalone_model/extract_data\n\nIf you want to update the test data, it should be updated in the\n`./scripts/create_test_data.R` script so that we know how it was created\nand we can do it again fairly easily. Steps are 1. Update the script and\ngenerate the test data 1. Update the standalone data which is built from\nthis `./scripts/update_standalone_data`. You might need to add a new\nmapping from R to serialized name if you are adding new input data 1.\nUnzip this for automated tests `./inst/standalone_model/extract_data`\n\n### Simulation model\n\n- The model was implemented using *Eigen::Tensor* containers. These were\n  preferred for several reasons:\n  - Benchmarking found they were slighlty more efficient than\n    *boost::multi_array*.\n  - Column-major indexing in the same order as R\n  - Other statistical packages (e.g. TMB, Stan) rely heavily on *Eigen*\n    so using *Eigen* containers slims the dependencies.\n\n### TODO\n\n- Restructuring the model code to identify more common code\n  - There are examples like general demographic projection and hiv\n    population demographic projection which are running similar\n    processes like ageing, non HIV mortality, migration. We should be\n    able to write a function for e.g. ageing which we can run on each of\n    our population matrices. Even for the HIV and ART stratified we can\n    add overloaded function to work with higher dimension data\n- Add a test that checks that no `double`s are used in `inst/include`\n  dir. We should be using templated `real_type` for TMB\n- Add a broad level overview of the algorithm - is there a diagram\n  available?\n- Convert string flags to the model to enums if we need to switch on\n  them in several places. This should make it easier to reason about in\n  C++ world and isolate the string checking to a single place\n- Previously `hiv_negative_pop` was fixed size by having dimensions\n  specified by template, how much does this speed up the code? Is there\n  a better way to do this?\n- Tidy up confusing looping see\n  \u003chttps://github.com/mrc-ide/frogger/pull/7#discussion_r1217847753\u003e\n- Add R casting helpers which return better errors than Rcpp see\n  \u003chttps://github.com/mrc-ide/frogger/pull/7#discussion_r1217884684\u003e\n- Add a helper to do 0 to base 1 conversion and check upper bounds see\n  \u003chttps://github.com/mrc-ide/frogger/pull/7#discussion_r1217888684\u003e\n- Review what we pass as parameters - can some of these be computed in\n  the struct ctor?\n  e.g. \u003chttps://github.com/mrc-ide/frogger/pull/7#discussion_r1217890466\u003e\n- Refactor `OutputState` to take a struct of state-space dimensions\n  instead of unpacking the subset of parameters we need. See\n  \u003chttps://github.com/mrc-ide/frogger/pull/12#discussion_r1245170775\u003e\n\n## License\n\nMIT © Imperial College of Science, Technology and Medicine\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrc-ide%2Ffrogger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmrc-ide%2Ffrogger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrc-ide%2Ffrogger/lists"}