diff --git a/previews/PR128/.documenter-siteinfo.json b/previews/PR128/.documenter-siteinfo.json index 886114e0e..1086a59e0 100644 --- a/previews/PR128/.documenter-siteinfo.json +++ b/previews/PR128/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.10.2","generation_timestamp":"2024-03-08T12:47:51","documenter_version":"1.3.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.10.2","generation_timestamp":"2024-03-08T12:57:41","documenter_version":"1.3.0"}} \ No newline at end of file diff --git a/previews/PR128/checklist/index.html b/previews/PR128/checklist/index.html index 4b471b756..52297d704 100644 --- a/previews/PR128/checklist/index.html +++ b/previews/PR128/checklist/index.html @@ -20,4 +20,4 @@ Either of those should automatically publish a new version to the Julia registry. - Once registered, the `TagBot.yml` workflow should create a tag, and rebuild the documentation for this tag. - - These steps can take quite a bit of time (1 hour or more), so don't be surprised if the new documentation takes a while to appear. + - These steps can take quite a bit of time (1 hour or more), so don't be surprised if the new documentation takes a while to appear. diff --git a/previews/PR128/contributing/index.html b/previews/PR128/contributing/index.html index f75ab0543..b2af40b74 100644 --- a/previews/PR128/contributing/index.html +++ b/previews/PR128/contributing/index.html @@ -1,2 +1,2 @@ -Contributing · EpiAware.jl

Contributing

This page details the some of the guidelines that should be followed when contributing to this package. It is adapted from Documenter.jl.

Branches

release-* branches are used for tagged minor versions of this package. This follows the same approach used in the main Julia repository, albeit on a much more modest scale.

Please open pull requests against the master branch rather than any of the release-* branches whenever possible.

Backports

Bug fixes are backported to the release-* branches using git cherry-pick -x by a EpiAware member and will become available in point releases of that particular minor version of the package.

Feel free to nominate commits that should be backported by opening an issue. Requests for new point releases to be tagged in METADATA.jl can also be made in the same way.

release-* branches

  • Each new minor version x.y.0 gets a branch called release-x.y (a protected branch).
  • New versions are usually tagged only from the release-x.y branches.
  • For patch releases, changes get backported to the release-x.y branch via a single PR with the standard name "Backports for x.y.z" and label "Type: Backport". The PR message links to all the PRs that are providing commits to the backport. The PR gets merged as a merge commit (i.e. not squashed).
  • The old release-* branches may be removed once they have outlived their usefulness.
  • Patch version milestones are used to keep track of which PRs get backported etc.

Style Guide

Follow the style of the surrounding text when making changes. When adding new features please try to stick to the following points whenever applicable. This project follows the SciML style guide.

Tests

Unit tests

