├── .Rbuildignore ├── .github ├── .gitignore ├── CODEOWNERS ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ ├── maintenance.md │ └── scientific-improvement.md ├── PULL_REQUEST_TEMPLATE │ ├── pull_request_template.md │ └── vulnerability.md ├── SUPPORT.md └── workflows │ ├── pkgdown.yaml │ ├── pre-commit.yaml │ └── r-cmd-check.yaml ├── .gitignore ├── .lintr ├── .pre-commit-config.yaml ├── .secrets.baseline ├── DESCRIPTION ├── LICENSE ├── NAMESPACE ├── NEWS.md ├── R ├── checkers.R ├── compile_model.R ├── data.R ├── delay_distribs.R ├── figures.R ├── generate_simulated_data.R ├── get_draws.R ├── get_params.R ├── get_stan_data.R ├── initialization.R ├── model_component_fwd_sim.R ├── model_diagnostics.R ├── preprocessing.R ├── utils.R ├── validate.R ├── wwinference-package.R └── wwinference.R ├── README.md ├── _pkgdown.yml ├── data-raw ├── covid_pmfs.R └── vignette_data.R ├── data ├── default_covid_gi.rda ├── default_covid_inf_to_hosp.rda ├── hosp_data.rda ├── hosp_data_eval.rda ├── subpop_hosp_data.rda ├── subpop_hosp_data_eval.rda ├── true_global_rt.rda ├── ww_data.rda └── ww_data_eval.rda ├── inst ├── extdata │ └── example_params.toml └── stan │ ├── functions │ ├── ar1.stan │ ├── convolve.stan │ ├── diff_ar1.stan │ ├── expgamma_lpdf.stan │ ├── hospitalization.stan │ ├── infections.stan │ ├── observation_model.stan │ └── utils.stan │ └── wwinference.stan ├── man ├── .DS_Store ├── add_pmfs.Rd ├── add_time_indexing.Rd ├── assert_cols_det_unique_row.Rd ├── assert_daily_data.Rd ├── assert_dates_within_frame.Rd ├── assert_df_not_empty.Rd ├── assert_elements_non_neg.Rd ├── assert_equivalent_indexing.Rd ├── assert_int_or_char.Rd ├── assert_no_dates_after_max.Rd ├── assert_no_repeated_elements.Rd ├── assert_non_missingness.Rd ├── assert_req_count_cols_present.Rd ├── assert_req_ww_cols_present.Rd ├── assert_rt_correct_length.Rd ├── assert_single_value.Rd ├── assert_site_lab_indices_align.Rd ├── assert_sufficient_days_of_data.Rd ├── assert_ww_site_pops_lt_total.Rd ├── autoescape_brackets.Rd ├── calc_rt.Rd ├── compile_model.Rd ├── convert_to_logmean.Rd ├── convert_to_logsd.Rd ├── create_dir.Rd ├── create_site_lab_map.Rd ├── default_covid_gi.Rd ├── default_covid_inf_to_hosp.Rd ├── downsample_for_frequency.Rd ├── drop_first_and_renormalize.Rd ├── figures │ ├── .DS_Store │ ├── logo.svg │ ├── wwinference_package_workflow.svg │ └── wwinference_workflow.png ├── flag_ww_outliers.Rd ├── format_hosp_data.Rd ├── format_subpop_hosp_data.Rd ├── format_ww_data.Rd ├── generate_simulated_data.Rd ├── get_count_data_sizes.Rd ├── get_count_indices.Rd ├── get_count_values.Rd ├── get_date_time_spine.Rd ├── get_draws.Rd ├── get_global_rt.Rd ├── get_ind_m.Rd ├── get_inits_for_one_chain.Rd ├── get_input_count_data_for_stan.Rd ├── get_input_ww_data_for_stan.Rd ├── get_lab_site_site_spine.Rd ├── get_lab_site_subpop_spine.Rd ├── get_mcmc_options.Rd ├── get_model_diagnostic_flags.Rd ├── get_model_spec.Rd ├── get_params.Rd ├── get_plot_forecasted_counts.Rd ├── get_plot_global_rt.Rd ├── get_plot_subpop_rt.Rd ├── get_plot_ww_conc.Rd ├── get_pred_obs_conc.Rd ├── get_pred_subpop_gen_per_n.Rd ├── get_site_subpop_spine.Rd ├── get_stan_data.Rd ├── get_time_varying_daily_ihr.Rd ├── get_ww_data_sizes.Rd ├── get_ww_indices_and_values.Rd ├── hosp_data.Rd ├── hosp_data_eval.Rd ├── indicate_ww_exclusions.Rd ├── make_hospital_onset_delay_pmf.Rd ├── make_incubation_period_pmf.Rd ├── make_reporting_delay_pmf.Rd ├── parameter_diagnostics.Rd ├── preprocess_count_data.Rd ├── preprocess_ww_data.Rd ├── simulate_double_censored_pmf.Rd ├── subpop_hosp_data.Rd ├── subpop_hosp_data_eval.Rd ├── subpop_inf_process.Rd ├── subpop_rt_process.Rd ├── summary_diagnostics.Rd ├── throw_type_error.Rd ├── to_simplex.Rd ├── true_global_rt.Rd ├── truncate_for_latency.Rd ├── validate_count_data.Rd ├── validate_data_jointly.Rd ├── validate_paramlist.Rd ├── validate_pmf.Rd ├── validate_ww_conc_data.Rd ├── ww_data.Rd ├── ww_data_eval.Rd ├── wwinference-package.Rd └── wwinference.Rd ├── model_definition.md ├── scratch └── sim_data_script.R ├── tests ├── testthat.R └── testthat │ ├── helper.R │ ├── setup.R │ ├── test_ar1.R │ ├── test_ar1_marginal_variance.R │ ├── test_checkers.R │ ├── test_diff_ar1.R │ ├── test_flag_as_ww_outliers.R │ ├── test_get_stan_data.R │ ├── test_helper.R │ ├── test_ihr_transform.R │ ├── test_indicate_ww_exclusions.R │ ├── test_models_run_without_ww.R │ ├── test_plots.R │ ├── test_pmfs_normalized.R │ ├── test_preprocess_count_data.R │ ├── test_preprocess_ww_data.R │ ├── test_rt_assembly.R │ └── test_wwinference.R └── vignettes └── wwinference.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^_pkgdown\.yml$ 2 | ^docs$ 3 | ^pkgdown$ 4 | ^\.github$ 5 | ^.*\.Rproj$ 6 | ^\.Rproj\.user$ 7 | 8 | # Misc 9 | ^data-raw$ 10 | ^model_definition\.md$ 11 | ^scratch$ 12 | 13 | # Hidden files/folders 14 | ^\..+ 15 | 16 | # Because R doesn't like having a copy of this 17 | # type of license in the package. 18 | LICENSE 19 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | *@kaitejohnson @dylanhmorris 2 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to `wwinference` 2 | 3 | This outlines how to propose a change to `wwinference`. 4 | 5 | ## Fixing typos 6 | 7 | You can fix typos, spelling mistakes, or grammatical errors in the documentation directly using the GitHub web interface, as long as the changes are made in the _source_ file. 8 | This generally means you'll need to edit [roxygen2 comments](https://roxygen2.r-lib.org/articles/roxygen2.html) in an `.R`, not a `.Rd` file. 9 | You can find the `.R` file that generates the `.Rd` by reading the comment in the first line. 10 | 11 | ## Bigger changes 12 | 13 | If you want to make a bigger change, it's a good idea to first file an issue and make sure someone from the team agrees that it’s needed. 14 | If you’ve found a bug, please file an issue that illustrates the bug with a minimal 15 | [reprex](https://www.tidyverse.org/help/#reprex) (this will also help you write a unit test, if needed). 16 | See our guide on [how to create a great issue](https://code-review.tidyverse.org/issues/) for more advice. 17 | 18 | ### Pull request process 19 | 20 | * Fork the package and clone onto your computer. If you haven't done this before, we recommend using `usethis::create_from_github("CDCgov/ww-inference-model", fork = TRUE)`. 21 | 22 | * Install all development dependencies with `devtools::install_dev_deps()`, and then make sure the package passes R CMD check by running `devtools::check()`. 23 | If R CMD check doesn't pass cleanly, it's a good idea to ask for help before continuing. 24 | * Create a Git branch for your pull request (PR). We recommend using `usethis::pr_init("brief-description-of-change")`. 25 | 26 | * Make your changes, commit to git, and then create a PR by running `usethis::pr_push()`, and following the prompts in your browser. 27 | The title of your PR should briefly describe the change. 28 | The body of your PR should contain `Fixes #issue-number`. 29 | 30 | * For user-facing changes, add a bullet to the top of `NEWS.md` (i.e. just below the first header). Follow the style described in . 31 | 32 | ### Code style 33 | 34 | * New code should follow the tidyverse [style guide](https://style.tidyverse.org). 35 | You can use the [styler](https://CRAN.R-project.org/package=styler) package to apply these styles, but please don't restyle code that has nothing to do with your PR. 36 | 37 | * We use [roxygen2](https://cran.r-project.org/package=roxygen2), with [Markdown syntax](https://cran.r-project.org/web/packages/roxygen2/vignettes/rd-formatting.html), for documentation. 38 | 39 | * We use [testthat](https://cran.r-project.org/package=testthat) for unit tests. 40 | Contributions with test cases included are easier to accept. 41 | 42 | ## Code of Conduct 43 | 44 | Please note that the RtGam project is released with a 45 | [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By contributing to this 46 | project you agree to abide by its terms. 47 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/maintenance.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Maintenance 3 | about: Questions and requests related to organizational support and maintenance 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **What type of help do you need?** 11 | 12 | * [ ] Question 13 | * [ ] New Repo 14 | * [ ] Delete Repo 15 | * [ ] User Membership (please make sure new members are familiar with the [CDC open practices](https://github.com/CDCgov/template/blob/master/open_practices.md#profile-setup) and set up their profile with name and org info to help people collaborate with them) 16 | * [ ] Other 17 | 18 | **Please describe how you'd like us to help.** 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/scientific-improvement.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Scientific improvement 3 | about: Suggest a way to improve an existing tool or pipeline 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Describe the improvement that needs to be made 11 | (e.g. update a parameter estimate, tweak the prior, modify the model) 12 | 13 | ## Provide links to references to methods or data sources 14 | 15 | ## Describe the changes expected to the model's outputs 16 | 17 | ## Suggest new tests that will need to be implemented 18 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/pull_request_template.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | **Please describe the bug this fixes or the feature this adds.** 10 | 11 | **Please describe how you tested this change. Include unit tests whenever possible.** 12 | 13 | **Did you create or modify any associated documentation with this change? If documentation is not included in PR, please link to related documentation.** 14 | 15 | **If you added or modified HTML, did you check that it was 508 compliant?** 16 | 17 | **Please tag any specific reviewers you would like to review this PR** 18 | 19 | **Please include the following checks for open source contributing?** 20 | 21 | * [ ] Did you check for sensitive data, and remove any? 22 | * [ ] Are additional approvals needed for this change? 23 | * [ ] Are there potential vulnerabilities or licensing issues with any new dependencies introduced? 24 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/vulnerability.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Vulnerability Maintenance 3 | about: Routine updates to address vulnerabilities. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **What vulnerabilities does this PR remove or update?** 11 | 12 | **Have you tested to make sure these updates do not cause unintended consequences?** 13 | 14 | **Are these patch updates? minor? major?** 15 | -------------------------------------------------------------------------------- /.github/SUPPORT.md: -------------------------------------------------------------------------------- 1 | # Getting help with wwinference 2 | 3 | Thanks for using wwinference! 4 | Before filing an issue, there are a few places to explore and pieces to put together to make the process as smooth as possible. 5 | 6 | ## Make a reprex 7 | 8 | Start by making a minimal **repr**oducible **ex**ample using the [reprex](https://reprex.tidyverse.org/) package. 9 | If you haven't heard of or used reprex before, you're in for a treat! 10 | Seriously, reprex will make all of your R-question-asking endeavors easier (which is a pretty insane ROI for the five to ten minutes it'll take you to learn what it's all about). 11 | For additional reprex pointers, check out the [Get help!](https://www.tidyverse.org/help/) section of the tidyverse site. 12 | 13 | ## Where to ask? 14 | 15 | [File an issue](https://github.com/CDCgov/ww-inference-model/issues/new)! 16 | 17 | Before opening a new issue, be sure to [search issues and pull requests](https://github.com/CDCgov/ww-inference-model/issues) to make sure the bug hasn't been reported and/or already fixed in the development version. 18 | By default, the search will be pre-populated with `is:issue is:open`. 19 | You can [edit the qualifiers](https://help.github.com/articles/searching-issues-and-pull-requests/) (e.g. `is:pr`, `is:closed`) as needed. 20 | For example, you'd simply remove `is:open` to search _all_ issues in the repo, open or closed. 21 | -------------------------------------------------------------------------------- /.github/workflows/pre-commit.yaml: -------------------------------------------------------------------------------- 1 | name: pre-commit 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: [main] 7 | 8 | jobs: 9 | pre-commit: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | - uses: actions/setup-python@v5 14 | with: 15 | python-version: "3.12" 16 | - uses: actions/cache@v4 17 | with: 18 | path: | 19 | ~/.cache/R/renv 20 | key: r-precommit-cache|${{ env.pythonLocation }}|${{ hashFiles('.pre-commit-config.yaml') }} 21 | - uses: pre-commit/action@v3.0.1 22 | -------------------------------------------------------------------------------- /.github/workflows/r-cmd-check.yaml: -------------------------------------------------------------------------------- 1 | name: R CMD check project packages 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: [main, prod] 7 | 8 | jobs: 9 | check-package: 10 | strategy: 11 | matrix: 12 | r-version: ["4.1.0", "release"] 13 | os: [windows-latest, ubuntu-latest] 14 | runs-on: ${{matrix.os}} 15 | steps: 16 | - uses: actions/checkout@v4 17 | - uses: r-lib/actions/setup-r@v2 18 | with: 19 | r-version: ${{matrix.r-version}} 20 | use-public-rspm: true 21 | extra-repositories: "https://mc-stan.org/r-packages/" 22 | - name: "Set up dependencies for wwinference" 23 | uses: r-lib/actions/setup-r-dependencies@v2 24 | with: 25 | needs: check 26 | - name: "Install cmdstan via cmdstanr" 27 | uses: epinowcast/actions/install-cmdstan@v1 28 | with: 29 | cmdstan-version: "latest" 30 | num-cores: 2 31 | - name: "Check wwinference package" 32 | uses: r-lib/actions/check-r-package@v2 33 | with: 34 | build_args: 'c("--no-manual", "--no-build-vignettes")' 35 | args: 'c("--no-manual", "--as-cran", "--ignore-vignettes")' 36 | -------------------------------------------------------------------------------- /.lintr: -------------------------------------------------------------------------------- 1 | linters: linters_with_defaults(object_usage_linter = NULL) 2 | encoding: "UTF-8" 3 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | ##### 3 | # Basic file cleanliness 4 | - repo: https://github.com/pre-commit/pre-commit-hooks 5 | rev: v4.6.0 6 | hooks: 7 | - id: check-added-large-files 8 | - id: check-yaml 9 | - id: check-toml 10 | - id: end-of-file-fixer 11 | - id: mixed-line-ending 12 | - id: trailing-whitespace 13 | ##### 14 | # Python 15 | - repo: https://github.com/psf/black 16 | rev: 24.4.2 17 | hooks: 18 | # if you have ipython notebooks, consider using 19 | # `black-jupyter` hook instead 20 | - id: black 21 | args: ['--line-length', '79'] 22 | - repo: https://github.com/PyCQA/isort 23 | rev: 5.13.2 24 | hooks: 25 | - id: isort 26 | args: ['--profile', 'black', 27 | '--line-length', '79'] 28 | - repo: https://github.com/astral-sh/ruff-pre-commit 29 | rev: v0.5.0 30 | hooks: 31 | - id: ruff 32 | ##### 33 | # R 34 | - repo: https://github.com/lorenzwalthert/precommit 35 | rev: v0.4.2 36 | hooks: 37 | - id: style-files 38 | args: [--style_pkg=styler, --style_fun=tidyverse_style, 39 | --cache-root=styler-perm] 40 | - id: use-tidy-description 41 | - id: lintr 42 | - id: readme-rmd-rendered 43 | - id: parsable-R 44 | - id: no-browser-statement 45 | - id: no-print-statement 46 | - id: no-debug-statement 47 | - id: deps-in-desc 48 | exclude: data-raw 49 | ##### 50 | # Java 51 | - repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks 52 | rev: v2.13.0 53 | hooks: 54 | - id: pretty-format-java 55 | args: [--aosp,--autofix] 56 | ##### 57 | # Julia 58 | # Due to lack of first-class Julia support, this needs Julia local install 59 | # and JuliaFormatter.jl installed in the library 60 | # - repo: https://github.com/domluna/JuliaFormatter.jl 61 | # rev: v1.0.39 62 | # hooks: 63 | # - id: julia-formatter 64 | ##### 65 | # Secrets 66 | - repo: https://github.com/Yelp/detect-secrets 67 | rev: v1.5.0 68 | hooks: 69 | - id: detect-secrets 70 | args: ['--baseline', '.secrets.baseline'] 71 | exclude: package.lock.json 72 | -------------------------------------------------------------------------------- /.secrets.baseline: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.4.0", 3 | "plugins_used": [ 4 | { 5 | "name": "ArtifactoryDetector" 6 | }, 7 | { 8 | "name": "AWSKeyDetector" 9 | }, 10 | { 11 | "name": "AzureStorageKeyDetector" 12 | }, 13 | { 14 | "name": "Base64HighEntropyString", 15 | "limit": 4.5 16 | }, 17 | { 18 | "name": "BasicAuthDetector" 19 | }, 20 | { 21 | "name": "CloudantDetector" 22 | }, 23 | { 24 | "name": "DiscordBotTokenDetector" 25 | }, 26 | { 27 | "name": "GitHubTokenDetector" 28 | }, 29 | { 30 | "name": "HexHighEntropyString", 31 | "limit": 3.0 32 | }, 33 | { 34 | "name": "IbmCloudIamDetector" 35 | }, 36 | { 37 | "name": "IbmCosHmacDetector" 38 | }, 39 | { 40 | "name": "JwtTokenDetector" 41 | }, 42 | { 43 | "name": "KeywordDetector", 44 | "keyword_exclude": "" 45 | }, 46 | { 47 | "name": "MailchimpDetector" 48 | }, 49 | { 50 | "name": "NpmDetector" 51 | }, 52 | { 53 | "name": "PrivateKeyDetector" 54 | }, 55 | { 56 | "name": "SendGridDetector" 57 | }, 58 | { 59 | "name": "SlackDetector" 60 | }, 61 | { 62 | "name": "SoftlayerDetector" 63 | }, 64 | { 65 | "name": "SquareOAuthDetector" 66 | }, 67 | { 68 | "name": "StripeDetector" 69 | }, 70 | { 71 | "name": "TwilioKeyDetector" 72 | } 73 | ], 74 | "filters_used": [ 75 | { 76 | "path": "detect_secrets.filters.allowlist.is_line_allowlisted" 77 | }, 78 | { 79 | "path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies", 80 | "min_level": 2 81 | }, 82 | { 83 | "path": "detect_secrets.filters.heuristic.is_indirect_reference" 84 | }, 85 | { 86 | "path": "detect_secrets.filters.heuristic.is_likely_id_string" 87 | }, 88 | { 89 | "path": "detect_secrets.filters.heuristic.is_lock_file" 90 | }, 91 | { 92 | "path": "detect_secrets.filters.heuristic.is_not_alphanumeric_string" 93 | }, 94 | { 95 | "path": "detect_secrets.filters.heuristic.is_potential_uuid" 96 | }, 97 | { 98 | "path": "detect_secrets.filters.heuristic.is_prefixed_with_dollar_sign" 99 | }, 100 | { 101 | "path": "detect_secrets.filters.heuristic.is_sequential_string" 102 | }, 103 | { 104 | "path": "detect_secrets.filters.heuristic.is_swagger_file" 105 | }, 106 | { 107 | "path": "detect_secrets.filters.heuristic.is_templated_secret" 108 | } 109 | ], 110 | "results": {}, 111 | "generated_at": "2023-09-24T19:52:08Z" 112 | } 113 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: wwinference 2 | Title: Jointly infers infection dynamics from wastewater data and epidemiological indicators 3 | Version: 0.1.1.99 4 | Authors@R: c( 5 | person(given = "Kaitlyn", 6 | family = "Johnson", 7 | role = c("aut", "cre"), 8 | email = "johnsonkaitlyne9@gmail.com", 9 | comment = c(ORCID = "0000-0001-8011-0012")), 10 | person(given = "Dylan", 11 | family = "Morris", 12 | role = c("aut"), 13 | email = "dylan@dylanhmorris.com", 14 | comment = c(ORCID = "0000-0002-3655-406X")), 15 | person(given = "Sam", 16 | family = "Abbott", 17 | role = c("aut"), 18 | email = "contact@samabbott.co.uk", 19 | comment = c(ORCID = "0000-0001-8057-8037")), 20 | person(given = "Christian", 21 | family = "Bernal Zelaya", 22 | role = c("aut"), 23 | email = "xuk0@cdc.gov"), 24 | person(given = "George", 25 | family = "Vega Yon", 26 | role = c("aut"), 27 | email = "g.vegayon@gmail.com", 28 | comment = c(ORCID = "0000-0002-3171-0844")), 29 | person(given = "Damon", 30 | family = "Bayer", 31 | role = c("aut"), 32 | email = "xum8@cdc.gov"), 33 | person(given = "Andrew", 34 | family = "Magee", 35 | role = c("aut"), 36 | email = "rzg0@cdc.gov"), 37 | person(given = "Scott", 38 | family = "Olesen", 39 | role = c("aut"), 40 | email = "ulp7@cdc.gov"), 41 | person(given = "Adam", 42 | family = "Howes", 43 | role = c("ctb"), 44 | email = "adamthowes@gmail.com", 45 | comment = c(ORCID = "0000-0003-2386-4031")), 46 | person(given = "Chirag", 47 | family = "Kumar", 48 | role = c("ctb"), 49 | email = "kzs9@cdc.gov"), 50 | person(given = "Alexander", 51 | family = "Keyel", 52 | role = c("ctb"), 53 | email = "alexander.keyel@health.ny.gov", 54 | comment = c(ORCID = "000-0001-5256-6274")), 55 | person(given = "Hannah", 56 | family = "Cohen", 57 | role = c("ctb"), 58 | email = "llg4@cdc.gov") 59 | ) 60 | Description: An implementation of a hierarchical semi-mechanistic renewal 61 | approach jointly calibrating to multiple wastewater concentrations datasets from 62 | subsets of a specified population and epidemioliogical indicators such as cases 63 | or hospital admissions from the whole population. Our framework is an extension 64 | of the widely used semi-mechanistic renewal framework EpiNow2, using a Bayesian 65 | latent variable approach implemented in the probabilistic programming language 66 | Stan. This package contains just the core components needed to fit these two 67 | data sources and produce the following outputs-- estimated and forecasted 68 | hospital admissions, estimated and forecasted wastewater concentrations, 69 | global R(t) estimates, local R(t) estimates for the subpopulations 70 | represented by each wastewater catchment area. 71 | License: Apache License (>= 2) 72 | URL: https://github.com/cdcgov/ww-inference-model/, https://cdcgov.github.io/ww-inference-model/ 73 | BugReports: https://github.com/cdcgov/ww-inference-model/issues/ 74 | Depends: 75 | R (>= 4.1.0) 76 | SystemRequirements: CmdStan (>=2.35.0) 77 | Encoding: UTF-8 78 | Roxygen: list(markdown = TRUE) 79 | RoxygenNote: 7.3.2 80 | Suggests: 81 | testthat (>= 3.0.0), 82 | bookdown, 83 | knitr, 84 | withr, 85 | rcmdcheck 86 | Config/testthat/edition: 3 87 | LazyData: true 88 | Imports: 89 | fs, 90 | dplyr, 91 | lubridate, 92 | glue, 93 | RcppTOML, 94 | cli, 95 | tibble, 96 | tidybayes, 97 | tidyr, 98 | purrr, 99 | cmdstanr (>= 0.8.0), 100 | rlang, 101 | scales, 102 | ggplot2, 103 | posterior, 104 | checkmate 105 | Remotes: 106 | stan-dev/cmdstanr 107 | VignetteBuilder: 108 | knitr 109 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(get_draws,data.frame) 4 | S3method(get_draws,default) 5 | S3method(get_draws,wwinference_fit) 6 | S3method(get_model_diagnostic_flags,default) 7 | S3method(get_model_diagnostic_flags,wwinference_fit) 8 | S3method(plot,wwinference_fit_draws) 9 | S3method(print,wwinference_fit) 10 | S3method(print,wwinference_fit_draws) 11 | S3method(summary,wwinference_fit) 12 | export(add_pmfs) 13 | export(add_time_indexing) 14 | export(calc_rt) 15 | export(compile_model) 16 | export(convert_to_logmean) 17 | export(convert_to_logsd) 18 | export(create_dir) 19 | export(flag_ww_outliers) 20 | export(generate_simulated_data) 21 | export(get_count_data_sizes) 22 | export(get_count_indices) 23 | export(get_count_values) 24 | export(get_date_time_spine) 25 | export(get_draws) 26 | export(get_draws_df) 27 | export(get_ind_m) 28 | export(get_input_count_data_for_stan) 29 | export(get_input_ww_data_for_stan) 30 | export(get_lab_site_site_spine) 31 | export(get_lab_site_subpop_spine) 32 | export(get_mcmc_options) 33 | export(get_model_diagnostic_flags) 34 | export(get_model_spec) 35 | export(get_params) 36 | export(get_plot_forecasted_counts) 37 | export(get_plot_global_rt) 38 | export(get_plot_subpop_rt) 39 | export(get_plot_ww_conc) 40 | export(get_site_subpop_spine) 41 | export(get_stan_data) 42 | export(get_ww_data_sizes) 43 | export(get_ww_indices_and_values) 44 | export(indicate_ww_exclusions) 45 | export(parameter_diagnostics) 46 | export(preprocess_count_data) 47 | export(preprocess_ww_data) 48 | export(summary_diagnostics) 49 | export(to_simplex) 50 | export(validate_paramlist) 51 | export(wwinference) 52 | importFrom(cmdstanr,cmdstan_model) 53 | importFrom(dplyr,arrange) 54 | importFrom(dplyr,as_tibble) 55 | importFrom(dplyr,distinct) 56 | importFrom(dplyr,filter) 57 | importFrom(dplyr,group_by) 58 | importFrom(dplyr,lag) 59 | importFrom(dplyr,lead) 60 | importFrom(dplyr,left_join) 61 | importFrom(dplyr,mutate) 62 | importFrom(dplyr,pull) 63 | importFrom(dplyr,rename) 64 | importFrom(dplyr,row_number) 65 | importFrom(dplyr,select) 66 | importFrom(dplyr,ungroup) 67 | importFrom(fs,path_package) 68 | importFrom(ggplot2,aes) 69 | importFrom(ggplot2,element_text) 70 | importFrom(ggplot2,facet_grid) 71 | importFrom(ggplot2,facet_wrap) 72 | importFrom(ggplot2,geom_bar) 73 | importFrom(ggplot2,geom_hline) 74 | importFrom(ggplot2,geom_line) 75 | importFrom(ggplot2,geom_point) 76 | importFrom(ggplot2,geom_ribbon) 77 | importFrom(ggplot2,geom_step) 78 | importFrom(ggplot2,geom_vline) 79 | importFrom(ggplot2,ggplot) 80 | importFrom(ggplot2,ggtitle) 81 | importFrom(ggplot2,labs) 82 | importFrom(ggplot2,scale_colour_discrete) 83 | importFrom(ggplot2,scale_fill_discrete) 84 | importFrom(ggplot2,scale_x_date) 85 | importFrom(ggplot2,scale_y_continuous) 86 | importFrom(ggplot2,theme) 87 | importFrom(ggplot2,theme_bw) 88 | importFrom(ggplot2,xlab) 89 | importFrom(ggplot2,ylab) 90 | importFrom(lubridate,ymd) 91 | importFrom(posterior,as_draws_list) 92 | importFrom(posterior,subset_draws) 93 | importFrom(rlang,.data) 94 | importFrom(rlang,sym) 95 | importFrom(stats,dnbinom) 96 | importFrom(stats,dweibull) 97 | importFrom(stats,ecdf) 98 | importFrom(stats,plogis) 99 | importFrom(stats,qlogis) 100 | importFrom(stats,rlnorm) 101 | importFrom(stats,rnbinom) 102 | importFrom(stats,rnorm) 103 | importFrom(stats,rt) 104 | importFrom(stats,sd) 105 | importFrom(stats,time) 106 | importFrom(tibble,tibble) 107 | importFrom(tidybayes,spread_draws) 108 | importFrom(tidybayes,stat_halfeye) 109 | importFrom(tidybayes,stat_slab) 110 | importFrom(tidyr,pivot_longer) 111 | importFrom(tidyr,pivot_wider) 112 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # wwinference 0.1.1.99 (dev) 2 | - Fixes the way the wastewater calibration and evaluation datasets are created 3 | to ensure that the dates align properly. ([#256](https://github.com/CDCgov/ww-inference-model/issues/256)) 4 | 5 | # wwinference 0.1.1 6 | This release includes a change to the default model priors. The previous release had an informative prior on a high magnitude of infection feedback. This release reduces the prior mode and also decreases the degree of prior certainty. This release also includes minor changes to plotting and pre-processing functions designed to make outputs more comprehensive and interpretable. 7 | 8 | ## User-visible changes 9 | - Add wastewater data into the forecast period to output in `generate_simulated_data()` function and as package data. Also adds subpopulation-level 10 | hospital admissions to output of function and package data. ([#184](https://github.com/CDCgov/ww-inference-model/issues/184)) 11 | - `wwinference` now checks whether `site_pop` is fixed per site (see issue [#223](https://github.com/CDCgov/ww-inference-model/issues/226) reported by [@akeyel](https://github.com/akeyel)). 12 | - Add package workflow diagram to readme ([#248](https://github.com/CDCgov/ww-inference-model/issues/248)) 13 | - `get_plot_subpop_rt()` now uses a shared y-axis to facilitate comparison of R(t) estimates) ([#245](https://github.com/CDCgov/ww-inference-model/issues/245)) 14 | 15 | ## Internal changes 16 | - Modified the priors on the infection feedback term and the step size of the weekly random walk in the effective reproductive number (issue [#227](https://github.com/CDCgov/ww-inference-model/issues/227)), based on benchmarking results from the evaluation pipeline described in the [PR](https://github.com/CDCgov/ww-inference-model/pull/236) corresponding to this change. 17 | - Updated the workflow for posting the pages artifact to PRs (issue [#229](https://github.com/CDCgov/ww-inference-model/issues/229)(https://github.com/CDCgov/ww-inference-model/issues/229)). 18 | - Modify `plot_forecasted_counts()` so that it does not require an evaluation dataset ([#218](https://github.com/CDCgov/ww-inference-model/pull/218)) 19 | 20 | # wwinference 0.1.0 21 | 22 | This is the first major release, focused on providing an initial version of the package. 23 | Note the package is still flagged as in development, though the authors plan on using it for production work in the coming weeks. 24 | As it's written, the package is intended to allow users to do the following: 25 | 26 | - Provide basic functionality to fit the wastewater-informed model to an example fitting COVID-19 hospital admissions and wastewater from a few sites ([#5](https://github.com/CDCgov/ww-inference-model/issues/5)) 27 | - Performs basic post-processing and plotting of data and modeled outputs, including calibrated, nowcasted, and forecasted count data (in the example, hospital admissions), wastewater concentrations, global R(t) estimates and subpopulation-level R(t) estimates 28 | - Provide an example in the vignette to fit the model to only the hospital admissions ([#24](https://github.com/CDCgov/ww-inference-model/issues/24)) 29 | - Validate input data validation with informative error messaging ([#37](https://github.com/CDCgov/ww-inference-model/issues/37), [#54](https://github.com/CDCgov/ww-inference-model/issues/54)) 30 | - Provide a wrapper function to generate forward simulated data with user-specified variables. It calls a number of functions to perform specific model components ([#27](https://github.com/CDCgov/ww-inference-model/issues/27)) 31 | - Contains S3 class methods applied to the output of the main model wrapper function, the `wwinference_fit` class object ([#58](https://github.com/CDCgov/ww-inference-model/issues/58)). 32 | - Wastewater concentration data is expected to be in log scale ([#122](https://github.com/CDCgov/ww-inference-model/pull/122)). 33 | -------------------------------------------------------------------------------- /R/compile_model.R: -------------------------------------------------------------------------------- 1 | #' Compile a stan model while pointing at the package default 2 | #' include directory (`stan`) for #include statements 3 | #' 4 | #' @description 5 | #' This function reads in and optionally compiles a Stan model. 6 | #' It is written to search the installed package `stan` directory 7 | #' for additional source files to include. Within each stan file, 8 | #' use `#include {path to your file with the stan directory}.stan` 9 | #' 10 | #' 11 | #' @details The code for this function has been adapted 12 | #' from code written (under an MIT license) as part of 13 | #' the [`epinowcast`](https://github.com/epinowcast/epinowcast) 14 | #' R package. 15 | #' 16 | #' @param model_filepath path to .stan file defining the model, default is 17 | #' `system.file("stan", "wwinference.stan", package = "wwinference") 18 | #' @param include_paths path(s) to directories to search for files 19 | #' specified in #include statements. Passed to [cmdstanr::cmdstan_model()]. 20 | #' Defaults to the `stan` subdirectory of the installed 21 | #' `wwinference` package. 22 | #' @param threads Number of threads to use in model compilation, 23 | #' as an integer. Passed to [cmdstanr::cmdstan_model()]. 24 | #' Default `FALSE` (use single-threaded compilation). 25 | #' @param target_dir Directory in which to save the compiled 26 | #' stan model binary. Passed as the `dir` keyword argument to 27 | #' [cmdstanr::cmdstan_model()]. Defaults to a temporary directory 28 | #' for the R session (the output of [tempdir()]). 29 | #' @param stanc_options Options for the stan compiler passed to 30 | #' [cmdstanr::cmdstan_model()], as a list. See that function's 31 | #' documentation for more details. Default `list()` (use default 32 | #' options). 33 | #' @param cpp_options Options for the C++ compiler passed to 34 | #' [cmdstanr::cmdstan_model()], as a list. See that function's 35 | #' documentation for more details. Default `list()` (use default 36 | #' options). 37 | #' @param verbose Write detailed output to the terminal while 38 | #' executing the function? Boolean, default `TRUE`. 39 | #' @param ... Additional keyword arguments passed to 40 | #' [cmdstanr::cmdstan_model()]. 41 | #' 42 | #' @return The resulting `cmdstanr` model object, as the output 43 | #' of [cmdstanr::cmdstan_model()]. 44 | #' @export 45 | compile_model <- function(model_filepath = system.file("stan", 46 | "wwinference.stan", 47 | package = "wwinference" 48 | ), 49 | include_paths = system.file( 50 | "stan", 51 | package = "wwinference" 52 | ), 53 | threads = FALSE, 54 | target_dir = tempdir(), 55 | stanc_options = list(), 56 | cpp_options = list(), 57 | verbose = TRUE, 58 | ...) { 59 | if (verbose) { 60 | cli::cli_inform( 61 | glue::glue(paste0( 62 | "Using model source file: ", 63 | "{model_filepath}" 64 | )) 65 | ) 66 | cli::cli_inform( 67 | sprintf( 68 | "Using include paths: %s", 69 | toString(include_paths) 70 | ) 71 | ) 72 | } 73 | 74 | create_dir(target_dir) 75 | 76 | model <- cmdstanr::cmdstan_model( 77 | model_filepath, 78 | include_paths = include_paths, 79 | compile = TRUE, 80 | stanc_options = stanc_options, 81 | cpp_options = cpp_options, 82 | threads = threads, 83 | dir = target_dir, 84 | ... 85 | ) 86 | 87 | if (verbose) { 88 | cli::cli_inform(paste0( 89 | "Model compiled or loaded successfully; ", 90 | "model executable binary located at: ", 91 | "{model$exe_file()}" 92 | )) 93 | } 94 | 95 | return(model) 96 | } 97 | -------------------------------------------------------------------------------- /R/get_params.R: -------------------------------------------------------------------------------- 1 | ## Get model parameters (priors and set params of set distributions)------------ 2 | #' @title Get parameters for model run 3 | #' 4 | #' @param param_file Path to a `.toml` file defining 5 | #' parameter values. 6 | #' 7 | #' @return a flat list mapping parameter names to corresponding 8 | #' values. 9 | #' @export 10 | #' 11 | #' @examples 12 | #' params <- get_params(param_file = fs::path_package("extdata", 13 | #' "example_params.toml", 14 | #' package = "wwinference" 15 | #' )) 16 | get_params <- function(param_file) { 17 | paramlist <- RcppTOML::parseTOML(param_file) 18 | validate_paramlist(paramlist) 19 | 20 | flat_paramlist <- c( 21 | paramlist$continuous_distribution_parameters, 22 | paramlist$timescale, 23 | paramlist$infection_process, 24 | paramlist$hospital_admission_observation_process, 25 | paramlist$wastewater_observation_process 26 | ) 27 | 28 | return(flat_paramlist) 29 | } 30 | 31 | #' Validate a parameter list 32 | #' 33 | #' @param paramlist The parameter list to validate 34 | #' 35 | #' @return the parameter list, on success, 36 | #' or raise an error 37 | #' @export 38 | validate_paramlist <- function(paramlist) { 39 | expected_sections <- c( 40 | "continuous_distribution_parameters", 41 | "hospital_admission_observation_process", 42 | "infection_process", 43 | "timescale", 44 | "wastewater_observation_process" 45 | ) 46 | 47 | 48 | missing_sections <- setdiff( 49 | names(paramlist), 50 | expected_sections 51 | ) 52 | 53 | if (length(missing_sections) > 0) { 54 | cli::cli_abort( 55 | paste0( 56 | "Parameter list missing expected ", 57 | "section(s) {missing_sections}" 58 | ) 59 | ) 60 | } 61 | 62 | ## additional validation logic can go here 63 | return(paramlist) 64 | } 65 | -------------------------------------------------------------------------------- /R/initialization.R: -------------------------------------------------------------------------------- 1 | #' Given a set of prior parameters and stan data, initialize the model 2 | #' near the center of the prior distribution 3 | #' 4 | #' @param stan_data a list of data elements that will be passed to stan 5 | #' @param stdev a numeric value indicating the standard deviation to sample 6 | #' from when initializing, particularly from a standard normal. Also acts as 7 | #' a multiplier on the prior standard deviation, to restrict the initial value 8 | #' to be sampled from the center of the prior. Default is 0.01 9 | #' 10 | #' @return a list of initial values for each of the parameters in the 11 | #' `wwinference` model 12 | get_inits_for_one_chain <- function(stan_data, stdev = 0.01) { 13 | # Define some variables 14 | pop <- stan_data$state_pop 15 | n_weeks <- as.numeric(stan_data$n_weeks) 16 | tot_weeks <- as.numeric(stan_data$tot_weeks) 17 | ot <- as.numeric(stan_data$ot) 18 | ht <- as.numeric(stan_data$ht) 19 | n_subpops <- as.numeric(stan_data$n_subpops) 20 | n_ww_lab_sites <- as.numeric(stan_data$n_ww_lab_sites) 21 | # Estimate of number of initial infections 22 | i_first_obs_est <- ( 23 | mean(stan_data$hosp[1:7], na.rm = TRUE) / stan_data$p_hosp_prior_mean 24 | ) 25 | 26 | logit_i_frac_est <- stats::qlogis(i_first_obs_est / pop) 27 | 28 | n_subpops <- as.numeric(stan_data$n_subpops) 29 | n_ww_lab_sites <- as.numeric(stan_data$n_ww_lab_sites) 30 | 31 | init_list <- list( 32 | w = stats::rnorm(n_weeks - 1, 0, stdev), 33 | offset_ref_log_r_t = stats::rnorm( 34 | stan_data$n_subpops > 1, 35 | stan_data$offset_ref_log_r_t_prior_mean, 36 | stdev 37 | ), 38 | offset_ref_logit_i_first_obs = stats::rnorm( 39 | stan_data$n_subpops > 1, 40 | stan_data$offset_ref_logit_i_first_obs_prior_mean, 41 | stdev 42 | ), 43 | offset_ref_initial_exp_growth_rate = stats::rnorm( 44 | stan_data$n_subpops > 1, 45 | stan_data$offset_ref_initial_exp_growth_rate_prior_mean, 46 | stdev 47 | ), 48 | eta_sd = abs(stats::rnorm(1, 0, stdev)), 49 | eta_i_first_obs = abs(stats::rnorm((n_subpops - 1), 0, stdev)), 50 | sigma_i_first_obs = abs(stats::rnorm(1, 0, stdev)), 51 | eta_initial_exp_growth_rate = abs(stats::rnorm((n_subpops - 1), 0, stdev)), 52 | sigma_initial_exp_growth_rate = abs(stats::rnorm(1, 0, stdev)), 53 | autoreg_rt = abs(stats::rnorm( 54 | 1, 55 | stan_data$autoreg_rt_a / 56 | (stan_data$autoreg_rt_a + stan_data$autoreg_rt_b), 57 | 0.05 58 | )), 59 | log_r_t_first_obs = stats::rnorm( 60 | 1, 61 | convert_to_logmean(1, stdev), 62 | convert_to_logsd(1, stdev) 63 | ), 64 | autoreg_rt_subpop = abs(stats::rnorm(1, 0.5, 0.05)), 65 | autoreg_p_hosp = abs(stats::rnorm(1, 1 / 100, 0.001)), 66 | sigma_rt = abs(stats::rnorm(1, 0, stdev)), 67 | i_first_obs_over_n = 68 | stats::plogis(stats::rnorm(1, logit_i_frac_est), 0.05), 69 | mean_initial_exp_growth_rate = stats::rnorm(1, 0, stdev), 70 | inv_sqrt_phi_h = 1 / sqrt(200) + stats::rnorm(1, 1 / 10000, 1 / 10000), 71 | mode_sigma_ww_site = abs(stats::rnorm( 72 | 1, stan_data$mode_sigma_ww_site_prior_mode, 73 | stdev * stan_data$mode_sigma_ww_site_prior_sd 74 | )), 75 | sd_log_sigma_ww_site = abs(stats::rnorm( 76 | 1, stan_data$sd_log_sigma_ww_site_prior_mode, 77 | stdev * stan_data$sd_log_sigma_ww_site_prior_sd 78 | )), 79 | eta_log_sigma_ww_site = abs(stats::rnorm(n_ww_lab_sites, 0, stdev)), 80 | p_hosp_mean = stats::rnorm( 81 | 1, stats::qlogis(stan_data$p_hosp_prior_mean), 82 | stdev 83 | ), 84 | p_hosp_w = stats::rnorm(tot_weeks, 0, stdev), 85 | p_hosp_w_sd = abs(stats::rnorm(1, 0.01, 0.001)), 86 | t_peak = stats::rnorm( 87 | 1, stan_data$viral_shedding_pars[1], 88 | stdev * stan_data$viral_shedding_pars[2] 89 | ), 90 | viral_peak = stats::rnorm( 91 | 1, stan_data$viral_shedding_pars[3], 92 | stdev * stan_data$viral_shedding_pars[4] 93 | ), 94 | dur_shed = stats::rnorm( 95 | 1, stan_data$viral_shedding_pars[5], 96 | stdev * stan_data$viral_shedding_pars[6] 97 | ), 98 | log10_g = stats::rnorm(1, stan_data$log10_g_prior_mean, 0.5), 99 | ww_site_mod_raw = abs(stats::rnorm(n_ww_lab_sites, 0, stdev)), 100 | ww_site_mod_sd = abs(stats::rnorm(1, 0, stdev)), 101 | hosp_wday_effect = to_simplex(abs( 102 | stats::rnorm(7, 1 / 7, stdev) 103 | )), 104 | infection_feedback = abs(stats::rnorm(1, 500, 20)) 105 | ) 106 | 107 | if (stan_data$n_subpops > 1) { 108 | init_list$error_rt_subpop <- matrix( 109 | stats::rnorm((n_subpops - 1) * n_weeks, 110 | mean = 0, 111 | sd = stdev 112 | ), 113 | (n_subpops - 1), 114 | n_weeks 115 | ) 116 | } 117 | 118 | return(init_list) 119 | } 120 | -------------------------------------------------------------------------------- /R/model_diagnostics.R: -------------------------------------------------------------------------------- 1 | #' Get a table of diagnostic flags 2 | #' 3 | #' @description 4 | #' This function takes in the output from a cmdstanr$sample() function (the 5 | #' fit object) and a series of diagnostic tolerances and returns 6 | #' a dataframe containing flags for whether any of the diagnostic thresholds 7 | #' were exceeded, which would indicate that the model did not properly 8 | #' converge. This funtion has a default method that takes 9 | #' the CmdStan fitting object, as well as an S3 method for objects of class 10 | #' 'wwinference_fit' 11 | #' 12 | #' 13 | #' @param x Either an object of the 'wwinference_fit' class or 14 | #' the R6 Cmdstan Object fit object 15 | #' @param ebmfi_tolerance float indicating the tolerance for EBMFI 16 | #' (estimated bayesian fraction of missing information), default is `0.2` 17 | #' @param divergences_tolerance float indicating the tolerance for the 18 | #' proportion of sampling iterations that are divergent, default is `0.01` 19 | #' @param frac_high_rhat_tolerance float indicating the tolerance for the 20 | #' proportion of parameters rhats>rhat_tolderance, default is `0.05` 21 | #' @param rhat_tolerance float indicating the tolerance for the rhat for 22 | #' individual parameters, default is `1.05` 23 | #' @param max_tree_depth_tol float indicating the tolerance for the proportion 24 | #' of iterations that exceed the maximum tree depth, default is `0.01`, 25 | #' @param ... additional arguments 26 | #' 27 | #' @family diagnostics 28 | #' @return flag_df: dataframe containing columns for each of the flags, 29 | #' if any flags are TRUE that indicates some model issue 30 | #' @export 31 | get_model_diagnostic_flags <- function(x, ...) { 32 | UseMethod("get_model_diagnostic_flags") 33 | } 34 | 35 | #' S3 method for getting a table of diagnostic flags fpr a wwinference_fit 36 | #' object 37 | #' 38 | #' This method overloads the generic get_model_diagnostic_flags function 39 | #' specifically for objects of type 'wwinference_fit'. 40 | #' 41 | #' @rdname get_model_diagnostic_flags 42 | #' @export 43 | get_model_diagnostic_flags.wwinference_fit <- function(x, ...) { 44 | get_model_diagnostic_flags.default( 45 | x = x$fit$result 46 | ) 47 | } 48 | 49 | #' @rdname get_model_diagnostic_flags 50 | #' @export 51 | get_model_diagnostic_flags.default <- function(x, 52 | ebmfi_tolerance = 0.2, 53 | divergences_tolerance = 0.01, 54 | frac_high_rhat_tolerance = 0.05, 55 | rhat_tolerance = 1.05, 56 | max_tree_depth_tol = 0.01, 57 | ...) { 58 | n_chains <- x$num_chains() 59 | iter_sampling <- x$metadata()$iter_sampling 60 | 61 | # Summary is a large dataframe with diagnostics for each parameters 62 | summary <- x$summary() 63 | diagnostic_summary <- x$diagnostic_summary(quiet = TRUE) 64 | 65 | flag_low_embfi <- mean(diagnostic_summary$ebfmi) <= ebmfi_tolerance 66 | max_n_divergences <- n_chains * iter_sampling * divergences_tolerance 67 | flag_too_many_divergences <- any( 68 | diagnostic_summary$num_divergent >= max_n_divergences 69 | ) 70 | frac_high_rhat <- as.numeric(mean(summary[, "rhat"]$rhat > rhat_tolerance, 71 | na.rm = TRUE 72 | )) 73 | flag_high_rhat <- frac_high_rhat >= frac_high_rhat_tolerance 74 | max_n_max_treedepth <- n_chains * iter_sampling * max_tree_depth_tol 75 | flag_high_max_treedepth <- any( 76 | diagnostic_summary$num_max_tree_depth >= max_n_max_treedepth 77 | ) 78 | 79 | flag_df <- data.frame( 80 | flag_high_max_treedepth, 81 | flag_too_many_divergences, 82 | flag_high_rhat, 83 | flag_low_embfi 84 | ) 85 | 86 | # Message if a flag doesn't pass. Still return 87 | # the same data, but we want user to know the issue 88 | if (any(flag_df[1, ])) { 89 | warning("Model flagged for convergence issues, run model diagnostics 90 | on the output stanfit object for more information") 91 | } 92 | return(flag_df) 93 | } 94 | 95 | 96 | #' Method for printing the CmdStan parameter diagnostics for a 97 | #' wwinference_fit_object 98 | #' 99 | #' @param ww_fit An object of class wwinference_fit 100 | #' @param ... additional arguments 101 | #' 102 | #' @family diagnostics 103 | #' @export 104 | parameter_diagnostics <- function(ww_fit, ...) { 105 | ww_fit$fit$result$summary() 106 | } 107 | 108 | #' Method for printing the CmdStan summary diagnostics for 109 | #' wwinference_fit_object 110 | #' 111 | #' @param ww_fit An object of class wwinference_fit 112 | #' @param ... additional arguments 113 | #' 114 | #' @family diagnostics 115 | #' @export 116 | summary_diagnostics <- function(ww_fit, ...) { 117 | ww_fit$fit$result$diagnostic_summary(quiet = TRUE) 118 | } 119 | -------------------------------------------------------------------------------- /R/utils.R: -------------------------------------------------------------------------------- 1 | #' Add probability mass functions 2 | #' 3 | #' This function allows the addition of probability mass functions (PMFs) to 4 | #' produce a new PMF. This is useful for example in the context of reporting 5 | #' delays where the PMF of the sum of two Poisson distributions is the 6 | #' convolution of the PMFs. 7 | #' 8 | #' This code was adapted from code written 9 | #' (under an MIT license) as part of the `epinowcast` 10 | #' package (https://github.com/epinowcast/epinowcast) 11 | #' 12 | #' @param pmfs A list of vectors describing the probability mass functions to 13 | #' 14 | #' @return A vector describing the probability mass function of the sum of the 15 | #' 16 | #' @export 17 | #' @examples 18 | #' # Sample and analytical PMFs for two Poisson distributions 19 | #' x <- rpois(10000, 5) 20 | #' xpmf <- dpois(0:20, 5) 21 | #' y <- rpois(10000, 7) 22 | #' ypmf <- dpois(0:20, 7) 23 | #' # Add sampled Poisson distributions up to get combined distribution 24 | #' z <- x + y 25 | #' # Analytical convolution of PMFs 26 | #' conv_pmf <- add_pmfs(list(xpmf, ypmf)) 27 | #' conv_cdf <- cumsum(conv_pmf) 28 | #' # Empirical convolution of PMFs 29 | #' cdf <- ecdf(z)(0:42) 30 | #' # Compare sampled and analytical CDFs 31 | #' plot(conv_cdf) 32 | #' lines(cdf, col = "black") 33 | add_pmfs <- function(pmfs) { 34 | d <- length(pmfs) 35 | if (d == 1) { 36 | return(pmfs[[1]]) 37 | } 38 | if (!is.list(pmfs)) { 39 | return(pmfs) 40 | } 41 | # P(Z = z) = sum_over_x(P(X = x) * P(Y = z - x)) # nolint 42 | return( 43 | Reduce(x = pmfs, f = function(conv, pmf) { 44 | lc <- length(conv) 45 | wd <- seq_len(lc) - 1 46 | proc <- numeric(lc + length(pmf)) 47 | for (j in seq_along(pmf)) { 48 | proc[j + wd] <- proc[j + wd] + pmf[j] * conv 49 | } 50 | return(proc) 51 | }) 52 | ) 53 | } 54 | 55 | #' @title Get index matrix 56 | #' @description Get a matrix to broadcast a vector from weekly to daily 57 | #' @param n_days number of days we will expand to 58 | #' @param n_weeks number of weeks those days correspond to 59 | #' 60 | #' @return a n_day x n_week matrix for multiplying by weekly estimated 61 | #' value to broadcast it to daily 62 | #' @export 63 | #' 64 | #' @examples 65 | #' ind_m <- get_ind_m(14, 2) 66 | get_ind_m <- function(n_days, n_weeks) { 67 | ind_m <- matrix(nrow = n_days, ncol = n_weeks) 68 | for (i in 1:n_days) { 69 | for (j in 1:n_weeks) { 70 | if (((i - 1) %/% 7) + 1 == j) { 71 | ind_m[i, j] <- 1 72 | } else { 73 | ind_m[i, j] <- 0 74 | } 75 | } 76 | } 77 | 78 | return(ind_m) 79 | } 80 | 81 | #' @title Create a new directory if one doesn't exist 82 | #' @description 83 | #' Function to create a directory for the specified output file path if needed. 84 | #' Does nothing if the target directory already exists. 85 | #' 86 | #' 87 | #' @param output_file_path file path that may or may not need to be created 88 | #' 89 | #' @export 90 | create_dir <- function(output_file_path) { 91 | if (!file.exists(output_file_path)) { 92 | fs::dir_create(output_file_path, recurse = TRUE, mode = "0777") 93 | Sys.chmod(output_file_path, mode = "0777", use_umask = FALSE) 94 | } 95 | } 96 | 97 | 98 | #' @title Get the mean of a Normal distribution for a random variable Y 99 | #' needed to ensure that the distribution of X = exp(Y) (which is Log-Normal) 100 | #' has a specified mean and sd. 101 | #' @description 102 | #' see arithmetic moments here 103 | #' https://en.wikipedia.org/wiki/Log-normal_distribution 104 | #' 105 | #' @param mean target mean for the Log-Normal distribution of X 106 | #' @param sd target sd for the Log-Normal distribution X 107 | #' 108 | #' @return corresponding mean for the underlying Normal 109 | #' distribution of Y = log(X). 110 | 111 | #' @export 112 | convert_to_logmean <- function(mean, sd) { 113 | logmean <- log(mean^2 / sqrt(sd^2 + mean^2)) 114 | return(logmean) 115 | } 116 | 117 | 118 | 119 | #' @title Get the sd of a Normal distribution for a random variable Y 120 | #' needed to ensure that the distribution of X = exp(Y) (which is Log-Normal) 121 | #' has a specified mean and sd. 122 | #' @description see arithmetic moments here 123 | #' https://en.wikipedia.org/wiki/Log-normal_distribution 124 | #' 125 | #' @param mean target mean for the Log-Normal distribution of X 126 | #' @param sd target sd for the Log-Normal distribution of X 127 | #' 128 | #' @return corresponding sd for the underlying Normal distribution of Y = log(X) 129 | #' @export 130 | convert_to_logsd <- function(mean, sd) { 131 | logsd <- sqrt(log(1 + (sd^2 / mean^2))) 132 | return(logsd) 133 | } 134 | 135 | #' @title Normalize vector to a simplex 136 | #' 137 | #' @param vector numeric vector 138 | #' 139 | #' @return vector whose entries sum to 1 140 | #' @export 141 | #' @examples 142 | #' to_simplex(c(1, 1, 1)) 143 | to_simplex <- function(vector) { 144 | if (any(vector < 0)) { 145 | cli::cli_abort( 146 | c( 147 | "Cannot normalize a vector with ", 148 | "negative entries to a simplex. ", 149 | "Got {vector}" 150 | ) 151 | ) 152 | } 153 | return(vector / sum(vector)) 154 | } 155 | 156 | #' Escape brackets returned in a string for passing to glue 157 | #' 158 | #' @param string A string vector containing `{}` 159 | #' 160 | #' @return A string vector where all single brackets are replaced with double 161 | #' brackets 162 | autoescape_brackets <- function(string) { 163 | return(gsub("\\{|\\}", "", string)) 164 | } 165 | -------------------------------------------------------------------------------- /R/wwinference-package.R: -------------------------------------------------------------------------------- 1 | #' @keywords internal 2 | "_PACKAGE" 3 | 4 | #' @importFrom lubridate ymd 5 | #' @importFrom tidybayes spread_draws stat_halfeye stat_slab 6 | #' @importFrom dplyr filter left_join select pull distinct mutate as_tibble 7 | #' rename ungroup arrange row_number group_by lead lag 8 | #' @importFrom tidyr pivot_wider pivot_longer 9 | #' @importFrom ggplot2 ggplot facet_wrap geom_line geom_hline geom_point 10 | #' geom_bar theme scale_y_continuous scale_colour_discrete scale_fill_discrete 11 | #' geom_ribbon scale_x_date facet_grid geom_vline labs aes ggtitle xlab ylab 12 | #' theme_bw element_text geom_step 13 | #' @importFrom cmdstanr cmdstan_model 14 | #' @importFrom posterior subset_draws as_draws_list 15 | #' @importFrom fs path_package 16 | #' @importFrom rlang sym .data 17 | #' @importFrom stats dnbinom dweibull ecdf plogis qlogis rlnorm rnbinom rnorm 18 | #' rt sd time 19 | #' @importFrom tibble tibble 20 | NULL 21 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | url: https://cdcgov.github.io/ww-inference-model/ 2 | template: 3 | bootstrap: 5 4 | math-rendering: mathjax 5 | 6 | development: 7 | mode: auto 8 | 9 | navbar: 10 | structure: 11 | right: [search, github, lightswitch, ver] 12 | components: 13 | ver: 14 | href: https://cdcgov.github.io/ww-inference-model/release 15 | icon: fa-toggle-on 16 | text: (switch to release) 17 | 18 | home: 19 | links: 20 | - text: Release site 21 | href: https://cdcgov.github.io/ww-inference-model/release/ 22 | - text: Dev site 23 | href: https://cdcgov.github.io/ww-inference-model/ 24 | -------------------------------------------------------------------------------- /data-raw/covid_pmfs.R: -------------------------------------------------------------------------------- 1 | # Load in the parameters 2 | params <- wwinference::get_params( 3 | system.file("extdata", "example_params.toml", 4 | package = "wwinference" 5 | ) 6 | ) 7 | 8 | # Put it all together 9 | default_covid_gi <- withr::with_seed(42, { 10 | wwinference:::simulate_double_censored_pmf( 11 | max = params$gt_max, meanlog = params$mu_gi, 12 | sdlog = params$sigma_gi, fun_dist = rlnorm, n = 5e6 13 | ) |> wwinference:::drop_first_and_renormalize() 14 | }) 15 | 16 | inc <- wwinference:::make_incubation_period_pmf( 17 | params$backward_scale, params$backward_shape, params$r 18 | ) 19 | sym_to_hosp <- wwinference:::make_hospital_onset_delay_pmf( 20 | params$neg_binom_mu, 21 | params$neg_binom_size 22 | ) 23 | default_covid_inf_to_hosp <- wwinference:::make_reporting_delay_pmf( 24 | inc, sym_to_hosp 25 | ) 26 | 27 | 28 | usethis::use_data(default_covid_gi, overwrite = TRUE) 29 | usethis::use_data(default_covid_inf_to_hosp, overwrite = TRUE) 30 | -------------------------------------------------------------------------------- /data-raw/vignette_data.R: -------------------------------------------------------------------------------- 1 | set.seed(1) 2 | simulated_data <- wwinference::generate_simulated_data() 3 | hosp_data_from_sim <- simulated_data$hosp_data 4 | ww_data <- simulated_data$ww_data 5 | ww_data_eval <- simulated_data$ww_data_eval 6 | hosp_data <- hosp_data_from_sim |> 7 | dplyr::mutate("location" = "example state") 8 | hosp_data_eval <- simulated_data$hosp_data_eval 9 | subpop_hosp_data <- simulated_data$subpop_hosp_data 10 | subpop_hosp_data_eval <- simulated_data$subpop_hosp_data_eval 11 | true_global_rt <- simulated_data$true_global_rt 12 | 13 | usethis::use_data(hosp_data, overwrite = TRUE) 14 | usethis::use_data(hosp_data_eval, overwrite = TRUE) 15 | usethis::use_data(ww_data, overwrite = TRUE) 16 | usethis::use_data(ww_data_eval, overwrite = TRUE) 17 | usethis::use_data(subpop_hosp_data, overwrite = TRUE) 18 | usethis::use_data(subpop_hosp_data_eval, overwrite = TRUE) 19 | usethis::use_data(true_global_rt, overwrite = TRUE) 20 | -------------------------------------------------------------------------------- /data/default_covid_gi.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDCgov/ww-inference-model/85a6d5c57e6f4c6450cd637750fa58e036a8c0dd/data/default_covid_gi.rda -------------------------------------------------------------------------------- /data/default_covid_inf_to_hosp.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDCgov/ww-inference-model/85a6d5c57e6f4c6450cd637750fa58e036a8c0dd/data/default_covid_inf_to_hosp.rda -------------------------------------------------------------------------------- /data/hosp_data.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDCgov/ww-inference-model/85a6d5c57e6f4c6450cd637750fa58e036a8c0dd/data/hosp_data.rda -------------------------------------------------------------------------------- /data/hosp_data_eval.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDCgov/ww-inference-model/85a6d5c57e6f4c6450cd637750fa58e036a8c0dd/data/hosp_data_eval.rda -------------------------------------------------------------------------------- /data/subpop_hosp_data.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDCgov/ww-inference-model/85a6d5c57e6f4c6450cd637750fa58e036a8c0dd/data/subpop_hosp_data.rda -------------------------------------------------------------------------------- /data/subpop_hosp_data_eval.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDCgov/ww-inference-model/85a6d5c57e6f4c6450cd637750fa58e036a8c0dd/data/subpop_hosp_data_eval.rda -------------------------------------------------------------------------------- /data/true_global_rt.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDCgov/ww-inference-model/85a6d5c57e6f4c6450cd637750fa58e036a8c0dd/data/true_global_rt.rda -------------------------------------------------------------------------------- /data/ww_data.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDCgov/ww-inference-model/85a6d5c57e6f4c6450cd637750fa58e036a8c0dd/data/ww_data.rda -------------------------------------------------------------------------------- /data/ww_data_eval.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDCgov/ww-inference-model/85a6d5c57e6f4c6450cd637750fa58e036a8c0dd/data/ww_data_eval.rda -------------------------------------------------------------------------------- /inst/extdata/example_params.toml: -------------------------------------------------------------------------------- 1 | [timescale] 2 | uot = 50 3 | 4 | [infection_process] 5 | r_prior_mean = 1 6 | r_prior_sd = 1 7 | sigma_rt_prior = 0.1 8 | dur_inf = 7 9 | 10 | sigma_i_first_obs_prior_mode = 0 11 | sigma_i_first_obs_prior_sd = 0.5 12 | i_first_obs_certainty = 5 13 | ## effective number of binomial trials 14 | ## in beta prior centered on estimated i_first_obs (estimated) /n 15 | 16 | mean_initial_exp_growth_rate_prior_mean = 0 17 | mean_initial_exp_growth_rate_prior_sd = 0.01 18 | sigma_initial_exp_growth_rate_prior_mode = 0 19 | sigma_initial_exp_growth_rate_prior_sd = 0.05 20 | 21 | autoreg_rt_a = 2 # shape1 parameter of autoreg term on Rt trend 22 | autoreg_rt_b = 40 # shape2 parameter of autoreg on Rt trend 23 | # mean = a/(a+b) = 0.05, stdv = sqrt(a)/b = sqrt(2)/40 = 0.035 24 | autoreg_rt_subpop_a = 1 # shape1 parameter of autoreg term on difference between 25 | # R(t) ref and R(t) subpop 26 | autoreg_rt_subpop_b = 4 # shape2 parameter of autoreg term on difference between 27 | # R(t) ref and R(t) subpop 28 | 29 | # Normal prior on fixed offset between central log scale R(t) and reference pop 30 | offset_ref_log_r_t_prior_mean = 0 31 | offset_ref_log_r_t_prior_sd = 0.2 32 | 33 | # Normal prior on fixed offset between central logit scale i_first_obs/n and reference pop i_first_obs/n 34 | offset_ref_logit_i_first_obs_prior_mean = 0 35 | offset_ref_logit_i_first_obs_prior_sd = 0.25 36 | 37 | # Normal prior on fixed offset between central initial exponential growth rate 38 | # and reference population initial exponential growth rate 39 | offset_ref_initial_exp_growth_rate_prior_mean = 0 40 | offset_ref_initial_exp_growth_rate_prior_sd = 0.025 41 | 42 | autoreg_p_hosp_a = 1 # shape1 parameter of autoreg term on IHR(t) trend 43 | autoreg_p_hosp_b = 100 # shape2 parameter of autoreg term on IHR(t) trend 44 | eta_sd_mean = 0.0278 # from posterior of fit to long time series 45 | eta_sd_sd = 0.01 46 | infection_feedback_prior_logmean = 4.498 # log(~90) from posterior of fit to long 47 | # time series 48 | infection_feedback_prior_logsd = 0.636 # log(~1.9) 49 | 50 | [hospital_admission_observation_process] 51 | # Hospitalization parameters (informative priors) 52 | # IHR estimate from: https://www.nature.com/articles/s41467-023-39661-5 53 | p_hosp_mean = 0.01 54 | p_hosp_sd_logit = 0.3 55 | 56 | # time variation in p_hosp 57 | p_hosp_w_sd_sd = 0.01 58 | 59 | inv_sqrt_phi_prior_mean = 0.1 # 1 / sqrt(100) 60 | inv_sqrt_phi_prior_sd = 0.1414214 # 1 / sqrt(50) 61 | hosp_wday_effect_prior_alpha = [5, 5, 5, 5, 5, 5, 5] 62 | # centered on equal effects for all days 63 | 64 | [wastewater_observation_process] 65 | ml_of_ww_per_person_day = 22.7e4 66 | t_peak_mean = 5 67 | t_peak_sd = 1 68 | viral_peak_mean = 5.1 69 | viral_peak_sd = 0.5 70 | duration_shedding_mean = 17 71 | duration_shedding_sd = 3 72 | log10_g_prior_mean = 12 73 | log10_g_prior_sd = 2 74 | log_g_prior_mean = 27.63102 # 12 * log(10) 75 | log_g_prior_sd = 4.60517 # 2 * log(10) 76 | 77 | mode_sigma_ww_site_prior_mode = 1 78 | mode_sigma_ww_site_prior_sd = 1 79 | sd_log_sigma_ww_site_prior_mode = 0 80 | sd_log_sigma_ww_site_prior_sd = 0.693 # log(2) 81 | 82 | ww_site_mod_sd_sd = 0.25 83 | log_phi_g_prior_mean = -2.302585 # log(0.1) 84 | # prior mean in individual level dispersion 85 | # in fecal shedding 86 | log_phi_g_prior_sd = 5 # wide std 87 | 88 | 89 | [continuous_distribution_parameters] 90 | # Generation Interval 91 | # From: Park, Sang Woo, et al. "Inferring the differences in incubation-period 92 | # and generation-interval distributions of the Delta and Omicron variants of 93 | # SARS-CoV-2." Proceedings of the National Academy of Sciences 120.22 (2023): 94 | # e2221887120. 95 | # from the object in Fig 4F corresponding to between household transmission 96 | # in Omicron https://github.com/parksw3/omicron-generation/blob/d36d4568bfd3b3d389b30282758b9c322cfe2b9f/figure/compare.R#L175 #nolint 97 | 98 | mu_gi = 0.92877 99 | sigma_gi = 0.526 # (using lognormal CDF and Park CIs of 2.7 and 3.2) 100 | gt_max = 15 # number of daily bins for discretization 101 | 102 | # Incubation period parameters 103 | # From: Park, Sang Woo, et al. "Inferring the differences in incubation-period 104 | # and generation-interval distributions of the Delta and Omicron variants of 105 | # SARS-CoV-2." Proceedings of the National Academy of Sciences 120.22 (2023): 106 | # e2221887120. 107 | r = 0.15 108 | backward_shape = 1.5 109 | backward_scale = 3.6 110 | 111 | # Symptom onset to hospital admission delay parameters 112 | # From fitting a negative binomial to data from 113 | # Danache et al 114 | # https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0261428 115 | neg_binom_mu = 6.98665 116 | neg_binom_size = 2.490848 117 | -------------------------------------------------------------------------------- /inst/stan/functions/ar1.stan: -------------------------------------------------------------------------------- 1 | /** 2 | * Assembles an AR(1) process out of its non-centered, non-scaled components. 3 | * @param mu vector of the mean value that the process preserves to 4 | * @param ac The autocorrelation coefficient. 5 | * @param sd The sd for the white noise/IID normal terms. 6 | * @param z vector of IID Normal(0,1) variables, the white noise/increment terms. 7 | * @param is_stat int serving as logical, should process be initialized at 8 | * stationary variance (1) or not (0)? Not valid for |ac| >= 1. 9 | * @return A vector, the values of the mean-preserving AR(1) process: 10 | * x[1] = x0, 11 | * x[i > 1] = mu + tvd[[i], where 12 | * tvd[i] = ac * tvd[i - 1] + sd* z[i] 13 | * Formally x(t) = mu(t) + delta(t) where 14 | * delta(t) = psi*delta(t-1) + eta(t) 15 | */ 16 | vector ar1(vector mu, real ac, real sd, vector z, int is_stat) { 17 | int n = num_elements(z); 18 | vector[n] eta; 19 | vector[n] x; 20 | vector[n] tvd; 21 | 22 | eta = sd * z; 23 | if(is_stat) { 24 | real adj; 25 | if (ac >= 1.0) { 26 | reject("AR(1) process is not stationary if ac >= 1."); 27 | } 28 | adj = 1.0 / sqrt(1.0 - ac^2); 29 | eta[1] = adj * eta[1]; 30 | } 31 | 32 | tvd[1] = eta[1]; 33 | for (t in 2:n) { 34 | tvd[t] = ac * tvd[t - 1] + eta[t]; 35 | } 36 | 37 | x = mu + tvd; 38 | return x; 39 | } 40 | -------------------------------------------------------------------------------- /inst/stan/functions/convolve.stan: -------------------------------------------------------------------------------- 1 | // This code was adapted from code written 2 | // (under an MIT license) as part of the `EpiNow2` 3 | // package (https://github.com/epiforecasts/EpiNow2) 4 | 5 | // convolve two vectors as a backwards dot product 6 | // y vector shoud be reversed 7 | // limited to the length of x and backwards looking for x indexes 8 | // designed for use convolve a case vector and a delay pmf 9 | vector convolve_dot_product(vector x, vector y, int len) { 10 | int ylen = num_elements(y); 11 | vector[len] z; 12 | for (s in 1 : len) { 13 | z[s] = dot_product(x[max(1, s - ylen + 1) : s], tail(y, min(ylen, s))); 14 | } 15 | return z; 16 | } 17 | -------------------------------------------------------------------------------- /inst/stan/functions/diff_ar1.stan: -------------------------------------------------------------------------------- 1 | /** 2 | * Assembles a differenced AR(1) process out of its non-centered, non-scaled 3 | * components. 4 | * @param x0 The initial value, or intercept. 5 | * @param ar The autocorrelation coefficient. 6 | * @param sd The standard deviation for the white noise/IID normal terms. 7 | * @param z Vector of IID Normal(0,1) variables, the white noise/increment terms. 8 | * @param is_stat int serving as logical. Passed as the `is_stat` 9 | * argument to function [ar1()]. Should the underlying AR(1) process on 10 | * the first differences be initialized at stationary variance (1) 11 | * or not (0)? Not valid for |ar| >= 1. 12 | * 13 | * @return A vector representing the values of the differenced 14 | * AR(1) process. 15 | */ 16 | vector diff_ar1(real x0, real ar, real sd, vector z, int is_stat) { 17 | int n = num_elements(z) + 1; 18 | vector[n] diffs; 19 | 20 | diffs[1] = x0; 21 | diffs[2:n] = ar1(rep_vector(0.0, n-1), ar, sd, z, is_stat); 22 | return cumulative_sum(diffs); 23 | } 24 | -------------------------------------------------------------------------------- /inst/stan/functions/expgamma_lpdf.stan: -------------------------------------------------------------------------------- 1 | real expgamma_lpdf(vector x, real shape_k, real scale_theta){ 2 | 3 | return(sum( 4 | -shape_k * log(scale_theta) - 5 | lgamma(shape_k) + 6 | shape_k * x - (exp(x) / scale_theta))); 7 | } 8 | 9 | real expgamma_lpdf(real x, real shape_k, real scale_theta){ 10 | 11 | return( 12 | -shape_k * log(scale_theta) - 13 | lgamma(shape_k) + 14 | shape_k * x - (exp(x) / scale_theta)); 15 | } 16 | 17 | real expgamma_lpdf(vector xs, 18 | vector shapes_k, 19 | vector scales_theta){ 20 | 21 | return(sum( 22 | -shapes_k .* log(scales_theta) - 23 | lgamma(shapes_k) + 24 | shapes_k .* xs - (exp(xs) ./ scales_theta))); 25 | } 26 | -------------------------------------------------------------------------------- /inst/stan/functions/hospitalization.stan: -------------------------------------------------------------------------------- 1 | /** 2 | * Assembles daily hospitalization probability vector from a weekly random walk. 3 | * Uses non-centered, non-scaled differences, initial value, and SD for the walk. 4 | * Multiplies by matrix to transform to daily. 5 | * 6 | * @param p_hosp_m matrix to handle conversion from weekly to daily 7 | * @param p_hosp_int intercept/first value, on unconstrained scale 8 | * @param p_hosp_w_sd, scaling factor for/SD of random walk 9 | * @param autoreg_p_hosp, autoreg parameter for IHR 10 | * @param p_hosp_w weekly deviations of the random walk, on unconstrained scale 11 | * @param tot_weeks, number of total weeks in calibration and forecast period 12 | * @param is_stat, whether or not AR(1) process starts at stationarity 13 | * @return A vector, daily probabilities of hospitalization 14 | */ 15 | vector assemble_p_hosp(matrix p_hosp_m, real p_hosp_mean, real p_hosp_w_sd, 16 | real autoreg_p_hosp, 17 | vector p_hosp_w, int tot_weeks, int is_stat) { 18 | vector[dims(p_hosp_m)[1]] p_hosp; 19 | vector[tot_weeks] p_hosp_in_weeks; 20 | 21 | p_hosp_in_weeks = ar1(rep_vector(p_hosp_mean, tot_weeks), 22 | autoreg_p_hosp, 23 | p_hosp_w_sd, 24 | p_hosp_w, 25 | is_stat); 26 | p_hosp = p_hosp_m * p_hosp_in_weeks; 27 | p_hosp = inv_logit(p_hosp); 28 | return p_hosp; 29 | } 30 | -------------------------------------------------------------------------------- /inst/stan/functions/infections.stan: -------------------------------------------------------------------------------- 1 | // This code was adapted from code written 2 | // (under an MIT license) as part of the `EpiNow2` 3 | // package (https://github.com/epiforecasts/EpiNow2) 4 | // calculate infectiousness (weighted sum of the generation interval and incident infections) 5 | real update_infectiousness(vector infections, vector gt_rev_pmf, 6 | int seeding_time, int index) { 7 | int gt_max = num_elements(gt_rev_pmf); 8 | // work out where to start the convolution of past infections with the 9 | // generation time distribution: (current_time - maximal generation time) if 10 | // that is >= 1, otherwise 1 (how far back to add infectiousness from) 11 | int inf_start = max(1, index + seeding_time - gt_max); 12 | // work out where to end the convolution: (current_time - 1) 13 | int inf_end = index + seeding_time - 1; 14 | // number of indices of the generation time to sum over (inf_end - inf_start + 1) 15 | // Either go all the way back or just go to where we start seeing infections 16 | int pmf_accessed = min(gt_max, index + seeding_time - 1); 17 | // calculate the elements of the convolution 18 | real new_inf = dot_product(infections[inf_start : inf_end], 19 | tail(gt_rev_pmf, pmf_accessed) 20 | // Last elements of reversed generation interval = first elemenets of generation interval! 21 | ); 22 | return new_inf; 23 | } 24 | 25 | /** 26 | * Computes the number of infections over time by updating the reproduction 27 | * number based on the effective infectiousness from previous days and 28 | * feedback from incidence data. Adapted from the EpiNow2 package. 29 | * 30 | * @param obs_r A vector of length `ot` representing the observed reproduction 31 | * numbers over a certain period. 32 | * 33 | * @param uot An integer representing the number of unobserved time steps 34 | * prior to the first observed value in `obs_r`. 35 | * 36 | * @param gt_rev_pmf A vector representing the reversed generation time 37 | * probability mass function. 38 | * 39 | * @param initial_infections An array of real numbers representing the initial 40 | * number of infections (in log scale) at the start of the unobserved period. 41 | * 42 | * @param initial_growth A real number representing the initial 43 | * growth rate of infections (in log scale) over the unobserved period. 44 | * 45 | * @param ht An integer representing the time horizon for the historical 46 | * tracking of infections. 47 | * 48 | * @param infection_feedback An optional array of real numbers providing 49 | * feedback to adjust the reproduction number based on recent incidence data. 50 | * 51 | * @param infection_feedback_pmf_rev A vector representing the 52 | * reversed probability mass function for the infection feedback. 53 | * 54 | * @return A tuple containing a vector of length `t` representing the number 55 | * of infections for each time step, combining both unobserved and observed 56 | * periods and a vector the same length as the input obs_r representing the 57 | * effective reproduction number at each time step. 58 | * @author Sam Abbott 59 | */ 60 | tuple(vector, vector) generate_infections(vector obs_r, int uot, vector gt_rev_pmf, 61 | real initial_infections, real initial_growth, 62 | int ht, real infection_feedback, vector infection_feedback_pmf_rev 63 | ) { 64 | // time indices and storage 65 | int at = num_elements(obs_r); // all time with R(t), including horizon time 66 | int t = at + uot; // uot + ot + Ht 67 | vector[at] rt = obs_r; 68 | vector[t] infections = rep_vector(0, t); 69 | real infectiousness; 70 | real infection_feedback_weighting; 71 | tuple(vector[t], vector[at]) output; 72 | 73 | // Initialise infections using daily growth 74 | infections[1] = initial_infections; 75 | if (uot > 1) { 76 | vector[uot-1] growth = rep_vector(initial_growth, uot-1); 77 | infections[2:uot] = initial_infections + cumulative_sum(growth); 78 | } 79 | infections[1:uot] = exp(infections[1:uot]); 80 | // iteratively update infections 81 | for (s in 1:at) { 82 | infectiousness = update_infectiousness(infections, gt_rev_pmf, uot, s); 83 | infection_feedback_weighting = update_infectiousness( 84 | infections, infection_feedback_pmf_rev, uot, s 85 | ); 86 | rt[s] = exp(log(rt[s]) - infection_feedback .* infection_feedback_weighting); 87 | infections[s + uot] = rt[s] * infectiousness; 88 | } 89 | 90 | // Assign tuple output 91 | output.1 = infections; 92 | output.2 = rt; 93 | return(output); 94 | } 95 | -------------------------------------------------------------------------------- /inst/stan/functions/observation_model.stan: -------------------------------------------------------------------------------- 1 | // This code was adapted from code written 2 | // (under an MIT license) as part of the `EpiNow2` 3 | // package (https://github.com/epiforecasts/EpiNow2) 4 | vector day_of_week_effect(vector reports, array[] int day_of_week, 5 | vector effect) { 6 | int t = num_elements(reports); 7 | int wl = num_elements(effect); 8 | // scale day of week effect 9 | vector[wl] scaled_effect = wl * effect; 10 | vector[t] scaled_reports; 11 | for (s in 1:t) { 12 | // add reporting effects (adjust for simplex scale) 13 | scaled_reports[s] = reports[s] * scaled_effect[day_of_week[s]]; 14 | } 15 | return scaled_reports; 16 | } 17 | 18 | vector get_vl_trajectory(real tpeak, real viral_peak, 19 | real duration_shedding, int n) { 20 | vector[n] s; 21 | real growth = viral_peak / tpeak; 22 | real wane = viral_peak / (duration_shedding - tpeak); 23 | 24 | for (t in 1 : n) { 25 | if (t <= tpeak) { 26 | s[t] = pow(10, growth * t); 27 | } else { 28 | s[t] = viral_peak + wane * tpeak - wane * t; 29 | if (s[t] < 0) { 30 | s[t] = 0; 31 | } 32 | s[t] = pow(10, s[t]); 33 | } 34 | } 35 | s = s / sum(s); 36 | return s; 37 | } 38 | -------------------------------------------------------------------------------- /inst/stan/functions/utils.stan: -------------------------------------------------------------------------------- 1 | // Functions to convert natural scale means/sd of a lognormal random variable Y 2 | // to corresponding means/sd of the underlying Normal random variable X = log(Y) 3 | real convert_to_logmean(real mean, real sd) { 4 | real logmean; 5 | logmean = log(mean ^ 2 / sqrt(sd ^ 2 + mean ^ 2)); 6 | return logmean; 7 | } 8 | 9 | real convert_to_logsd(real mean, real sd) { 10 | real logsd; 11 | logsd = sqrt(log(1 + (sd ^ 2 / mean ^ 2))); 12 | return logsd; 13 | } 14 | -------------------------------------------------------------------------------- /man/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDCgov/ww-inference-model/85a6d5c57e6f4c6450cd637750fa58e036a8c0dd/man/.DS_Store -------------------------------------------------------------------------------- /man/add_pmfs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{add_pmfs} 4 | \alias{add_pmfs} 5 | \title{Add probability mass functions} 6 | \usage{ 7 | add_pmfs(pmfs) 8 | } 9 | \arguments{ 10 | \item{pmfs}{A list of vectors describing the probability mass functions to} 11 | } 12 | \value{ 13 | A vector describing the probability mass function of the sum of the 14 | } 15 | \description{ 16 | This function allows the addition of probability mass functions (PMFs) to 17 | produce a new PMF. This is useful for example in the context of reporting 18 | delays where the PMF of the sum of two Poisson distributions is the 19 | convolution of the PMFs. 20 | } 21 | \details{ 22 | This code was adapted from code written 23 | (under an MIT license) as part of the \code{epinowcast} 24 | package (https://github.com/epinowcast/epinowcast) 25 | } 26 | \examples{ 27 | # Sample and analytical PMFs for two Poisson distributions 28 | x <- rpois(10000, 5) 29 | xpmf <- dpois(0:20, 5) 30 | y <- rpois(10000, 7) 31 | ypmf <- dpois(0:20, 7) 32 | # Add sampled Poisson distributions up to get combined distribution 33 | z <- x + y 34 | # Analytical convolution of PMFs 35 | conv_pmf <- add_pmfs(list(xpmf, ypmf)) 36 | conv_cdf <- cumsum(conv_pmf) 37 | # Empirical convolution of PMFs 38 | cdf <- ecdf(z)(0:42) 39 | # Compare sampled and analytical CDFs 40 | plot(conv_cdf) 41 | lines(cdf, col = "black") 42 | } 43 | -------------------------------------------------------------------------------- /man/add_time_indexing.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/get_stan_data.R 3 | \name{add_time_indexing} 4 | \alias{add_time_indexing} 5 | \title{Add time indexing to count data} 6 | \usage{ 7 | add_time_indexing(input_count_data) 8 | } 9 | \arguments{ 10 | \item{input_count_data}{data frame with dates and counts, 11 | but without time indexing.} 12 | } 13 | \value{ 14 | The same data frame, with an added 15 | time index, including NA rows if dates internal 16 | to the timeseries are missing admissions data. 17 | } 18 | \description{ 19 | Add time indexing to count data 20 | } 21 | \examples{ 22 | hosp_data_example <- tibble::tibble( 23 | date = lubridate::ymd("2024-01-01", "2024-01-02", "2024-01-06"), 24 | daily_hosp_admits = c(5, 3, 8) 25 | ) 26 | hosp_data_w_t <- add_time_indexing(hosp_data_example) 27 | } 28 | -------------------------------------------------------------------------------- /man/assert_cols_det_unique_row.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/checkers.R 3 | \name{assert_cols_det_unique_row} 4 | \alias{assert_cols_det_unique_row} 5 | \title{Check a set of columns in a data frame uniquely identify 6 | data frame rows.} 7 | \usage{ 8 | assert_cols_det_unique_row( 9 | df, 10 | unique_key_columns, 11 | arg = "x", 12 | call = rlang::caller_env(), 13 | add_err_msg = "" 14 | ) 15 | } 16 | \arguments{ 17 | \item{df}{the dataframe to check} 18 | 19 | \item{unique_key_columns}{Columns that, taken together, should 20 | uniquely identify a row in the data frame.} 21 | 22 | \item{arg}{the name of the unique grouping to check} 23 | 24 | \item{call}{Calling environment to be passed to \code{\link[cli:cli_abort]{cli::cli_abort()}} for 25 | traceback.} 26 | 27 | \item{add_err_msg}{string containing an additional error message, 28 | default is the empty string (\code{""})} 29 | } 30 | \value{ 31 | NULL, invisibly 32 | } 33 | \description{ 34 | Equivalently, this checks that when grouping by the columns in question, 35 | each group has a single entry 36 | } 37 | -------------------------------------------------------------------------------- /man/assert_daily_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/checkers.R 3 | \name{assert_daily_data} 4 | \alias{assert_daily_data} 5 | \title{Assert that the vector of dates being passed in contains dates for each day} 6 | \usage{ 7 | assert_daily_data(dates, call = rlang::caller_env(), add_err_msg = "") 8 | } 9 | \arguments{ 10 | \item{dates}{the vector of dates to check, must be of Date type} 11 | 12 | \item{call}{Calling environment to be passed to \code{\link[cli:cli_abort]{cli::cli_abort()}} for 13 | traceback.} 14 | 15 | \item{add_err_msg}{add_err_msg string containing an additional error message, 16 | default is the empty string (\code{""})} 17 | } 18 | \value{ 19 | NULL invisible 20 | } 21 | \description{ 22 | This function checks to make sure that the date vector being passed in 23 | is complete for every day between the minimum and maximum dates. It can 24 | have repeated values. 25 | } 26 | -------------------------------------------------------------------------------- /man/assert_dates_within_frame.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/checkers.R 3 | \name{assert_dates_within_frame} 4 | \alias{assert_dates_within_frame} 5 | \title{Assert that the second vector of dates is within the period after the first 6 | date in the first set of dats and the maximum date} 7 | \usage{ 8 | assert_dates_within_frame( 9 | dates1, 10 | dates2, 11 | max_date, 12 | call = rlang::caller_env(), 13 | add_err_msg = "" 14 | ) 15 | } 16 | \arguments{ 17 | \item{dates1}{the vector of dates to check, must of date type} 18 | 19 | \item{dates2}{the vector of dates to compare to, must be of date type} 20 | 21 | \item{max_date}{the maximum date the testing dates should be} 22 | 23 | \item{call}{Calling environment to be passed to \code{\link[cli:cli_abort]{cli::cli_abort()}} for 24 | traceback.} 25 | 26 | \item{add_err_msg}{add_err_msg string containing an additional error message, 27 | default is the empty string (\code{""})} 28 | } 29 | \value{ 30 | NULL invisible 31 | } 32 | \description{ 33 | Assert that the second vector of dates is within the period after the first 34 | date in the first set of dats and the maximum date 35 | } 36 | -------------------------------------------------------------------------------- /man/assert_df_not_empty.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/checkers.R 3 | \name{assert_df_not_empty} 4 | \alias{assert_df_not_empty} 5 | \title{Assert that the dataframe being passed to the function is not empty} 6 | \usage{ 7 | assert_df_not_empty(x, arg = "x", call = rlang::caller_env(), add_err_msg = "") 8 | } 9 | \arguments{ 10 | \item{x}{the dataframe to check} 11 | 12 | \item{arg}{the name of the dataframe to check} 13 | 14 | \item{call}{Calling environment to be passed to \code{\link[cli:cli_abort]{cli::cli_abort()}} for 15 | traceback.} 16 | 17 | \item{add_err_msg}{add_err_msg string containing an additional error message, 18 | default is the empty string (\code{""})} 19 | } 20 | \value{ 21 | NULL invisible 22 | } 23 | \description{ 24 | Assert that the dataframe being passed to the function is not empty 25 | } 26 | -------------------------------------------------------------------------------- /man/assert_elements_non_neg.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/checkers.R 3 | \name{assert_elements_non_neg} 4 | \alias{assert_elements_non_neg} 5 | \title{Assert that all elements of a vector are non-negative} 6 | \usage{ 7 | assert_elements_non_neg( 8 | x, 9 | arg = "x", 10 | call = rlang::caller_env(), 11 | add_err_msg = "" 12 | ) 13 | } 14 | \arguments{ 15 | \item{x}{vector of arguments to check for negativity} 16 | 17 | \item{arg}{string to print the name of the element your checking} 18 | 19 | \item{call}{Calling environment to be passed to \code{\link[cli:cli_abort]{cli::cli_abort()}} for 20 | traceback.} 21 | 22 | \item{add_err_msg}{string containing an additional error message, 23 | default is the empty string (\code{""})} 24 | } 25 | \value{ 26 | NULL, invisibly 27 | } 28 | \description{ 29 | Assert that all elements of a vector are non-negative 30 | } 31 | -------------------------------------------------------------------------------- /man/assert_equivalent_indexing.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/checkers.R 3 | \name{assert_equivalent_indexing} 4 | \alias{assert_equivalent_indexing} 5 | \title{Assert that two tibbles of date and time mapping align} 6 | \usage{ 7 | assert_equivalent_indexing( 8 | first_data, 9 | second_data, 10 | arg1 = "x1", 11 | arg2 = "x2", 12 | call = rlang::caller_env(), 13 | add_err_msg = "" 14 | ) 15 | } 16 | \arguments{ 17 | \item{first_data}{a tibble containing the columns \code{date} (with IS08601 18 | dates) and \code{t} (integers of time in days)} 19 | 20 | \item{second_data}{a tibble containing the columns \code{date} (with 21 | IS08601 dates) and \code{t} (integers of time in days)} 22 | 23 | \item{arg1}{string to print the name of the element your checking, 24 | default is \code{x1}} 25 | 26 | \item{arg2}{string to print the name of the element your checking, 27 | default is \code{x2}} 28 | 29 | \item{call}{Calling environment to be passed to \code{\link[cli:cli_abort]{cli::cli_abort()}} for 30 | traceback.} 31 | 32 | \item{add_err_msg}{add_err_msg string containing an additional error message, 33 | default is the empty string (\code{""})} 34 | } 35 | \value{ 36 | NULL invisible 37 | } 38 | \description{ 39 | Assert that two tibbles of date and time mapping align 40 | } 41 | -------------------------------------------------------------------------------- /man/assert_int_or_char.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/checkers.R 3 | \name{assert_int_or_char} 4 | \alias{assert_int_or_char} 5 | \title{Assert that a vector is either of a vector of integers or a vector of 6 | characters} 7 | \usage{ 8 | assert_int_or_char(x, arg = "x", call = rlang::caller_env()) 9 | } 10 | \arguments{ 11 | \item{x}{Object with type checking} 12 | 13 | \item{arg}{Name of the argument supplying the object} 14 | 15 | \item{call}{Calling environment to be passed to \code{\link[cli:cli_abort]{cli::cli_abort()}}} 16 | } 17 | \value{ 18 | NULL, invisibly 19 | } 20 | \description{ 21 | This is for unique identifiers of groupings, which we will allow to 22 | either be character or integers. 23 | } 24 | -------------------------------------------------------------------------------- /man/assert_no_dates_after_max.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/checkers.R 3 | \name{assert_no_dates_after_max} 4 | \alias{assert_no_dates_after_max} 5 | \title{Check that all dates in dataframe passed in are before a specified date} 6 | \usage{ 7 | assert_no_dates_after_max( 8 | date_vector, 9 | max_date, 10 | arg_dates = "y", 11 | arg_max_date = "x", 12 | call = rlang::caller_env() 13 | ) 14 | } 15 | \arguments{ 16 | \item{date_vector}{vector of dates} 17 | 18 | \item{max_date}{string indicating the maximum date in ISO8601 convention 19 | e.g. YYYY-MM-DD} 20 | 21 | \item{arg_dates}{string to print the name of the data you are checking the 22 | dates for} 23 | 24 | \item{arg_max_date}{string to print the name of the maximum date you are 25 | checkign the data for} 26 | 27 | \item{call}{Calling environment to be passed to \code{\link[cli:cli_abort]{cli::cli_abort()}} for 28 | traceback.} 29 | } 30 | \value{ 31 | NULL, invisibly 32 | } 33 | \description{ 34 | This function is specifically meant to ensure that the data in the 35 | \code{date_vector} specified does not contain dates after a given \code{max_date}. The 36 | intended use-case for this is to ensure that one doesn't accidentally 37 | pass in data that extends beyond the forecast date, as ideally the user 38 | is providing vintaged "as of" datasets or at the very least is filtering the 39 | data so that they are not including in their inference data that was 40 | made available after the forecast was made. 41 | } 42 | -------------------------------------------------------------------------------- /man/assert_no_repeated_elements.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/checkers.R 3 | \name{assert_no_repeated_elements} 4 | \alias{assert_no_repeated_elements} 5 | \title{Check that there are no repeated elements in the vector} 6 | \usage{ 7 | assert_no_repeated_elements( 8 | x, 9 | arg = "x", 10 | call = rlang::caller_env(), 11 | add_err_msg = "" 12 | ) 13 | } 14 | \arguments{ 15 | \item{x}{the vector to check} 16 | 17 | \item{arg}{the name of the vector to check} 18 | 19 | \item{call}{Calling environment to be passed to \code{\link[cli:cli_abort]{cli::cli_abort()}} for 20 | traceback.} 21 | 22 | \item{add_err_msg}{string containing an additional error message, 23 | default is the empty string (\code{""})} 24 | } 25 | \value{ 26 | NULL, invisibly 27 | } 28 | \description{ 29 | This function checks that the elements of a vector are 30 | not repeated. 31 | } 32 | -------------------------------------------------------------------------------- /man/assert_non_missingness.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/checkers.R 3 | \name{assert_non_missingness} 4 | \alias{assert_non_missingness} 5 | \title{Assert that there is no missignness in a particular vector} 6 | \usage{ 7 | assert_non_missingness( 8 | x, 9 | arg = "x", 10 | call = rlang::caller_env(), 11 | add_err_msg = "" 12 | ) 13 | } 14 | \arguments{ 15 | \item{x}{the vector to check} 16 | 17 | \item{arg}{the name of the vector to check} 18 | 19 | \item{call}{Calling environment to be passed to \code{\link[cli:cli_abort]{cli::cli_abort()}} for 20 | traceback.} 21 | 22 | \item{add_err_msg}{string containing an additional error message, 23 | default is the empty string (\code{""})} 24 | } 25 | \value{ 26 | NULL, invisibly 27 | } 28 | \description{ 29 | Assert that there is no missignness in a particular vector 30 | } 31 | -------------------------------------------------------------------------------- /man/assert_req_count_cols_present.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/checkers.R 3 | \name{assert_req_count_cols_present} 4 | \alias{assert_req_count_cols_present} 5 | \title{Check that the input count data contains all the required column names} 6 | \usage{ 7 | assert_req_count_cols_present( 8 | count_data, 9 | count_col_name, 10 | pop_size_col_name, 11 | add_req_col_names = c("date"), 12 | call = rlang::caller_env() 13 | ) 14 | } 15 | \arguments{ 16 | \item{count_data}{tibble containing the input count data} 17 | 18 | \item{count_col_name}{string indicating the name of the column containing 19 | the count data} 20 | 21 | \item{pop_size_col_name}{string indicating the name of the column containing 22 | the population size of the count catchment area} 23 | 24 | \item{add_req_col_names}{vector of strings indicating the required count 25 | data column names, the defaults is \code{"date"}} 26 | 27 | \item{call}{Calling environment to be passed to \code{\link[cli:cli_abort]{cli::cli_abort()}} for 28 | traceback.} 29 | } 30 | \value{ 31 | NULL, invisibly 32 | } 33 | \description{ 34 | This function is intended to be used to check that the count data that 35 | gets passed into \code{\link[=preprocess_count_data]{preprocess_count_data()}} contains the required columns. If 36 | it does not, we want to tell the user which columns are missing. This will 37 | not however, ensure that the elements of the column are of the right type, 38 | or check that the values of them make sense. 39 | } 40 | -------------------------------------------------------------------------------- /man/assert_req_ww_cols_present.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/checkers.R 3 | \name{assert_req_ww_cols_present} 4 | \alias{assert_req_ww_cols_present} 5 | \title{Check that the input wastewater data contains all the required column names} 6 | \usage{ 7 | assert_req_ww_cols_present( 8 | ww_data, 9 | conc_col_name, 10 | lod_col_name, 11 | add_req_col_names = c("date", "site", "lab", "site_pop"), 12 | call = rlang::caller_env() 13 | ) 14 | } 15 | \arguments{ 16 | \item{ww_data}{tibble containing the input wastewater data} 17 | 18 | \item{conc_col_name}{string indicating the name of the column containing 19 | the concentration measurements in the wastewater data} 20 | 21 | \item{lod_col_name}{string indicating the name of the column containing 22 | the concentration measurements in the wastewater data} 23 | 24 | \item{add_req_col_names}{vector of strings indicating the required wastewater 25 | column names, the defaults are \code{c("date", "site", "lab", "site_pop")}} 26 | 27 | \item{call}{Calling environment to be passed to \code{\link[cli:cli_abort]{cli::cli_abort()}} for 28 | traceback.} 29 | } 30 | \value{ 31 | NULL, invisibly 32 | } 33 | \description{ 34 | This function is intended to be used to check that the wastewater data that 35 | gets passed into \code{\link[=preprocess_ww_data]{preprocess_ww_data()}} contains the required columns. If 36 | it does not, we want to tell the user which column are missing. This will not 37 | however, ensure that the elements of the column are of the right type, 38 | or check that the values of them make sense. 39 | } 40 | -------------------------------------------------------------------------------- /man/assert_rt_correct_length.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/checkers.R 3 | \name{assert_rt_correct_length} 4 | \alias{assert_rt_correct_length} 5 | \title{Assert that R(t) specified for generating simulated data is of sufficient 6 | length} 7 | \usage{ 8 | assert_rt_correct_length( 9 | r_in_weeks, 10 | ot, 11 | nt, 12 | forecast_horizon, 13 | call = rlang::caller_env() 14 | ) 15 | } 16 | \arguments{ 17 | \item{r_in_weeks}{a vector indicating the R(t) in weeks} 18 | 19 | \item{ot}{integer indicating the observed time: length of hospital admissions 20 | calibration time in days} 21 | 22 | \item{nt}{integer indicating the nowcast time: length of time between last 23 | hospital admissions date and forecast date in days} 24 | 25 | \item{forecast_horizon}{integer indicating the duration of the forecast in 26 | days e.g. 28 days} 27 | 28 | \item{call}{Calling environment to be passed to \code{\link[cli:cli_abort]{cli::cli_abort()}} for 29 | traceback.} 30 | } 31 | \value{ 32 | NULL, invisible 33 | } 34 | \description{ 35 | Assert that R(t) specified for generating simulated data is of sufficient 36 | length 37 | } 38 | -------------------------------------------------------------------------------- /man/assert_single_value.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/checkers.R 3 | \name{assert_single_value} 4 | \alias{assert_single_value} 5 | \title{Assert that there is only a single value in a particular column} 6 | \usage{ 7 | assert_single_value(x, arg = "x", call = rlang::caller_env(), add_err_msg = "") 8 | } 9 | \arguments{ 10 | \item{x}{the vector to check} 11 | 12 | \item{arg}{the name of the vector to check} 13 | 14 | \item{call}{Calling environment to be passed to \code{\link[cli:cli_abort]{cli::cli_abort()}} for 15 | traceback.} 16 | 17 | \item{add_err_msg}{string containing an additional error message, 18 | default is the empty string (\code{""})} 19 | } 20 | \value{ 21 | NULL, invisibly 22 | } 23 | \description{ 24 | Assert that there is only a single value in a particular column 25 | } 26 | -------------------------------------------------------------------------------- /man/assert_site_lab_indices_align.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/checkers.R 3 | \name{assert_site_lab_indices_align} 4 | \alias{assert_site_lab_indices_align} 5 | \title{Assert that the specified site and lab indices line up} 6 | \usage{ 7 | assert_site_lab_indices_align(site, lab, call = rlang::caller_env()) 8 | } 9 | \arguments{ 10 | \item{site}{vector of integers indicating which site (WWTP) each separate 11 | lab-site observation comes frm} 12 | 13 | \item{lab}{ector of integers indicating which lab the lab-site observations 14 | come from} 15 | 16 | \item{call}{Calling environment to be passed to \code{\link[cli:cli_abort]{cli::cli_abort()}} for 17 | traceback.} 18 | } 19 | \value{ 20 | NULL, invisibly 21 | } 22 | \description{ 23 | Assert that the specified site and lab indices line up 24 | } 25 | -------------------------------------------------------------------------------- /man/assert_sufficient_days_of_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/checkers.R 3 | \name{assert_sufficient_days_of_data} 4 | \alias{assert_sufficient_days_of_data} 5 | \title{Assert that the vector of dates spans at least the specified 6 | calibration time} 7 | \usage{ 8 | assert_sufficient_days_of_data( 9 | date_vector, 10 | data_name, 11 | calibration_time, 12 | call = rlang::caller_env(), 13 | add_err_msg = "" 14 | ) 15 | } 16 | \arguments{ 17 | \item{date_vector}{the vector of dates to check, must be of Date type} 18 | 19 | \item{data_name}{What data correspond to the dates in \code{date_vector}. 20 | Used to make the error message informative (e.g. 21 | "hospital admissions data")} 22 | 23 | \item{calibration_time}{integer indicating the number of days that 24 | the dates must span} 25 | 26 | \item{call}{Calling environment to be passed to \code{\link[cli:cli_abort]{cli::cli_abort()}} for 27 | traceback.} 28 | 29 | \item{add_err_msg}{add_err_msg string containing an additional error message, 30 | default is the empty string (\code{""})} 31 | } 32 | \value{ 33 | NULL invisible 34 | } 35 | \description{ 36 | Assert that the vector of dates spans at least the specified 37 | calibration time 38 | } 39 | -------------------------------------------------------------------------------- /man/assert_ww_site_pops_lt_total.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/checkers.R 3 | \name{assert_ww_site_pops_lt_total} 4 | \alias{assert_ww_site_pops_lt_total} 5 | \title{Assert that the sum of the wastewater site populations don't exceed 6 | the total population} 7 | \usage{ 8 | assert_ww_site_pops_lt_total( 9 | pop_size, 10 | ww_pop_sites, 11 | call = rlang::caller_env() 12 | ) 13 | } 14 | \arguments{ 15 | \item{pop_size}{integer indicating the population size in the hypothetical 16 | state} 17 | 18 | \item{ww_pop_sites}{vector indicating the population size in the 19 | catchment area in each of those sites} 20 | 21 | \item{call}{Calling environment to be passed to \code{\link[cli:cli_abort]{cli::cli_abort()}} for 22 | traceback.} 23 | } 24 | \value{ 25 | NULL, invisibly 26 | } 27 | \description{ 28 | Assert that the sum of the wastewater site populations don't exceed 29 | the total population 30 | } 31 | -------------------------------------------------------------------------------- /man/autoescape_brackets.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{autoescape_brackets} 4 | \alias{autoescape_brackets} 5 | \title{Escape brackets returned in a string for passing to glue} 6 | \usage{ 7 | autoescape_brackets(string) 8 | } 9 | \arguments{ 10 | \item{string}{A string vector containing \code{{}}} 11 | } 12 | \value{ 13 | A string vector where all single brackets are replaced with double 14 | brackets 15 | } 16 | \description{ 17 | Escape brackets returned in a string for passing to glue 18 | } 19 | -------------------------------------------------------------------------------- /man/calc_rt.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model_component_fwd_sim.R 3 | \name{calc_rt} 4 | \alias{calc_rt} 5 | \title{Back- calculate R(t) from incident infections and the generation interval} 6 | \usage{ 7 | calc_rt(new_i, convolve_fxn, generation_interval, uot, tot_time) 8 | } 9 | \arguments{ 10 | \item{new_i}{vector of numerics that spans the length of \code{tot_time}, 11 | representing the new incident infections per day} 12 | 13 | \item{convolve_fxn}{function used to convolve infections with delay pmf 14 | This will typically take the \code{convolve_dot_product()} function from the 15 | \code{wwinference.stan} model} 16 | 17 | \item{generation_interval}{vector of simplex describing the probability of 18 | each time from infection to onwards transmission} 19 | 20 | \item{uot}{integer indicating the days for exponential growth initialization 21 | to occur (referred to as unobserved time)} 22 | 23 | \item{tot_time}{integer indicating the total time we have incident 24 | infections for} 25 | } 26 | \value{ 27 | a numeric vector of length(\code{tot_time} - \code{uot}) that represents 28 | the effective reproductive number 29 | } 30 | \description{ 31 | Note that the forward renewal process is not a simple convolution of 32 | incident infections and the generation interval -- because it assumes that 33 | the generation interval being passed in is indexed starting at day 1, and 34 | that on any particular index day there is no contribution from individuals 35 | infected on that day. This is a reasonable assumption, but to align the 36 | implementation of the forward process with our backward process, we have to 37 | add a 0 density to day 0 of the passed in generation interval. 38 | } 39 | -------------------------------------------------------------------------------- /man/compile_model.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/compile_model.R 3 | \name{compile_model} 4 | \alias{compile_model} 5 | \title{Compile a stan model while pointing at the package default 6 | include directory (\code{stan}) for #include statements} 7 | \usage{ 8 | compile_model( 9 | model_filepath = system.file("stan", "wwinference.stan", package = "wwinference"), 10 | include_paths = system.file("stan", package = "wwinference"), 11 | threads = FALSE, 12 | target_dir = tempdir(), 13 | stanc_options = list(), 14 | cpp_options = list(), 15 | verbose = TRUE, 16 | ... 17 | ) 18 | } 19 | \arguments{ 20 | \item{model_filepath}{path to .stan file defining the model, default is 21 | `system.file("stan", "wwinference.stan", package = "wwinference")} 22 | 23 | \item{include_paths}{path(s) to directories to search for files 24 | specified in #include statements. Passed to \code{\link[cmdstanr:cmdstan_model]{cmdstanr::cmdstan_model()}}. 25 | Defaults to the \code{stan} subdirectory of the installed 26 | \code{wwinference} package.} 27 | 28 | \item{threads}{Number of threads to use in model compilation, 29 | as an integer. Passed to \code{\link[cmdstanr:cmdstan_model]{cmdstanr::cmdstan_model()}}. 30 | Default \code{FALSE} (use single-threaded compilation).} 31 | 32 | \item{target_dir}{Directory in which to save the compiled 33 | stan model binary. Passed as the \code{dir} keyword argument to 34 | \code{\link[cmdstanr:cmdstan_model]{cmdstanr::cmdstan_model()}}. Defaults to a temporary directory 35 | for the R session (the output of \code{\link[=tempdir]{tempdir()}}).} 36 | 37 | \item{stanc_options}{Options for the stan compiler passed to 38 | \code{\link[cmdstanr:cmdstan_model]{cmdstanr::cmdstan_model()}}, as a list. See that function's 39 | documentation for more details. Default \code{list()} (use default 40 | options).} 41 | 42 | \item{cpp_options}{Options for the C++ compiler passed to 43 | \code{\link[cmdstanr:cmdstan_model]{cmdstanr::cmdstan_model()}}, as a list. See that function's 44 | documentation for more details. Default \code{list()} (use default 45 | options).} 46 | 47 | \item{verbose}{Write detailed output to the terminal while 48 | executing the function? Boolean, default \code{TRUE}.} 49 | 50 | \item{...}{Additional keyword arguments passed to 51 | \code{\link[cmdstanr:cmdstan_model]{cmdstanr::cmdstan_model()}}.} 52 | } 53 | \value{ 54 | The resulting \code{cmdstanr} model object, as the output 55 | of \code{\link[cmdstanr:cmdstan_model]{cmdstanr::cmdstan_model()}}. 56 | } 57 | \description{ 58 | This function reads in and optionally compiles a Stan model. 59 | It is written to search the installed package \code{stan} directory 60 | for additional source files to include. Within each stan file, 61 | use \verb{#include \{path to your file with the stan directory\}.stan} 62 | } 63 | \details{ 64 | The code for this function has been adapted 65 | from code written (under an MIT license) as part of 66 | the \href{https://github.com/epinowcast/epinowcast}{\code{epinowcast}} 67 | R package. 68 | } 69 | -------------------------------------------------------------------------------- /man/convert_to_logmean.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{convert_to_logmean} 4 | \alias{convert_to_logmean} 5 | \title{Get the mean of a Normal distribution for a random variable Y 6 | needed to ensure that the distribution of X = exp(Y) (which is Log-Normal) 7 | has a specified mean and sd.} 8 | \usage{ 9 | convert_to_logmean(mean, sd) 10 | } 11 | \arguments{ 12 | \item{mean}{target mean for the Log-Normal distribution of X} 13 | 14 | \item{sd}{target sd for the Log-Normal distribution X} 15 | } 16 | \value{ 17 | corresponding mean for the underlying Normal 18 | distribution of Y = log(X). 19 | } 20 | \description{ 21 | see arithmetic moments here 22 | https://en.wikipedia.org/wiki/Log-normal_distribution 23 | } 24 | -------------------------------------------------------------------------------- /man/convert_to_logsd.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{convert_to_logsd} 4 | \alias{convert_to_logsd} 5 | \title{Get the sd of a Normal distribution for a random variable Y 6 | needed to ensure that the distribution of X = exp(Y) (which is Log-Normal) 7 | has a specified mean and sd.} 8 | \usage{ 9 | convert_to_logsd(mean, sd) 10 | } 11 | \arguments{ 12 | \item{mean}{target mean for the Log-Normal distribution of X} 13 | 14 | \item{sd}{target sd for the Log-Normal distribution of X} 15 | } 16 | \value{ 17 | corresponding sd for the underlying Normal distribution of Y = log(X) 18 | } 19 | \description{ 20 | see arithmetic moments here 21 | https://en.wikipedia.org/wiki/Log-normal_distribution 22 | } 23 | -------------------------------------------------------------------------------- /man/create_dir.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{create_dir} 4 | \alias{create_dir} 5 | \title{Create a new directory if one doesn't exist} 6 | \usage{ 7 | create_dir(output_file_path) 8 | } 9 | \arguments{ 10 | \item{output_file_path}{file path that may or may not need to be created} 11 | } 12 | \description{ 13 | Function to create a directory for the specified output file path if needed. 14 | Does nothing if the target directory already exists. 15 | } 16 | -------------------------------------------------------------------------------- /man/create_site_lab_map.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model_component_fwd_sim.R 3 | \name{create_site_lab_map} 4 | \alias{create_site_lab_map} 5 | \title{Create a mapping of sites, labs, and population sizes in each site} 6 | \usage{ 7 | create_site_lab_map(site, lab, ww_pop_sites) 8 | } 9 | \arguments{ 10 | \item{site}{vector of integers or characters uniquely identifying a site, 11 | or the population in the wastewater catchment area} 12 | 13 | \item{lab}{vector of integer or character uniquely identifying a lab where 14 | a sample was processed} 15 | 16 | \item{ww_pop_sites}{vector of integers indicating the population size in 17 | each site} 18 | } 19 | \value{ 20 | a tibble mapping sites, labs and population sizes 21 | } 22 | \description{ 23 | Create a mapping of sites, labs, and population sizes in each site 24 | } 25 | -------------------------------------------------------------------------------- /man/default_covid_gi.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{default_covid_gi} 5 | \alias{default_covid_gi} 6 | \title{COVID-19 post-Omicron generation interval probability mass function} 7 | \format{ 8 | An object of class \code{numeric} of length 15. 9 | } 10 | \source{ 11 | covid_pmfs.R 12 | } 13 | \usage{ 14 | default_covid_gi 15 | } 16 | \description{ 17 | \describe{ 18 | A vector that sums to 1, with each element representing the daily 19 | probability of secondary onward transmission occurring on that day. The 20 | first element of this vector represents the day after primary transmission 21 | occurred, it is assumed to be impossible for primary and secondary 22 | transmission to occur on the same day. 23 | } 24 | } 25 | \keyword{datasets} 26 | -------------------------------------------------------------------------------- /man/default_covid_inf_to_hosp.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{default_covid_inf_to_hosp} 5 | \alias{default_covid_inf_to_hosp} 6 | \title{COVID-19 time delay distribution from infection to hospital admission} 7 | \format{ 8 | An object of class \code{numeric} of length 55. 9 | } 10 | \source{ 11 | covid_pmfs.R 12 | } 13 | \usage{ 14 | default_covid_inf_to_hosp 15 | } 16 | \description{ 17 | \describe{ 18 | A vector that sums to 1, with each element representing the daily 19 | probabilty of transitioning from infected to hospitalized, conditioned on 20 | being infected and eventually ending up hospitalized. The first element 21 | represents the probability of being infected and admitted to the hospital 22 | on the same day 23 | } 24 | } 25 | \keyword{datasets} 26 | -------------------------------------------------------------------------------- /man/downsample_for_frequency.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model_component_fwd_sim.R 3 | \name{downsample_for_frequency} 4 | \alias{downsample_for_frequency} 5 | \title{Downsample the predicted wastewater concentrations based on the 6 | lab site reporting frequency} 7 | \usage{ 8 | downsample_for_frequency( 9 | log_conc_lab_site, 10 | n_lab_sites, 11 | ot, 12 | ht, 13 | nt, 14 | lab_site_reporting_freq 15 | ) 16 | } 17 | \arguments{ 18 | \item{log_conc_lab_site}{The matrix of n_lab_sites by n time points 19 | indicating the underlying expected observed concentrations} 20 | 21 | \item{n_lab_sites}{Integer indicating the number of unique lab-site 22 | combinations} 23 | 24 | \item{ot}{integer indicating the number of days we will have observed data 25 | for in the calibration period} 26 | 27 | \item{ht}{integer indicating the time after the last observed time to 28 | the end of the forecast time} 29 | 30 | \item{nt}{integer indicating the time after the last observed epi indicator 31 | and before the forecast date, of which there can still be wastewater 32 | observations} 33 | 34 | \item{lab_site_reporting_freq}{vector indicating the mean frequency of 35 | wastewater measurements in each site per day (e.g. 1/7 is once per week)} 36 | } 37 | \value{ 38 | A sparse matrix of \code{n_lab_sites} rows and \code{ot} + \code{ht} columns of 39 | but with NAs for when observations are not measured/reported. 40 | } 41 | \description{ 42 | Downsample the predicted wastewater concentrations based on the 43 | lab site reporting frequency 44 | } 45 | -------------------------------------------------------------------------------- /man/drop_first_and_renormalize.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/delay_distribs.R 3 | \name{drop_first_and_renormalize} 4 | \alias{drop_first_and_renormalize} 5 | \title{Drop the first element of a simplex and re-normalize the result to sum to 1.} 6 | \usage{ 7 | drop_first_and_renormalize(x) 8 | } 9 | \arguments{ 10 | \item{x}{A numeric vector, sums to 1. Corresponds to a discretized PDF or PMF 11 | (usually the GI distribution).} 12 | } 13 | \value{ 14 | A numeric vector, sums to 1. 15 | } 16 | \description{ 17 | When this vector corresponds to the generation interval distribution, we 18 | want to drop this first bin. The renewal equation assumes that same-day 19 | infection and onward transmission does not occur, and we assume 20 | everything is 1 indexed not 0 indeced. We need to 21 | manually drop the first element from the PMF vector. 22 | } 23 | -------------------------------------------------------------------------------- /man/figures/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDCgov/ww-inference-model/85a6d5c57e6f4c6450cd637750fa58e036a8c0dd/man/figures/.DS_Store -------------------------------------------------------------------------------- /man/figures/wwinference_workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CDCgov/ww-inference-model/85a6d5c57e6f4c6450cd637750fa58e036a8c0dd/man/figures/wwinference_workflow.png -------------------------------------------------------------------------------- /man/flag_ww_outliers.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/preprocessing.R 3 | \name{flag_ww_outliers} 4 | \alias{flag_ww_outliers} 5 | \title{Flag WW outliers} 6 | \usage{ 7 | flag_ww_outliers( 8 | ww_data, 9 | conc_col_name = "log_genome_copies_per_ml", 10 | rho_threshold = 2, 11 | log_conc_threshold = 3, 12 | threshold_n_dps = 1 13 | ) 14 | } 15 | \arguments{ 16 | \item{ww_data}{dataframe containing the following columns: site, lab, 17 | lab_site_index, date, a column for concentration, and below_lod} 18 | 19 | \item{conc_col_name}{string, name of the column containing the concentration 20 | measurements in the wastewater data, default is \code{genome_copies_per_ml}} 21 | 22 | \item{rho_threshold}{float indicating the z-score threshold for "jump"} 23 | 24 | \item{log_conc_threshold}{float indicating the z-score threshold for 25 | log concentration} 26 | 27 | \item{threshold_n_dps}{min number of data points above the LOD per lab-site} 28 | } 29 | \value{ 30 | ww_w_outliers_flaged dataframe containing all of the columns in 31 | ww_data input dataframe plus two additional columns: 32 | \code{flag_as_ww_outlier} and \code{exclude} 33 | \verb{flag as_ww_outlier} contains a 0 if the datapoint is not an outlier and a 1 34 | if it is an outlier. \code{exclude} tells the model whether or not to exclude that 35 | data point, which here is by default set to 0 for all data points (even 36 | those flagged as outliers). Excluding the outliers is a second optional 37 | step. 38 | } 39 | \description{ 40 | Flag WW outliers 41 | } 42 | \examples{ 43 | ww_data <- wwinference::ww_data 44 | ww_data_preprocessed <- wwinference::preprocess_ww_data(ww_data) 45 | ww_data_outliers_flagged <- flag_ww_outliers(ww_data_preprocessed) 46 | } 47 | -------------------------------------------------------------------------------- /man/format_hosp_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model_component_fwd_sim.R 3 | \name{format_hosp_data} 4 | \alias{format_hosp_data} 5 | \title{Format the hospital admissions data into a tidy dataframe} 6 | \usage{ 7 | format_hosp_data(pred_obs_hosp, dur_obs, pop_size, date_df) 8 | } 9 | \arguments{ 10 | \item{pred_obs_hosp}{vector of non-negative integers indicating the number 11 | of hospital admissions on each day} 12 | 13 | \item{dur_obs}{integer indicating the number of days we want the 14 | observations for} 15 | 16 | \item{pop_size}{integer indicating the population size of the admissions 17 | catchment area} 18 | 19 | \item{date_df}{tibble of columns \code{date} and \code{t} that map time in days to 20 | dates} 21 | } 22 | \value{ 23 | a tidy dataframe containing counts of admissions by date alongside 24 | population size 25 | } 26 | \description{ 27 | Format the hospital admissions data into a tidy dataframe 28 | } 29 | -------------------------------------------------------------------------------- /man/format_subpop_hosp_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model_component_fwd_sim.R 3 | \name{format_subpop_hosp_data} 4 | \alias{format_subpop_hosp_data} 5 | \title{Format the subpopulation-level hospital admissions data into a tidy 6 | dataframe} 7 | \usage{ 8 | format_subpop_hosp_data(pred_obs_hosp_subpop, dur_obs, subpop_map, date_df) 9 | } 10 | \arguments{ 11 | \item{pred_obs_hosp_subpop}{matrix of non-negative integers indicating the 12 | number of hospital admissions on each day in each subpopulation. Rows are 13 | subpopulations, columns are time points} 14 | 15 | \item{dur_obs}{integer indicating the number of days we want the 16 | observations for} 17 | 18 | \item{subpop_map}{tibble mapping the numbered subpopulations to the 19 | wastewater sites, must contain columns "subpop_index" and "subpop_name"} 20 | 21 | \item{date_df}{tibble of columns \code{date} and \code{t} that map time in days to 22 | dates} 23 | } 24 | \value{ 25 | a tidy dataframe containing counts of admissions by date alongside 26 | population size for each subpopulation 27 | } 28 | \description{ 29 | Format the subpopulation-level hospital admissions data into a tidy 30 | dataframe 31 | } 32 | -------------------------------------------------------------------------------- /man/format_ww_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model_component_fwd_sim.R 3 | \name{format_ww_data} 4 | \alias{format_ww_data} 5 | \title{Format the wastewater data as a tidy data frame} 6 | \usage{ 7 | format_ww_data( 8 | log_obs_conc_lab_site, 9 | ot, 10 | ht, 11 | date_df, 12 | site_lab_map, 13 | lod_lab_site 14 | ) 15 | } 16 | \arguments{ 17 | \item{log_obs_conc_lab_site}{matrix of numeric values where rows are the 18 | site-lab combinations and columns are the observed time points} 19 | 20 | \item{ot}{integer indicating the number of days we will have observed data 21 | for in the calibration period} 22 | 23 | \item{ht}{integer indicating the time after the last observed epi indicator 24 | and before the forecast date, of which there can still be wastewater 25 | observations} 26 | 27 | \item{date_df}{tibble of columns \code{date} and \code{t} that map time in days to 28 | dates} 29 | 30 | \item{site_lab_map}{tibble mapping sites, labs, lab site indices, and the 31 | population size of the site} 32 | 33 | \item{lod_lab_site}{vector of numerics indicating the LOD in each lab and 34 | site combination} 35 | } 36 | \value{ 37 | a tidy dataframe containing observed wastewater concentrations 38 | in log estimated genome copies per mL for each site and lab at each time 39 | point 40 | } 41 | \description{ 42 | Format the wastewater data as a tidy data frame 43 | } 44 | -------------------------------------------------------------------------------- /man/get_count_data_sizes.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/get_stan_data.R 3 | \name{get_count_data_sizes} 4 | \alias{get_count_data_sizes} 5 | \title{Get count data integer sizes for stan} 6 | \usage{ 7 | get_count_data_sizes( 8 | input_count_data, 9 | forecast_date, 10 | forecast_horizon, 11 | calibration_time, 12 | last_count_data_date, 13 | uot, 14 | count_col_name = "count" 15 | ) 16 | } 17 | \arguments{ 18 | \item{input_count_data}{a dataframe with the input count data} 19 | 20 | \item{forecast_date}{string indicating the forecast date} 21 | 22 | \item{forecast_horizon}{integer indicating the number of days to make a 23 | forecast for} 24 | 25 | \item{calibration_time}{integer indicating the max duration in days that 26 | the model is calibrated to hospital admissions for} 27 | 28 | \item{last_count_data_date}{string indicating the date of the last observed 29 | count data point} 30 | 31 | \item{uot}{integer indicating the time of model initialization when there are 32 | no observations} 33 | 34 | \item{count_col_name}{A string represeting the name of the column in the 35 | input_count_data that indicates the number of daily counts, 36 | default is \code{count}} 37 | } 38 | \value{ 39 | A list containing the integer sizes of the follow variables that 40 | the stan model requires: 41 | ht: integer indicating horizon time for the model(hospital admissions 42 | nowcast + forecast time in days) 43 | ot: integer indicating the total duration of time that model for producing 44 | counts (e.g. cases or admissions) has available calibration data 45 | oht: integer indicating the number of count observations 46 | n_weeks: number of weeks (rounded up) that counts are generated 47 | from the model 48 | tot_weeks: number of week(rounded up) that infections are generated for 49 | } 50 | \description{ 51 | Get count data integer sizes for stan 52 | } 53 | -------------------------------------------------------------------------------- /man/get_count_indices.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/get_stan_data.R 3 | \name{get_count_indices} 4 | \alias{get_count_indices} 5 | \title{Get count data indices} 6 | \usage{ 7 | get_count_indices(input_count_data) 8 | } 9 | \arguments{ 10 | \item{input_count_data}{a dataframe with the input count data} 11 | } 12 | \value{ 13 | A list containing the vectors of indices that 14 | the stan model requires: 15 | count_times: a vector of integer times corresponding to the times when the 16 | count observations were made 17 | } 18 | \description{ 19 | Get count data indices 20 | } 21 | -------------------------------------------------------------------------------- /man/get_count_values.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/get_stan_data.R 3 | \name{get_count_values} 4 | \alias{get_count_values} 5 | \title{Get count values} 6 | \usage{ 7 | get_count_values(input_count_data, ot, ht, count_col_name = "count") 8 | } 9 | \arguments{ 10 | \item{input_count_data}{a dataframe with the input count data} 11 | 12 | \item{ot}{integer indicating the total duration of time that the 13 | model has available calibration data in days} 14 | 15 | \item{ht}{integer indicating the number of days to produce count estimates 16 | outside the calibration period (forecast + nowcast time) in days} 17 | 18 | \item{count_col_name}{A string representing the name of the column in the 19 | input_count_data that indicates the number of daily counts of the 20 | epidemiological indicator, e.g. cases or hospital admissions, 21 | default is \code{count}} 22 | } 23 | \value{ 24 | A list containing the necessary vectors of values that 25 | the stan model requires: 26 | counts: a vector of number of daily count observations 27 | day_of_week: a vector indicating the day of the week of each of the dates 28 | in the calibration and forecast period 29 | } 30 | \description{ 31 | Get count values 32 | } 33 | -------------------------------------------------------------------------------- /man/get_date_time_spine.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/get_stan_data.R 3 | \name{get_date_time_spine} 4 | \alias{get_date_time_spine} 5 | \title{Get date time spine to map to model output} 6 | \usage{ 7 | get_date_time_spine( 8 | forecast_date, 9 | input_count_data, 10 | last_count_data_date, 11 | calibration_time, 12 | forecast_horizon 13 | ) 14 | } 15 | \arguments{ 16 | \item{forecast_date}{a character string in ISO8601 format (YYYY-MM-DD) 17 | indicating the date that the forecast is to be made.} 18 | 19 | \item{input_count_data}{a dataframe of the count data to be passed 20 | directly to stan, , must have the following columns: date, count, total_pop} 21 | 22 | \item{last_count_data_date}{string indicating the date of the last observed 23 | count data point in 1SO8601 format (YYYY-MM-DD)} 24 | 25 | \item{calibration_time}{integer indicating the number of days to calibrate 26 | the model for, default is \code{90}} 27 | 28 | \item{forecast_horizon}{integer indicating the number of days, including the 29 | forecast date, to produce forecasts for, default is \code{28}} 30 | } 31 | \value{ 32 | a tibble containing an integer for time mapped to the corresponding 33 | date, for the entire calibration and forecast period 34 | } 35 | \description{ 36 | Get date time spine to map to model output 37 | } 38 | -------------------------------------------------------------------------------- /man/get_draws.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/get_draws.R 3 | \name{get_draws} 4 | \alias{get_draws} 5 | \alias{get_draws_df} 6 | \alias{get_draws.wwinference_fit} 7 | \alias{get_draws.default} 8 | \alias{get_draws.data.frame} 9 | \alias{plot.wwinference_fit_draws} 10 | \title{Postprocess to generate a draws dataframe} 11 | \usage{ 12 | get_draws(x, ..., what = "all") 13 | 14 | get_draws_df(x, ...) 15 | 16 | \method{get_draws}{wwinference_fit}(x, ..., what = "all") 17 | 18 | \method{get_draws}{default}(x, ..., what = "all") 19 | 20 | \method{get_draws}{data.frame}( 21 | x, 22 | count_data, 23 | date_time_spine, 24 | site_subpop_spine, 25 | lab_site_subpop_spine, 26 | stan_data_list, 27 | fit_obj, 28 | ..., 29 | what = "all" 30 | ) 31 | 32 | \method{plot}{wwinference_fit_draws}(x, y = NULL, what, ...) 33 | } 34 | \arguments{ 35 | \item{x}{An object of class \code{get_draws}.} 36 | 37 | \item{...}{additional arguments} 38 | 39 | \item{what}{Character vector. Specifies the variables to extract from the 40 | draws. It could be any from \code{"all"} \code{"predicted_counts"}, \code{"predicted_ww"}, 41 | \code{"global_rt"}, or \code{"subpop_rt"}. When \code{what = "all"} (the default), 42 | the function will extract all four variables.} 43 | 44 | \item{count_data}{A dataframe of the preprocessed daily count data (e.g. 45 | hospital admissions) from the "global" population} 46 | 47 | \item{date_time_spine}{tibble mapping dates to time in days} 48 | 49 | \item{site_subpop_spine}{tibble mapping sites to subpopulations} 50 | 51 | \item{lab_site_subpop_spine}{tibble mapping lab-sites to subpopulations} 52 | 53 | \item{stan_data_list}{A list containing all the data passed to stan for 54 | fitting the model} 55 | 56 | \item{fit_obj}{a CmdStan object that is the output of fitting the model to 57 | \code{x} and \code{count_data}} 58 | 59 | \item{y}{Ignored in the the case of \code{plot}.} 60 | } 61 | \value{ 62 | A tibble containing the full set of posterior draws of the 63 | estimated, nowcasted, and forecasted: counts, site-level wastewater 64 | concentrations, "global"(e.g. state) R(t) estimate, and the "local" (site + 65 | the one auxiliary subpopulation) R(t) estimates. In the instance where there 66 | are observations, the data will be joined to each draw of the predicted 67 | observation to facilitate plotting. 68 | } 69 | \description{ 70 | This function takes in the two input data sources, the CmdStan fit object, 71 | and the 3 relevant mappings from stan indices to the real data, in order 72 | to generate a dataframe containing the posterior draws of the counts (e.g. 73 | hospital admissions), the wastewater concentration values, the "global" R(t), 74 | and the "local" R(t) estimates + the critical metadata in the data. 75 | This funtion has a default method that takes the two sets of input data, 76 | the last of stan arguments, and the CmdStan fitting object, as well as an S3 77 | method for objects of class 'wwinference_fit' 78 | 79 | This method overloads the generic \code{get_draws} function specifically 80 | for objects of type 'wwinference_fit'. 81 | } 82 | \details{ 83 | The function \code{get_draws_df()} has been deprecated in favor of \code{get_draws()}. 84 | 85 | The plot method for \code{wwinference_fit_draws} is a wrapper of 86 | \code{get_plot_forecasted_counts}, \code{get_plot_ww_conc}, \code{get_plot_global_rt}, 87 | and \code{get_plot_subpop_rt}. Depending on the value of \code{what}, the function 88 | will call the appropriate method. 89 | } 90 | -------------------------------------------------------------------------------- /man/get_global_rt.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model_component_fwd_sim.R 3 | \name{get_global_rt} 4 | \alias{get_global_rt} 5 | \title{Function to generate a global weekly R(t) estimate with added noise} 6 | \usage{ 7 | get_global_rt(r_in_weeks, n_weeks, global_rt_sd, zero_padding = 1e-08) 8 | } 9 | \arguments{ 10 | \item{r_in_weeks}{The mean R(t) for each week of the simulation in natural 11 | scale, can be longer than the n_weeks} 12 | 13 | \item{n_weeks}{The number of weeks that we want to simulate the data for} 14 | 15 | \item{global_rt_sd}{The variation in the R(t) estimate to add 16 | intrinsic variability to the infection dynamics} 17 | 18 | \item{zero_padding}{Numeric value to replace any negative R(t) values with.} 19 | } 20 | \value{ 21 | a weekly R(t) estimate with added noise 22 | } 23 | \description{ 24 | Function to generate a global weekly R(t) estimate with added noise 25 | } 26 | -------------------------------------------------------------------------------- /man/get_ind_m.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{get_ind_m} 4 | \alias{get_ind_m} 5 | \title{Get index matrix} 6 | \usage{ 7 | get_ind_m(n_days, n_weeks) 8 | } 9 | \arguments{ 10 | \item{n_days}{number of days we will expand to} 11 | 12 | \item{n_weeks}{number of weeks those days correspond to} 13 | } 14 | \value{ 15 | a n_day x n_week matrix for multiplying by weekly estimated 16 | value to broadcast it to daily 17 | } 18 | \description{ 19 | Get a matrix to broadcast a vector from weekly to daily 20 | } 21 | \examples{ 22 | ind_m <- get_ind_m(14, 2) 23 | } 24 | -------------------------------------------------------------------------------- /man/get_inits_for_one_chain.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/initialization.R 3 | \name{get_inits_for_one_chain} 4 | \alias{get_inits_for_one_chain} 5 | \title{Given a set of prior parameters and stan data, initialize the model 6 | near the center of the prior distribution} 7 | \usage{ 8 | get_inits_for_one_chain(stan_data, stdev = 0.01) 9 | } 10 | \arguments{ 11 | \item{stan_data}{a list of data elements that will be passed to stan} 12 | 13 | \item{stdev}{a numeric value indicating the standard deviation to sample 14 | from when initializing, particularly from a standard normal. Also acts as 15 | a multiplier on the prior standard deviation, to restrict the initial value 16 | to be sampled from the center of the prior. Default is 0.01} 17 | } 18 | \value{ 19 | a list of initial values for each of the parameters in the 20 | \code{wwinference} model 21 | } 22 | \description{ 23 | Given a set of prior parameters and stan data, initialize the model 24 | near the center of the prior distribution 25 | } 26 | -------------------------------------------------------------------------------- /man/get_input_count_data_for_stan.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/get_stan_data.R 3 | \name{get_input_count_data_for_stan} 4 | \alias{get_input_count_data_for_stan} 5 | \title{Get the input count data to pass directly to stan} 6 | \usage{ 7 | get_input_count_data_for_stan(preprocessed_count_data, calibration_time) 8 | } 9 | \arguments{ 10 | \item{preprocessed_count_data}{a dataframe with the input count data, must 11 | have the following columns: date, count, total_pop} 12 | 13 | \item{calibration_time}{integer indicating the max duration in days that 14 | the model is calibrated to the count data for} 15 | } 16 | \value{ 17 | datatframe of count data passed to stan 18 | } 19 | \description{ 20 | Get the input count data to pass directly to stan 21 | } 22 | -------------------------------------------------------------------------------- /man/get_input_ww_data_for_stan.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/get_stan_data.R 3 | \name{get_input_ww_data_for_stan} 4 | \alias{get_input_ww_data_for_stan} 5 | \title{Get the input ww data passed directly to stan} 6 | \usage{ 7 | get_input_ww_data_for_stan( 8 | preprocessed_ww_data, 9 | first_count_data_date, 10 | last_count_data_date, 11 | calibration_time 12 | ) 13 | } 14 | \arguments{ 15 | \item{preprocessed_ww_data}{a dataframe with the input wastewater data with 16 | no gaps, must have the following columns: date, site, lab, 17 | genome_copies_per_ml, site_pop, below_lod, and if removing outliers, 18 | flag_as_ww_outlier} 19 | 20 | \item{first_count_data_date}{The earliest day with an observation in the ' 21 | count dataset, in ISO8601 format (YYYY-MM-DD)} 22 | 23 | \item{last_count_data_date}{the last date that a count observation is 24 | presen, in ISO8601 format (YYYY-MM-DD)} 25 | 26 | \item{calibration_time}{integer indicating the max duration in days that 27 | the model is calibrated to the count data for} 28 | } 29 | \value{ 30 | dataframe of the ww data passed to stan 31 | } 32 | \description{ 33 | Get the input ww data passed directly to stan 34 | } 35 | -------------------------------------------------------------------------------- /man/get_lab_site_site_spine.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/get_stan_data.R 3 | \name{get_lab_site_site_spine} 4 | \alias{get_lab_site_site_spine} 5 | \title{Get mapping from lab-site to site} 6 | \usage{ 7 | get_lab_site_site_spine(input_ww_data) 8 | } 9 | \arguments{ 10 | \item{input_ww_data}{a dataframe of the wastewater data to be passed 11 | directly to stan, must have the following columns: date, site, lab, 12 | genome_copies_per_ml, site_pop, below_lod, and exclude} 13 | } 14 | \value{ 15 | a dataframe mapping the unique combinations of sites and labs 16 | to their indices in the model and the population of the site in that 17 | observation unit (lab_site) 18 | } 19 | \description{ 20 | Get mapping from lab-site to site 21 | } 22 | -------------------------------------------------------------------------------- /man/get_lab_site_subpop_spine.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/get_stan_data.R 3 | \name{get_lab_site_subpop_spine} 4 | \alias{get_lab_site_subpop_spine} 5 | \title{Get lab-site subpopulation spine} 6 | \usage{ 7 | get_lab_site_subpop_spine(lab_site_site_spine, site_subpop_spine) 8 | } 9 | \arguments{ 10 | \item{lab_site_site_spine}{tibble mapping lab-sites to sites} 11 | 12 | \item{site_subpop_spine}{tibble mapping sites to subpopulations} 13 | } 14 | \value{ 15 | a tibble mapping lab-sites to subpopulations 16 | } 17 | \description{ 18 | Get lab-site subpopulation spine 19 | } 20 | -------------------------------------------------------------------------------- /man/get_mcmc_options.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wwinference.R 3 | \name{get_mcmc_options} 4 | \alias{get_mcmc_options} 5 | \title{Get MCMC options} 6 | \usage{ 7 | get_mcmc_options( 8 | iter_warmup = 750, 9 | iter_sampling = 500, 10 | seed = NULL, 11 | chains = 4, 12 | adapt_delta = 0.95, 13 | max_treedepth = 12 14 | ) 15 | } 16 | \arguments{ 17 | \item{iter_warmup}{integer indicating the number of warm-up iterations, 18 | default is \code{750}.} 19 | 20 | \item{iter_sampling}{integer indicating the number of sampling iterations, 21 | default is \code{500}.} 22 | 23 | \item{seed}{integer, A seed for the (P)RNG to pass to CmdStan. In the case 24 | of multi-chain sampling the single seed will automatically be augmented by 25 | the the run (chain) ID so that each chain uses a different seed. 26 | Default is \code{NULL}.} 27 | 28 | \item{chains}{integer indicating the number of MCMC chains to run, default 29 | is \code{4}.} 30 | 31 | \item{adapt_delta}{float between 0 and 1 indicating the average acceptance 32 | probability, default is \code{0.95}.} 33 | 34 | \item{max_treedepth}{integer indicating the maximum tree depth of the 35 | sampler, default is 12.} 36 | } 37 | \value{ 38 | A list of MCMC settings with the values given by the function. 39 | arguments 40 | } 41 | \description{ 42 | This function returns a list of MCMC settings to pass to the 43 | \code{\link[cmdstanr:model-method-sample]{$sample()}} function to fit the model. 44 | The default settings are specified for production-level runs. 45 | All input arguments to \code{\link[cmdstanr:model-method-sample]{$sample()}} 46 | are configurable by the user. See 47 | \code{\link[cmdstanr:model-method-sample]{$sample()}} documentation 48 | for details of the available arguments. 49 | } 50 | -------------------------------------------------------------------------------- /man/get_model_diagnostic_flags.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model_diagnostics.R 3 | \name{get_model_diagnostic_flags} 4 | \alias{get_model_diagnostic_flags} 5 | \alias{get_model_diagnostic_flags.wwinference_fit} 6 | \alias{get_model_diagnostic_flags.default} 7 | \title{Get a table of diagnostic flags} 8 | \usage{ 9 | get_model_diagnostic_flags(x, ...) 10 | 11 | \method{get_model_diagnostic_flags}{wwinference_fit}(x, ...) 12 | 13 | \method{get_model_diagnostic_flags}{default}( 14 | x, 15 | ebmfi_tolerance = 0.2, 16 | divergences_tolerance = 0.01, 17 | frac_high_rhat_tolerance = 0.05, 18 | rhat_tolerance = 1.05, 19 | max_tree_depth_tol = 0.01, 20 | ... 21 | ) 22 | } 23 | \arguments{ 24 | \item{x}{Either an object of the 'wwinference_fit' class or 25 | the R6 Cmdstan Object fit object} 26 | 27 | \item{...}{additional arguments} 28 | 29 | \item{ebmfi_tolerance}{float indicating the tolerance for EBMFI 30 | (estimated bayesian fraction of missing information), default is \code{0.2}} 31 | 32 | \item{divergences_tolerance}{float indicating the tolerance for the 33 | proportion of sampling iterations that are divergent, default is \code{0.01}} 34 | 35 | \item{frac_high_rhat_tolerance}{float indicating the tolerance for the 36 | proportion of parameters rhats>rhat_tolderance, default is \code{0.05}} 37 | 38 | \item{rhat_tolerance}{float indicating the tolerance for the rhat for 39 | individual parameters, default is \code{1.05}} 40 | 41 | \item{max_tree_depth_tol}{float indicating the tolerance for the proportion 42 | of iterations that exceed the maximum tree depth, default is \code{0.01},} 43 | } 44 | \value{ 45 | flag_df: dataframe containing columns for each of the flags, 46 | if any flags are TRUE that indicates some model issue 47 | } 48 | \description{ 49 | This function takes in the output from a cmdstanr$sample() function (the 50 | fit object) and a series of diagnostic tolerances and returns 51 | a dataframe containing flags for whether any of the diagnostic thresholds 52 | were exceeded, which would indicate that the model did not properly 53 | converge. This funtion has a default method that takes 54 | the CmdStan fitting object, as well as an S3 method for objects of class 55 | 'wwinference_fit' 56 | 57 | This method overloads the generic get_model_diagnostic_flags function 58 | specifically for objects of type 'wwinference_fit'. 59 | } 60 | \seealso{ 61 | Other diagnostics: 62 | \code{\link{parameter_diagnostics}()}, 63 | \code{\link{summary_diagnostics}()}, 64 | \code{\link{wwinference}()} 65 | } 66 | \concept{diagnostics} 67 | -------------------------------------------------------------------------------- /man/get_model_spec.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wwinference.R 3 | \name{get_model_spec} 4 | \alias{get_model_spec} 5 | \title{Get model specifications} 6 | \usage{ 7 | get_model_spec( 8 | generation_interval = wwinference::default_covid_gi, 9 | inf_to_count_delay = wwinference::default_covid_inf_to_hosp, 10 | infection_feedback_pmf = wwinference::default_covid_gi, 11 | include_ww = TRUE, 12 | compute_likelihood = TRUE, 13 | params = get_params(system.file("extdata", "example_params.toml", package = 14 | "wwinference")) 15 | ) 16 | } 17 | \arguments{ 18 | \item{generation_interval}{vector of a simplex (must sum to 1) describing 19 | the daily probability of onwards transmission, default is package data 20 | provided for the COVID-19 generation interval post-Omicron} 21 | 22 | \item{inf_to_count_delay}{vector of a simplex (must sum to 1) describing the 23 | daily probability of transitioning from infection to whatever the count 24 | variable is, e.g. hospital admissions or cases. Default corresonds to the 25 | delay distribution from COVID-19 infection to hospital admission} 26 | 27 | \item{infection_feedback_pmf}{vector of a simplex (must sum to 1) describing 28 | the delay from incident infection to feedback in the transmission dynamics. 29 | The default is the COVID-19 generation interval} 30 | 31 | \item{include_ww}{Boolean indicating whether or not to include the wastewater 32 | data into the model, default is \code{TRUE} which will get passed to stan and 33 | tell the model to evaluate the likelihood with the wastewater data} 34 | 35 | \item{compute_likelihood}{Boolean indicating whether or not to compute the 36 | likelihood using the data, default is \code{TRUE} which will fit the model to the 37 | data. If set to \code{FALSE}, the model will sample from the priors.} 38 | 39 | \item{params}{a list of parameters corresponding to model 40 | priors and disease/data specific parameters. Default is for COVID-19 hospital 41 | admissions and viral concentrations in wastewater} 42 | } 43 | \value{ 44 | a list of model specs to be passed to the \code{get_stan_data()} function 45 | } 46 | \description{ 47 | This function returns a nested list containing the model specifications 48 | in the function arguments. All defaults are set for the case of fitting a 49 | post-omicron COVID-19 model with joint inference of hospital admissions 50 | and data on wastewater viral concentrations 51 | } 52 | \examples{ 53 | model_spec_list <- get_model_spec() 54 | } 55 | -------------------------------------------------------------------------------- /man/get_params.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/get_params.R 3 | \name{get_params} 4 | \alias{get_params} 5 | \title{Get parameters for model run} 6 | \usage{ 7 | get_params(param_file) 8 | } 9 | \arguments{ 10 | \item{param_file}{Path to a \code{.toml} file defining 11 | parameter values.} 12 | } 13 | \value{ 14 | a flat list mapping parameter names to corresponding 15 | values. 16 | } 17 | \description{ 18 | Get parameters for model run 19 | } 20 | \examples{ 21 | params <- get_params(param_file = fs::path_package("extdata", 22 | "example_params.toml", 23 | package = "wwinference" 24 | )) 25 | } 26 | -------------------------------------------------------------------------------- /man/get_plot_forecasted_counts.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/figures.R 3 | \name{get_plot_forecasted_counts} 4 | \alias{get_plot_forecasted_counts} 5 | \title{Get plot of fit and forecasted counts} 6 | \usage{ 7 | get_plot_forecasted_counts( 8 | draws, 9 | forecast_date, 10 | count_data_eval = NULL, 11 | count_data_eval_col_name = NULL, 12 | count_type = "hospital admissions", 13 | n_draws_to_plot = 100 14 | ) 15 | } 16 | \arguments{ 17 | \item{draws}{A dataframe containing the posterior draws with the data joined 18 | to it. This is the \code{draws_df} output of a call to \code{\link[=wwinference]{wwinference()}}. It 19 | expects the following column names: \code{date}, \code{pred_value}, \code{draw}, 20 | and \code{name}} 21 | 22 | \item{forecast_date}{A string indicating the date we made the forecast, for 23 | plotting, in ISO8601 format YYYY-MM-DD} 24 | 25 | \item{count_data_eval}{A dataframe containing the count data we will 26 | evaluate the forecasts against. Must contain the columns \code{date} and 27 | a column indicating the count data to evaluate against, with the name 28 | of that column specified as the \code{count_data_eval_col_name}. Default is 29 | NULL, which will result in no evaluation data being plotted.} 30 | 31 | \item{count_data_eval_col_name}{string indicating the name of the count 32 | data to evaluate against the forecasted count data. Default is NULL, 33 | corresponding to no evaluation data being plotted.} 34 | 35 | \item{count_type}{A string indicating what data the counts refer to, 36 | default is \verb{hospital admissions}} 37 | 38 | \item{n_draws_to_plot}{An integer indicating how many draws from the 39 | posterior to include in the plot, default is \code{100}} 40 | } 41 | \value{ 42 | A ggplot object containing the posterior draw of the estimated, 43 | nowcasted, and forecasted counts alongside the data used to 44 | calibrate the model and subsequently observed counts (if any) against which 45 | to evaluate the forecast performance. 46 | } 47 | \description{ 48 | Get plot of fit and forecasted counts 49 | } 50 | -------------------------------------------------------------------------------- /man/get_plot_global_rt.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/figures.R 3 | \name{get_plot_global_rt} 4 | \alias{get_plot_global_rt} 5 | \title{Get plot of fit, nowcasted, and forecasted "global" R(t)} 6 | \usage{ 7 | get_plot_global_rt(draws, forecast_date, n_draws_to_plot = 100) 8 | } 9 | \arguments{ 10 | \item{draws}{A dataframe containing the posterior draws with the data joined 11 | to it. This is the \code{draws_df} output of a call to \code{\link[=wwinference]{wwinference()}}. It 12 | expects the following column names: \code{date}, \code{pred_value}, \code{draw}, 13 | and \code{name}.} 14 | 15 | \item{forecast_date}{A string indicating the date we made the forecast, for 16 | plotting, in ISO8601 format YYYY-MM-DD} 17 | 18 | \item{n_draws_to_plot}{An integer indicating how many draws from the 19 | posterior to include in the plot, default is \code{100}} 20 | } 21 | \value{ 22 | A ggplot object containing the posterior draws of the global R(t) 23 | estimate 24 | } 25 | \description{ 26 | Get plot of fit, nowcasted, and forecasted "global" R(t) 27 | } 28 | -------------------------------------------------------------------------------- /man/get_plot_subpop_rt.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/figures.R 3 | \name{get_plot_subpop_rt} 4 | \alias{get_plot_subpop_rt} 5 | \title{Get plot of fit, nowcasted, and forecasted R(t) in each subpopulation} 6 | \usage{ 7 | get_plot_subpop_rt(draws, forecast_date, n_draws_to_plot = 100) 8 | } 9 | \arguments{ 10 | \item{draws}{A dataframe containing the posterior draws with the data joined 11 | to it. This is \code{draws_df} output of the call to \code{\link[=wwinference]{wwinference()}}. It 12 | expects the following column names: \code{date}, \code{pred_value}, \code{draw}, 13 | and \code{name}.} 14 | 15 | \item{forecast_date}{A string indicating the date we made the forecast, for 16 | plotting, in ISO8601 format YYYY-MM-DD} 17 | 18 | \item{n_draws_to_plot}{An integer indicating how many draws from the 19 | posterior to include in the plot, default is \code{100}} 20 | } 21 | \value{ 22 | A ggplot object containing faceted plots of the R(t) estimate in each 23 | subpopulation (so wastewater sites + those not on wastewater) 24 | } 25 | \description{ 26 | Get plot of fit, nowcasted, and forecasted R(t) in each subpopulation 27 | } 28 | -------------------------------------------------------------------------------- /man/get_plot_ww_conc.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/figures.R 3 | \name{get_plot_ww_conc} 4 | \alias{get_plot_ww_conc} 5 | \title{Get plot of fit and forecasted wastewater concentrations} 6 | \usage{ 7 | get_plot_ww_conc(draws, forecast_date, n_draws_to_plot = 100) 8 | } 9 | \arguments{ 10 | \item{draws}{A dataframe containing the posterior draws with the data joined 11 | to it. This is the \code{draws_df} output of a call to \code{\link[=wwinference]{wwinference()}}. It 12 | expects the following column names: \code{date}, \code{pred_value}, \code{draw}, 13 | and \code{name}.} 14 | 15 | \item{forecast_date}{A string indicating the date we made the forecast, for 16 | plotting, in ISO8601 format YYYY-MM-DD} 17 | 18 | \item{n_draws_to_plot}{An integer indicating how many draws from the 19 | posterior to include in the plot, default is \code{100}} 20 | } 21 | \value{ 22 | a ggplot object containing faceted plots of the wastewaster 23 | concentrations in each site and lab combination 24 | } 25 | \description{ 26 | Get plot of fit and forecasted wastewater concentrations 27 | } 28 | -------------------------------------------------------------------------------- /man/get_pred_obs_conc.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model_component_fwd_sim.R 3 | \name{get_pred_obs_conc} 4 | \alias{get_pred_obs_conc} 5 | \title{Get the predicted concentrations in each lab site} 6 | \usage{ 7 | get_pred_obs_conc( 8 | n_lab_sites, 9 | ot, 10 | ht, 11 | log_g_over_n_site, 12 | log_m_lab_sites, 13 | sigma_ww_lab_site, 14 | site, 15 | ml_of_ww_per_person_day 16 | ) 17 | } 18 | \arguments{ 19 | \item{n_lab_sites}{Integer indicating the number of unique combinations of 20 | labs and sites in the dataset.} 21 | 22 | \item{ot}{integer indicating the number of days we will have observed data 23 | for in the calibration period} 24 | 25 | \item{ht}{integer indicating the time after the last observed time to} 26 | 27 | \item{log_g_over_n_site}{matrix of n_site rows and ot + ht columns indicating 28 | the genomes per person each day in each site} 29 | 30 | \item{log_m_lab_sites}{vector of the lab-site mutlipliers} 31 | 32 | \item{sigma_ww_lab_site}{vector of the lab_site observation errors} 33 | 34 | \item{site}{vector of integers indicating which site (WWTP) each separate 35 | lab-site observation comes from} 36 | 37 | \item{ml_of_ww_per_person_day}{Scalar indicating the number of mL of 38 | wastewater produced per person per day} 39 | } 40 | \value{ 41 | A matrix of \code{n_lab_sites} rows and \code{ot} + \code{ht} columns indcating the 42 | predicted concentration of wastewater in each lab-site and day 43 | } 44 | \description{ 45 | Get the predicted concentrations in each lab site 46 | } 47 | -------------------------------------------------------------------------------- /man/get_pred_subpop_gen_per_n.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model_component_fwd_sim.R 3 | \name{get_pred_subpop_gen_per_n} 4 | \alias{get_pred_subpop_gen_per_n} 5 | \title{Get the predicted genomes per person in each subpopulation} 6 | \usage{ 7 | get_pred_subpop_gen_per_n( 8 | convolve_fxn, 9 | n_sites, 10 | uot, 11 | ot, 12 | ht, 13 | new_i_over_n_site, 14 | log10_g_prior_mean, 15 | vl_trajectory 16 | ) 17 | } 18 | \arguments{ 19 | \item{convolve_fxn}{function used to convolve infections with delay pmf. 20 | This will typically take \code{convolve_dot_product()} function from the 21 | \code{wwinference.stan} model} 22 | 23 | \item{n_sites}{integer indicating the number of sites} 24 | 25 | \item{uot}{integer indicating the days for exponential growth initialization 26 | to occur (referred to as unobserved time)} 27 | 28 | \item{ot}{integer indicating the number of days we will have observed data 29 | for in the calibration period} 30 | 31 | \item{ht}{integer indicating the time after the last observed time to} 32 | 33 | \item{new_i_over_n_site}{matrix of n_subpops rows x n total time points 34 | columns indicating the per capita infections in each subpopulation} 35 | 36 | \item{log10_g_prior_mean}{log10 scale prior on the number of genomes shed 37 | per infection} 38 | 39 | \item{vl_trajectory}{vector of simplex indicating the proportion of all 40 | shedding occuring on each day after infection} 41 | } 42 | \value{ 43 | A matrix of \code{n_sites} rows and \code{ot}+ \code{ht} columns indicating 44 | the predicted number of genomes per person per day in each site each day 45 | } 46 | \description{ 47 | Get the predicted genomes per person in each subpopulation 48 | } 49 | -------------------------------------------------------------------------------- /man/get_site_subpop_spine.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/get_stan_data.R 3 | \name{get_site_subpop_spine} 4 | \alias{get_site_subpop_spine} 5 | \title{Get site to subpopulation map} 6 | \usage{ 7 | get_site_subpop_spine(input_ww_data, input_count_data) 8 | } 9 | \arguments{ 10 | \item{input_ww_data}{a dataframe of the wastewater data to be passed 11 | directly to stan, must have the following columns: date, site, lab, 12 | genome_copies_per_ml, site_pop, below_lod, and exclude} 13 | 14 | \item{input_count_data}{a dataframe of the count data to be passed 15 | directly to stan, , must have the following columns: date, count, total_pop} 16 | } 17 | \value{ 18 | a dataframe mapping the sites to the corresponding subpopulation and 19 | subpopulation index, plus the population in each subpopulation. Imposes 20 | the logic to add a subpopulation if the total population is greater than 21 | the sum of the site populations in the input wastewater data 22 | } 23 | \description{ 24 | Get site to subpopulation map 25 | } 26 | -------------------------------------------------------------------------------- /man/get_time_varying_daily_ihr.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model_component_fwd_sim.R 3 | \name{get_time_varying_daily_ihr} 4 | \alias{get_time_varying_daily_ihr} 5 | \title{Get time varying IHR} 6 | \usage{ 7 | get_time_varying_daily_ihr(p_hosp_mean, uot, ot, ht, tot_weeks, p_hosp_w_sd_sd) 8 | } 9 | \arguments{ 10 | \item{p_hosp_mean}{mean probability of hospital admission given infection} 11 | 12 | \item{uot}{integer indicating the days for exponential growth initialization 13 | to occur (referred to as unobserved time)} 14 | 15 | \item{ot}{integer indicating the number of days we will have observed data 16 | for in the calibration period} 17 | 18 | \item{ht}{integer indicating the time after the last observed time to 19 | forecast} 20 | 21 | \item{tot_weeks}{integer indicating the total number of weeks including the 22 | \code{uot}} 23 | 24 | \item{p_hosp_w_sd_sd}{the standard deviation in logit scale of the 25 | IHR} 26 | } 27 | \value{ 28 | a vector of daily IHR values 29 | } 30 | \description{ 31 | Get time varying IHR 32 | } 33 | -------------------------------------------------------------------------------- /man/get_ww_data_sizes.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/get_stan_data.R 3 | \name{get_ww_data_sizes} 4 | \alias{get_ww_data_sizes} 5 | \title{Get the integer sizes of the wastewater input data} 6 | \usage{ 7 | get_ww_data_sizes(ww_data, lod_col_name = "below_lod") 8 | } 9 | \arguments{ 10 | \item{ww_data}{Input wastewater dataframe containing one row 11 | per observation, with outliers already removed} 12 | 13 | \item{lod_col_name}{A string representing the name of the 14 | column in the input_ww_data that provides a 0 if the data point is not above 15 | the LOD and a 1 if the data is below the LOD, default value is \code{below_LOD}} 16 | } 17 | \value{ 18 | A list containing the integer sizes of the follow variables that 19 | the stan model requires: 20 | owt: number of wastewater observations 21 | n_censored: number of censored wastewater observations (below the LOD) 22 | n_uncensored: number of uncensored wastewter observations (above the LOD) 23 | n_ww_sites: number of wastewater sites 24 | n_ww_lab_sites: number of unique wastewater site-lab combinations 25 | } 26 | \description{ 27 | Get the integer sizes of the wastewater input data 28 | } 29 | -------------------------------------------------------------------------------- /man/get_ww_indices_and_values.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/get_stan_data.R 3 | \name{get_ww_indices_and_values} 4 | \alias{get_ww_indices_and_values} 5 | \title{Get wastewater indices and values for stan} 6 | \usage{ 7 | get_ww_indices_and_values( 8 | input_ww_data, 9 | date_time_spine, 10 | lab_site_site_spine, 11 | site_subpop_spine, 12 | lab_site_subpop_spine 13 | ) 14 | } 15 | \arguments{ 16 | \item{input_ww_data}{tibble with the input wastewater data and indices 17 | needed for stan} 18 | 19 | \item{date_time_spine}{tibble mapping dates to time in days} 20 | 21 | \item{lab_site_site_spine}{tibble mapping lab-sites to sites} 22 | 23 | \item{site_subpop_spine}{tibble mapping sites to subpopulations} 24 | 25 | \item{lab_site_subpop_spine}{tibble mapping lab-sites to subpopulations} 26 | } 27 | \value{ 28 | a list of the vectors needed for stan 29 | } 30 | \description{ 31 | Get wastewater indices and values for stan 32 | } 33 | -------------------------------------------------------------------------------- /man/hosp_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{hosp_data} 5 | \alias{hosp_data} 6 | \title{Example hospital admissions dataset} 7 | \format{ 8 | An object of class \code{tbl_df} (inherits from \code{tbl}, \code{data.frame}) with 90 rows and 4 columns. 9 | } 10 | \source{ 11 | vignette_data.R 12 | } 13 | \usage{ 14 | hosp_data 15 | } 16 | \description{ 17 | A dataset containing the simulated daily hospital admissions 18 | (labeled here as \code{daily_hosp_admits}) by date of admission (\code{date}). 19 | Additional columns that are required are the population size of the 20 | population contributing to the hospital admissions. It is assumed that 21 | the wastewater sites are subsets of this larger population, which 22 | is in the package data assumed to be from a hypothetical US state. 23 | The data generated are daily hospital admissions but they could be any other 24 | epidemiological count dataset e.g. cases. This data should only contain 25 | hospital admissions that would have been available as of the date that 26 | the forecast was made. We recommend that users try to format their data 27 | to match this format. 28 | } 29 | \details{ 30 | This data is generated via the default values in the 31 | \code{generate_simulated_data()} function. They represent the bare minimum 32 | required fields needed to pass to the model, and we recommend that users 33 | try to format their own data to match this format. 34 | 35 | The variables are as follows: 36 | \describe{ 37 | \item{date}{Date the hospital admissions occurred, formatte din ISO8601 38 | standatds as YYYY-MM-DD} 39 | \item{daily_hosp_admits}{The number of individuals admitted to the 40 | hospital on that date, available as of the forecast date} 41 | \item{state_pop}{The number of people contributing to the daily hospital 42 | admissions} 43 | \item{location}{ A string indicating the location that all of the 44 | data is coming from. This is not a necessary column, but instead is 45 | included to more realistically mirror a typical workflow} 46 | } 47 | } 48 | \keyword{datasets} 49 | -------------------------------------------------------------------------------- /man/hosp_data_eval.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{hosp_data_eval} 5 | \alias{hosp_data_eval} 6 | \title{Example hospital admissions dataset for evaluation} 7 | \format{ 8 | An object of class \code{tbl_df} (inherits from \code{tbl}, \code{data.frame}) with 127 rows and 3 columns. 9 | } 10 | \source{ 11 | vignette_data.R 12 | } 13 | \usage{ 14 | hosp_data_eval 15 | } 16 | \description{ 17 | A dataset containing the simulated daily hospital admissions that the model 18 | will be evaluated against (labeled here as \code{daily_hosp_admits_for_eval}) 19 | by date of admission (\code{date}). This data is not needed to fit the model, 20 | but is used in the Getting Started vignette to demonstrate the forecasted 21 | hospital admissions compared to those later observed. 22 | } 23 | \details{ 24 | This data is generated via the default values in the 25 | \code{generate_simulated_data()} function. 26 | 27 | The variables are as follows: 28 | \describe{ 29 | \item{date}{Date the hospital admissions occurred, formatte din ISO8601 30 | standatds as YYYY-MM-DD} 31 | \item{daily_hosp_admits_for_eval}{The number of individuals admitted to the 32 | hospital on that date, available beyond the forecast date for evaluating 33 | the forecasted hospital admissions} 34 | \item{state_pop}{The number of people contributing to the daily hospital 35 | admissions} 36 | } 37 | } 38 | \keyword{datasets} 39 | -------------------------------------------------------------------------------- /man/indicate_ww_exclusions.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/preprocessing.R 3 | \name{indicate_ww_exclusions} 4 | \alias{indicate_ww_exclusions} 5 | \title{Indicate data that we want to exclude from model fitting} 6 | \usage{ 7 | indicate_ww_exclusions( 8 | data, 9 | outlier_col_name = "flag_as_ww_outlier", 10 | remove_outliers = TRUE 11 | ) 12 | } 13 | \arguments{ 14 | \item{data}{A dataframe containing a column indicating outliers, called 15 | \code{outlier_col_name}.} 16 | 17 | \item{outlier_col_name}{A character string indicating the name of the column 18 | containing the outlier indicator, must contain only 0 or 1} 19 | 20 | \item{remove_outliers}{A boolean indicating whether or not to exclude the 21 | outliers from the fitting. If TRUE, copy outliers to exclusions, if FALSE, 22 | set exclusions to none} 23 | } 24 | \value{ 25 | a dataframe with the same columns as in \code{data} plus an additional 26 | \code{exclude} column containing 0s for the data to be passed to the model 27 | and 1s where the data should be excluded 28 | } 29 | \description{ 30 | This function takes in a dataframe which contains an outlier 31 | column name specified by the \code{outlier_col_name}. 32 | } 33 | \examples{ 34 | data <- tibble::tibble( 35 | date = lubridate::ymd(c("2023-10-01", "2023-10-02")), 36 | genome_copies_per_mL = c(300, 3e6), 37 | flag_as_ww_outlier = c(0, 1), 38 | exclude = c(0, 0) 39 | ) 40 | data_w_exclusions <- indicate_ww_exclusions(data, 41 | outlier_col_name = "flag_as_ww_outlier", 42 | remove_outliers = TRUE 43 | ) 44 | } 45 | -------------------------------------------------------------------------------- /man/make_hospital_onset_delay_pmf.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/delay_distribs.R 3 | \name{make_hospital_onset_delay_pmf} 4 | \alias{make_hospital_onset_delay_pmf} 5 | \title{Make hospital onset delay pmf} 6 | \usage{ 7 | make_hospital_onset_delay_pmf( 8 | neg_binom_mu = 6.98665, 9 | neg_binom_size = 2.490848 10 | ) 11 | } 12 | \arguments{ 13 | \item{neg_binom_mu}{float indicating the mean of the negative binomial shaped 14 | delay from symptom onset to hospital admissions, default is \code{6.98665} from 15 | fit to data in above paper} 16 | 17 | \item{neg_binom_size}{float indicating the dispersion parameter in the 18 | negative binomial delay from symptom onset to hospital admissions, default 19 | is \code{2.490848} from fit to data in above paper} 20 | } 21 | \value{ 22 | pmf of distribution from symptom onset to hospital admission 23 | } 24 | \description{ 25 | Uses the parameter estimates from cfa-parameter-estimates, 26 | which is based on Danache et al linelist data from symptom onset to hospital 27 | admission. See below: 28 | https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0261428 29 | } 30 | -------------------------------------------------------------------------------- /man/make_incubation_period_pmf.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/delay_distribs.R 3 | \name{make_incubation_period_pmf} 4 | \alias{make_incubation_period_pmf} 5 | \title{Make incubation period pmf} 6 | \usage{ 7 | make_incubation_period_pmf( 8 | backward_scale = 3.6, 9 | backward_shape = 1.5, 10 | r = 0.15 11 | ) 12 | } 13 | \arguments{ 14 | \item{backward_scale}{numeric indicating the scale parameter for the Weibull 15 | used in producing the incubation period distribution. default is \code{3.60} for 16 | COVID} 17 | 18 | \item{backward_shape}{numeric indicating the shape parameter for the Weibull 19 | used in producing the incubation period distribution, default is \code{1.50} for 20 | COVID} 21 | 22 | \item{r}{numeric indicating the exponential rate used in producing the 23 | correction on the incubaion period distribution, default is \code{0.15} for COVID} 24 | } 25 | \value{ 26 | pmf of incubation period 27 | } 28 | \description{ 29 | When the default arguments are used, this returns a pmf 30 | corresponding to the incubation period for COVID after Omicron used in 31 | Park et al 2023. These estimates are from early Omicron. 32 | } 33 | -------------------------------------------------------------------------------- /man/make_reporting_delay_pmf.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/delay_distribs.R 3 | \name{make_reporting_delay_pmf} 4 | \alias{make_reporting_delay_pmf} 5 | \title{Make reporting delay pmf} 6 | \usage{ 7 | make_reporting_delay_pmf(incubation_period_pmf, hospital_onset_delay_pmf) 8 | } 9 | \arguments{ 10 | \item{incubation_period_pmf}{a numeric vector, sums to 1, indicating 11 | the probability of time from infection to symptom onset} 12 | 13 | \item{hospital_onset_delay_pmf}{a numeric vector, sums to 1, indicating the 14 | proabbility of time from symptom onset to hospital admissions} 15 | } 16 | \value{ 17 | convolution of incubation period and sympton onset to hospital 18 | admission pmf 19 | } 20 | \description{ 21 | Convolve the incubation period pmf with the symptom to hospital admission pmf 22 | and normalize 23 | } 24 | -------------------------------------------------------------------------------- /man/parameter_diagnostics.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model_diagnostics.R 3 | \name{parameter_diagnostics} 4 | \alias{parameter_diagnostics} 5 | \title{Method for printing the CmdStan parameter diagnostics for a 6 | wwinference_fit_object} 7 | \usage{ 8 | parameter_diagnostics(ww_fit, ...) 9 | } 10 | \arguments{ 11 | \item{ww_fit}{An object of class wwinference_fit} 12 | 13 | \item{...}{additional arguments} 14 | } 15 | \description{ 16 | Method for printing the CmdStan parameter diagnostics for a 17 | wwinference_fit_object 18 | } 19 | \seealso{ 20 | Other diagnostics: 21 | \code{\link{get_model_diagnostic_flags}()}, 22 | \code{\link{summary_diagnostics}()}, 23 | \code{\link{wwinference}()} 24 | } 25 | \concept{diagnostics} 26 | -------------------------------------------------------------------------------- /man/preprocess_count_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/preprocessing.R 3 | \name{preprocess_count_data} 4 | \alias{preprocess_count_data} 5 | \title{Pre-process hospital admissions data, converting column names to those 6 | that \code{\link[=get_stan_data]{get_stan_data()}} expects.} 7 | \usage{ 8 | preprocess_count_data( 9 | count_data, 10 | count_col_name = "daily_hosp_admits", 11 | pop_size_col_name = "state_pop" 12 | ) 13 | } 14 | \arguments{ 15 | \item{count_data}{dataframe containing the following columns: date, 16 | a count column, and a population size column} 17 | 18 | \item{count_col_name}{name of the column containing the epidemiological 19 | indicator, default is \code{daily_hosp_admits}} 20 | 21 | \item{pop_size_col_name}{name of the column containing the population size 22 | of that the counts are coming from, default is \code{state_pop}} 23 | } 24 | \value{ 25 | a dataframe containing the hospital admissions data renamed to 26 | have the following columns \code{date}, \code{count}, and \code{total_pop} 27 | } 28 | \description{ 29 | Pre-process hospital admissions data, converting column names to those 30 | that \code{\link[=get_stan_data]{get_stan_data()}} expects. 31 | } 32 | \examples{ 33 | hosp_data <- tibble::tibble( 34 | date = lubridate::ymd(c("2023-11-01", "2023-11-02")), 35 | daily_admits = c(10, 20), 36 | state_pop = c(1e6, 1e6) 37 | ) 38 | hosp_data_preprocessed <- preprocess_count_data( 39 | hosp_data, 40 | "daily_admits", 41 | "state_pop" 42 | ) 43 | } 44 | -------------------------------------------------------------------------------- /man/preprocess_ww_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/preprocessing.R 3 | \name{preprocess_ww_data} 4 | \alias{preprocess_ww_data} 5 | \title{Pre-process wastewater input data, adding needed indices and flagging 6 | potential outliers} 7 | \usage{ 8 | preprocess_ww_data( 9 | ww_data, 10 | conc_col_name = "log_genome_copies_per_ml", 11 | lod_col_name = "log_lod" 12 | ) 13 | } 14 | \arguments{ 15 | \item{ww_data}{dataframe containing the following columns: site, lab, 16 | date, site_pop, a column for concentration, and a column for the 17 | limit of detection} 18 | 19 | \item{conc_col_name}{string indicating the name of the column containing 20 | virus genome concentration measurements in log genome copies per mL, 21 | default is \code{log_genome_copies_per_ml}} 22 | 23 | \item{lod_col_name}{string indicating the name of the column containing 24 | the limits of detection for each wastewater measurement, default is 25 | \code{log_lod_sewage}. Note that any values in the \code{conc_col_name} 26 | equal to the limit of detection will be treated as below the limit of 27 | detection.} 28 | } 29 | \value{ 30 | a dataframe containing the same columns as ww_data except 31 | the \code{conc_col_name} will be replaced with \code{log_genome_copies_per_ml} and 32 | the \code{lod_col_name} will be replaced with \code{log_lod_sewage} plus the following 33 | additional columns needed for the stan model: 34 | lab_site_index, site_index, flag_as_ww_outlier, below_lod, lab_site_name, 35 | exclude 36 | } 37 | \description{ 38 | Pre-process wastewater input data, adding needed indices and flagging 39 | potential outliers 40 | } 41 | \examples{ 42 | ww_data <- tibble::tibble( 43 | date = lubridate::ymd(rep(c("2023-11-01", "2023-11-02"), 2)), 44 | site = c(rep(1, 2), rep(2, 2)), 45 | lab = c(1, 1, 1, 1), 46 | log_conc = log(c(345.2, 784.1, 401.5, 681.8)), 47 | log_lod = log(c(20, 20, 15, 15)), 48 | site_pop = c(rep(2e5, 2), rep(4e5, 2)) 49 | ) 50 | ww_data_preprocessed <- preprocess_ww_data(ww_data, 51 | conc_col_name = "log_conc", 52 | lod_col_name = "log_lod" 53 | ) 54 | } 55 | -------------------------------------------------------------------------------- /man/simulate_double_censored_pmf.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/delay_distribs.R 3 | \name{simulate_double_censored_pmf} 4 | \alias{simulate_double_censored_pmf} 5 | \title{Simulate daily double censored PMF. From epinowcast: 6 | https://package.epinowcast.org/dev/reference/simulate_double_censored_pmf.html #nolint} 7 | \usage{ 8 | simulate_double_censored_pmf( 9 | max, 10 | fun_primary = stats::runif, 11 | primary_args = list(), 12 | fun_dist = stats::rlnorm, 13 | dist_args = list(...), 14 | n = 1e+06, 15 | ... 16 | ) 17 | } 18 | \arguments{ 19 | \item{max}{Maximum value for the computed CDF. If not specified, the maximum 20 | value is the maximum simulated delay.} 21 | 22 | \item{fun_primary}{Primary distribution function (default is \code{runif}).} 23 | 24 | \item{primary_args}{List of additional arguments to be passed to the primary 25 | distribution function.} 26 | 27 | \item{fun_dist}{Distribution function to be added to the primary (default is 28 | \code{rlnorm}).} 29 | 30 | \item{dist_args}{List of additional arguments to be passed to the 31 | distribution function.} 32 | 33 | \item{n}{Number of simulations (default is 1e6).} 34 | 35 | \item{...}{Additional arguments to be passed to the distribution function. 36 | This is an alternative to \code{dist_args}.} 37 | } 38 | \value{ 39 | A numeric vector representing the PMF. 40 | } 41 | \description{ 42 | This function simulates the probability mass function of a daily 43 | double-censored process. The process involves two distributions: a primary 44 | distribution which represents the censoring process for the primary event 45 | and another distribution (which is offset by the primary). 46 | } 47 | \details{ 48 | Based off of: 49 | https://www.medrxiv.org/content/10.1101/2024.01.12.24301247v1 50 | } 51 | -------------------------------------------------------------------------------- /man/subpop_hosp_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{subpop_hosp_data} 5 | \alias{subpop_hosp_data} 6 | \title{Example subpopulation level hospital admissions dataset} 7 | \format{ 8 | An object of class \code{tbl_df} (inherits from \code{tbl}, \code{data.frame}) with 450 rows and 4 columns. 9 | } 10 | \source{ 11 | vignette_data.R 12 | } 13 | \usage{ 14 | subpop_hosp_data 15 | } 16 | \description{ 17 | A dataset containing the simulated daily hospital admissions 18 | (labeled here as \code{daily_hosp_admits}) by date of admission (\code{date}) in 19 | each subpopulation. 20 | Additional columns that are the population size of the 21 | population contributing to the hospital admissions. In this instance, 22 | the subpopulations here are each of the wastewater catchment areas plus 23 | an additional subpopulation for the portion of the population not captured 24 | by wastewater surveillance. The data generated are daily hospital 25 | admissions but they could be any other epidemiological count dataset e.g. 26 | cases. This data should only contain hospital admissions that would have 27 | been available as of the date that the forecast was made. 28 | } 29 | \details{ 30 | This data is generated via the default values in the 31 | \code{generate_simulated_data()} function. 32 | 33 | The variables are as follows: 34 | \describe{ 35 | \item{date}{Date the hospital admissions occurred, formatted in ISO8601 36 | standards as YYYY-MM-DD} 37 | \item{subpop_name}{A string indicating the subpopulation the hospital 38 | admissiosn corresponds to. This is either a wastewater site, or the 39 | remainder of the population} 40 | \item{daily_hosp_admits}{The number of individuals admitted to the 41 | hospital on that date, available as of the forecast date} 42 | \item{subpop_pop}{The number of people contributing to the daily hospital 43 | admissions in each subpopulation} 44 | } 45 | } 46 | \keyword{datasets} 47 | -------------------------------------------------------------------------------- /man/subpop_hosp_data_eval.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{subpop_hosp_data_eval} 5 | \alias{subpop_hosp_data_eval} 6 | \title{Example subpopulation level retrospective hospital admissions dataset} 7 | \format{ 8 | An object of class \code{tbl_df} (inherits from \code{tbl}, \code{data.frame}) with 635 rows and 4 columns. 9 | } 10 | \source{ 11 | vignette_data.R 12 | } 13 | \usage{ 14 | subpop_hosp_data_eval 15 | } 16 | \description{ 17 | A dataset containing the simulated daily hospital admissions 18 | (labeled here as \code{daily_hosp_admits}) by date of admission (\code{date}) in 19 | each subpopulation observed retrospectively. 20 | Additional columns that are required are the population size of the 21 | population contributing to the hospital admissions. In this instance, 22 | the subpopulations here are each of the wastewater catchment areas plus 23 | an additional subpopulation for the portion of the population not captured 24 | by wastewater surveillance. The data generated are daily hospital 25 | admissions but they could be any other epidemiological count dataset e.g. 26 | cases.This data should contain hospital admissions retrospectively beyond 27 | the forecast date in order to evaluate the forecasts. 28 | } 29 | \details{ 30 | This data is generated via the default values in the 31 | \code{generate_simulated_data()} function. They represent the bare minimumum 32 | required fields needed to pass to the model, and we recommend that users 33 | try to format their own data to match this format. 34 | 35 | The variables are as follows: 36 | \describe{ 37 | \item{date}{Date the hospital admissions occurred, formatted in ISO8601 38 | standards as YYYY-MM-DD} 39 | \item{subpop_name}{A string indicating the subpopulation the hospital 40 | admissions corresponds to. This is either a wastewater site, or the 41 | remainder of the population} 42 | \item{daily_hosp_admits_for_eval}{The number of individuals admitted to the 43 | hospital on that date, available as of the forecast date} 44 | \item{subpop_pop}{The number of people contributing to the daily hospital 45 | admissions in each subpopulation} 46 | } 47 | } 48 | \keyword{datasets} 49 | -------------------------------------------------------------------------------- /man/subpop_inf_process.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model_component_fwd_sim.R 3 | \name{subpop_inf_process} 4 | \alias{subpop_inf_process} 5 | \title{Get the subpopulation level incident infections} 6 | \usage{ 7 | subpop_inf_process( 8 | generate_inf_fxn, 9 | n_subpops, 10 | uot, 11 | ot, 12 | ht, 13 | unadj_r_site, 14 | initial_growth, 15 | initial_growth_prior_sd, 16 | i0_over_n, 17 | sd_i0_over_n, 18 | generation_interval, 19 | infection_feedback, 20 | infection_feedback_pmf, 21 | pop_fraction 22 | ) 23 | } 24 | \arguments{ 25 | \item{generate_inf_fxn}{function indicating how to generate infections, 26 | This will typically take the \code{generate_infections()} function from the 27 | \code{wwinference.stan} model.} 28 | 29 | \item{n_subpops}{integer indicating the number of subpopulations} 30 | 31 | \item{uot}{integer indicating the days for exponential growth initialization 32 | to occur (referred to as unobserved time)} 33 | 34 | \item{ot}{integer indicating the number of days we will have observed data 35 | for in the calibration period} 36 | 37 | \item{ht}{integer indicating the time after the last observed time to 38 | forecast} 39 | 40 | \item{unadj_r_site}{n_subpop x n_weeks matrix of the unadjusted site level 41 | R(t)} 42 | 43 | \item{initial_growth}{float indicating the mean of the initial growth rate 44 | in the unobserved time} 45 | 46 | \item{initial_growth_prior_sd}{float indicating the standard deviation on 47 | the initial growth rate across subpopulations} 48 | 49 | \item{i0_over_n}{float indicating the mean of the initial per capita 50 | infections} 51 | 52 | \item{sd_i0_over_n}{float indicating the standard deviation of the log of the 53 | initial infections per capita across subpopulations} 54 | 55 | \item{generation_interval}{vector of simplex describing the probability of 56 | each time from infection to onwards transmission} 57 | 58 | \item{infection_feedback}{numeric indicating the strength of the infection 59 | feedback} 60 | 61 | \item{infection_feedback_pmf}{vector of simplex describing the delay from 62 | incident infections to feedback on incident infections} 63 | 64 | \item{pop_fraction}{vector of a simplex of length n_subpops, indicating 65 | the proportion of the global population that subpopulation represents} 66 | } 67 | \value{ 68 | A list containing 3 outputs: i_n: n_subpop X total days matrix of 69 | daily incident infections per capita in each subpopulation, r_site: adjusted 70 | subpopulation level R(t) estimate, i_n_global: vector of daily incident 71 | infections per capita in the global population 72 | } 73 | \description{ 74 | Get the subpopulation level incident infections 75 | } 76 | -------------------------------------------------------------------------------- /man/subpop_rt_process.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model_component_fwd_sim.R 3 | \name{subpop_rt_process} 4 | \alias{subpop_rt_process} 5 | \title{Get subpopulation level R(t) estimates assuming time and space independence} 6 | \usage{ 7 | subpop_rt_process(n_subpops, r_weeks, subpop_level_rt_variation) 8 | } 9 | \arguments{ 10 | \item{n_subpops}{integer indicating the number of subpopulations, 11 | usually this will be n_sites + 1} 12 | 13 | \item{r_weeks}{The "global" R(t) in weeks} 14 | 15 | \item{subpop_level_rt_variation}{The standard deviation of the Gaussian 16 | to generate deviation at the site level in the R(t) estimate} 17 | } 18 | \value{ 19 | A n_sites+1 by n_weeks matrix containing the subpopulation R(t)s 20 | } 21 | \description{ 22 | Get subpopulation level R(t) estimates assuming time and space independence 23 | } 24 | -------------------------------------------------------------------------------- /man/summary_diagnostics.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model_diagnostics.R 3 | \name{summary_diagnostics} 4 | \alias{summary_diagnostics} 5 | \title{Method for printing the CmdStan summary diagnostics for 6 | wwinference_fit_object} 7 | \usage{ 8 | summary_diagnostics(ww_fit, ...) 9 | } 10 | \arguments{ 11 | \item{ww_fit}{An object of class wwinference_fit} 12 | 13 | \item{...}{additional arguments} 14 | } 15 | \description{ 16 | Method for printing the CmdStan summary diagnostics for 17 | wwinference_fit_object 18 | } 19 | \seealso{ 20 | Other diagnostics: 21 | \code{\link{get_model_diagnostic_flags}()}, 22 | \code{\link{parameter_diagnostics}()}, 23 | \code{\link{wwinference}()} 24 | } 25 | \concept{diagnostics} 26 | -------------------------------------------------------------------------------- /man/throw_type_error.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/checkers.R 3 | \name{throw_type_error} 4 | \alias{throw_type_error} 5 | \title{Throw an informative type error on a user-provided input} 6 | \usage{ 7 | throw_type_error(object, arg_name, expected_type, call = rlang::caller_env()) 8 | } 9 | \arguments{ 10 | \item{object}{Object with incorrect type} 11 | 12 | \item{arg_name}{Name of the argument corresponding to \code{object}} 13 | 14 | \item{expected_type}{The type that the user should provide instead} 15 | 16 | \item{call}{The calling environment to be reflected in the error message} 17 | } 18 | \value{ 19 | This function is called for its side effect of throwing an error. It 20 | should never return. 21 | } 22 | \description{ 23 | Follows the guidance from \code{\link[rlang:abort]{rlang::abort()}} on applying a call and a class 24 | in the error message. Used as a base in type-checkers to throw a properly 25 | formatted error. 26 | } 27 | -------------------------------------------------------------------------------- /man/to_simplex.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{to_simplex} 4 | \alias{to_simplex} 5 | \title{Normalize vector to a simplex} 6 | \usage{ 7 | to_simplex(vector) 8 | } 9 | \arguments{ 10 | \item{vector}{numeric vector} 11 | } 12 | \value{ 13 | vector whose entries sum to 1 14 | } 15 | \description{ 16 | Normalize vector to a simplex 17 | } 18 | \examples{ 19 | to_simplex(c(1, 1, 1)) 20 | } 21 | -------------------------------------------------------------------------------- /man/true_global_rt.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{true_global_rt} 5 | \alias{true_global_rt} 6 | \title{Global R(t) estimate dataset} 7 | \format{ 8 | An object of class \code{tbl_df} (inherits from \code{tbl}, \code{data.frame}) with 127 rows and 4 columns. 9 | } 10 | \source{ 11 | vignette_data.R 12 | } 13 | \usage{ 14 | true_global_rt 15 | } 16 | \description{ 17 | A dataset containing the the simulated unadjusted daily R(t) estimate 18 | as well as the realized R(t) estimate for the overall "global" population. 19 | This realized R(t) is generated by summing the incident infections from 20 | each of the subpopulations (the populations in each wastewater catchment 21 | area plus an additional one representing the remainder of the population). 22 | The R(t) is then back-calculated by dividing the total incident infection 23 | time seres by the convolution of the infection time series and the 24 | generation interval. 25 | } 26 | \details{ 27 | This data is generated via the default values in the 28 | \code{generate_simulated_data()} function. 29 | 30 | The variables are as follows: 31 | \describe{ 32 | \item{unadj_rt}{The daily global unadjusted R(t). The log of the 33 | unadjusted R(t) is the central value around which the subpopulation 34 | R(t) values are drawn from each week.} 35 | \item{realized_rt}{The daily value of the realized global R(t). This is 36 | calculated by summing up the subpopulation level incident infections and 37 | then dividing by the convolution of the total incident infections and the 38 | generation interval to get the R(t) value that corresponds to the 39 | global incident infections} 40 | \item{t}{The time index in days} 41 | \item{date}{Date the hospital admissions occurred, formatte din ISO8601 42 | standatds as YYYY-MM-DD} 43 | } 44 | } 45 | \keyword{datasets} 46 | -------------------------------------------------------------------------------- /man/truncate_for_latency.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model_component_fwd_sim.R 3 | \name{truncate_for_latency} 4 | \alias{truncate_for_latency} 5 | \title{Truncate the predicted wastewater concentrations based on the 6 | lab site reporting latency and the observed time and horizon time} 7 | \usage{ 8 | truncate_for_latency( 9 | log_conc_lab_site, 10 | n_lab_sites, 11 | ot, 12 | ht, 13 | nt, 14 | lab_site_reporting_latency 15 | ) 16 | } 17 | \arguments{ 18 | \item{log_conc_lab_site}{The matrix of n_lab_sites by n time points 19 | indicating the underlying expected observed concentrations} 20 | 21 | \item{n_lab_sites}{Integer indicating the number of unique lab-site 22 | combinations} 23 | 24 | \item{ot}{integer indicating the number of days we will have observed data 25 | for in the calibration period} 26 | 27 | \item{ht}{integer indicating the time after the last observed time to 28 | the end of the forecast time} 29 | 30 | \item{nt}{integer indicating the time after the last observed epi indicator 31 | and before the forecast date, of which there can still be wastewater 32 | observations} 33 | 34 | \item{lab_site_reporting_latency}{vector indicating the number of days 35 | from the forecast date of the last possible observation} 36 | } 37 | \value{ 38 | A sparse matrix of \code{n_lab_sites} rows and \code{ot} + \code{ht} columns of 39 | but with NAs for when observations are not measured/reported. 40 | } 41 | \description{ 42 | Truncate the predicted wastewater concentrations based on the 43 | lab site reporting latency and the observed time and horizon time 44 | } 45 | -------------------------------------------------------------------------------- /man/validate_count_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/validate.R 3 | \name{validate_count_data} 4 | \alias{validate_count_data} 5 | \title{Validate user-provided count data} 6 | \usage{ 7 | validate_count_data( 8 | count_data, 9 | count_col_name, 10 | pop_size_col_name, 11 | call = rlang::caller_env() 12 | ) 13 | } 14 | \arguments{ 15 | \item{count_data}{tibble containing the input count data} 16 | 17 | \item{count_col_name}{string indicating the name of the column containing 18 | the count data} 19 | 20 | \item{pop_size_col_name}{string indicating the name of the column containing 21 | the population size of the count catchment area} 22 | 23 | \item{call}{Calling environment to be passed to \code{\link[cli:cli_abort]{cli::cli_abort()}} for 24 | traceback.} 25 | } 26 | \value{ 27 | NULL, invisibly 28 | } 29 | \description{ 30 | Validate user-provided count data 31 | } 32 | -------------------------------------------------------------------------------- /man/validate_data_jointly.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/validate.R 3 | \name{validate_data_jointly} 4 | \alias{validate_data_jointly} 5 | \title{Validate that both count data and wastewater data are coherent and 6 | compatible with one another and the the user-specified parameters} 7 | \usage{ 8 | validate_data_jointly( 9 | input_count_data, 10 | input_ww_data, 11 | date_time_spine, 12 | lab_site_site_spine, 13 | site_subpop_spine, 14 | lab_site_subpop_spine, 15 | calibration_time, 16 | forecast_date 17 | ) 18 | } 19 | \arguments{ 20 | \item{input_count_data}{tibble containing the input count data that has 21 | been filtered and is ready to be passed into stan} 22 | 23 | \item{input_ww_data}{tibble containing the input wastewater data that has 24 | been filtered and is ready to be passed into stan} 25 | 26 | \item{date_time_spine}{tibble mapping dates to time in days} 27 | 28 | \item{lab_site_site_spine}{tibble mapping lab-sites to sites} 29 | 30 | \item{site_subpop_spine}{tibble mapping sites to subpopulations} 31 | 32 | \item{lab_site_subpop_spine}{tibble mapping lab-sites to subpopulations} 33 | 34 | \item{calibration_time}{integer indicating the calibration time} 35 | 36 | \item{forecast_date}{IS08 formatted date indicating the forecast date} 37 | } 38 | \value{ 39 | NULL, invisibly 40 | } 41 | \description{ 42 | Validate that both count data and wastewater data are coherent and 43 | compatible with one another and the the user-specified parameters 44 | } 45 | -------------------------------------------------------------------------------- /man/validate_paramlist.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/get_params.R 3 | \name{validate_paramlist} 4 | \alias{validate_paramlist} 5 | \title{Validate a parameter list} 6 | \usage{ 7 | validate_paramlist(paramlist) 8 | } 9 | \arguments{ 10 | \item{paramlist}{The parameter list to validate} 11 | } 12 | \value{ 13 | the parameter list, on success, 14 | or raise an error 15 | } 16 | \description{ 17 | Validate a parameter list 18 | } 19 | -------------------------------------------------------------------------------- /man/validate_pmf.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/validate.R 3 | \name{validate_pmf} 4 | \alias{validate_pmf} 5 | \title{Validate that the pmf vector being passed to stan 6 | is a valid probability mass function. It must sum to 1 and 7 | have all non-negative entries.} 8 | \usage{ 9 | validate_pmf( 10 | pmf, 11 | calibration_time, 12 | count_data, 13 | tolerance = 1e-06, 14 | arg = "x", 15 | call = rlang::caller_env() 16 | ) 17 | } 18 | \arguments{ 19 | \item{pmf}{simplex vector describing a probabilty of an event ocurring on 20 | each day} 21 | 22 | \item{calibration_time}{integer indicating the calibration time} 23 | 24 | \item{count_data}{tibble containing the input count data ready to be passed 25 | to stan} 26 | 27 | \item{tolerance}{numeric indicating the allowable difference between the 28 | sum of the pmf and 1, default is \code{1e-6}} 29 | 30 | \item{arg}{name of the argument supplying the object} 31 | 32 | \item{call}{The calling environment to be reflected in the error message} 33 | } 34 | \value{ 35 | NULL, invisibly 36 | } 37 | \description{ 38 | Validate that the pmf vector being passed to stan 39 | is a valid probability mass function. It must sum to 1 and 40 | have all non-negative entries. 41 | } 42 | -------------------------------------------------------------------------------- /man/validate_ww_conc_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/validate.R 3 | \name{validate_ww_conc_data} 4 | \alias{validate_ww_conc_data} 5 | \title{Validate user-provided wastewater concentration data} 6 | \usage{ 7 | validate_ww_conc_data( 8 | ww_data, 9 | conc_col_name, 10 | lod_col_name, 11 | call = rlang::caller_env() 12 | ) 13 | } 14 | \arguments{ 15 | \item{ww_data}{tibble containing the input wastewater data} 16 | 17 | \item{conc_col_name}{string indicating the name of the column containing 18 | the concentration measurements in the wastewater data} 19 | 20 | \item{lod_col_name}{string indicating the name of the column containing 21 | the limit of detection for each measurement in the wastewater data} 22 | 23 | \item{call}{Calling environment to be passed to \code{\link[cli:cli_abort]{cli::cli_abort()}} for 24 | traceback.} 25 | } 26 | \value{ 27 | NULL, invisibly 28 | } 29 | \description{ 30 | Validate user-provided wastewater concentration data 31 | } 32 | -------------------------------------------------------------------------------- /man/ww_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{ww_data} 5 | \alias{ww_data} 6 | \title{Example wastewater dataset.} 7 | \format{ 8 | \subsection{ww_data}{ 9 | 10 | A tibble with 102 rows and 6 columns 11 | \describe{ 12 | \item{date}{Sample collection date, formatted in ISO8601 standards as 13 | YYYY-MM-DD} 14 | \item{site}{The wastewater treatment plant where the sample was collected} 15 | \item{lab}{The lab where the sample was processed} 16 | \item{log_genome_copies_per_ml}{The natural log of the wastewater 17 | concentration measured on the date specified, collected in the site 18 | specified, and processed in the lab specified. The package expects 19 | this quantity in units of log estimated genome copies per mL.} 20 | \item{log_lod}{The log of the limit of detection in the site and lab on a 21 | particular day of the quantification device (e.g. PCR). This should be in 22 | units of log estimated genome copies per mL.} 23 | \item{site_pop}{The population size of the wastewater catchment area 24 | represented by the site variable} 25 | \item{location}{ A string indicating the location that all of the 26 | data is coming from. This is not a necessary column, but instead is 27 | included to more realistically mirror a typical workflow} 28 | } 29 | } 30 | } 31 | \source{ 32 | vignette_data.R 33 | } 34 | \usage{ 35 | ww_data 36 | } 37 | \description{ 38 | A dataset containing the simulated wastewater concentrations 39 | (labeled here as \code{log_genome_copies_per_ml}) by sample collection date 40 | (\code{date}), the site where the sample was collected (\code{site}) and the lab 41 | where the samples were processed (\code{lab}). Additional columns that are 42 | required attributes needed for the model are the limit of detection for 43 | that lab on each day (labeled here as \code{log_lod}) and the population size of 44 | the wastewater catchment area represented by the wastewater concentrations 45 | in each \code{site}. 46 | } 47 | \details{ 48 | This data is generated via the default values in the 49 | \code{generate_simulated_data()} function. They represent the bare minumum 50 | required fields needed to pass to the model, and we recommend that users 51 | try to format their own data to match this format. 52 | 53 | The variables are as follows: 54 | } 55 | \keyword{datasets} 56 | -------------------------------------------------------------------------------- /man/ww_data_eval.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{ww_data_eval} 5 | \alias{ww_data_eval} 6 | \title{Example evaluation wastewater dataset.} 7 | \format{ 8 | \subsection{ww_data_eval}{ 9 | 10 | A tibble with 126 rows and 6 columns 11 | \describe{ 12 | \item{date}{Sample collection date, formatted in ISO8601 standards as 13 | YYYY-MM-DD} 14 | \item{site}{The wastewater treatment plant where the sample was collected} 15 | \item{lab}{The lab where the sample was processed} 16 | \item{log_genome_copies_per_ml_eval}{The natural log of the wastewater 17 | concentration measured on the date specified, collected in the site 18 | specified, and processed in the lab specified. The package expects 19 | this quantity in units of log estimated genome copies per mL.} 20 | \item{log_lod}{The log of the limit of detection in the site and lab on a 21 | particular day of the quantification device (e.g. PCR). This should be in 22 | units of log estimated genome copies per mL.} 23 | \item{site_pop}{The population size of the wastewater catchment area 24 | represented by the site variable} 25 | \item{location}{ A string indicating the location that all of the 26 | data is coming from. This is not a necessary column, but instead is 27 | included to more realistically mirror a typical workflow} 28 | } 29 | } 30 | } 31 | \source{ 32 | vignette_data.R 33 | } 34 | \usage{ 35 | ww_data_eval 36 | } 37 | \description{ 38 | A dataset containing the simulated retrospective wastewater concentrations 39 | (labeled here as \code{log_genome_copies_per_ml_eval}) by sample collection date 40 | (\code{date}), the site where the sample was collected (\code{site}) and the lab 41 | where the samples were processed (\code{lab}). Additional columns that are 42 | required attributes needed for the model are the limit of detection for 43 | that lab on each day (labeled here as \code{log_lod}) and the population size of 44 | the wastewater catchment area represented by the wastewater concentrations 45 | in each \code{site}. 46 | } 47 | \details{ 48 | This data is generated via the default values in the 49 | \code{generate_simulated_data()} function. They represent the bare minumum 50 | required fields needed to pass to the model, and we recommend that users 51 | try to format their own data to match this format. 52 | 53 | The variables are as follows: 54 | } 55 | \keyword{datasets} 56 | -------------------------------------------------------------------------------- /man/wwinference-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wwinference-package.R 3 | \docType{package} 4 | \name{wwinference-package} 5 | \alias{wwinference-package} 6 | \title{wwinference: Jointly infers infection dynamics from wastewater data and epidemiological indicators} 7 | \description{ 8 | An implementation of a hierarchical semi-mechanistic renewal approach jointly calibrating to multiple wastewater concentrations datasets from subsets of a specified population and epidemioliogical indicators such as cases or hospital admissions from the whole population. Our framework is an extension of the widely used semi-mechanistic renewal framework EpiNow2, using a Bayesian latent variable approach implemented in the probabilistic programming language Stan. This package contains just the core components needed to fit these two data sources and produce the following outputs-- estimated and forecasted hospital admissions, estimated and forecasted wastewater concentrations, global R(t) estimates, local R(t) estimates for the subpopulations represented by each wastewater catchment area. 9 | } 10 | \seealso{ 11 | Useful links: 12 | \itemize{ 13 | \item \url{https://github.com/cdcgov/ww-inference-model/} 14 | \item \url{https://cdcgov.github.io/ww-inference-model/} 15 | \item Report bugs at \url{https://github.com/cdcgov/ww-inference-model/issues/} 16 | } 17 | 18 | } 19 | \author{ 20 | \strong{Maintainer}: Kaitlyn Johnson \email{uox1@cdc.gov} (\href{https://orcid.org/0000-0001-8011-0012}{ORCID}) 21 | 22 | Authors: 23 | \itemize{ 24 | \item Dylan Morris \email{dylan@dylanhmorris.com} (\href{https://orcid.org/0000-0002-3655-406X}{ORCID}) 25 | \item Sam Abbott \email{contact@samabbott.co.uk} (\href{https://orcid.org/0000-0001-8057-8037}{ORCID}) 26 | \item Christian Bernal Zelaya \email{xuk0@cdc.gov} 27 | \item George Vega Yon \email{g.vegayon@gmail.com} (\href{https://orcid.org/0000-0002-3171-0844}{ORCID}) 28 | \item Damon Bayer \email{xum8@cdc.gov} 29 | \item Andrew Magee \email{rzg0@cdc.gov} 30 | \item Scott Olesen \email{ulp7@cdc.gov} 31 | } 32 | 33 | Other contributors: 34 | \itemize{ 35 | \item Adam Howes \email{adamthowes@gmail.com} (\href{https://orcid.org/0000-0003-2386-4031}{ORCID}) [contributor] 36 | \item Chirag Kumar \email{kzs9@cdc.gov} [contributor] 37 | \item Alexander Keyel \email{alexander.keyel@health.ny.gov} (\href{https://orcid.org/000-0001-5256-6274}{ORCID}) [contributor] 38 | \item Hannah Cohen \email{llg4@cdc.gov} [contributor] 39 | } 40 | 41 | } 42 | \keyword{internal} 43 | -------------------------------------------------------------------------------- /scratch/sim_data_script.R: -------------------------------------------------------------------------------- 1 | # Specify all of the simulation settings (eventually we will put this into 2 | # vignette_data.R but leave as scratch for now) 3 | 4 | # Hacky way of pulling in all the functions in R 5 | list.files(file.path("R"), full.names = TRUE) |> 6 | purrr::walk(source) 7 | 8 | r_in_weeks <- c( 9 | rep(1.1, 5), rep(0.9, 5), 10 | 1 + 0.007 * 1:16 11 | ) 12 | n_sites <- 4 13 | ww_pop_sites <- c(4e5, 2e5, 1e5, 5e4) 14 | pop_size <- 3e6 15 | site <- c(1, 1, 2, 3, 4) 16 | lab <- c(1, 2, 3, 3, 3) 17 | ot <- 90 18 | nt <- 9 19 | forecast_horizon <- 28 20 | sim_start_date <- lubridate::ymd("2023-09-01") 21 | hosp_wday_effect <- c( 22 | 0.95, 1.01, 1.02, 23 | 1.02, 1.01, 1, 24 | 0.99 25 | ) / 7 26 | i0_over_n <- 5e-4 27 | initial_growth <- 1e-4 28 | sd_in_lab_level_multiplier <- 0.25 29 | mean_obs_error_in_ww_lab_site <- 0.2 30 | mean_reporting_freq <- 1 / 5 31 | sd_reporting_freq <- 1 / 20 32 | mean_reporting_latency <- 7 33 | sd_reporting_latency <- 3 34 | mean_log_lod <- 3.8 35 | sd_log_lod <- 0.2 36 | global_rt_sd <- 0.03 37 | sigma_eps <- 0.05 38 | sd_i0_over_n <- 0.5 39 | infection_feedback <- TRUE 40 | subpop_phi <- c(25, 50, 70, 40, 100) 41 | input_params_path <- 42 | fs::path_package("extdata", 43 | "example_params.toml", 44 | package = "wwinference" 45 | ) 46 | if_feedback <- FALSE 47 | 48 | # R(t) comparison 49 | rt_r <- new_i_over_n / (convolve(new_i_over_n, 50 | rev(c(0, generation_interval)), 51 | type = "open" 52 | ))[1:(uot + ot + ht)] 53 | 54 | test <- tibble::tibble( 55 | rt_stan = rt, 56 | rt_r = rt_r, 57 | t = 1:(ot + ht) 58 | ) 59 | 60 | ggplot(test) + 61 | geom_line(aes(x = t, y = rt_r), 62 | color = "black", 63 | linewidth = 2 64 | ) + 65 | geom_line(aes(x = t, y = rt_stan), color = "red") 66 | 67 | 68 | 69 | new_i_test <- rt_r * (convolve(new_i_over_n, rev(generation_interval), type = "open")[1:(ot + ht)]) # nolint 70 | plot(new_i_test) 71 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | # This file is part of the standard setup for testthat. 2 | # It is recommended that you do not modify it. 3 | # 4 | # Where should you do additional test configuration? 5 | # Learn more about the roles of various files in: 6 | # * https://r-pkgs.org/testing-design.html#sec-tests-files-overview 7 | # * https://testthat.r-lib.org/articles/special-files.html 8 | 9 | library(testthat) 10 | library(wwinference) 11 | 12 | test_check("wwinference") 13 | -------------------------------------------------------------------------------- /tests/testthat/helper.R: -------------------------------------------------------------------------------- 1 | get_nonmatrix_names_from_draws <- function(draws) { 2 | posterior::as_draws_list(draws)[[1]] |> 3 | names() |> 4 | strsplit(split = "[", fixed = TRUE) |> 5 | sapply(function(x) { 6 | x[1] 7 | }) |> 8 | unique() 9 | } 10 | 11 | get_par_dims_flat <- function(draws) { 12 | par_names_no_dim <- get_nonmatrix_names_from_draws(draws) 13 | par_names_with_dim <- posterior::as_draws_list(draws)[[1]] %>% 14 | names() 15 | counts <- sapply(par_names_no_dim, function(par) { 16 | full <- paste0("^", par, "$") 17 | pre_dim <- paste0("^", par, "\\[") 18 | sum( 19 | grepl(full, par_names_with_dim) | grepl(pre_dim, par_names_with_dim) 20 | ) 21 | }) 22 | return(counts) 23 | } 24 | 25 | logit_fn <- function(p) { 26 | stats::qlogis(p) 27 | } 28 | 29 | inv_logit_fn <- function(x) { 30 | stats::plogis(x) 31 | } 32 | 33 | 34 | #' Reference R implementation of a zero-mean AR(1) 35 | #' assembly from a set of z scores, 36 | #' a standard deviation, and 37 | #' an autocorrelation coefficient 38 | #' 39 | #' @param z a vector of z scores 40 | #' @param sd the standard deviation of the AR(1) process 41 | #' error distribution, as a scalar 42 | #' @param ac the autocorrelation coefficient of the AR(1) 43 | #' process, as a scalar 44 | #' @param stationary Whether to initialize the process 45 | #' at stationarity. Boolean, default `FALSE`. 46 | #' @return Vector of values of the zero-mean AR(1) process 47 | ar1_from_z_scores <- function(z, sd, ar, stationary = FALSE) { 48 | x <- rep(NA, length(z)) 49 | 50 | x[1] <- z[1] * sd 51 | if (stationary) { 52 | stat_sd <- sd / sqrt(1 - ar * ar) 53 | x[1] <- z[1] * stat_sd 54 | } 55 | 56 | for (i in 2:length(z)) { 57 | x[i] <- ar * x[i - 1] + z[i] * sd 58 | } 59 | 60 | return(x) 61 | } 62 | 63 | #' Reference R implementation of a first 64 | #' differenced zero-mean AR(1) assembly 65 | #' from an initial 66 | #' value, a set of z scores, 67 | #' a standard deviation, and 68 | #' an autocorrelation coefficient 69 | #' 70 | #' @param x0 the initial value of the first difference 71 | #' ar1 process 72 | #' @param ar the autocorrelation coefficient of the 73 | #' underlying zero-mean AR(1) process, as a scalar 74 | #' @param sd the standard deviation, of the underlying 75 | #' AR(1) process, as a scalar 76 | #' @param z a vector of z scores 77 | #' @param stationary Whether to initialize the underlying 78 | #' AR(1) on the first differences at stationarity. 79 | #' Boolean, default `FALSE`. 80 | #' @return Vector of values of the first differenced 81 | #' zero-mean AR(1) process 82 | diff_ar1_from_z_scores <- function(x0, ar, sd, z, stationary = FALSE) { 83 | n <- length(z) + 1 84 | diffs <- rep(NA, n) 85 | diffs[1] <- x0 86 | diffs[2:n] <- ar1_from_z_scores( 87 | z, sd, ar, 88 | stationary = stationary 89 | ) 90 | 91 | return(cumsum(diffs)) 92 | } 93 | 94 | 95 | 96 | #' Alternative R implementation of a first 97 | #' differenced zero-mean AR(1) assembly 98 | #' from an initial 99 | #' value, a set of z scores, 100 | #' a standard deviation, and 101 | #' an autocorrelation coefficient 102 | #' 103 | #' @param x0 the initial value of the first difference 104 | #' ar1 process 105 | #' @param ar the autocorrelation coefficient of the 106 | #' underlying zero-mean AR(1) process, as a scalar 107 | #' @param sd the standard deviation, of the underlying 108 | #' AR(1) process, as a scalar 109 | #' @param z a vector of z scores 110 | #' @param stationary Whether to initialize the underlying 111 | #' AR(1) on the first differences at stationarity. 112 | #' Boolean, default `FALSE`. 113 | #' @return Vector of values of the first differenced 114 | #' zero-mean AR(1) process 115 | diff_ar1_from_z_scores_alt <- function(x0, ar, sd, z, stationary = FALSE) { 116 | n <- length(z) + 1 117 | x <- rep(NA, n) 118 | x[1] <- x0 119 | 120 | first_sd <- sd 121 | 122 | if (stationary) { 123 | first_sd <- first_sd / sqrt(1 - ar^2) 124 | } 125 | 126 | x[2] <- x[1] + first_sd * z[1] 127 | 128 | for (i in 3:n) { 129 | x[i] <- x[i - 1] + ar * (x[i - 1] - x[i - 2]) + sd * z[i - 1] 130 | } 131 | 132 | return(x) 133 | } 134 | 135 | silent_wwinference <- function(...) { 136 | utils::capture.output( 137 | fit <- suppressMessages(wwinference(...)) 138 | ) 139 | return(fit) 140 | } 141 | -------------------------------------------------------------------------------- /tests/testthat/setup.R: -------------------------------------------------------------------------------- 1 | testthat_stan_include <- function() { 2 | system.file( 3 | "stan", 4 | package = "wwinference" 5 | ) 6 | } 7 | 8 | model_file_path_id <- system.file( 9 | "stan", "wwinference.stan", 10 | package = "wwinference" 11 | ) 12 | 13 | cat("\nsetup.R is compiling the stan model in preparation for testing.\n") 14 | 15 | # precompiled site-level infection dynamics model 16 | compiled_site_inf_model <- cmdstanr::cmdstan_model( 17 | model_file_path_id, 18 | force_recompile = TRUE, 19 | compile_standalone = TRUE, 20 | include = testthat_stan_include(), 21 | dir = tempdir() 22 | ) 23 | 24 | params <- wwinference::get_params( 25 | system.file("extdata", "example_params.toml", 26 | package = "wwinference" 27 | ) 28 | ) 29 | -------------------------------------------------------------------------------- /tests/testthat/test_ar1.R: -------------------------------------------------------------------------------- 1 | test_that("Test AR(1) function in stan.", { 2 | model <- compiled_site_inf_model 3 | 4 | withr::with_seed(42, { 5 | z <- rnorm(10) 6 | 7 | stan_ar <- model$functions$ar1( 8 | mu = rep(0, length(z)), 9 | ac = 0.73, 10 | sd = 1.26, 11 | z = z, 12 | is_stat = TRUE 13 | ) 14 | r_ar <- ar1_from_z_scores(z, 1.26, 0.73, TRUE) 15 | 16 | testthat::expect_equal( 17 | stan_ar, 18 | r_ar 19 | ) 20 | 21 | stan_ar_nonstat <- model$functions$ar1( 22 | mu = rep(0, length(z)), 23 | ac = 0.73, 24 | sd = 1.26, 25 | z = z, 26 | is_stat = FALSE 27 | ) 28 | 29 | testthat::expect_true( 30 | all(abs(stan_ar - stan_ar_nonstat) > testthat::testthat_tolerance()) 31 | ) 32 | 33 | r_ar_nonstat <- ar1_from_z_scores(z, 1.26, 0.73, FALSE) 34 | 35 | testthat::expect_equal( 36 | stan_ar_nonstat, 37 | r_ar_nonstat 38 | ) 39 | }) 40 | }) 41 | -------------------------------------------------------------------------------- /tests/testthat/test_ar1_marginal_variance.R: -------------------------------------------------------------------------------- 1 | test_explanation <- paste0( 2 | "When running a stationary AR(1) process initialized from the stationary ", 3 | "variance, the marginal variances should be larger than when compared to an ", 4 | "AR(1) process initialized from the (smaller) variance of the residuals. ", 5 | "(At least, until stationarity is reached.)" 6 | ) 7 | 8 | test_that(test_explanation, { 9 | model <- compiled_site_inf_model 10 | 11 | withr::with_seed(42, { 12 | stationary <- sapply(1:1e3, function(i) { 13 | z <- rnorm(10) 14 | 15 | model$functions$ar1( 16 | mu = rep(0, length(z)), 17 | ac = 0.95, 18 | sd = 0.15, 19 | z = z, 20 | is_stat = TRUE 21 | ) 22 | }) 23 | 24 | nonstationary <- sapply(1:1e3, function(i) { 25 | z <- rnorm(10) 26 | 27 | model$functions$ar1( 28 | mu = rep(0, length(z)), 29 | ac = 0.95, 30 | sd = 0.15, 31 | z = z, 32 | is_stat = FALSE 33 | ) 34 | }) 35 | 36 | testthat::expect_true( 37 | all(apply(stationary, 1, var) > apply(nonstationary, 1, var)) 38 | ) 39 | }) 40 | }) 41 | -------------------------------------------------------------------------------- /tests/testthat/test_diff_ar1.R: -------------------------------------------------------------------------------- 1 | test_that( 2 | "Test differenced AR(1) Stan function agrees with R", 3 | { 4 | model <- compiled_site_inf_model 5 | 6 | withr::with_seed(42, { 7 | z <- rnorm(100) 8 | ar <- runif(1) 9 | sd <- exp(rnorm(1, 0, 0.5)) 10 | x0 <- rnorm(1, 0, 5) 11 | 12 | for (stat in c(TRUE, FALSE)) { 13 | stan_ar_diff <- model$functions$diff_ar1( 14 | x0 = x0, 15 | ar = ar, 16 | sd = sd, 17 | z = z, 18 | is_stat = stat 19 | ) 20 | 21 | r_ar_diff <- diff_ar1_from_z_scores( 22 | x0 = x0, 23 | ar = ar, 24 | sd = sd, 25 | z = z, 26 | stationary = stat 27 | ) 28 | r_ar_diff_alt <- diff_ar1_from_z_scores_alt( 29 | x0 = x0, 30 | ar = ar, 31 | sd = sd, 32 | z = z, 33 | stationary = stat 34 | ) 35 | 36 | expect_equal( 37 | stan_ar_diff, 38 | r_ar_diff 39 | ) 40 | expect_equal( 41 | stan_ar_diff, 42 | r_ar_diff_alt 43 | ) 44 | } 45 | }) 46 | } 47 | ) 48 | -------------------------------------------------------------------------------- /tests/testthat/test_flag_as_ww_outliers.R: -------------------------------------------------------------------------------- 1 | # Create a dummy dataset that mimics the structure expected by the function 2 | dummy_data <- tibble::tibble( 3 | site = rep("Site1", 10), 4 | lab = rep("Lab1", 10), 5 | lab_site_index = rep(1, 10), 6 | date = as.Date("2021-01-01") + 0:9, 7 | log_genome_copies_per_ml = log(c( 8 | 100, 150, 100, 200, 270, 200, 9 | NA, 400, 20, 600 10 | )), 11 | below_lod = c(0, 0, 0, 0, 0, 0, 0, 0, 1, 0) 12 | ) 13 | 14 | 15 | test_that("function returns a dataframe with correct columns", { 16 | result <- flag_ww_outliers(dummy_data) 17 | 18 | testthat::expect_true("flag_as_ww_outlier" %in% names(result)) 19 | testthat::expect_true("exclude" %in% names(result)) 20 | }) 21 | 22 | test_that("function flags outliers correctly", { 23 | # Modify dummy_data to create an outlier scenario 24 | dummy_data <- tibble::tibble( 25 | site = rep("Site1", 12), 26 | lab = rep("Lab1", 12), 27 | lab_site_index = rep(1, 12), 28 | date = as.Date("2021-01-01") + 0:11, 29 | log_genome_copies_per_ml = log(c( 30 | 100, 120, 100, 110, 115, 130, 110, 200, NA, 31 | 100, 20, 500000 32 | )), 33 | below_lod = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0) 34 | ) 35 | 36 | result <- flag_ww_outliers(dummy_data, 37 | log_conc_threshold = 1 38 | ) 39 | 40 | # Check if the known outlier is flagged correctly 41 | testthat::expect_true(sum(result$flag_as_ww_outlier) > 0) 42 | # Check that this hasn't yet been labeled for exclusion 43 | testthat::expect_true(sum(result$exclude) == 0) 44 | }) 45 | 46 | test_that("function does not flag non-outliers", { 47 | # Modify dummy_data to have no outliers 48 | dummy_data <- tibble::tibble( 49 | site = rep("Site1", 12), 50 | lab = rep("Lab1", 12), 51 | lab_site_index = rep(1, 12), 52 | date = as.Date("2021-01-01") + 0:11, 53 | log_genome_copies_per_ml = log(c( 54 | 100, 120, 100, 110, 115, 130, 110, 200, NA, 55 | 100, 20, 150 56 | )), 57 | below_lod = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0) 58 | ) 59 | 60 | result <- flag_ww_outliers(dummy_data) 61 | 62 | # Check that there is no outlier to be flagged 63 | testthat::expect_true(sum(result$flag_as_ww_outlier) == 0) 64 | # Check that this hasn't yet been labeled for exclusion 65 | testthat::expect_true(sum(result$exclude) == 0) 66 | }) 67 | 68 | test_that("function handles NA values appropriately", { 69 | # Include NAs in concentration column and check behavior 70 | dummy_data <- tibble::tibble( 71 | site = rep("Site1", 12), 72 | lab = rep("Lab1", 12), 73 | lab_site_index = rep(1, 12), 74 | date = as.Date("2021-01-01") + 0:11, 75 | log_genome_copies_per_ml = c( 76 | NA, 120, 100, 110, NA, 130, 110, 200, NA, 77 | 100, 20, 150 78 | ), 79 | below_lod = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0) 80 | ) 81 | 82 | result <- flag_ww_outliers(dummy_data) 83 | 84 | # Ensure NAs are handled according to specifications (not flagged as outliers) 85 | testthat::expect_true(sum(result$flag_as_ww_outlier) == 0) 86 | # Check that this hasn't yet been labeled for exclusion 87 | testthat::expect_true(sum(result$exclude) == 0) 88 | }) 89 | 90 | test_that("rho_threshold and log_conc threshold parameters works as expected", { 91 | dummy_data <- tibble::tibble( 92 | site = rep("Site1", 12), 93 | lab = rep("Lab1", 12), 94 | lab_site_index = rep(1, 12), 95 | date = as.Date("2021-01-01") + 0:11, 96 | log_genome_copies_per_ml = c( 97 | 100, 120, 100, 110, 115, 1000, 110, 100, NA, 98 | 100, 20, 100 99 | ), 100 | below_lod = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0) 101 | ) 102 | 103 | # With a high rho threshold, we definitely won't flag the last result 104 | high_rho_threshold_result <- flag_ww_outliers(dummy_data, 105 | rho_threshold = 5, 106 | log_conc_threshold = 5 107 | ) 108 | # With a low rho threshold we should flag the last point 109 | low_rho_threshold_result <- flag_ww_outliers(dummy_data, 110 | rho_threshold = 0.5, 111 | log_conc_threshold = 0.5 112 | ) 113 | 114 | # Expect fewer outliers with higher threshold and more with lower threshold 115 | testthat::expect_true(sum( 116 | low_rho_threshold_result$flag_as_ww_outlier 117 | ) > sum( 118 | high_rho_threshold_result$flag_as_ww_outlier 119 | )) 120 | }) 121 | 122 | 123 | 124 | test_that("exclude column is set to zero by default", { 125 | result <- flag_ww_outliers(dummy_data) 126 | 127 | expect_true(all(result$exclude == 0)) 128 | }) 129 | -------------------------------------------------------------------------------- /tests/testthat/test_helper.R: -------------------------------------------------------------------------------- 1 | test_that("Make sure we can find and load files we need for other tests.", { 2 | # Compiled model object should exist in the workspace, with functions exposed 3 | testthat::expect_true( 4 | exists("compiled_site_inf_model") 5 | ) 6 | 7 | testthat::expect_true( 8 | "CmdStanModel" %in% class(compiled_site_inf_model) 9 | ) 10 | 11 | testthat::expect_no_error( 12 | compiled_site_inf_model$functions$convert_to_logmean(1.0, 1.0) 13 | ) 14 | }) 15 | -------------------------------------------------------------------------------- /tests/testthat/test_ihr_transform.R: -------------------------------------------------------------------------------- 1 | test_that("Test logit-scale random walk on IHR in stan works", { 2 | model <- compiled_site_inf_model 3 | 4 | weeks_to_days <- get_ind_m( 5 | 168, 6 | 24 7 | ) 8 | ndays <- dim(weeks_to_days)[1] 9 | nweeks <- dim(weeks_to_days)[2] 10 | 11 | # Make sure we cover a wide range 12 | sigma <- 0.5 13 | ac <- 0.1 14 | std_normal <- rnorm((nweeks)) 15 | mu <- rep(logit_fn(0.01), (nweeks)) 16 | 17 | # Build the vector ourselves using the AR1 function from stan 18 | p_hosp_r <- model$functions$ar1(mu, ac, sigma, std_normal, 1) 19 | p_hosp_r <- rep(p_hosp_r, each = 7) # In R, expand weekly to daily 20 | p_hosp_r <- inv_logit_fn(p_hosp_r) # convert to natural scale 21 | p_hosp_r <- p_hosp_r[1:ndays] # Trim to size 22 | 23 | 24 | # Get vector from stan and compare 25 | p_hosp_stan <- model$functions$assemble_p_hosp( 26 | weeks_to_days, # matrix to expand from weekly to daily 27 | mu[1], # intercept to regress back to 28 | sigma, # SD 29 | ac, # autocorrelation factor 30 | std_normal, 31 | nweeks, 32 | 1 33 | ) 34 | 35 | testthat::expect_equal( 36 | p_hosp_stan, 37 | p_hosp_r 38 | ) 39 | }) 40 | -------------------------------------------------------------------------------- /tests/testthat/test_indicate_ww_exclusions.R: -------------------------------------------------------------------------------- 1 | # Test data setup 2 | data <- tibble::tibble( 3 | date = lubridate::ymd(c("2023-10-01", "2023-10-02")), 4 | genome_copies_per_mL = c(300, 3e6), 5 | flag_as_ww_outlier = c(0, 1), 6 | exclude = c(0, 0) 7 | ) 8 | 9 | # Test that function returns a dataframe with an additional 'exclude' column 10 | test_that("Function returns dataframe with 'exclude' column", { 11 | processed <- indicate_ww_exclusions(data, 12 | outlier_col_name = "flag_as_ww_outlier", 13 | remove_outliers = TRUE 14 | ) 15 | 16 | expect_true( 17 | checkmate::check_names(names(processed), must.include = "exclude") 18 | ) 19 | }) 20 | 21 | # Test that outliers are correctly marked for exclusion when 22 | # remove_outliers is TRUE 23 | test_that("Outliers are marked for exclusion when remove_outliers is TRUE", { 24 | processed <- indicate_ww_exclusions(data, 25 | outlier_col_name = "flag_as_ww_outlier", 26 | remove_outliers = TRUE 27 | ) 28 | 29 | expected_exclude <- c(0, 1) # Second row should be marked as an outlier 30 | 31 | expect_equal(processed$exclude, expected_exclude) 32 | }) 33 | 34 | # Test that no rows are marked for exclusion when remove_outliers is FALSE 35 | test_that("No rows are marked for exclusion when remove_outliers is FALSE", { 36 | processed <- indicate_ww_exclusions(data, 37 | outlier_col_name = "flag_as_ww_outlier", 38 | remove_outliers = FALSE 39 | ) 40 | 41 | expected_exclude <- c(0, 0) # No rows should be excluded 42 | 43 | expect_equal(processed$exclude, expected_exclude) 44 | }) 45 | -------------------------------------------------------------------------------- /tests/testthat/test_models_run_without_ww.R: -------------------------------------------------------------------------------- 1 | options(cmdstanr_warn_inits = FALSE) 2 | 3 | hosp_data <- wwinference::hosp_data 4 | ww_data <- wwinference::ww_data 5 | params <- wwinference::get_params( 6 | fs::path_package("extdata", "example_params.toml", 7 | package = "wwinference" 8 | ) 9 | ) 10 | 11 | 12 | # Data pre-processing -------------------------------------------------------- 13 | ww_data_preprocessed <- wwinference::preprocess_ww_data( 14 | ww_data, 15 | conc_col_name = "log_genome_copies_per_ml", 16 | lod_col_name = "log_lod" 17 | ) 18 | 19 | hosp_data_preprocessed <- wwinference::preprocess_count_data( 20 | hosp_data, 21 | count_col_name = "daily_hosp_admits", 22 | pop_size_col_name = "state_pop" 23 | ) 24 | 25 | ww_data_to_fit <- wwinference::indicate_ww_exclusions( 26 | ww_data_preprocessed, 27 | outlier_col_name = "flag_as_ww_outlier", 28 | remove_outliers = TRUE 29 | ) 30 | 31 | forecast_date <- "2023-12-06" 32 | calibration_time <- 90 33 | forecast_horizon <- 28 34 | generation_interval <- wwinference::default_covid_gi 35 | inf_to_hosp <- wwinference::default_covid_inf_to_hosp 36 | 37 | # Assign infection feedback equal to the generation interval 38 | infection_feedback_pmf <- generation_interval 39 | 40 | model_spec <- wwinference::get_model_spec( 41 | generation_interval = generation_interval, 42 | inf_to_count_delay = inf_to_hosp, 43 | infection_feedback_pmf = infection_feedback_pmf, 44 | params = params 45 | ) 46 | 47 | mcmc_options <- list( 48 | seed = 5, 49 | iter_warmup = 500, 50 | iter_sampling = 250, 51 | chains = 2, 52 | show_messages = FALSE, 53 | show_exceptions = FALSE 54 | ) 55 | 56 | generate_initial_values <- TRUE 57 | 58 | model_test_data <- list( 59 | ww_data = ww_data_to_fit, 60 | count_data = hosp_data_preprocessed, 61 | forecast_date = forecast_date, 62 | calibration_time = calibration_time, 63 | forecast_horizon = forecast_horizon, 64 | model_spec = model_spec, 65 | fit_opts = mcmc_options, 66 | generate_initial_values = generate_initial_values, 67 | compiled_model = compiled_site_inf_model 68 | ) 69 | 70 | 71 | test_that("Test that the model runs on simulated data when include_ww=0.", { 72 | ####### 73 | # run model briefly on the simulated data 74 | ####### 75 | model_test_data_no_ww <- model_test_data 76 | model_test_data_no_ww$model_spec$include_ww <- 0 77 | 78 | expect_no_error(withr::with_seed(55, { 79 | fit <- do.call( 80 | wwinference::wwinference, 81 | model_test_data_no_ww 82 | ) 83 | })) 84 | }) 85 | 86 | test_that("Test that the model runs without wastewater, include_ww=0.", { 87 | ####### 88 | # run model briefly on the simulated data 89 | ####### 90 | model_test_data_no_ww <- model_test_data 91 | model_test_data_no_ww$model_spec$include_ww <- 0 92 | model_test_data_no_ww$ww_data <- tibble::tibble() 93 | 94 | expect_warning( 95 | withr::with_seed(55, { 96 | fit <- do.call( 97 | wwinference::wwinference, 98 | model_test_data_no_ww 99 | ) 100 | }), 101 | regex = "No wastewater data was passed to the model." 102 | ) 103 | }) 104 | 105 | test_that("Test that the model runs without wastewater, include_ww=1.", { 106 | ####### 107 | # run model briefly on the simulated data 108 | ####### 109 | model_test_data_no_ww <- model_test_data 110 | model_test_data_no_ww$model_spec$include_ww <- 1 111 | model_test_data_no_ww$ww_data <- tibble::tibble() 112 | 113 | expect_warning( 114 | withr::with_seed(55, { 115 | fit <- do.call( 116 | wwinference::wwinference, 117 | model_test_data_no_ww 118 | ) 119 | }), 120 | regex = "No wastewater data was passed to the model." 121 | ) 122 | }) 123 | -------------------------------------------------------------------------------- /tests/testthat/test_plots.R: -------------------------------------------------------------------------------- 1 | t_length <- 127 2 | forecast_date <- "2024-01-01" 3 | data <- tibble::tibble( 4 | date = seq( 5 | from = lubridate::ymd("2023-10-01"), 6 | to = lubridate::ymd("2023-10-01") + lubridate::days(t_length - 1), 7 | by = "days" 8 | ), 9 | observed_value = sample(10:25, t_length, replace = TRUE) 10 | ) 11 | 12 | draws <- tibble::tibble() 13 | for (i in 1:100) { 14 | draws_i <- data |> 15 | dplyr::mutate( 16 | pred_value = observed_value + 17 | runif(t_length, min = -10, max = 10), 18 | draw = i 19 | ) 20 | draws <- dplyr::bind_rows(draws, draws_i) 21 | } 22 | 23 | test_draws <- draws |> 24 | dplyr::mutate( 25 | observed_value = ifelse(date < forecast_date, observed_value, NA) 26 | ) 27 | 28 | test_eval_data <- data |> 29 | dplyr::rename("daily_hosp_admits_eval" = observed_value) 30 | 31 | 32 | 33 | 34 | test_that("Test there is no error with eval data", { 35 | expect_no_error( 36 | get_plot_forecasted_counts( 37 | draws = test_draws, 38 | forecast_date = forecast_date, 39 | count_data_eval = test_eval_data, 40 | count_data_eval_col_name = "daily_hosp_admits_eval" 41 | ) 42 | ) 43 | }) 44 | 45 | 46 | test_that("Test there is no error without eval data", { 47 | expect_no_error( 48 | get_plot_forecasted_counts( 49 | draws = test_draws, 50 | forecast_date = forecast_date 51 | ) 52 | ) 53 | }) 54 | -------------------------------------------------------------------------------- /tests/testthat/test_pmfs_normalized.R: -------------------------------------------------------------------------------- 1 | test_that("Test that bundled PMFs in the package data sum to 1", { 2 | model <- compiled_site_inf_model 3 | 4 | shedding_pdf <- model$functions$get_vl_trajectory( 5 | tpeak = 5, 6 | viral_peak = 5, 7 | duration_shedding = 17, 8 | n = 100 9 | ) 10 | 11 | testthat::expect_equal(sum(shedding_pdf), 1.0) 12 | 13 | 14 | default_spec <- wwinference::get_model_spec() 15 | 16 | generation_interval <- default_spec$generation_interval 17 | testthat::expect_equal(sum(generation_interval), 1.0) 18 | 19 | 20 | inf_to_count_delay <- default_spec$inf_to_count_delay 21 | testthat::expect_equal(sum(inf_to_count_delay), 1.0) 22 | 23 | inf_feedback <- default_spec$infection_feedback_pmf 24 | testthat::expect_equal(sum(inf_feedback), 1.0) 25 | }) 26 | -------------------------------------------------------------------------------- /tests/testthat/test_rt_assembly.R: -------------------------------------------------------------------------------- 1 | test_that(paste0( 2 | "Test that assembling an unadjusted R(t) ", 3 | "vector using R (language) code gives the ", 4 | "same result as doing it via our custom Stan", 5 | "functions when those are loaded into R" 6 | ), { 7 | model <- compiled_site_inf_model 8 | 9 | weeks_to_days <- get_ind_m( 10 | 168, 11 | 24 12 | ) 13 | ndays <- dim(weeks_to_days)[1] 14 | nweeks <- dim(weeks_to_days)[2] 15 | 16 | ## Make sure we cover a wide range 17 | sigma <- 5 18 | ac <- 0.25 19 | 20 | withr::with_seed(5325, { 21 | std_normal <- rnorm((nweeks - 1)) 22 | init_val <- rnorm(1, 0.5, 0.25) 23 | }) 24 | 25 | ## Build the vector ourselves 26 | unadj_log_r_weeks_r <- diff_ar1_from_z_scores( 27 | init_val, ac, sigma, std_normal, 28 | stationary = FALSE 29 | ) 30 | unadj_log_r_days_r <- rep(unadj_log_r_weeks_r, 31 | each = 7 32 | ) # In R, expand weekly to daily 33 | 34 | ## convert to linear scale and trim to size 35 | unadj_r_days_r <- exp(unadj_log_r_days_r)[1:ndays] 36 | 37 | 38 | ## Compute in the same way it is done in stan 39 | unadj_log_r_weeks_stan <- model$functions$diff_ar1( 40 | init_val, 41 | ac, 42 | sigma, 43 | std_normal, 44 | is_stat = FALSE 45 | ) |> 46 | as.numeric() 47 | 48 | expect_equal( 49 | unadj_log_r_weeks_r, 50 | unadj_log_r_weeks_stan 51 | ) 52 | 53 | unadj_r_days_stan <- exp( 54 | weeks_to_days %*% unadj_log_r_weeks_stan 55 | ) |> 56 | as.numeric() 57 | 58 | expect_equal( 59 | unadj_r_days_r, 60 | unadj_r_days_stan 61 | ) 62 | }) 63 | -------------------------------------------------------------------------------- /tests/testthat/test_wwinference.R: -------------------------------------------------------------------------------- 1 | # Generate test data 2 | ww_data <- tibble::tibble( 3 | date = rep(seq( 4 | from = lubridate::ymd("2023-08-01"), 5 | to = lubridate::ymd("2023-11-01"), 6 | by = "weeks" 7 | ), 2), 8 | site = c(rep(1, 14), rep(2, 14)), 9 | lab = c(rep(1, 28)), 10 | conc = abs(rnorm(28, mean = 500, sd = 50)), 11 | lod = c(rep(20, 14), rep(15, 14)), 12 | site_pop = c(rep(2e5, 14), rep(4e5, 14)) 13 | ) 14 | 15 | ww_data_preprocessed <- preprocess_ww_data(ww_data, 16 | conc_col_name = "conc", 17 | lod_col_name = "lod" 18 | ) 19 | input_ww_data <- indicate_ww_exclusions(ww_data_preprocessed) 20 | 21 | hosp_data <- tibble::tibble( 22 | date = seq( 23 | from = lubridate::ymd("2023-07-01"), 24 | to = lubridate::ymd("2023-10-30"), 25 | by = "days" 26 | ), 27 | daily_admits = sample(5:70, 122, replace = TRUE), 28 | state_pop = rep(1e6, 122) 29 | ) 30 | 31 | input_count_data <- preprocess_count_data( 32 | hosp_data, 33 | "daily_admits", 34 | "state_pop" 35 | ) 36 | 37 | generation_interval <- to_simplex(c(0.01, 0.2, 0.3, 0.2, 0.1, 0.1, 0.01)) 38 | inf_to_count_delay <- to_simplex(c( 39 | rep(0.01, 12), rep(0.2, 4), 40 | rep(0.01, 10) 41 | )) 42 | infection_feedback_pmf <- generation_interval 43 | 44 | params <- get_params( 45 | system.file("extdata", "example_params.toml", 46 | package = "wwinference" 47 | ) 48 | ) 49 | forecast_date <- "2023-11-06" 50 | calibration_time <- 90 51 | forecast_horizon <- 28 52 | include_ww <- 1 53 | 54 | 55 | test_that("wwinference model can compile", { 56 | expect_no_error(compile_model()) 57 | }) 58 | 59 | test_that("Function to get mcmc options produces the expected outputs", { 60 | mcmc_options <- get_mcmc_options() 61 | expected_names <- c( 62 | "iter_warmup", "iter_sampling", "seed", "adapt_delta", "max_treedepth" 63 | ) 64 | checkmate::expect_names(names(mcmc_options), must.include = expected_names) 65 | }) 66 | 67 | test_that("Function to get model specs produces expected outputs", { 68 | model_spec <- get_model_spec() 69 | expected_names <- c( 70 | "generation_interval", "inf_to_count_delay", 71 | "infection_feedback_pmf", "include_ww", 72 | "compute_likelihood", "params" 73 | ) 74 | # Checkmade doesn't work here for a list, says it must be a character vector 75 | expect_true(all(names(model_spec) %in% expected_names)) 76 | }) 77 | 78 | test_that("Passing invalid args to fit_opts throws an error ", { 79 | expect_error( 80 | wwinference( 81 | ww_data = input_ww_data, 82 | count_data = input_count_data, 83 | forecast_date = forecast_date, 84 | model_spec = get_model_spec(), 85 | fit_opts = list(not_an_arg = 4) 86 | ), 87 | regexp = c("Names must be a subset of ") 88 | ) 89 | }) 90 | --------------------------------------------------------------------------------