diff --git a/.github/workflows/synthetic-validation.yaml b/.github/workflows/synthetic-validation.yaml index b42f5c77f..d7f731cf7 100644 --- a/.github/workflows/synthetic-validation.yaml +++ b/.github/workflows/synthetic-validation.yaml @@ -13,14 +13,18 @@ on: workflow_dispatch: jobs: - synthetic-valiation: + synthetic-validation: runs-on: macos-latest env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - uses: actions/checkout@master - - uses: r-lib/actions/setup-r@v2 + - name: Setup R + uses: r-lib/actions/setup-r@v2 + + - name: Setup pandoc + uses: r-lib/actions/setup-pandoc@v2 - uses: r-lib/actions/setup-r-dependencies@v2 with: @@ -30,12 +34,17 @@ jobs: here scoringutils loo + data.table + rstan + any::rmarkdown matrixStats local::. - name: Run synthetic validation run: | - source("inst/dev/recover-synthetic/rt.R") - shell: Rscript {0} + Rscript -e ' + source("inst/dev/recover-synthetic/rt.R") + source("inst/dev/recover-synthetic/eval_rt.R") + ' - name: Upload validation figures uses: actions/upload-artifact@v4 @@ -50,3 +59,29 @@ jobs: name: fits retention-days: 5 path: synthetic.rds + + - name: Render synthetic recovery md + run: | + rmarkdown::render("inst/dev/synthetic_recovery.md") + shell: Rscript {0} + + - name: Upload markdown + uses: actions/upload-artifact@v4 + with: + name: synthetic_recovery + retention-days: 5 + path: inst/dev/synthetic_recovery.html + + - name: Post the artifact + uses: CDCgov/cfa-actions/post-artifact@main + if: ${{ github.event_name == 'pull_request' }} + with: + artifact-name: synthetic_recovery + gh-token: ${{ secrets.GITHUB_TOKEN }} + message: 'Thank you for your contribution ${{ github.actor }} :rocket:! Your { artifact-name } markdown is ready for download :point_right: [here]({ artifact-url }) :point_left:!' + + + + + + diff --git a/NEWS.md b/NEWS.md index 404b50d03..110b8db3f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -34,6 +34,7 @@ - The `...` argument in `estimate_secondary()` has been removed because it was not used. By @jamesmbaazam in #894 and reviewed by @. - All examples now use the natural parameters of distributions rather than the mean and standard deviation when specifying uncertain distributions. This is to eliminate warnings and encourage best practice. By @jamesmbaazam in #893 and reviewed by @sbfnk. - Updated the methodology vignettes, By @sbfnk in #919 and reviewed by @seabbs and @jamesmbaazam. +- The ways that `dist_spec()` with certain/uncertain parameters can be constrained has been clarified. By @sbfnk in #940 and reviewed by @jamesmbaazam. # EpiNow2 1.6.1 diff --git a/R/checks.R b/R/checks.R index fb44140d5..c2fcb7af5 100644 --- a/R/checks.R +++ b/R/checks.R @@ -111,9 +111,10 @@ check_stan_delay <- function(dist) { if (any(is.infinite(max(dist))) && !(attr(dist, "cdf_cutoff") > 0)) { cli_abort( c( - "i" = "All distribution passed to the model need to have a + "i" = "All distributions passed to the model need to have a {col_blue(\"finite maximum\")}, which can be achieved either by - setting {.var max} or non-zero {.var cdf_cutoff}." + setting {.var max} or, if using a distribution with fixed parameters, + non-zero {.var cdf_cutoff}." ) ) } diff --git a/R/dist_spec.R b/R/dist_spec.R index cce218198..54af52292 100644 --- a/R/dist_spec.R +++ b/R/dist_spec.R @@ -751,8 +751,8 @@ plot.dist_spec <- function(x, samples = 50L, res = 1, cumulative = TRUE, ...) { c( "!" = "All distributions in {.var x} must have a finite maximum value.", - "i" = "You can set a finite maximum either as an - argument to {.fn plot} or when defining the distribution." + "i" = "You can set a finite maximum or CDF cutoff + when defining the distribution." ) ) } diff --git a/R/opts.R b/R/opts.R index ca5c11dda..956e7843d 100644 --- a/R/opts.R +++ b/R/opts.R @@ -1199,7 +1199,8 @@ filter_opts <- function(opts, region) { #' @param dist A #' @param default_cdf_cutoff Numeric; default CDF cutoff to be used if an #' unconstrained distribution is passed as `dist`. If `dist` is already -#' constrained by having a maximum or CDF cutoff this is ignored. +#' constrained by having a maximum or CDF cutoff this is ignored. Note that +#' this can only be done for objects with fixed parameters. #' @param cdf_cutoff_set Logical; whether the default CDF cutoff has been set by #' the user; if yes and `dist` is constrained a warning is issued #' @importFrom cli cli_inform cli_warn diff --git a/README.Rmd b/README.Rmd index 404dc479f..50902591a 100644 --- a/README.Rmd +++ b/README.Rmd @@ -163,11 +163,12 @@ you can file an issue [here](https://github.com/epiforecasts/EpiNow2/issues). We ## Contributors + -All contributions to this project are gratefully acknowledged using the [`allcontributors` package](https://github.com/ropensci/allcontributors) following the [all-contributors](https://allcontributors.org) specification. Contributions of any kind are welcome! +All contributions to this project are gratefully acknowledged using the [`allcontributors` package](https://github.com/ropensci/allcontributors) following the [allcontributors](https://allcontributors.org) specification. Contributions of any kind are welcome! ### Code @@ -181,16 +182,17 @@ All contributions to this project are gratefully acknowledged using the [`allcon actions-user, ellisp, jdmunday, +kaitejohnson, pearsonca, JAllen42, -kaitejohnson, adamkucharski, andrjohns, Bisaloo, LloydChapman, medewitt, nikosbosse, -sophiemeakin +sophiemeakin, +zsusswein @@ -231,7 +233,7 @@ All contributions to this project are gratefully acknowledged using the [`allcon nlinton, martinamcm, adrian-lison, -zsusswein +micahwiesner67 @@ -250,3 +252,4 @@ All contributions to this project are gratefully acknowledged using the [`allcon + diff --git a/README.md b/README.md index ec7364d57..67891f57f 100644 --- a/README.md +++ b/README.md @@ -257,7 +257,7 @@ guide](https://github.com/epiforecasts/EpiNow2/blob/main/.github/CONTRIBUTING.md All contributions to this project are gratefully acknowledged using the [`allcontributors` package](https://github.com/ropensci/allcontributors) -following the [all-contributors](https://allcontributors.org) +following the [allcontributors](https://allcontributors.org) specification. Contributions of any kind are welcome! ### Code @@ -271,16 +271,17 @@ specification. Contributions of any kind are welcome! actions-user, ellisp, jdmunday, +kaitejohnson, pearsonca, JAllen42, -kaitejohnson, adamkucharski, andrjohns, Bisaloo, LloydChapman, medewitt, nikosbosse, -sophiemeakin +sophiemeakin, +zsusswein ### Issue Authors @@ -318,7 +319,7 @@ specification. Contributions of any kind are welcome! nlinton, martinamcm, adrian-lison, -zsusswein +micahwiesner67 ### Issue Contributors diff --git a/inst/dev/figs/rt_backcalc_nuts.png b/inst/dev/figs/rt_backcalc_nuts.png deleted file mode 100644 index 4c63a4e4a..000000000 Binary files a/inst/dev/figs/rt_backcalc_nuts.png and /dev/null differ diff --git a/inst/dev/figs/rt_gp_nuts.png b/inst/dev/figs/rt_gp_nuts.png deleted file mode 100644 index e90e5fc08..000000000 Binary files a/inst/dev/figs/rt_gp_nuts.png and /dev/null differ diff --git a/inst/dev/figs/rt_gp_rw_nuts.png b/inst/dev/figs/rt_gp_rw_nuts.png deleted file mode 100644 index c202f3cd6..000000000 Binary files a/inst/dev/figs/rt_gp_rw_nuts.png and /dev/null differ diff --git a/inst/dev/figs/rt_weekly_rw_nuts.png b/inst/dev/figs/rt_weekly_rw_nuts.png deleted file mode 100644 index 214bcac81..000000000 Binary files a/inst/dev/figs/rt_weekly_rw_nuts.png and /dev/null differ diff --git a/inst/dev/recover-synthetic/plot.R b/inst/dev/recover-synthetic/plot.R index 66dc21ea8..9bd729fe1 100644 --- a/inst/dev/recover-synthetic/plot.R +++ b/inst/dev/recover-synthetic/plot.R @@ -17,7 +17,8 @@ save_ggplot <- function(plot, name, prefix = "") { ggplot2::ggsave( here::here("inst", "dev", "figs", paste0(prefix, name, ".png")), plot, - dpi = 300, width = 9, height = 6 + dpi = 300, width = 9, height = 6, + create.dir = TRUE ) } diff --git a/inst/dev/synthetic_recovery.md b/inst/dev/synthetic_recovery.md new file mode 100644 index 000000000..250534ffb --- /dev/null +++ b/inst/dev/synthetic_recovery.md @@ -0,0 +1,32 @@ +# Synthetic Recovery visual results + +This file combines the figures generated in `rt.R` into a single file, used to +confirm that the fits to synthetic data with different EpiNow2 +specifications work as expected. + +In all figures, the black dots indicate the ground truth R(t) estimate, used to +generate the synthetic data used for model fitting. + +### Estimate from the default Gaussian Process settings using the No-U-Turn (NUTS) sampler +![](./figs/rt_gp_nuts.png) +![](./figs/inf_gp_nuts.png) + +### Estimate from back-calculation +![](./figs/rt_backcalc_nuts.png) +![](./figs/inf_backcalc_nuts.png) + +### Estimate from a weekly random walk, with no Gaussian process +![](./figs/rt_weekly_rw_nuts.png) +![](./figs/inf_weekly_rw_nuts.png) + +### Estimate from a monthly random walk + a stationary Gaussian process +![](./figs/rt_gp_rw_nuts.png) +![](./figs/inf_gp_rw_nuts.png) + + +### Comparison of different model specs +CRPS over time evaluated against known R(t) +![](./figs/rt_crps.png) +CRPS over time evaluated against infections +![](./figs/inf_crps.png) + diff --git a/man/apply_default_cdf_cutoff.Rd b/man/apply_default_cdf_cutoff.Rd index 5e88fdee6..514d66487 100644 --- a/man/apply_default_cdf_cutoff.Rd +++ b/man/apply_default_cdf_cutoff.Rd @@ -11,7 +11,8 @@ apply_default_cdf_cutoff(dist, default_cdf_cutoff, cdf_cutoff_set) \item{default_cdf_cutoff}{Numeric; default CDF cutoff to be used if an unconstrained distribution is passed as \code{dist}. If \code{dist} is already -constrained by having a maximum or CDF cutoff this is ignored.} +constrained by having a maximum or CDF cutoff this is ignored. Note that +this can only be done for objects with fixed parameters.} \item{cdf_cutoff_set}{Logical; whether the default CDF cutoff has been set by the user; if yes and \code{dist} is constrained a warning is issued} diff --git a/man/delay_opts.Rd b/man/delay_opts.Rd index dc383a541..fcdaa58c6 100644 --- a/man/delay_opts.Rd +++ b/man/delay_opts.Rd @@ -22,7 +22,8 @@ a fixed distribution with all mass at 0, i.e. no delay.} \item{default_cdf_cutoff}{Numeric; default CDF cutoff to be used if an unconstrained distribution is passed as \code{dist}. If \code{dist} is already -constrained by having a maximum or CDF cutoff this is ignored.} +constrained by having a maximum or CDF cutoff this is ignored. Note that +this can only be done for objects with fixed parameters.} \item{weight_prior}{Logical; if TRUE (default), any priors given in \code{dist} will be weighted by the number of observation data points, in doing so diff --git a/man/generation_time_opts.Rd b/man/generation_time_opts.Rd index 8306d7a61..47798bd57 100644 --- a/man/generation_time_opts.Rd +++ b/man/generation_time_opts.Rd @@ -45,7 +45,8 @@ passing a nonparametric distribution the first element should be zero (see \item{default_cdf_cutoff}{Numeric; default CDF cutoff to be used if an unconstrained distribution is passed as \code{dist}. If \code{dist} is already -constrained by having a maximum or CDF cutoff this is ignored.} +constrained by having a maximum or CDF cutoff this is ignored. Note that +this can only be done for objects with fixed parameters.} \item{weight_prior}{Logical; if TRUE (default), any priors given in \code{dist} will be weighted by the number of observation data points, in doing so diff --git a/man/trunc_opts.Rd b/man/trunc_opts.Rd index f3e6d560e..0fb45a8d3 100644 --- a/man/trunc_opts.Rd +++ b/man/trunc_opts.Rd @@ -16,7 +16,8 @@ no truncation.} \item{default_cdf_cutoff}{Numeric; default CDF cutoff to be used if an unconstrained distribution is passed as \code{dist}. If \code{dist} is already -constrained by having a maximum or CDF cutoff this is ignored.} +constrained by having a maximum or CDF cutoff this is ignored. Note that +this can only be done for objects with fixed parameters.} \item{weight_prior}{Logical; if TRUE, the truncation prior will be weighted by the number of observation data points, in doing so approximately placing