As is conventional for Julia packages, unit tests are located at test/*.jl with the entrypoint test/runtests.jl.

End to end testing

Tests that build example package docs from source and inspect the results (end to end tests) are located in /test/examples. The main entry points are test/examples/make.jl for building and test/examples/test.jl for doing some basic checks on the generated outputs.

+Contributing · EpiAware.jl

Contributing

This page details the some of the guidelines that should be followed when contributing to this package. It is adapted from Documenter.jl.

Branches

release-* branches are used for tagged minor versions of this package. This follows the same approach used in the main Julia repository, albeit on a much more modest scale.

Please open pull requests against the master branch rather than any of the release-* branches whenever possible.

Backports

Bug fixes are backported to the release-* branches using git cherry-pick -x by a EpiAware member and will become available in point releases of that particular minor version of the package.

Feel free to nominate commits that should be backported by opening an issue. Requests for new point releases to be tagged in METADATA.jl can also be made in the same way.

release-* branches

  • Each new minor version x.y.0 gets a branch called release-x.y (a protected branch).
  • New versions are usually tagged only from the release-x.y branches.
  • For patch releases, changes get backported to the release-x.y branch via a single PR with the standard name "Backports for x.y.z" and label "Type: Backport". The PR message links to all the PRs that are providing commits to the backport. The PR gets merged as a merge commit (i.e. not squashed).
  • The old release-* branches may be removed once they have outlived their usefulness.
  • Patch version milestones are used to keep track of which PRs get backported etc.

Style Guide

Follow the style of the surrounding text when making changes. When adding new features please try to stick to the following points whenever applicable. This project follows the SciML style guide.

Tests

Unit tests

As is conventional for Julia packages, unit tests are located at test/*.jl with the entrypoint test/runtests.jl.

End to end testing

Tests that build example package docs from source and inspect the results (end to end tests) are located in /test/examples. The main entry points are test/examples/make.jl for building and test/examples/test.jl for doing some basic checks on the generated outputs.

diff --git a/previews/PR128/examples/getting_started/index.html b/previews/PR128/examples/getting_started/index.html index b1c07783c..453d94b15 100644 --- a/previews/PR128/examples/getting_started/index.html +++ b/previews/PR128/examples/getting_started/index.html @@ -163,7 +163,7 @@ 133 - +

Inference

Fixing $Z_0 = 0$ for the random walk was based on inference principles; in this model $Z_0$ and $\log I_0$ are non-identifiable.

However, we now treat the generated data as truth_data and make inference without fixing any other parameters.

We do the inference by MCMC/NUTS using the Turing NUTS sampler with default warm-up steps.

@@ -284,7 +284,7 @@

Inference - +

Reproductive number back-calculation

As mentioned at the top, we don't directly use the concept of reproductive numbers in this note. However, we can back-calculate the implied $\mathcal{R}(t)$ values, conditional on the specified generation interval being correct.

Here we spaghetti plot posterior sampled time-varying reproductive numbers against the actual.

@@ -313,4 +313,4 @@

- + diff --git a/previews/PR128/index.html b/previews/PR128/index.html index 77f27d188..130399d11 100644 --- a/previews/PR128/index.html +++ b/previews/PR128/index.html @@ -1,2 +1,2 @@ -EpiAware.jl: Real-time epidemic monitoring · EpiAware.jl

EpiAware.jl

Infectious disease situational awareness modelling toolkit for Julia.

A package for building and fitting situational awareness models for infectious diseases. The package is designed to be flexible and extensible, and to provide a consistent interface for fitting and simulating models.

Package Features

  • Flexible: The package is designed to be flexible and extensible, and to provide a consistent interface for fitting and simulating models.
  • Modular: The package is designed to be modular, with a clear separation between the model and the data.
  • Extensible: The package is designed to be extensible, with a clear separation between the model and the data.
  • Consistent: The package is designed to provide a consistent interface for fitting and simulating models.
  • Efficient: The package is designed to be efficient, with a clear separation between the model and the data.

See the Index for the complete list of documented functions and types.

Manual Outline

    Library Outline

    Index

      +EpiAware.jl: Real-time epidemic monitoring · EpiAware.jl

      EpiAware.jl

      Infectious disease situational awareness modelling toolkit for Julia.

      A package for building and fitting situational awareness models for infectious diseases. The package is designed to be flexible and extensible, and to provide a consistent interface for fitting and simulating models.

      Package Features

      • Flexible: The package is designed to be flexible and extensible, and to provide a consistent interface for fitting and simulating models.
      • Modular: The package is designed to be modular, with a clear separation between the model and the data.
      • Extensible: The package is designed to be extensible, with a clear separation between the model and the data.
      • Consistent: The package is designed to provide a consistent interface for fitting and simulating models.
      • Efficient: The package is designed to be efficient, with a clear separation between the model and the data.

      See the Index for the complete list of documented functions and types.

      Manual Outline

        Library Outline

        Index

          diff --git a/previews/PR128/lib/internals/index.html b/previews/PR128/lib/internals/index.html index 628063438..71577dbbf 100644 --- a/previews/PR128/lib/internals/index.html +++ b/previews/PR128/lib/internals/index.html @@ -3,7 +3,7 @@ μ, α ) -> Distributions.NegativeBinomial -

          Methods

          NegativeBinomialMeanClust(μ, α)

          defined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/utilities.jl:210.

          source
          EpiAware._continue_manypathfinder!Method

          continuemanypathfinder! Continue running the pathfinder algorithm until a pathfinder succeeds or the maximum number of tries is reached.

          Arguments

          • pfs: An array of pathfinder objects.
          • mdl::DynamicPPL.Model: The model to perform inference on.
          • max_tries: The maximum number of tries to run the pathfinder algorithm. Default is Inf.
          • nruns: The number of times to run the pathfinder function.
          • kwargs...: Additional keyword arguments passed to pathfinder.

          Returns

          • pfs: The updated array of pathfinder objects.

          Signatures

          _continue_manypathfinder!(
          +

          Methods

          NegativeBinomialMeanClust(μ, α)

          defined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/utilities.jl:210.

          source
          EpiAware._continue_manypathfinder!Method

          continuemanypathfinder! Continue running the pathfinder algorithm until a pathfinder succeeds or the maximum number of tries is reached.

          Arguments

          • pfs: An array of pathfinder objects.
          • mdl::DynamicPPL.Model: The model to perform inference on.
          • max_tries: The maximum number of tries to run the pathfinder algorithm. Default is Inf.
          • nruns: The number of times to run the pathfinder function.
          • kwargs...: Additional keyword arguments passed to pathfinder.

          Returns

          • pfs: The updated array of pathfinder objects.

          Signatures

          _continue_manypathfinder!(
               pfs,
               mdl::DynamicPPL.Model;
               max_tries,
          @@ -16,8 +16,8 @@
               max_tries,
               nruns,
               kwargs...
          -)

          defined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/inference-methods.jl:42.

          source
          EpiAware._get_best_elbo_pathfinderMethod

          getbestelbopathfinder Selects the pathfinder with the highest ELBO estimate from a list of pathfinders.

          Arguments

          • pfs: A list of pathfinders results or Symbol values indicating failure.

          Returns

          The pathfinder with the highest ELBO estimate.


          Signatures

          _get_best_elbo_pathfinder(pfs) -> Any
          -

          Methods

          _get_best_elbo_pathfinder(pfs)

          defined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/inference-methods.jl:72.

          source
          EpiAware._run_manypathfinderMethod

          runmanypathfinder

          Run pathfinder multiple times and store the results in an array. Fails safely.

          Arguments

          • mdl::DynamicPPL.Model: The Turing model to be used for inference.
          • nruns: The number of times to run the pathfinder function.
          • kwargs...: Additional keyword arguments passed to pathfinder.

          Returns

          An array of PathfinderResult objects or Symbol values indicating success or failure.


          Signatures

          _run_manypathfinder(mdl::DynamicPPL.Model; nruns, kwargs...)
          -

          Methods

          _run_manypathfinder(mdl; nruns, kwargs...)

          defined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/inference-methods.jl:13.

          source
          EpiAware.generate_observation_kernelMethod

          generateobservationkernel generateobservationkernel(delayint, timehorizon)

          Generate an observation kernel matrix based on the given delay interval and time horizon.

          Arguments

          • delay_int::Vector{Float64}: The delay PMF vector.
          • time_horizon::Int: The number of time steps of the observation period.

          Returns

          • K::SparseMatrixCSC{Float64, Int}: The observation kernel matrix.

          Signatures

          generate_observation_kernel(delay_int, time_horizon) -> Any
          -

          Methods

          generate_observation_kernel(delay_int, time_horizon)

          defined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/utilities.jl:229.

          source
          EpiAware.neg_MGFMethod

          negMGF negMGF(r, w::AbstractVector)

          Compute the negative moment generating function (MGF) for a given rate r and weights w.

          Arguments

          • r: The rate parameter.
          • w: An abstract vector of weights.

          Returns

          The value of the negative MGF.


          Signatures

          neg_MGF(r, w::AbstractVector) -> Any
          -

          Methods

          neg_MGF(r, w)

          defined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/utilities.jl:132.

          source
          +)

          defined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/inference-methods.jl:42.

          source
          EpiAware._get_best_elbo_pathfinderMethod

          getbestelbopathfinder Selects the pathfinder with the highest ELBO estimate from a list of pathfinders.

          Arguments

          • pfs: A list of pathfinders results or Symbol values indicating failure.

          Returns

          The pathfinder with the highest ELBO estimate.


          Signatures

          _get_best_elbo_pathfinder(pfs) -> Any
          +

          Methods

          _get_best_elbo_pathfinder(pfs)

          defined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/inference-methods.jl:72.

          source
          EpiAware._run_manypathfinderMethod

          runmanypathfinder

          Run pathfinder multiple times and store the results in an array. Fails safely.

          Arguments

          • mdl::DynamicPPL.Model: The Turing model to be used for inference.
          • nruns: The number of times to run the pathfinder function.
          • kwargs...: Additional keyword arguments passed to pathfinder.

          Returns

          An array of PathfinderResult objects or Symbol values indicating success or failure.


          Signatures

          _run_manypathfinder(mdl::DynamicPPL.Model; nruns, kwargs...)
          +

          Methods

          _run_manypathfinder(mdl; nruns, kwargs...)

          defined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/inference-methods.jl:13.

          source
          EpiAware.generate_observation_kernelMethod

          generateobservationkernel generateobservationkernel(delayint, timehorizon)

          Generate an observation kernel matrix based on the given delay interval and time horizon.

          Arguments

          • delay_int::Vector{Float64}: The delay PMF vector.
          • time_horizon::Int: The number of time steps of the observation period.

          Returns

          • K::SparseMatrixCSC{Float64, Int}: The observation kernel matrix.

          Signatures

          generate_observation_kernel(delay_int, time_horizon) -> Any
          +

          Methods

          generate_observation_kernel(delay_int, time_horizon)

          defined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/utilities.jl:229.

          source
          EpiAware.neg_MGFMethod

          negMGF negMGF(r, w::AbstractVector)

          Compute the negative moment generating function (MGF) for a given rate r and weights w.

          Arguments

          • r: The rate parameter.
          • w: An abstract vector of weights.

          Returns

          The value of the negative MGF.


          Signatures

          neg_MGF(r, w::AbstractVector) -> Any
          +

          Methods

          neg_MGF(r, w)

          defined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/utilities.jl:132.

          source
          diff --git a/previews/PR128/lib/public/index.html b/previews/PR128/lib/public/index.html index f6e46ddcd..493b0349c 100644 --- a/previews/PR128/lib/public/index.html +++ b/previews/PR128/lib/public/index.html @@ -1,2 +1,2 @@ -Public API · EpiAware.jl
          +Public API · EpiAware.jl
          diff --git a/previews/PR128/man/guide/index.html b/previews/PR128/man/guide/index.html index 429b42347..b1db11034 100644 --- a/previews/PR128/man/guide/index.html +++ b/previews/PR128/man/guide/index.html @@ -1,2 +1,2 @@ -Guide · EpiAware.jl
          +Guide · EpiAware.jl
          diff --git a/previews/PR128/release-notes/index.html b/previews/PR128/release-notes/index.html index 9be075ff5..e68e89bf1 100644 --- a/previews/PR128/release-notes/index.html +++ b/previews/PR128/release-notes/index.html @@ -1,2 +1,2 @@ -Release notes · EpiAware.jl
          +Release notes · EpiAware.jl
          diff --git a/previews/PR128/search_index.js b/previews/PR128/search_index.js index 9f49cbb45..083e2c918 100644 --- a/previews/PR128/search_index.js +++ b/previews/PR128/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"checklist/#Checklists","page":"Release checklist","title":"Checklists","text":"","category":"section"},{"location":"checklist/","page":"Release checklist","title":"Release checklist","text":"The purpose of this page is to collate a series of checklists for commonly performed changes to the source code of EpiAware. It has been adapted from Documenter.jl.","category":"page"},{"location":"checklist/","page":"Release checklist","title":"Release checklist","text":"In each case, copy the checklist into the description of the pull request.","category":"page"},{"location":"checklist/#Making-a-release","page":"Release checklist","title":"Making a release","text":"","category":"section"},{"location":"checklist/","page":"Release checklist","title":"Release checklist","text":"In preparation for a release, use the following checklist. These steps should be performed on a branch with an open pull request, either for a topic branch, or for a new branch release-1.y.z (\"Release version 1.y.z\") if multiple changes have accumulated on the master branch since the last release.","category":"page"},{"location":"checklist/","page":"Release checklist","title":"Release checklist","text":"## Pre-release\n\n - [ ] Change the version number in `Project.toml`\n * If the release is breaking, increment MAJOR\n * If the release adds a new user-visible feature, increment MINOR\n * Otherwise (bug-fixes, documentation improvements), increment PATCH\n - [ ] Update `CHANGELOG.md`, following the existing style (in particular, make sure that the change log for this version has the correct version number and date).\n - [ ] Run `make changelog`, to make sure that all the issue references in `CHANGELOG.md` are up to date.\n - [ ] Check that the commit messages in this PR do not contain `[ci skip]`\n - [ ] Run https://github.com/JuliaDocs/Documenter.jl/actions/workflows/regression-tests.yml\n using a `workflow_dispatch` trigger to check for any changes that broke extensions.\n\n## The release\n\n - [ ] After merging the pull request, tag the release. There are two options for this:\n\n 1. [Comment `[at]JuliaRegistrator register` on the GitHub commit.](https://github.com/JuliaRegistries/Registrator.jl#via-the-github-app)\n 2. Use [JuliaHub's package registration feature](https://help.juliahub.com/juliahub/stable/contribute/#registrator) to trigger the registration.\n\n Either of those should automatically publish a new version to the Julia registry.\n - Once registered, the `TagBot.yml` workflow should create a tag, and rebuild the documentation for this tag.\n - These steps can take quite a bit of time (1 hour or more), so don't be surprised if the new documentation takes a while to appear.","category":"page"},{"location":"release-notes/","page":"Release notes","title":"Release notes","text":"EditURL = \"https://github.com/JuliaDocs/Documenter.jl/blob/master/CHANGELOG.md\"","category":"page"},{"location":"release-notes/#Release-notes","page":"Release notes","title":"Release notes","text":"","category":"section"},{"location":"release-notes/","page":"Release notes","title":"Release notes","text":"The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.","category":"page"},{"location":"release-notes/#Unreleased","page":"Release notes","title":"Unreleased","text":"","category":"section"},{"location":"release-notes/#Added","page":"Release notes","title":"Added","text":"","category":"section"},{"location":"release-notes/#Changed","page":"Release notes","title":"Changed","text":"","category":"section"},{"location":"release-notes/#Fixed","page":"Release notes","title":"Fixed","text":"","category":"section"},{"location":"lib/internals/#internal-Documentation","page":"Internals","title":"internal Documentation","text":"","category":"section"},{"location":"lib/internals/","page":"Internals","title":"Internals","text":"Documentation for EpiAware.jl's internal interface.","category":"page"},{"location":"lib/internals/#Contents","page":"Internals","title":"Contents","text":"","category":"section"},{"location":"lib/internals/","page":"Internals","title":"Internals","text":"Pages = [\"internal.md\"]\nDepth = 2:2","category":"page"},{"location":"lib/internals/#Index","page":"Internals","title":"Index","text":"","category":"section"},{"location":"lib/internals/","page":"Internals","title":"Internals","text":"Pages = [\"internals.md\"]","category":"page"},{"location":"lib/internals/#Internal-API","page":"Internals","title":"Internal API","text":"","category":"section"},{"location":"lib/internals/","page":"Internals","title":"Internals","text":"Modules = [EpiAware]\nPublic = false","category":"page"},{"location":"lib/internals/#EpiAware.NegativeBinomialMeanClust-Tuple{Any, Any}","page":"Internals","title":"EpiAware.NegativeBinomialMeanClust","text":"NegativeBinomialMeanClust NegativeBinomialMeanClust(μ, α)\n\nCompute the mean-cluster factor negative binomial distribution.\n\nArguments\n\nμ: The mean of the distribution.\nα: The clustering factor parameter.\n\nReturns\n\nA NegativeBinomial distribution object.\n\n\n\nSignatures\n\nNegativeBinomialMeanClust(\n μ,\n α\n) -> Distributions.NegativeBinomial\n\n\n\n\nMethods\n\nNegativeBinomialMeanClust(μ, α)\n\ndefined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/utilities.jl:210.\n\n\n\n\n\n","category":"method"},{"location":"lib/internals/#EpiAware._continue_manypathfinder!-Tuple{Any, DynamicPPL.Model}","page":"Internals","title":"EpiAware._continue_manypathfinder!","text":"continuemanypathfinder! Continue running the pathfinder algorithm until a pathfinder succeeds or the maximum number of tries is reached.\n\nArguments\n\npfs: An array of pathfinder objects.\nmdl::DynamicPPL.Model: The model to perform inference on.\nmax_tries: The maximum number of tries to run the pathfinder algorithm. Default is Inf.\nnruns: The number of times to run the pathfinder function.\nkwargs...: Additional keyword arguments passed to pathfinder.\n\nReturns\n\npfs: The updated array of pathfinder objects.\n\n\n\nSignatures\n\n_continue_manypathfinder!(\n pfs,\n mdl::DynamicPPL.Model;\n max_tries,\n nruns,\n kwargs...\n)\n\n\n\n\nMethods\n\n_continue_manypathfinder!(\n pfs,\n mdl;\n max_tries,\n nruns,\n kwargs...\n)\n\ndefined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/inference-methods.jl:42.\n\n\n\n\n\n","category":"method"},{"location":"lib/internals/#EpiAware._get_best_elbo_pathfinder-Tuple{Any}","page":"Internals","title":"EpiAware._get_best_elbo_pathfinder","text":"getbestelbopathfinder Selects the pathfinder with the highest ELBO estimate from a list of pathfinders.\n\nArguments\n\npfs: A list of pathfinders results or Symbol values indicating failure.\n\nReturns\n\nThe pathfinder with the highest ELBO estimate.\n\n\n\nSignatures\n\n_get_best_elbo_pathfinder(pfs) -> Any\n\n\n\n\nMethods\n\n_get_best_elbo_pathfinder(pfs)\n\ndefined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/inference-methods.jl:72.\n\n\n\n\n\n","category":"method"},{"location":"lib/internals/#EpiAware._run_manypathfinder-Tuple{DynamicPPL.Model}","page":"Internals","title":"EpiAware._run_manypathfinder","text":"runmanypathfinder\n\nRun pathfinder multiple times and store the results in an array. Fails safely.\n\nArguments\n\nmdl::DynamicPPL.Model: The Turing model to be used for inference.\nnruns: The number of times to run the pathfinder function.\nkwargs...: Additional keyword arguments passed to pathfinder.\n\nReturns\n\nAn array of PathfinderResult objects or Symbol values indicating success or failure.\n\n\n\nSignatures\n\n_run_manypathfinder(mdl::DynamicPPL.Model; nruns, kwargs...)\n\n\n\n\nMethods\n\n_run_manypathfinder(mdl; nruns, kwargs...)\n\ndefined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/inference-methods.jl:13.\n\n\n\n\n\n","category":"method"},{"location":"lib/internals/#EpiAware.generate_observation_kernel-Tuple{Any, Any}","page":"Internals","title":"EpiAware.generate_observation_kernel","text":"generateobservationkernel generateobservationkernel(delayint, timehorizon)\n\nGenerate an observation kernel matrix based on the given delay interval and time horizon.\n\nArguments\n\ndelay_int::Vector{Float64}: The delay PMF vector.\ntime_horizon::Int: The number of time steps of the observation period.\n\nReturns\n\nK::SparseMatrixCSC{Float64, Int}: The observation kernel matrix.\n\n\n\nSignatures\n\ngenerate_observation_kernel(delay_int, time_horizon) -> Any\n\n\n\n\nMethods\n\ngenerate_observation_kernel(delay_int, time_horizon)\n\ndefined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/utilities.jl:229.\n\n\n\n\n\n","category":"method"},{"location":"lib/internals/#EpiAware.neg_MGF-Tuple{Any, AbstractVector}","page":"Internals","title":"EpiAware.neg_MGF","text":"negMGF negMGF(r, w::AbstractVector)\n\nCompute the negative moment generating function (MGF) for a given rate r and weights w.\n\nArguments\n\nr: The rate parameter.\nw: An abstract vector of weights.\n\nReturns\n\nThe value of the negative MGF.\n\n\n\nSignatures\n\nneg_MGF(r, w::AbstractVector) -> Any\n\n\n\n\nMethods\n\nneg_MGF(r, w)\n\ndefined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/utilities.jl:132.\n\n\n\n\n\n","category":"method"},{"location":"contributing/#Contributing","page":"Contributing","title":"Contributing","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"This page details the some of the guidelines that should be followed when contributing to this package. It is adapted from Documenter.jl.","category":"page"},{"location":"contributing/#Branches","page":"Contributing","title":"Branches","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"release-* branches are used for tagged minor versions of this package. This follows the same approach used in the main Julia repository, albeit on a much more modest scale.","category":"page"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"Please open pull requests against the master branch rather than any of the release-* branches whenever possible.","category":"page"},{"location":"contributing/#Backports","page":"Contributing","title":"Backports","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"Bug fixes are backported to the release-* branches using git cherry-pick -x by a EpiAware member and will become available in point releases of that particular minor version of the package.","category":"page"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"Feel free to nominate commits that should be backported by opening an issue. Requests for new point releases to be tagged in METADATA.jl can also be made in the same way.","category":"page"},{"location":"contributing/#release-*-branches","page":"Contributing","title":"release-* branches","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"Each new minor version x.y.0 gets a branch called release-x.y (a protected branch).\nNew versions are usually tagged only from the release-x.y branches.\nFor patch releases, changes get backported to the release-x.y branch via a single PR with the standard name \"Backports for x.y.z\" and label \"Type: Backport\". The PR message links to all the PRs that are providing commits to the backport. The PR gets merged as a merge commit (i.e. not squashed).\nThe old release-* branches may be removed once they have outlived their usefulness.\nPatch version milestones are used to keep track of which PRs get backported etc.","category":"page"},{"location":"contributing/#Style-Guide","page":"Contributing","title":"Style Guide","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"Follow the style of the surrounding text when making changes. When adding new features please try to stick to the following points whenever applicable. This project follows the SciML style guide.","category":"page"},{"location":"contributing/#Tests","page":"Contributing","title":"Tests","text":"","category":"section"},{"location":"contributing/#Unit-tests","page":"Contributing","title":"Unit tests","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"As is conventional for Julia packages, unit tests are located at test/*.jl with the entrypoint test/runtests.jl.","category":"page"},{"location":"contributing/#End-to-end-testing","page":"Contributing","title":"End to end testing","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"Tests that build example package docs from source and inspect the results (end to end tests) are located in /test/examples. The main entry points are test/examples/make.jl for building and test/examples/test.jl for doing some basic checks on the generated outputs.","category":"page"},{"location":"examples/getting_started/","page":"Getting started","title":"Getting started","text":"\n\n\n\n\n\n\n\n\n\n\n

          Getting stated with EpiAware

          This tutorial introduces the basic functionality of EpiAware. EpiAware is a package for making inferences on epidemiological case/determined infection data using a model-based approach.

          \n\n\n

          EpiAware models

          The models we consider are discrete-time $t = 1,\\dots, T$ with a latent random process, $Z_t$ generating stochasticity in the number of new infections $I_t$ at each time step. Observations are treated as downstream random variables determined by the actual infections and a model of infection to observation delay.

          Mathematical definition

          $$\\begin{align}\nZ_\\cdot &\\sim \\mathcal{P}(\\mathbb{R}^T) | \\theta_Z, \\\\\nI_0 &\\sim f_0(\\theta_I), \\\\\nI_t &\\sim g_I(\\{I_s, Z_s\\}_{s < t}, \\theta_{I}), \\\\\ny_t &\\sim f_O(\\{I_s\\}_{s \\leq t}, \\theta_{O}).\n\\end{align}$$

          Where, $\\mathcal{P}(\\mathbb{R}^T) | \\theta_Z$ is a parametric process on $\\mathbb{R}^T$. $f_0$ and $f_O$ are parametric distributions on, respectively, the initial number of infections and the observed case data conditional on underlying infections. $g_I$ is distribution of new infections conditional on infections and latent process in the past. Note that we assume that new infections are conditional on the strict past, whereas new observations can depend on infections on the same time step.

          Code structure outline

          An EpiAware model in code is created from three modular components:

          Reproductive number

          EpiAware models do not need to specify a time-varying reproductive number $\\mathcal{R}_t$ to generate $I_\\cdot$, however, this is often a quantity of interest. When not directly used we will typically back-calculate $\\mathcal{R}_t$ from the generated infections:

          $$\\mathcal{R}_t = {I_t \\over \\sum_{s \\geq 1} g_s I_{t-s} }.$$

          Where $g_s$ is a discrete generation interval. For this reason, even when not using a reproductive number approach directly, we ask for a generation interval.

          \n\n\n

          Random walk LatentModel

          As an example, we choose the latent process as a random walk with parameters $\\theta_Z$:

          Conditional on the parameters the random walk is then generated by white noise:

          $$\\begin{align}\nZ_t &= Z_0 + \\sigma_{RW} \\sum_{t= 1}^T \\epsilon_t, \\\\\n\\epsilon_t &\\sim \\mathcal{N}(0,1).\n\\end{align}$$

          In EpiAware we provide a constructor for random walk latent models with priors for $\\theta_Z$. We choose priors,

          $$\\begin{align}\nZ_0 &\\sim \\mathcal{N}(0,1),\\\\\n\\sigma^2_Z &\\sim \\text{HalfNormal}(0.01).\n\\end{align}$$

          \n\n
          rwp = EpiAware.RandomWalk(Normal(),\n    truncated(Normal(0.0, 0.02), 0.0, 0.5))
          \n
          RandomWalk{Normal{Float64}, Truncated{Normal{Float64}, Continuous, Float64, Float64, Float64}}(Distributions.Normal{Float64}(μ=0.0, σ=1.0), Truncated(Distributions.Normal{Float64}(μ=0.0, σ=0.02); lower=0.0, upper=0.5))
          \n\n\n

          Direct infection EpiModel

          This is a simple model where the unobserved log-infections are directly generated by the latent process $Z$.

          $$\\log I_t = \\log I_0 + Z_t.$$

          As discussed above, we still ask for a defined generation interval, which can be used to calculate $\\mathcal{R}_t$.

          \n\n
          truth_GI = Gamma(2, 5)
          \n
          Distributions.Gamma{Float64}(α=2.0, θ=5.0)
          \n\n\n

          The EpiData constructor performs double interval censoring to convert our continuous estimate of the generation interval into a discretized version. We also implement right truncation using the keyword D_gen.

          \n\n
          model_data = EpiData(truth_GI, D_gen = 10.0)
          \n
          EpiData{Float64, typeof(exp)}([0.056722565637507084, 0.0944813112842689, 0.11668723746973605, 0.12773814268679387, 0.130948497124998, 0.1287976856448402, 0.12312384970427602, 0.11527489380975135, 0.10622581663782862], 9, exp)
          \n\n\n

          We can supply a prior for the initial log_infections.

          \n\n
          log_I0_prior = Normal(log(100.0), 1.0)
          \n
          Distributions.Normal{Float64}(μ=4.605170185988092, σ=1.0)
          \n\n\n

          And construct the EpiModel.

          \n\n
          epi_model = DirectInfections(model_data, log_I0_prior)
          \n
          DirectInfections{Normal{Float64}}(EpiData{Float64, typeof(exp)}([0.056722565637507084, 0.0944813112842689, 0.11668723746973605, 0.12773814268679387, 0.130948497124998, 0.1287976856448402, 0.12312384970427602, 0.11527489380975135, 0.10622581663782862], 9, exp), Distributions.Normal{Float64}(μ=4.605170185988092, σ=1.0))
          \n\n\n

          Delayed Observations ObservationModel

          The observation model is a negative binomial distribution with mean μ and cluster factor 1 / r. Delays are implemented as the action of a sparse kernel on the infections $I(t)$.

          $$\\begin{align}\ny_t &\\sim \\text{NegBinomial}(\\mu = \\sum_{s\\geq 0} K[t, t-s] I(s), r), \\\\\n1 / r &\\sim \\text{Gamma}(3, 0.05/3).\n\\end{align}$$

          \n\n\n

          We also set up the inference to occur over 100 days.

          \n\n
          time_horizon = 100
          \n
          100
          \n\n\n

          We choose a simple observation model where infections are observed 0, 1, 2, 3 days later with equal probability.

          \n\n
          obs_model = EpiAware.DelayObservations(\n    fill(0.25, 4),\n    time_horizon,\n    truncated(Gamma(5, 0.05 / 5), 1e-3, 0.2)\n)
          \n
          DelayObservations{Float64, Truncated{Gamma{Float64}, Continuous, Float64, Float64, Float64}}(sparse(Integer[1, 2, 3, 4, 2, 3, 4, 5, 3, 4  …  97, 98, 99, 100, 98, 99, 100, 99, 100, 100], Integer[1, 1, 1, 1, 2, 2, 2, 2, 3, 3  …  97, 97, 97, 97, 98, 98, 98, 99, 99, 100], [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25  …  0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25], 100, 100), Truncated(Distributions.Gamma{Float64}(α=5.0, θ=0.01); lower=0.001, upper=0.2))
          \n\n\n

          Generate cases from the EpiAware model

          Having chosen an EpiModel, LatentModel and ObservationModel, we can implement the model as a Turing model using make_epi_aware.

          By giving missing to the first argument, we indicate that case data will be generated from the model rather than treated as fixed.

          \n\n
          full_epi_aware_mdl = make_epi_aware(missing, time_horizon;\n    epi_model = epi_model,\n    latent_model = rwp,\n    observation_model = obs_model)
          \n
          Model{typeof(make_epi_aware), (:y_t, :time_steps), (:epi_model, :latent_model, :observation_model, :pos_shift), (:y_t,), Tuple{Missing, Int64}, Tuple{DirectInfections{Normal{Float64}}, RandomWalk{Normal{Float64}, Truncated{Normal{Float64}, Continuous, Float64, Float64, Float64}}, DelayObservations{Float64, Truncated{Gamma{Float64}, Continuous, Float64, Float64, Float64}}, Float64}, DefaultContext}(EpiAware.make_epi_aware, (y_t = missing, time_steps = 100), (epi_model = DirectInfections{Normal{Float64}}(EpiData{Float64, typeof(exp)}([0.056722565637507084, 0.0944813112842689, 0.11668723746973605, 0.12773814268679387, 0.130948497124998, 0.1287976856448402, 0.12312384970427602, 0.11527489380975135, 0.10622581663782862], 9, exp), Distributions.Normal{Float64}(μ=4.605170185988092, σ=1.0)), latent_model = RandomWalk{Normal{Float64}, Truncated{Normal{Float64}, Continuous, Float64, Float64, Float64}}(Distributions.Normal{Float64}(μ=0.0, σ=1.0), Truncated(Distributions.Normal{Float64}(μ=0.0, σ=0.02); lower=0.0, upper=0.5)), observation_model = DelayObservations{Float64, Truncated{Gamma{Float64}, Continuous, Float64, Float64, Float64}}(sparse(Integer[1, 2, 3, 4, 2, 3, 4, 5, 3, 4  …  97, 98, 99, 100, 98, 99, 100, 99, 100, 100], Integer[1, 1, 1, 1, 2, 2, 2, 2, 3, 3  …  97, 97, 97, 97, 98, 98, 98, 99, 99, 100], [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25  …  0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25], 100, 100), Truncated(Distributions.Gamma{Float64}(α=5.0, θ=0.01); lower=0.001, upper=0.2)), pos_shift = 1.0e-6), DefaultContext())
          \n\n\n

          We choose some fixed parameters:

          \n\n
          fixed_parameters = (rw_init = 0.0, init_incidence = log(100.0))
          \n
          (rw_init = 0.0, init_incidence = 4.605170185988092)
          \n\n\n

          We fix these parameters using fix, and generate a random epidemic.

          \n\n
          cond_generative_model = fix(full_epi_aware_mdl, fixed_parameters)
          \n
          Model{typeof(make_epi_aware), (:y_t, :time_steps), (:epi_model, :latent_model, :observation_model, :pos_shift), (:y_t,), Tuple{Missing, Int64}, Tuple{DirectInfections{Normal{Float64}}, RandomWalk{Normal{Float64}, Truncated{Normal{Float64}, Continuous, Float64, Float64, Float64}}, DelayObservations{Float64, Truncated{Gamma{Float64}, Continuous, Float64, Float64, Float64}}, Float64}, DynamicPPL.FixedContext{@NamedTuple{rw_init::Float64, init_incidence::Float64}, DefaultContext}}(EpiAware.make_epi_aware, (y_t = missing, time_steps = 100), (epi_model = DirectInfections{Normal{Float64}}(EpiData{Float64, typeof(exp)}([0.056722565637507084, 0.0944813112842689, 0.11668723746973605, 0.12773814268679387, 0.130948497124998, 0.1287976856448402, 0.12312384970427602, 0.11527489380975135, 0.10622581663782862], 9, exp), Distributions.Normal{Float64}(μ=4.605170185988092, σ=1.0)), latent_model = RandomWalk{Normal{Float64}, Truncated{Normal{Float64}, Continuous, Float64, Float64, Float64}}(Distributions.Normal{Float64}(μ=0.0, σ=1.0), Truncated(Distributions.Normal{Float64}(μ=0.0, σ=0.02); lower=0.0, upper=0.5)), observation_model = DelayObservations{Float64, Truncated{Gamma{Float64}, Continuous, Float64, Float64, Float64}}(sparse(Integer[1, 2, 3, 4, 2, 3, 4, 5, 3, 4  …  97, 98, 99, 100, 98, 99, 100, 99, 100, 100], Integer[1, 1, 1, 1, 2, 2, 2, 2, 3, 3  …  97, 97, 97, 97, 98, 98, 98, 99, 99, 100], [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25  …  0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25], 100, 100), Truncated(Distributions.Gamma{Float64}(α=5.0, θ=0.01); lower=0.001, upper=0.2)), pos_shift = 1.0e-6), FixedContext((rw_init = 0.0, init_incidence = 4.605170185988092), DynamicPPL.DefaultContext()))
          \n\n
          random_epidemic = rand(cond_generative_model)
          \n
          (ϵ_t = [0.06193274031408013, 0.2784058141640002, -0.5958244153640522, 0.04665938957338174, 1.0857940215432762, -1.5765649225859841, 0.1759399913010747, 0.8653808054093252, -2.790281005549307, -1.8920155582259128  …  0.6331957502904532, 0.747446113596017, -0.5200214906974596, -0.25155469243873996, 1.219317449444866, 1.0026816589160366, 0.972024394360624, 1.546409924955377, -0.5841980481085709, 0.46774878539798725], σ²_RW = 0.011688248379804358, neg_bin_cluster_factor = 0.045993428570571836, var\"y_t[1]\" = 23, var\"y_t[2]\" = 41, var\"y_t[3]\" = 78, var\"y_t[4]\" = 106, var\"y_t[5]\" = 111, var\"y_t[6]\" = 51, var\"y_t[7]\" = 131, var\"y_t[8]\" = 94, var\"y_t[9]\" = 114, var\"y_t[10]\" = 57, var\"y_t[11]\" = 82, var\"y_t[12]\" = 101, var\"y_t[13]\" = 62, var\"y_t[14]\" = 54, var\"y_t[15]\" = 25, var\"y_t[16]\" = 67, var\"y_t[17]\" = 41, var\"y_t[18]\" = 42, var\"y_t[19]\" = 62, var\"y_t[20]\" = 52, var\"y_t[21]\" = 40, var\"y_t[22]\" = 35, var\"y_t[23]\" = 27, var\"y_t[24]\" = 25, var\"y_t[25]\" = 37, var\"y_t[26]\" = 30, var\"y_t[27]\" = 35, var\"y_t[28]\" = 24, var\"y_t[29]\" = 34, var\"y_t[30]\" = 55, var\"y_t[31]\" = 47, var\"y_t[32]\" = 34, var\"y_t[33]\" = 42, var\"y_t[34]\" = 55, var\"y_t[35]\" = 54, var\"y_t[36]\" = 36, var\"y_t[37]\" = 37, var\"y_t[38]\" = 35, var\"y_t[39]\" = 48, var\"y_t[40]\" = 33, var\"y_t[41]\" = 19, var\"y_t[42]\" = 34, var\"y_t[43]\" = 23, var\"y_t[44]\" = 24, var\"y_t[45]\" = 27, var\"y_t[46]\" = 26, var\"y_t[47]\" = 33, var\"y_t[48]\" = 55, var\"y_t[49]\" = 50, var\"y_t[50]\" = 18, var\"y_t[51]\" = 41, var\"y_t[52]\" = 40, var\"y_t[53]\" = 30, var\"y_t[54]\" = 35, var\"y_t[55]\" = 32, var\"y_t[56]\" = 41, var\"y_t[57]\" = 14, var\"y_t[58]\" = 41, var\"y_t[59]\" = 50, var\"y_t[60]\" = 33, var\"y_t[61]\" = 30, var\"y_t[62]\" = 26, var\"y_t[63]\" = 37, var\"y_t[64]\" = 29, var\"y_t[65]\" = 57, var\"y_t[66]\" = 37, var\"y_t[67]\" = 73, var\"y_t[68]\" = 66, var\"y_t[69]\" = 25, var\"y_t[70]\" = 26, var\"y_t[71]\" = 53, var\"y_t[72]\" = 29, var\"y_t[73]\" = 34, var\"y_t[74]\" = 44, var\"y_t[75]\" = 36, var\"y_t[76]\" = 64, var\"y_t[77]\" = 46, var\"y_t[78]\" = 79, var\"y_t[79]\" = 49, var\"y_t[80]\" = 39, var\"y_t[81]\" = 46, var\"y_t[82]\" = 54, var\"y_t[83]\" = 62, var\"y_t[84]\" = 80, var\"y_t[85]\" = 51, var\"y_t[86]\" = 71, var\"y_t[87]\" = 97, var\"y_t[88]\" = 57, var\"y_t[89]\" = 63, var\"y_t[90]\" = 98, var\"y_t[91]\" = 87, var\"y_t[92]\" = 87, var\"y_t[93]\" = 72, var\"y_t[94]\" = 104, var\"y_t[95]\" = 67, var\"y_t[96]\" = 95, var\"y_t[97]\" = 111, var\"y_t[98]\" = 106, var\"y_t[99]\" = 131, var\"y_t[100]\" = 133)
          \n\n
          true_infections = generated_quantities(cond_generative_model, random_epidemic).I_t
          \n
          100-element Vector{Float64}:\n 100.67181511895441\n 103.74800570314704\n  97.27568364428603\n  97.76762565191419\n 109.94509222391163\n  92.71545442116756\n  94.49589865152171\n   ⋮\n  94.05911393711102\n 104.82848926439922\n 116.44432682511656\n 137.63414764968175\n 129.21014668216262\n 135.9122523877274
          \n\n
          generated_obs = generated_quantities(cond_generative_model, random_epidemic).generated_y_t
          \n
          100-element Vector{Int64}:\n  23\n  41\n  78\n 106\n 111\n  51\n 131\n   ⋮\n  67\n  95\n 111\n 106\n 131\n 133
          \n\n\n\n\n","category":"page"},{"location":"examples/getting_started/#Inference","page":"Getting started","title":"Inference","text":"","category":"section"},{"location":"examples/getting_started/","page":"Getting started","title":"Getting started","text":"
          \n

          Fixing $Z_0 = 0$ for the random walk was based on inference principles; in this model $Z_0$ and $\\log I_0$ are non-identifiable.

          However, we now treat the generated data as truth_data and make inference without fixing any other parameters.

          We do the inference by MCMC/NUTS using the Turing NUTS sampler with default warm-up steps.

          \n\n
          truth_data = generated_obs
          \n
          100-element Vector{Int64}:\n  23\n  41\n  78\n 106\n 111\n  51\n 131\n   ⋮\n  67\n  95\n 111\n 106\n 131\n 133
          \n\n
          inference_mdl = fix(\n    make_epi_aware(truth_data, time_horizon;\n        epi_model = epi_model,\n        latent_model = rwp,\n        observation_model = obs_model),\n    (rw_init = 0.0,)\n)
          \n
          Model{typeof(make_epi_aware), (:y_t, :time_steps), (:epi_model, :latent_model, :observation_model, :pos_shift), (), Tuple{Vector{Int64}, Int64}, Tuple{DirectInfections{Normal{Float64}}, RandomWalk{Normal{Float64}, Truncated{Normal{Float64}, Continuous, Float64, Float64, Float64}}, DelayObservations{Float64, Truncated{Gamma{Float64}, Continuous, Float64, Float64, Float64}}, Float64}, DynamicPPL.FixedContext{@NamedTuple{rw_init::Float64}, DefaultContext}}(EpiAware.make_epi_aware, (y_t = [23, 41, 78, 106, 111, 51, 131, 94, 114, 57  …  87, 87, 72, 104, 67, 95, 111, 106, 131, 133], time_steps = 100), (epi_model = DirectInfections{Normal{Float64}}(EpiData{Float64, typeof(exp)}([0.056722565637507084, 0.0944813112842689, 0.11668723746973605, 0.12773814268679387, 0.130948497124998, 0.1287976856448402, 0.12312384970427602, 0.11527489380975135, 0.10622581663782862], 9, exp), Distributions.Normal{Float64}(μ=4.605170185988092, σ=1.0)), latent_model = RandomWalk{Normal{Float64}, Truncated{Normal{Float64}, Continuous, Float64, Float64, Float64}}(Distributions.Normal{Float64}(μ=0.0, σ=1.0), Truncated(Distributions.Normal{Float64}(μ=0.0, σ=0.02); lower=0.0, upper=0.5)), observation_model = DelayObservations{Float64, Truncated{Gamma{Float64}, Continuous, Float64, Float64, Float64}}(sparse(Integer[1, 2, 3, 4, 2, 3, 4, 5, 3, 4  …  97, 98, 99, 100, 98, 99, 100, 99, 100, 100], Integer[1, 1, 1, 1, 2, 2, 2, 2, 3, 3  …  97, 97, 97, 97, 98, 98, 98, 99, 99, 100], [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25  …  0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25], 100, 100), Truncated(Distributions.Gamma{Float64}(α=5.0, θ=0.01); lower=0.001, upper=0.2)), pos_shift = 1.0e-6), FixedContext((rw_init = 0.0,), DynamicPPL.DefaultContext()))
          \n\n\n

          Initialising inference

          It is possible for the default warm-up process for NUTS to get stuck in low probability or otherwise degenerate regions of parameter space.

          To make NUTS more robust we provide manypathfinder, which is built on pathfinder variational inference from Pathfinder.jl. manypathfinder runs nruns pathfinder processes on the inference problem and returns the pathfinder run with maximum estimated ELBO.

          manypathfinder differs from Pathfinder.multipathfinder; multipathfinder is aimed at sampling from a potentially non-Gaussian target distribution which is first approximated as a uniformly weighted collection of normal approximations from pathfinder runs. manypathfinder is aimed at moving rapidly to a 'good' part of parameter space, and is robust to runs that fail.

          \n\n
          best_pf = manypathfinder(inference_mdl, 10; nruns = 20, executor = Transducers.ThreadedEx());
          \n\n\n\n

          We can use draws from the best pathfinder run to initialise NUTS.

          \n\n
          best_pf.draws_transformed
          \n
          iterationchainϵ_t[1]ϵ_t[2]ϵ_t[3]ϵ_t[4]ϵ_t[5]ϵ_t[6]...
          111-0.5144120.2152780.5903350.2397940.08614980.207969
          2210.175048-0.0220944-0.02002820.04072580.0310463-0.0428177
          3310.09032750.03484940.2828270.2393090.170582-0.139658
          4410.02286280.18310.1038940.1694070.0156059-0.133446
          5510.035848-0.0290472-0.2667810.1142220.07160660.0381202
          \n\n
          init_params = collect.(eachrow(best_pf.draws_transformed.value[1:4, :, 1]))
          \n
          4-element Vector{Vector{Float64}}:\n [-0.5144118124067896, 0.2152782113428215, 0.5903349691527211, 0.23979397988077622, 0.08614982980550409, 0.20796946509559994, -0.3903867127705256, -0.031059014249590677, -0.14995527247931853, -0.16244535432535046  …  0.061425336667904146, 0.01815311825284796, 0.29430315855864436, 0.4705235835897221, 0.790855766187655, 0.14404378027882073, 0.13370353699068532, 0.05856901084292262, 4.528786585706038, 0.01982303226146891]\n [0.17504799576770153, -0.02209444432244148, -0.02002823737606905, 0.040725822965111985, 0.031046347499243086, -0.042817722039409686, -0.10266435274540478, -0.3300313580334851, -0.24216722548064856, -0.32790554974512787  …  0.43007101479884213, 0.6907669705888795, 0.5511164195982637, 0.08633502877327975, 0.35581838375781943, -0.059632281807551285, 0.1045595275352122, 0.03387333974977781, 4.511037053680907, 0.027042599769282562]\n [0.09032747424872527, 0.034849440031800384, 0.2828270931903191, 0.23930911134742228, 0.17058211996835151, -0.13965761636751214, -0.2561325238265822, -0.2973356086161662, -0.3342723124114416, -0.5874018602763282  …  0.23741502405042764, 0.8682489439870135, 0.6848008339493292, 0.7290627956402452, 0.11708194959961493, 0.16903261721947005, 0.16653060634717645, 0.03605153934606213, 4.398407314279318, 0.027491732148055725]\n [0.022862818291666878, 0.18310039326444139, 0.10389356726393245, 0.16940749438834096, 0.015605906523095124, -0.13344623334715608, -0.18221945544950677, -0.19339612901623, -0.3758707816072445, -0.5293085682668266  …  0.5879921589285066, 0.21880141872883024, 0.5122949496467248, 0.48562059638880106, 0.15447654286932389, 0.29264316454368433, -0.10281980545168146, 0.04928524123732956, 4.573038829935848, 0.02839534879650567]
          \n\n\n

          NB: We are running this inference run for speed rather than accuracy as a demonstration. Use a higher target acceptance and more samples in a typical workflow.

          \n\n
          begin\n    target_acc_rate = 0.8\n    chn = sample(inference_mdl,\n        NUTS(target_acc_rate; adtype = AutoReverseDiff(true)),\n        MCMCThreads(),\n        250,\n        4;\n        init_params,\n        drop_warmup = true)\nend
          \n
          iterationchainϵ_t[1]ϵ_t[2]ϵ_t[3]ϵ_t[4]ϵ_t[5]ϵ_t[6]...
          112610.979711-0.773393-1.60955-0.096919-1.28560.283769
          212710.09156170.0456590.900820.1734830.0393357-0.565341
          312810.308018-0.153457-0.1754050.5024990.360626-0.512947
          41291-1.317560.2272061.1854-1.12723-0.706268-1.67822
          51301-0.166139-1.102481.968321.08574-1.53504-0.384448
          613110.17235-1.010041.55780.963792-1.36685-0.757544
          71321-0.0278682-0.740871.526351.13509-1.19339-0.82255
          813310.702821.497180.07904530.4098620.2084370.973433
          91341-0.707574-1.273180.12351-0.0613653-0.0174426-0.813638
          101351-0.694009-1.246760.3887980.100689-0.00853176-0.861363
          ...
          \n\n\n

          Predictive plotting

          We can spaghetti plot generated case data from the version of the model which hasn't conditioned on case data using posterior parameters inferred from the version conditioned on observed data. This is known as posterior predictive checking, and is a useful diagnostic tool for Bayesian inference (see here).

          Because we are using synthetic data we can also plot the model predictions for the unobserved infections and check that (at least in this example) we were able to capture some unobserved/latent variables in the process accurate.

          \n\n
          let\n    post_check_mdl = fix(full_epi_aware_mdl, (rw_init = 0.0,))\n    post_check_y_t = mapreduce(hcat, generated_quantities(post_check_mdl, chn)) do gen\n        gen.generated_y_t\n    end\n\n    predicted_I_t = mapreduce(hcat, generated_quantities(inference_mdl, chn)) do gen\n        gen.I_t\n    end\n\n    p1 = plot(post_check_y_t, c = :grey, alpha = 0.05, lab = \"\")\n    scatter!(p1, truth_data,\n        lab = \"Observed cases\",\n        xlabel = \"Time\",\n        ylabel = \"Cases\",\n        title = \"Post. predictive checking: cases\",\n        ylims = (-0.5, maximum(truth_data) * 1.5),\n        c = :green)\n\n    p2 = plot(predicted_I_t, c = :grey, alpha = 0.05, lab = \"\")\n    scatter!(p2, true_infections,\n        lab = \"Actual infections\",\n        xlabel = \"Time\",\n        ylabel = \"Unobserved Infections\",\n        title = \"Post. predictions: infections\",\n        ylims = (-0.5, maximum(true_infections) * 1.5),\n        c = :red)\n\n    plot(p1, p2,\n        layout = (1, 2),\n        size = (700, 400))\nend
          \n\n\n\n

          As well as checking the posterior predictions for latent infections, we can also check how well inference recovered unknown parameters, such as the random walk variance or the cluster factor of the negative binomial observations.

          \n\n
          let\n    parameters_to_plot = (:σ²_RW, :neg_bin_cluster_factor)\n\n    plts = map(parameters_to_plot) do name\n        var_samples = chn[name] |> vec\n        histogram(var_samples,\n            bins = 50,\n            norm = :pdf,\n            lw = 0,\n            fillalpha = 0.5,\n            lab = \"MCMC\")\n        vline!([getfield(random_epidemic, name)], lab = \"True value\")\n        title!(string(name))\n    end\n    plot(plts..., layout = (2, 1))\nend
          \n\n\n","category":"page"},{"location":"examples/getting_started/#Reproductive-number-back-calculation","page":"Getting started","title":"Reproductive number back-calculation","text":"","category":"section"},{"location":"examples/getting_started/","page":"Getting started","title":"Getting started","text":"
          \n

          As mentioned at the top, we don't directly use the concept of reproductive numbers in this note. However, we can back-calculate the implied $\\mathcal{R}(t)$ values, conditional on the specified generation interval being correct.

          Here we spaghetti plot posterior sampled time-varying reproductive numbers against the actual.

          \n\n
          let\n    n = epi_model.data.len_gen_int\n    Rt_denom = [dot(reverse(epi_model.data.gen_int), true_infections[(t - n):(t - 1)])\n                for t in (n + 1):length(true_infections)]\n    true_Rt = true_infections[(n + 1):end] ./ Rt_denom\n\n    predicted_Rt = mapreduce(hcat, generated_quantities(inference_mdl, chn)) do gen\n        _It = gen.I_t\n        _Rt_denom = [dot(reverse(epi_model.data.gen_int), _It[(t - n):(t - 1)])\n                     for t in (n + 1):length(_It)]\n        Rt = _It[(n + 1):end] ./ _Rt_denom\n    end\n\n    plt = plot((n + 1):time_horizon, predicted_Rt, c = :grey, alpha = 0.05, lab = \"\")\n    plot!(plt, (n + 1):time_horizon, true_Rt,\n        lab = \"true Rt\",\n        xlabel = \"Time\",\n        ylabel = \"Rt\",\n        title = \"Post. predictions: reproductive number\",\n        c = :red,\n        lw = 2)\nend
          \n\n\n","category":"page"},{"location":"examples/getting_started/","page":"Getting started","title":"Getting started","text":"EditURL = \"https://github.com/CDCgov/Rt-without-renewal/blob/main/docs/src/examples/getting_started.jl\"","category":"page"},{"location":"lib/public/#Public-Documentation","page":"Public API","title":"Public Documentation","text":"","category":"section"},{"location":"lib/public/","page":"Public API","title":"Public API","text":"Documentation for EpiAware.jl's public interface.","category":"page"},{"location":"lib/public/","page":"Public API","title":"Public API","text":"See the Internals section of the manual for internal package docs covering all submodules.","category":"page"},{"location":"lib/public/#Contents","page":"Public API","title":"Contents","text":"","category":"section"},{"location":"lib/public/","page":"Public API","title":"Public API","text":"Pages = [\"public.md\"]\nDepth = 2:2","category":"page"},{"location":"lib/public/#Index","page":"Public API","title":"Index","text":"","category":"section"},{"location":"lib/public/","page":"Public API","title":"Public API","text":"Pages = [\"public.md\"]","category":"page"},{"location":"lib/public/#Public-API","page":"Public API","title":"Public API","text":"","category":"section"},{"location":"#EpiAware.jl","page":"EpiAware.jl: Real-time epidemic monitoring","title":"EpiAware.jl","text":"","category":"section"},{"location":"","page":"EpiAware.jl: Real-time epidemic monitoring","title":"EpiAware.jl: Real-time epidemic monitoring","text":"Infectious disease situational awareness modelling toolkit for Julia.","category":"page"},{"location":"","page":"EpiAware.jl: Real-time epidemic monitoring","title":"EpiAware.jl: Real-time epidemic monitoring","text":"A package for building and fitting situational awareness models for infectious diseases. The package is designed to be flexible and extensible, and to provide a consistent interface for fitting and simulating models.","category":"page"},{"location":"#Package-Features","page":"EpiAware.jl: Real-time epidemic monitoring","title":"Package Features","text":"","category":"section"},{"location":"","page":"EpiAware.jl: Real-time epidemic monitoring","title":"EpiAware.jl: Real-time epidemic monitoring","text":"Flexible: The package is designed to be flexible and extensible, and to provide a consistent interface for fitting and simulating models.\nModular: The package is designed to be modular, with a clear separation between the model and the data.\nExtensible: The package is designed to be extensible, with a clear separation between the model and the data.\nConsistent: The package is designed to provide a consistent interface for fitting and simulating models.\nEfficient: The package is designed to be efficient, with a clear separation between the model and the data.","category":"page"},{"location":"","page":"EpiAware.jl: Real-time epidemic monitoring","title":"EpiAware.jl: Real-time epidemic monitoring","text":"See the Index for the complete list of documented functions and types.","category":"page"},{"location":"#Manual-Outline","page":"EpiAware.jl: Real-time epidemic monitoring","title":"Manual Outline","text":"","category":"section"},{"location":"","page":"EpiAware.jl: Real-time epidemic monitoring","title":"EpiAware.jl: Real-time epidemic monitoring","text":"Pages = [\n \"man/contributing.md\",\n]\nDepth = 1","category":"page"},{"location":"#Library-Outline","page":"EpiAware.jl: Real-time epidemic monitoring","title":"Library Outline","text":"","category":"section"},{"location":"","page":"EpiAware.jl: Real-time epidemic monitoring","title":"EpiAware.jl: Real-time epidemic monitoring","text":"Pages = [\"lib/public.md\", \"lib/internals.md\"]","category":"page"},{"location":"#main-index","page":"EpiAware.jl: Real-time epidemic monitoring","title":"Index","text":"","category":"section"},{"location":"","page":"EpiAware.jl: Real-time epidemic monitoring","title":"EpiAware.jl: Real-time epidemic monitoring","text":"Pages = [\"lib/public.md\"]","category":"page"}] +[{"location":"checklist/#Checklists","page":"Release checklist","title":"Checklists","text":"","category":"section"},{"location":"checklist/","page":"Release checklist","title":"Release checklist","text":"The purpose of this page is to collate a series of checklists for commonly performed changes to the source code of EpiAware. It has been adapted from Documenter.jl.","category":"page"},{"location":"checklist/","page":"Release checklist","title":"Release checklist","text":"In each case, copy the checklist into the description of the pull request.","category":"page"},{"location":"checklist/#Making-a-release","page":"Release checklist","title":"Making a release","text":"","category":"section"},{"location":"checklist/","page":"Release checklist","title":"Release checklist","text":"In preparation for a release, use the following checklist. These steps should be performed on a branch with an open pull request, either for a topic branch, or for a new branch release-1.y.z (\"Release version 1.y.z\") if multiple changes have accumulated on the master branch since the last release.","category":"page"},{"location":"checklist/","page":"Release checklist","title":"Release checklist","text":"## Pre-release\n\n - [ ] Change the version number in `Project.toml`\n * If the release is breaking, increment MAJOR\n * If the release adds a new user-visible feature, increment MINOR\n * Otherwise (bug-fixes, documentation improvements), increment PATCH\n - [ ] Update `CHANGELOG.md`, following the existing style (in particular, make sure that the change log for this version has the correct version number and date).\n - [ ] Run `make changelog`, to make sure that all the issue references in `CHANGELOG.md` are up to date.\n - [ ] Check that the commit messages in this PR do not contain `[ci skip]`\n - [ ] Run https://github.com/JuliaDocs/Documenter.jl/actions/workflows/regression-tests.yml\n using a `workflow_dispatch` trigger to check for any changes that broke extensions.\n\n## The release\n\n - [ ] After merging the pull request, tag the release. There are two options for this:\n\n 1. [Comment `[at]JuliaRegistrator register` on the GitHub commit.](https://github.com/JuliaRegistries/Registrator.jl#via-the-github-app)\n 2. Use [JuliaHub's package registration feature](https://help.juliahub.com/juliahub/stable/contribute/#registrator) to trigger the registration.\n\n Either of those should automatically publish a new version to the Julia registry.\n - Once registered, the `TagBot.yml` workflow should create a tag, and rebuild the documentation for this tag.\n - These steps can take quite a bit of time (1 hour or more), so don't be surprised if the new documentation takes a while to appear.","category":"page"},{"location":"release-notes/","page":"Release notes","title":"Release notes","text":"EditURL = \"https://github.com/JuliaDocs/Documenter.jl/blob/master/CHANGELOG.md\"","category":"page"},{"location":"release-notes/#Release-notes","page":"Release notes","title":"Release notes","text":"","category":"section"},{"location":"release-notes/","page":"Release notes","title":"Release notes","text":"The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.","category":"page"},{"location":"release-notes/#Unreleased","page":"Release notes","title":"Unreleased","text":"","category":"section"},{"location":"release-notes/#Added","page":"Release notes","title":"Added","text":"","category":"section"},{"location":"release-notes/#Changed","page":"Release notes","title":"Changed","text":"","category":"section"},{"location":"release-notes/#Fixed","page":"Release notes","title":"Fixed","text":"","category":"section"},{"location":"lib/internals/#internal-Documentation","page":"Internals","title":"internal Documentation","text":"","category":"section"},{"location":"lib/internals/","page":"Internals","title":"Internals","text":"Documentation for EpiAware.jl's internal interface.","category":"page"},{"location":"lib/internals/#Contents","page":"Internals","title":"Contents","text":"","category":"section"},{"location":"lib/internals/","page":"Internals","title":"Internals","text":"Pages = [\"internal.md\"]\nDepth = 2:2","category":"page"},{"location":"lib/internals/#Index","page":"Internals","title":"Index","text":"","category":"section"},{"location":"lib/internals/","page":"Internals","title":"Internals","text":"Pages = [\"internals.md\"]","category":"page"},{"location":"lib/internals/#Internal-API","page":"Internals","title":"Internal API","text":"","category":"section"},{"location":"lib/internals/","page":"Internals","title":"Internals","text":"Modules = [EpiAware]\nPublic = false","category":"page"},{"location":"lib/internals/#EpiAware.NegativeBinomialMeanClust-Tuple{Any, Any}","page":"Internals","title":"EpiAware.NegativeBinomialMeanClust","text":"NegativeBinomialMeanClust NegativeBinomialMeanClust(μ, α)\n\nCompute the mean-cluster factor negative binomial distribution.\n\nArguments\n\nμ: The mean of the distribution.\nα: The clustering factor parameter.\n\nReturns\n\nA NegativeBinomial distribution object.\n\n\n\nSignatures\n\nNegativeBinomialMeanClust(\n μ,\n α\n) -> Distributions.NegativeBinomial\n\n\n\n\nMethods\n\nNegativeBinomialMeanClust(μ, α)\n\ndefined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/utilities.jl:210.\n\n\n\n\n\n","category":"method"},{"location":"lib/internals/#EpiAware._continue_manypathfinder!-Tuple{Any, DynamicPPL.Model}","page":"Internals","title":"EpiAware._continue_manypathfinder!","text":"continuemanypathfinder! Continue running the pathfinder algorithm until a pathfinder succeeds or the maximum number of tries is reached.\n\nArguments\n\npfs: An array of pathfinder objects.\nmdl::DynamicPPL.Model: The model to perform inference on.\nmax_tries: The maximum number of tries to run the pathfinder algorithm. Default is Inf.\nnruns: The number of times to run the pathfinder function.\nkwargs...: Additional keyword arguments passed to pathfinder.\n\nReturns\n\npfs: The updated array of pathfinder objects.\n\n\n\nSignatures\n\n_continue_manypathfinder!(\n pfs,\n mdl::DynamicPPL.Model;\n max_tries,\n nruns,\n kwargs...\n)\n\n\n\n\nMethods\n\n_continue_manypathfinder!(\n pfs,\n mdl;\n max_tries,\n nruns,\n kwargs...\n)\n\ndefined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/inference-methods.jl:42.\n\n\n\n\n\n","category":"method"},{"location":"lib/internals/#EpiAware._get_best_elbo_pathfinder-Tuple{Any}","page":"Internals","title":"EpiAware._get_best_elbo_pathfinder","text":"getbestelbopathfinder Selects the pathfinder with the highest ELBO estimate from a list of pathfinders.\n\nArguments\n\npfs: A list of pathfinders results or Symbol values indicating failure.\n\nReturns\n\nThe pathfinder with the highest ELBO estimate.\n\n\n\nSignatures\n\n_get_best_elbo_pathfinder(pfs) -> Any\n\n\n\n\nMethods\n\n_get_best_elbo_pathfinder(pfs)\n\ndefined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/inference-methods.jl:72.\n\n\n\n\n\n","category":"method"},{"location":"lib/internals/#EpiAware._run_manypathfinder-Tuple{DynamicPPL.Model}","page":"Internals","title":"EpiAware._run_manypathfinder","text":"runmanypathfinder\n\nRun pathfinder multiple times and store the results in an array. Fails safely.\n\nArguments\n\nmdl::DynamicPPL.Model: The Turing model to be used for inference.\nnruns: The number of times to run the pathfinder function.\nkwargs...: Additional keyword arguments passed to pathfinder.\n\nReturns\n\nAn array of PathfinderResult objects or Symbol values indicating success or failure.\n\n\n\nSignatures\n\n_run_manypathfinder(mdl::DynamicPPL.Model; nruns, kwargs...)\n\n\n\n\nMethods\n\n_run_manypathfinder(mdl; nruns, kwargs...)\n\ndefined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/inference-methods.jl:13.\n\n\n\n\n\n","category":"method"},{"location":"lib/internals/#EpiAware.generate_observation_kernel-Tuple{Any, Any}","page":"Internals","title":"EpiAware.generate_observation_kernel","text":"generateobservationkernel generateobservationkernel(delayint, timehorizon)\n\nGenerate an observation kernel matrix based on the given delay interval and time horizon.\n\nArguments\n\ndelay_int::Vector{Float64}: The delay PMF vector.\ntime_horizon::Int: The number of time steps of the observation period.\n\nReturns\n\nK::SparseMatrixCSC{Float64, Int}: The observation kernel matrix.\n\n\n\nSignatures\n\ngenerate_observation_kernel(delay_int, time_horizon) -> Any\n\n\n\n\nMethods\n\ngenerate_observation_kernel(delay_int, time_horizon)\n\ndefined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/utilities.jl:229.\n\n\n\n\n\n","category":"method"},{"location":"lib/internals/#EpiAware.neg_MGF-Tuple{Any, AbstractVector}","page":"Internals","title":"EpiAware.neg_MGF","text":"negMGF negMGF(r, w::AbstractVector)\n\nCompute the negative moment generating function (MGF) for a given rate r and weights w.\n\nArguments\n\nr: The rate parameter.\nw: An abstract vector of weights.\n\nReturns\n\nThe value of the negative MGF.\n\n\n\nSignatures\n\nneg_MGF(r, w::AbstractVector) -> Any\n\n\n\n\nMethods\n\nneg_MGF(r, w)\n\ndefined at /home/runner/work/Rt-without-renewal/Rt-without-renewal/src/utilities.jl:132.\n\n\n\n\n\n","category":"method"},{"location":"contributing/#Contributing","page":"Contributing","title":"Contributing","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"This page details the some of the guidelines that should be followed when contributing to this package. It is adapted from Documenter.jl.","category":"page"},{"location":"contributing/#Branches","page":"Contributing","title":"Branches","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"release-* branches are used for tagged minor versions of this package. This follows the same approach used in the main Julia repository, albeit on a much more modest scale.","category":"page"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"Please open pull requests against the master branch rather than any of the release-* branches whenever possible.","category":"page"},{"location":"contributing/#Backports","page":"Contributing","title":"Backports","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"Bug fixes are backported to the release-* branches using git cherry-pick -x by a EpiAware member and will become available in point releases of that particular minor version of the package.","category":"page"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"Feel free to nominate commits that should be backported by opening an issue. Requests for new point releases to be tagged in METADATA.jl can also be made in the same way.","category":"page"},{"location":"contributing/#release-*-branches","page":"Contributing","title":"release-* branches","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"Each new minor version x.y.0 gets a branch called release-x.y (a protected branch).\nNew versions are usually tagged only from the release-x.y branches.\nFor patch releases, changes get backported to the release-x.y branch via a single PR with the standard name \"Backports for x.y.z\" and label \"Type: Backport\". The PR message links to all the PRs that are providing commits to the backport. The PR gets merged as a merge commit (i.e. not squashed).\nThe old release-* branches may be removed once they have outlived their usefulness.\nPatch version milestones are used to keep track of which PRs get backported etc.","category":"page"},{"location":"contributing/#Style-Guide","page":"Contributing","title":"Style Guide","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"Follow the style of the surrounding text when making changes. When adding new features please try to stick to the following points whenever applicable. This project follows the SciML style guide.","category":"page"},{"location":"contributing/#Tests","page":"Contributing","title":"Tests","text":"","category":"section"},{"location":"contributing/#Unit-tests","page":"Contributing","title":"Unit tests","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"As is conventional for Julia packages, unit tests are located at test/*.jl with the entrypoint test/runtests.jl.","category":"page"},{"location":"contributing/#End-to-end-testing","page":"Contributing","title":"End to end testing","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"Tests that build example package docs from source and inspect the results (end to end tests) are located in /test/examples. The main entry points are test/examples/make.jl for building and test/examples/test.jl for doing some basic checks on the generated outputs.","category":"page"},{"location":"examples/getting_started/","page":"Getting started","title":"Getting started","text":"\n\n\n\n\n\n\n\n\n\n\n

          Getting stated with EpiAware

          This tutorial introduces the basic functionality of EpiAware. EpiAware is a package for making inferences on epidemiological case/determined infection data using a model-based approach.

          \n\n\n

          EpiAware models

          The models we consider are discrete-time $t = 1,\\dots, T$ with a latent random process, $Z_t$ generating stochasticity in the number of new infections $I_t$ at each time step. Observations are treated as downstream random variables determined by the actual infections and a model of infection to observation delay.

          Mathematical definition

          $$\\begin{align}\nZ_\\cdot &\\sim \\mathcal{P}(\\mathbb{R}^T) | \\theta_Z, \\\\\nI_0 &\\sim f_0(\\theta_I), \\\\\nI_t &\\sim g_I(\\{I_s, Z_s\\}_{s < t}, \\theta_{I}), \\\\\ny_t &\\sim f_O(\\{I_s\\}_{s \\leq t}, \\theta_{O}).\n\\end{align}$$

          Where, $\\mathcal{P}(\\mathbb{R}^T) | \\theta_Z$ is a parametric process on $\\mathbb{R}^T$. $f_0$ and $f_O$ are parametric distributions on, respectively, the initial number of infections and the observed case data conditional on underlying infections. $g_I$ is distribution of new infections conditional on infections and latent process in the past. Note that we assume that new infections are conditional on the strict past, whereas new observations can depend on infections on the same time step.

          Code structure outline

          An EpiAware model in code is created from three modular components:

          Reproductive number

          EpiAware models do not need to specify a time-varying reproductive number $\\mathcal{R}_t$ to generate $I_\\cdot$, however, this is often a quantity of interest. When not directly used we will typically back-calculate $\\mathcal{R}_t$ from the generated infections:

          $$\\mathcal{R}_t = {I_t \\over \\sum_{s \\geq 1} g_s I_{t-s} }.$$

          Where $g_s$ is a discrete generation interval. For this reason, even when not using a reproductive number approach directly, we ask for a generation interval.

          \n\n\n

          Random walk LatentModel

          As an example, we choose the latent process as a random walk with parameters $\\theta_Z$:

          Conditional on the parameters the random walk is then generated by white noise:

          $$\\begin{align}\nZ_t &= Z_0 + \\sigma_{RW} \\sum_{t= 1}^T \\epsilon_t, \\\\\n\\epsilon_t &\\sim \\mathcal{N}(0,1).\n\\end{align}$$

          In EpiAware we provide a constructor for random walk latent models with priors for $\\theta_Z$. We choose priors,

          $$\\begin{align}\nZ_0 &\\sim \\mathcal{N}(0,1),\\\\\n\\sigma^2_Z &\\sim \\text{HalfNormal}(0.01).\n\\end{align}$$

          \n\n
          rwp = EpiAware.RandomWalk(Normal(),\n    truncated(Normal(0.0, 0.02), 0.0, 0.5))
          \n
          RandomWalk{Normal{Float64}, Truncated{Normal{Float64}, Continuous, Float64, Float64, Float64}}(Distributions.Normal{Float64}(μ=0.0, σ=1.0), Truncated(Distributions.Normal{Float64}(μ=0.0, σ=0.02); lower=0.0, upper=0.5))
          \n\n\n

          Direct infection EpiModel

          This is a simple model where the unobserved log-infections are directly generated by the latent process $Z$.

          $$\\log I_t = \\log I_0 + Z_t.$$

          As discussed above, we still ask for a defined generation interval, which can be used to calculate $\\mathcal{R}_t$.

          \n\n
          truth_GI = Gamma(2, 5)
          \n
          Distributions.Gamma{Float64}(α=2.0, θ=5.0)
          \n\n\n

          The EpiData constructor performs double interval censoring to convert our continuous estimate of the generation interval into a discretized version. We also implement right truncation using the keyword D_gen.

          \n\n
          model_data = EpiData(truth_GI, D_gen = 10.0)
          \n
          EpiData{Float64, typeof(exp)}([0.056722565637507084, 0.0944813112842689, 0.11668723746973605, 0.12773814268679387, 0.130948497124998, 0.1287976856448402, 0.12312384970427602, 0.11527489380975135, 0.10622581663782862], 9, exp)
          \n\n\n

          We can supply a prior for the initial log_infections.

          \n\n
          log_I0_prior = Normal(log(100.0), 1.0)
          \n
          Distributions.Normal{Float64}(μ=4.605170185988092, σ=1.0)
          \n\n\n

          And construct the EpiModel.

          \n\n
          epi_model = DirectInfections(model_data, log_I0_prior)
          \n
          DirectInfections{Normal{Float64}}(EpiData{Float64, typeof(exp)}([0.056722565637507084, 0.0944813112842689, 0.11668723746973605, 0.12773814268679387, 0.130948497124998, 0.1287976856448402, 0.12312384970427602, 0.11527489380975135, 0.10622581663782862], 9, exp), Distributions.Normal{Float64}(μ=4.605170185988092, σ=1.0))
          \n\n\n

          Delayed Observations ObservationModel

          The observation model is a negative binomial distribution with mean μ and cluster factor 1 / r. Delays are implemented as the action of a sparse kernel on the infections $I(t)$.

          $$\\begin{align}\ny_t &\\sim \\text{NegBinomial}(\\mu = \\sum_{s\\geq 0} K[t, t-s] I(s), r), \\\\\n1 / r &\\sim \\text{Gamma}(3, 0.05/3).\n\\end{align}$$

          \n\n\n

          We also set up the inference to occur over 100 days.

          \n\n
          time_horizon = 100
          \n
          100
          \n\n\n

          We choose a simple observation model where infections are observed 0, 1, 2, 3 days later with equal probability.

          \n\n
          obs_model = EpiAware.DelayObservations(\n    fill(0.25, 4),\n    time_horizon,\n    truncated(Gamma(5, 0.05 / 5), 1e-3, 0.2)\n)
          \n
          DelayObservations{Float64, Truncated{Gamma{Float64}, Continuous, Float64, Float64, Float64}}(sparse(Integer[1, 2, 3, 4, 2, 3, 4, 5, 3, 4  …  97, 98, 99, 100, 98, 99, 100, 99, 100, 100], Integer[1, 1, 1, 1, 2, 2, 2, 2, 3, 3  …  97, 97, 97, 97, 98, 98, 98, 99, 99, 100], [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25  …  0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25], 100, 100), Truncated(Distributions.Gamma{Float64}(α=5.0, θ=0.01); lower=0.001, upper=0.2))
          \n\n\n

          Generate cases from the EpiAware model

          Having chosen an EpiModel, LatentModel and ObservationModel, we can implement the model as a Turing model using make_epi_aware.

          By giving missing to the first argument, we indicate that case data will be generated from the model rather than treated as fixed.

          \n\n
          full_epi_aware_mdl = make_epi_aware(missing, time_horizon;\n    epi_model = epi_model,\n    latent_model = rwp,\n    observation_model = obs_model)
          \n
          Model{typeof(make_epi_aware), (:y_t, :time_steps), (:epi_model, :latent_model, :observation_model, :pos_shift), (:y_t,), Tuple{Missing, Int64}, Tuple{DirectInfections{Normal{Float64}}, RandomWalk{Normal{Float64}, Truncated{Normal{Float64}, Continuous, Float64, Float64, Float64}}, DelayObservations{Float64, Truncated{Gamma{Float64}, Continuous, Float64, Float64, Float64}}, Float64}, DefaultContext}(EpiAware.make_epi_aware, (y_t = missing, time_steps = 100), (epi_model = DirectInfections{Normal{Float64}}(EpiData{Float64, typeof(exp)}([0.056722565637507084, 0.0944813112842689, 0.11668723746973605, 0.12773814268679387, 0.130948497124998, 0.1287976856448402, 0.12312384970427602, 0.11527489380975135, 0.10622581663782862], 9, exp), Distributions.Normal{Float64}(μ=4.605170185988092, σ=1.0)), latent_model = RandomWalk{Normal{Float64}, Truncated{Normal{Float64}, Continuous, Float64, Float64, Float64}}(Distributions.Normal{Float64}(μ=0.0, σ=1.0), Truncated(Distributions.Normal{Float64}(μ=0.0, σ=0.02); lower=0.0, upper=0.5)), observation_model = DelayObservations{Float64, Truncated{Gamma{Float64}, Continuous, Float64, Float64, Float64}}(sparse(Integer[1, 2, 3, 4, 2, 3, 4, 5, 3, 4  …  97, 98, 99, 100, 98, 99, 100, 99, 100, 100], Integer[1, 1, 1, 1, 2, 2, 2, 2, 3, 3  …  97, 97, 97, 97, 98, 98, 98, 99, 99, 100], [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25  …  0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25], 100, 100), Truncated(Distributions.Gamma{Float64}(α=5.0, θ=0.01); lower=0.001, upper=0.2)), pos_shift = 1.0e-6), DefaultContext())
          \n\n\n

          We choose some fixed parameters:

          \n\n
          fixed_parameters = (rw_init = 0.0, init_incidence = log(100.0))
          \n
          (rw_init = 0.0, init_incidence = 4.605170185988092)
          \n\n\n

          We fix these parameters using fix, and generate a random epidemic.

          \n\n
          cond_generative_model = fix(full_epi_aware_mdl, fixed_parameters)
          \n
          Model{typeof(make_epi_aware), (:y_t, :time_steps), (:epi_model, :latent_model, :observation_model, :pos_shift), (:y_t,), Tuple{Missing, Int64}, Tuple{DirectInfections{Normal{Float64}}, RandomWalk{Normal{Float64}, Truncated{Normal{Float64}, Continuous, Float64, Float64, Float64}}, DelayObservations{Float64, Truncated{Gamma{Float64}, Continuous, Float64, Float64, Float64}}, Float64}, DynamicPPL.FixedContext{@NamedTuple{rw_init::Float64, init_incidence::Float64}, DefaultContext}}(EpiAware.make_epi_aware, (y_t = missing, time_steps = 100), (epi_model = DirectInfections{Normal{Float64}}(EpiData{Float64, typeof(exp)}([0.056722565637507084, 0.0944813112842689, 0.11668723746973605, 0.12773814268679387, 0.130948497124998, 0.1287976856448402, 0.12312384970427602, 0.11527489380975135, 0.10622581663782862], 9, exp), Distributions.Normal{Float64}(μ=4.605170185988092, σ=1.0)), latent_model = RandomWalk{Normal{Float64}, Truncated{Normal{Float64}, Continuous, Float64, Float64, Float64}}(Distributions.Normal{Float64}(μ=0.0, σ=1.0), Truncated(Distributions.Normal{Float64}(μ=0.0, σ=0.02); lower=0.0, upper=0.5)), observation_model = DelayObservations{Float64, Truncated{Gamma{Float64}, Continuous, Float64, Float64, Float64}}(sparse(Integer[1, 2, 3, 4, 2, 3, 4, 5, 3, 4  …  97, 98, 99, 100, 98, 99, 100, 99, 100, 100], Integer[1, 1, 1, 1, 2, 2, 2, 2, 3, 3  …  97, 97, 97, 97, 98, 98, 98, 99, 99, 100], [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25  …  0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25], 100, 100), Truncated(Distributions.Gamma{Float64}(α=5.0, θ=0.01); lower=0.001, upper=0.2)), pos_shift = 1.0e-6), FixedContext((rw_init = 0.0, init_incidence = 4.605170185988092), DynamicPPL.DefaultContext()))
          \n\n
          random_epidemic = rand(cond_generative_model)
          \n
          (ϵ_t = [0.06193274031408013, 0.2784058141640002, -0.5958244153640522, 0.04665938957338174, 1.0857940215432762, -1.5765649225859841, 0.1759399913010747, 0.8653808054093252, -2.790281005549307, -1.8920155582259128  …  0.6331957502904532, 0.747446113596017, -0.5200214906974596, -0.25155469243873996, 1.219317449444866, 1.0026816589160366, 0.972024394360624, 1.546409924955377, -0.5841980481085709, 0.46774878539798725], σ²_RW = 0.011688248379804358, neg_bin_cluster_factor = 0.045993428570571836, var\"y_t[1]\" = 23, var\"y_t[2]\" = 41, var\"y_t[3]\" = 78, var\"y_t[4]\" = 106, var\"y_t[5]\" = 111, var\"y_t[6]\" = 51, var\"y_t[7]\" = 131, var\"y_t[8]\" = 94, var\"y_t[9]\" = 114, var\"y_t[10]\" = 57, var\"y_t[11]\" = 82, var\"y_t[12]\" = 101, var\"y_t[13]\" = 62, var\"y_t[14]\" = 54, var\"y_t[15]\" = 25, var\"y_t[16]\" = 67, var\"y_t[17]\" = 41, var\"y_t[18]\" = 42, var\"y_t[19]\" = 62, var\"y_t[20]\" = 52, var\"y_t[21]\" = 40, var\"y_t[22]\" = 35, var\"y_t[23]\" = 27, var\"y_t[24]\" = 25, var\"y_t[25]\" = 37, var\"y_t[26]\" = 30, var\"y_t[27]\" = 35, var\"y_t[28]\" = 24, var\"y_t[29]\" = 34, var\"y_t[30]\" = 55, var\"y_t[31]\" = 47, var\"y_t[32]\" = 34, var\"y_t[33]\" = 42, var\"y_t[34]\" = 55, var\"y_t[35]\" = 54, var\"y_t[36]\" = 36, var\"y_t[37]\" = 37, var\"y_t[38]\" = 35, var\"y_t[39]\" = 48, var\"y_t[40]\" = 33, var\"y_t[41]\" = 19, var\"y_t[42]\" = 34, var\"y_t[43]\" = 23, var\"y_t[44]\" = 24, var\"y_t[45]\" = 27, var\"y_t[46]\" = 26, var\"y_t[47]\" = 33, var\"y_t[48]\" = 55, var\"y_t[49]\" = 50, var\"y_t[50]\" = 18, var\"y_t[51]\" = 41, var\"y_t[52]\" = 40, var\"y_t[53]\" = 30, var\"y_t[54]\" = 35, var\"y_t[55]\" = 32, var\"y_t[56]\" = 41, var\"y_t[57]\" = 14, var\"y_t[58]\" = 41, var\"y_t[59]\" = 50, var\"y_t[60]\" = 33, var\"y_t[61]\" = 30, var\"y_t[62]\" = 26, var\"y_t[63]\" = 37, var\"y_t[64]\" = 29, var\"y_t[65]\" = 57, var\"y_t[66]\" = 37, var\"y_t[67]\" = 73, var\"y_t[68]\" = 66, var\"y_t[69]\" = 25, var\"y_t[70]\" = 26, var\"y_t[71]\" = 53, var\"y_t[72]\" = 29, var\"y_t[73]\" = 34, var\"y_t[74]\" = 44, var\"y_t[75]\" = 36, var\"y_t[76]\" = 64, var\"y_t[77]\" = 46, var\"y_t[78]\" = 79, var\"y_t[79]\" = 49, var\"y_t[80]\" = 39, var\"y_t[81]\" = 46, var\"y_t[82]\" = 54, var\"y_t[83]\" = 62, var\"y_t[84]\" = 80, var\"y_t[85]\" = 51, var\"y_t[86]\" = 71, var\"y_t[87]\" = 97, var\"y_t[88]\" = 57, var\"y_t[89]\" = 63, var\"y_t[90]\" = 98, var\"y_t[91]\" = 87, var\"y_t[92]\" = 87, var\"y_t[93]\" = 72, var\"y_t[94]\" = 104, var\"y_t[95]\" = 67, var\"y_t[96]\" = 95, var\"y_t[97]\" = 111, var\"y_t[98]\" = 106, var\"y_t[99]\" = 131, var\"y_t[100]\" = 133)
          \n\n
          true_infections = generated_quantities(cond_generative_model, random_epidemic).I_t
          \n
          100-element Vector{Float64}:\n 100.67181511895441\n 103.74800570314704\n  97.27568364428603\n  97.76762565191419\n 109.94509222391163\n  92.71545442116756\n  94.49589865152171\n   ⋮\n  94.05911393711102\n 104.82848926439922\n 116.44432682511656\n 137.63414764968175\n 129.21014668216262\n 135.9122523877274
          \n\n
          generated_obs = generated_quantities(cond_generative_model, random_epidemic).generated_y_t
          \n
          100-element Vector{Int64}:\n  23\n  41\n  78\n 106\n 111\n  51\n 131\n   ⋮\n  67\n  95\n 111\n 106\n 131\n 133
          \n\n\n\n\n","category":"page"},{"location":"examples/getting_started/#Inference","page":"Getting started","title":"Inference","text":"","category":"section"},{"location":"examples/getting_started/","page":"Getting started","title":"Getting started","text":"
          \n

          Fixing $Z_0 = 0$ for the random walk was based on inference principles; in this model $Z_0$ and $\\log I_0$ are non-identifiable.

          However, we now treat the generated data as truth_data and make inference without fixing any other parameters.

          We do the inference by MCMC/NUTS using the Turing NUTS sampler with default warm-up steps.

          \n\n
          truth_data = generated_obs
          \n
          100-element Vector{Int64}:\n  23\n  41\n  78\n 106\n 111\n  51\n 131\n   ⋮\n  67\n  95\n 111\n 106\n 131\n 133
          \n\n
          inference_mdl = fix(\n    make_epi_aware(truth_data, time_horizon;\n        epi_model = epi_model,\n        latent_model = rwp,\n        observation_model = obs_model),\n    (rw_init = 0.0,)\n)
          \n
          Model{typeof(make_epi_aware), (:y_t, :time_steps), (:epi_model, :latent_model, :observation_model, :pos_shift), (), Tuple{Vector{Int64}, Int64}, Tuple{DirectInfections{Normal{Float64}}, RandomWalk{Normal{Float64}, Truncated{Normal{Float64}, Continuous, Float64, Float64, Float64}}, DelayObservations{Float64, Truncated{Gamma{Float64}, Continuous, Float64, Float64, Float64}}, Float64}, DynamicPPL.FixedContext{@NamedTuple{rw_init::Float64}, DefaultContext}}(EpiAware.make_epi_aware, (y_t = [23, 41, 78, 106, 111, 51, 131, 94, 114, 57  …  87, 87, 72, 104, 67, 95, 111, 106, 131, 133], time_steps = 100), (epi_model = DirectInfections{Normal{Float64}}(EpiData{Float64, typeof(exp)}([0.056722565637507084, 0.0944813112842689, 0.11668723746973605, 0.12773814268679387, 0.130948497124998, 0.1287976856448402, 0.12312384970427602, 0.11527489380975135, 0.10622581663782862], 9, exp), Distributions.Normal{Float64}(μ=4.605170185988092, σ=1.0)), latent_model = RandomWalk{Normal{Float64}, Truncated{Normal{Float64}, Continuous, Float64, Float64, Float64}}(Distributions.Normal{Float64}(μ=0.0, σ=1.0), Truncated(Distributions.Normal{Float64}(μ=0.0, σ=0.02); lower=0.0, upper=0.5)), observation_model = DelayObservations{Float64, Truncated{Gamma{Float64}, Continuous, Float64, Float64, Float64}}(sparse(Integer[1, 2, 3, 4, 2, 3, 4, 5, 3, 4  …  97, 98, 99, 100, 98, 99, 100, 99, 100, 100], Integer[1, 1, 1, 1, 2, 2, 2, 2, 3, 3  …  97, 97, 97, 97, 98, 98, 98, 99, 99, 100], [0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25  …  0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25], 100, 100), Truncated(Distributions.Gamma{Float64}(α=5.0, θ=0.01); lower=0.001, upper=0.2)), pos_shift = 1.0e-6), FixedContext((rw_init = 0.0,), DynamicPPL.DefaultContext()))
          \n\n\n

          Initialising inference

          It is possible for the default warm-up process for NUTS to get stuck in low probability or otherwise degenerate regions of parameter space.

          To make NUTS more robust we provide manypathfinder, which is built on pathfinder variational inference from Pathfinder.jl. manypathfinder runs nruns pathfinder processes on the inference problem and returns the pathfinder run with maximum estimated ELBO.

          manypathfinder differs from Pathfinder.multipathfinder; multipathfinder is aimed at sampling from a potentially non-Gaussian target distribution which is first approximated as a uniformly weighted collection of normal approximations from pathfinder runs. manypathfinder is aimed at moving rapidly to a 'good' part of parameter space, and is robust to runs that fail.

          \n\n
          best_pf = manypathfinder(inference_mdl, 10; nruns = 20, executor = Transducers.ThreadedEx());
          \n\n\n\n

          We can use draws from the best pathfinder run to initialise NUTS.

          \n\n
          best_pf.draws_transformed
          \n
          iterationchainϵ_t[1]ϵ_t[2]ϵ_t[3]ϵ_t[4]ϵ_t[5]ϵ_t[6]...
          111-0.5144120.2152780.5903350.2397940.08614980.207969
          2210.175048-0.0220944-0.02002820.04072580.0310463-0.0428177
          3310.09032750.03484940.2828270.2393090.170582-0.139658
          4410.02286280.18310.1038940.1694070.0156059-0.133446
          5510.035848-0.0290472-0.2667810.1142220.07160660.0381202
          \n\n
          init_params = collect.(eachrow(best_pf.draws_transformed.value[1:4, :, 1]))
          \n
          4-element Vector{Vector{Float64}}:\n [-0.5144118124067896, 0.2152782113428215, 0.5903349691527211, 0.23979397988077622, 0.08614982980550409, 0.20796946509559994, -0.3903867127705256, -0.031059014249590677, -0.14995527247931853, -0.16244535432535046  …  0.061425336667904146, 0.01815311825284796, 0.29430315855864436, 0.4705235835897221, 0.790855766187655, 0.14404378027882073, 0.13370353699068532, 0.05856901084292262, 4.528786585706038, 0.01982303226146891]\n [0.17504799576770153, -0.02209444432244148, -0.02002823737606905, 0.040725822965111985, 0.031046347499243086, -0.042817722039409686, -0.10266435274540478, -0.3300313580334851, -0.24216722548064856, -0.32790554974512787  …  0.43007101479884213, 0.6907669705888795, 0.5511164195982637, 0.08633502877327975, 0.35581838375781943, -0.059632281807551285, 0.1045595275352122, 0.03387333974977781, 4.511037053680907, 0.027042599769282562]\n [0.09032747424872527, 0.034849440031800384, 0.2828270931903191, 0.23930911134742228, 0.17058211996835151, -0.13965761636751214, -0.2561325238265822, -0.2973356086161662, -0.3342723124114416, -0.5874018602763282  …  0.23741502405042764, 0.8682489439870135, 0.6848008339493292, 0.7290627956402452, 0.11708194959961493, 0.16903261721947005, 0.16653060634717645, 0.03605153934606213, 4.398407314279318, 0.027491732148055725]\n [0.022862818291666878, 0.18310039326444139, 0.10389356726393245, 0.16940749438834096, 0.015605906523095124, -0.13344623334715608, -0.18221945544950677, -0.19339612901623, -0.3758707816072445, -0.5293085682668266  …  0.5879921589285066, 0.21880141872883024, 0.5122949496467248, 0.48562059638880106, 0.15447654286932389, 0.29264316454368433, -0.10281980545168146, 0.04928524123732956, 4.573038829935848, 0.02839534879650567]
          \n\n\n

          NB: We are running this inference run for speed rather than accuracy as a demonstration. Use a higher target acceptance and more samples in a typical workflow.

          \n\n
          begin\n    target_acc_rate = 0.8\n    chn = sample(inference_mdl,\n        NUTS(target_acc_rate; adtype = AutoReverseDiff(true)),\n        MCMCThreads(),\n        250,\n        4;\n        init_params,\n        drop_warmup = true)\nend
          \n
          iterationchainϵ_t[1]ϵ_t[2]ϵ_t[3]ϵ_t[4]ϵ_t[5]ϵ_t[6]...
          112610.979711-0.773393-1.60955-0.096919-1.28560.283769
          212710.09156170.0456590.900820.1734830.0393357-0.565341
          312810.308018-0.153457-0.1754050.5024990.360626-0.512947
          41291-1.317560.2272061.1854-1.12723-0.706268-1.67822
          51301-0.166139-1.102481.968321.08574-1.53504-0.384448
          613110.17235-1.010041.55780.963792-1.36685-0.757544
          71321-0.0278682-0.740871.526351.13509-1.19339-0.82255
          813310.702821.497180.07904530.4098620.2084370.973433
          91341-0.707574-1.273180.12351-0.0613653-0.0174426-0.813638
          101351-0.694009-1.246760.3887980.100689-0.00853176-0.861363
          ...
          \n\n\n

          Predictive plotting

          We can spaghetti plot generated case data from the version of the model which hasn't conditioned on case data using posterior parameters inferred from the version conditioned on observed data. This is known as posterior predictive checking, and is a useful diagnostic tool for Bayesian inference (see here).

          Because we are using synthetic data we can also plot the model predictions for the unobserved infections and check that (at least in this example) we were able to capture some unobserved/latent variables in the process accurate.

          \n\n
          let\n    post_check_mdl = fix(full_epi_aware_mdl, (rw_init = 0.0,))\n    post_check_y_t = mapreduce(hcat, generated_quantities(post_check_mdl, chn)) do gen\n        gen.generated_y_t\n    end\n\n    predicted_I_t = mapreduce(hcat, generated_quantities(inference_mdl, chn)) do gen\n        gen.I_t\n    end\n\n    p1 = plot(post_check_y_t, c = :grey, alpha = 0.05, lab = \"\")\n    scatter!(p1, truth_data,\n        lab = \"Observed cases\",\n        xlabel = \"Time\",\n        ylabel = \"Cases\",\n        title = \"Post. predictive checking: cases\",\n        ylims = (-0.5, maximum(truth_data) * 1.5),\n        c = :green)\n\n    p2 = plot(predicted_I_t, c = :grey, alpha = 0.05, lab = \"\")\n    scatter!(p2, true_infections,\n        lab = \"Actual infections\",\n        xlabel = \"Time\",\n        ylabel = \"Unobserved Infections\",\n        title = \"Post. predictions: infections\",\n        ylims = (-0.5, maximum(true_infections) * 1.5),\n        c = :red)\n\n    plot(p1, p2,\n        layout = (1, 2),\n        size = (700, 400))\nend
          \n\n\n\n

          As well as checking the posterior predictions for latent infections, we can also check how well inference recovered unknown parameters, such as the random walk variance or the cluster factor of the negative binomial observations.

          \n\n
          let\n    parameters_to_plot = (:σ²_RW, :neg_bin_cluster_factor)\n\n    plts = map(parameters_to_plot) do name\n        var_samples = chn[name] |> vec\n        histogram(var_samples,\n            bins = 50,\n            norm = :pdf,\n            lw = 0,\n            fillalpha = 0.5,\n            lab = \"MCMC\")\n        vline!([getfield(random_epidemic, name)], lab = \"True value\")\n        title!(string(name))\n    end\n    plot(plts..., layout = (2, 1))\nend
          \n\n\n","category":"page"},{"location":"examples/getting_started/#Reproductive-number-back-calculation","page":"Getting started","title":"Reproductive number back-calculation","text":"","category":"section"},{"location":"examples/getting_started/","page":"Getting started","title":"Getting started","text":"
          \n

          As mentioned at the top, we don't directly use the concept of reproductive numbers in this note. However, we can back-calculate the implied $\\mathcal{R}(t)$ values, conditional on the specified generation interval being correct.

          Here we spaghetti plot posterior sampled time-varying reproductive numbers against the actual.

          \n\n
          let\n    n = epi_model.data.len_gen_int\n    Rt_denom = [dot(reverse(epi_model.data.gen_int), true_infections[(t - n):(t - 1)])\n                for t in (n + 1):length(true_infections)]\n    true_Rt = true_infections[(n + 1):end] ./ Rt_denom\n\n    predicted_Rt = mapreduce(hcat, generated_quantities(inference_mdl, chn)) do gen\n        _It = gen.I_t\n        _Rt_denom = [dot(reverse(epi_model.data.gen_int), _It[(t - n):(t - 1)])\n                     for t in (n + 1):length(_It)]\n        Rt = _It[(n + 1):end] ./ _Rt_denom\n    end\n\n    plt = plot((n + 1):time_horizon, predicted_Rt, c = :grey, alpha = 0.05, lab = \"\")\n    plot!(plt, (n + 1):time_horizon, true_Rt,\n        lab = \"true Rt\",\n        xlabel = \"Time\",\n        ylabel = \"Rt\",\n        title = \"Post. predictions: reproductive number\",\n        c = :red,\n        lw = 2)\nend
          \n\n\n","category":"page"},{"location":"examples/getting_started/","page":"Getting started","title":"Getting started","text":"EditURL = \"https://github.com/CDCgov/Rt-without-renewal/blob/main/docs/src/examples/getting_started.jl\"","category":"page"},{"location":"lib/public/#Public-Documentation","page":"Public API","title":"Public Documentation","text":"","category":"section"},{"location":"lib/public/","page":"Public API","title":"Public API","text":"Documentation for EpiAware.jl's public interface.","category":"page"},{"location":"lib/public/","page":"Public API","title":"Public API","text":"See the Internals section of the manual for internal package docs covering all submodules.","category":"page"},{"location":"lib/public/#Contents","page":"Public API","title":"Contents","text":"","category":"section"},{"location":"lib/public/","page":"Public API","title":"Public API","text":"Pages = [\"public.md\"]\nDepth = 2:2","category":"page"},{"location":"lib/public/#Index","page":"Public API","title":"Index","text":"","category":"section"},{"location":"lib/public/","page":"Public API","title":"Public API","text":"Pages = [\"public.md\"]","category":"page"},{"location":"lib/public/#Public-API","page":"Public API","title":"Public API","text":"","category":"section"},{"location":"#EpiAware.jl","page":"EpiAware.jl: Real-time epidemic monitoring","title":"EpiAware.jl","text":"","category":"section"},{"location":"","page":"EpiAware.jl: Real-time epidemic monitoring","title":"EpiAware.jl: Real-time epidemic monitoring","text":"Infectious disease situational awareness modelling toolkit for Julia.","category":"page"},{"location":"","page":"EpiAware.jl: Real-time epidemic monitoring","title":"EpiAware.jl: Real-time epidemic monitoring","text":"A package for building and fitting situational awareness models for infectious diseases. The package is designed to be flexible and extensible, and to provide a consistent interface for fitting and simulating models.","category":"page"},{"location":"#Package-Features","page":"EpiAware.jl: Real-time epidemic monitoring","title":"Package Features","text":"","category":"section"},{"location":"","page":"EpiAware.jl: Real-time epidemic monitoring","title":"EpiAware.jl: Real-time epidemic monitoring","text":"Flexible: The package is designed to be flexible and extensible, and to provide a consistent interface for fitting and simulating models.\nModular: The package is designed to be modular, with a clear separation between the model and the data.\nExtensible: The package is designed to be extensible, with a clear separation between the model and the data.\nConsistent: The package is designed to provide a consistent interface for fitting and simulating models.\nEfficient: The package is designed to be efficient, with a clear separation between the model and the data.","category":"page"},{"location":"","page":"EpiAware.jl: Real-time epidemic monitoring","title":"EpiAware.jl: Real-time epidemic monitoring","text":"See the Index for the complete list of documented functions and types.","category":"page"},{"location":"#Manual-Outline","page":"EpiAware.jl: Real-time epidemic monitoring","title":"Manual Outline","text":"","category":"section"},{"location":"","page":"EpiAware.jl: Real-time epidemic monitoring","title":"EpiAware.jl: Real-time epidemic monitoring","text":"Pages = [\n \"man/contributing.md\",\n]\nDepth = 1","category":"page"},{"location":"#Library-Outline","page":"EpiAware.jl: Real-time epidemic monitoring","title":"Library Outline","text":"","category":"section"},{"location":"","page":"EpiAware.jl: Real-time epidemic monitoring","title":"EpiAware.jl: Real-time epidemic monitoring","text":"Pages = [\"lib/public.md\", \"lib/internals.md\"]","category":"page"},{"location":"#main-index","page":"EpiAware.jl: Real-time epidemic monitoring","title":"Index","text":"","category":"section"},{"location":"","page":"EpiAware.jl: Real-time epidemic monitoring","title":"EpiAware.jl: Real-time epidemic monitoring","text":"Pages = [\"lib/public.md\"]","category":"page"}] }