-
Notifications
You must be signed in to change notification settings - Fork 12
Add self-isolation to simulation model #213
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
7010745
72ad3a4
0d08134
288b179
28b0f5d
93dd770
b9d3a4d
0799e08
30cac1b
8ba78b3
a815ebe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,15 +8,17 @@ | |
| #' and `asymptomatic` | ||
| #' @param delays a `list` with class `<ringbp_delay_opts>`: the | ||
| #' delay distribution `function`s for the \pkg{ringbp} model, returned | ||
| #' by [delay_opts()]. Contains two elements: `incubation_period` and | ||
| #' `onset_to_isolation` | ||
| #' by [delay_opts()]. Contains 4 elements: `incubation_period`, | ||
| #' `onset_to_isolation`, `latent_period` and `onset_to_self_isolation` | ||
| #' @param event_probs a `list` with class `<ringbp_event_prob_opts>`: the | ||
| #' event probabilities for the \pkg{ringbp} model, returned by | ||
| #' [event_prob_opts()]. Contains three elements: `asymptomatic`, | ||
| #' `presymptomatic_transmission` and `symptomatic_traced` | ||
| #' [event_prob_opts()]. Contains 5 elements: `asymptomatic`, | ||
| #' `presymptomatic_transmission`, `alpha`, `symptomatic_traced` and | ||
| #' `symptomatic_self_isolate` | ||
| #' @param interventions a `list` with class `<ringbp_intervention_opts>`: | ||
| #' the intervention settings for the \pkg{ringbp} model, returned by | ||
| #' [intervention_opts()]. Contains one element: `quarantine` | ||
| #' [intervention_opts()]. Contains 2 elements: `quarantine` and | ||
| #' `test_sensitivity` | ||
| #' | ||
| #' @importFrom data.table data.table rbindlist fcase fifelse copy | ||
| #' @importFrom stats runif rnbinom rbinom | ||
|
|
@@ -122,41 +124,56 @@ outbreak_step <- function(case_data, | |
| sampled = FALSE, | ||
| # assign negative test result (FALSE) as placeholder; | ||
| # will draw test result for symptomatic cases below | ||
| test_positive = FALSE | ||
| test_positive = FALSE, | ||
| # assign no isolation as placeholder; symptomatic, test-positive, | ||
| # traced or quarantined isolation time sampled below | ||
| isolated_time = Inf | ||
| )][, | ||
| # draws a sample to see if this person is asymptomatic | ||
| asymptomatic := runif(.N) < event_probs$asymptomatic | ||
| ][, | ||
| # onset of new case is exposure + incubation period sample | ||
| onset := exposure + delays$incubation_period(.N) | ||
| ][ | ||
| # draw a sample to see if each person self-isolates if symptomatic | ||
| asymptomatic == FALSE, | ||
| self_isolate := runif(.N) < event_probs$symptomatic_self_isolate | ||
| ] | ||
|
|
||
| # draw a sample for missing and test result | ||
| prob_samples[ | ||
| infector_asymptomatic == FALSE, | ||
| traced := runif(.N) < event_probs$symptomatic_traced | ||
| ][ | ||
| asymptomatic == FALSE, | ||
| asymptomatic == FALSE & self_isolate == FALSE, | ||
| test_positive := runif(.N) <= interventions$test_sensitivity | ||
| ] | ||
|
|
||
| prob_samples[, isolated_time := { | ||
| ref_time <- onset + delays$onset_to_isolation(.N) | ||
| fcase( | ||
| # asymptomatic: never isolated | ||
| asymptomatic, Inf, | ||
| # symptomatic, false-negative test: never isolated | ||
| !test_positive, Inf, | ||
| # symptomatic, test-positive, not traced: isolated at symptom onset + delay | ||
| !traced, ref_time, | ||
| # symptomatic, test-positive, traced, quarantine: | ||
| # earliest of infector / infectee isolation time | ||
| rep(interventions$quarantine, .N), pmin(ref_time, infector_isolation_time), | ||
| # symptomatic, test-positive, traced, no quarantine: | ||
| # earliest of symptom onset + delay / infector isolation time | ||
| default = pmin(ref_time, pmax(onset, infector_isolation_time)) | ||
| ) | ||
| }] | ||
| # symptomatic, self-isolate, not tested: | ||
| # isolated at symptom onset + self-isolation delay | ||
| prob_samples[ | ||
| self_isolate == TRUE, | ||
| isolated_time := onset + delays$onset_to_self_isolation(.N) | ||
| ] | ||
|
Comment on lines
+155
to
+157
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Guard the self-isolation sampler with an explicit option cross-check. On Line 156, 🛡️ Proposed fix outbreak_step <- function(case_data,
offspring,
delays,
event_probs,
interventions) {
checkmate::assert_data_table(case_data)
checkmate::assert_class(offspring, "ringbp_offspring_opts")
checkmate::assert_class(delays, "ringbp_delay_opts")
checkmate::assert_class(event_probs, "ringbp_event_prob_opts")
checkmate::assert_class(interventions, "ringbp_intervention_opts")
+ cross_check_opts(delays = delays, event_probs = event_probs)🤖 Prompt for AI Agents
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair point. I'm not going to add Tagging @pearsonca as we've discussed potentially moving some of the exported functions (incl. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the generally-easiest approach here is to rip outbreak_step into a public-with-validation outbreak_step and an internal no-validation internal_outbreak_step (or similar naming). i imagine that also means moving some of the validation into the overall public-facing simulation runner previously handled by outbreak_step. that seem straightforward enough, if now is the time? but maybe approach as a focus PR on that, then rebase this changeset onto that.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would leave this for a subsequent PR specifically working on the package namespace. From my side, the primary (and only?) reason for leaving the functions that It also relates #118.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd lean towards more to do with the model structure, so agree for another PR whichever way end up pursuing. an even easier version would be to update the documents for these exported-but-internal-ish functions to make clear that they don't do validation. caveat utor, etc. |
||
|
|
||
| # asymptomatic and symptomatic with false-negative test: | ||
| # never isolated remain Inf | ||
| prob_samples[ | ||
| !self_isolate & !asymptomatic & test_positive, | ||
| isolated_time := { | ||
| ref_time <- onset + delays$onset_to_isolation(.N) | ||
| fcase( | ||
| # symptomatic, test-positive, not traced: isolated at symptom onset + delay | ||
| !traced, ref_time, | ||
| # symptomatic, test-positive, traced, quarantine: | ||
| # earliest of infector / infectee isolation time | ||
| rep(interventions$quarantine, .N), pmin(ref_time, infector_isolation_time), | ||
| # symptomatic, test-positive, traced, no quarantine: | ||
| # earliest of symptom onset + delay / infector isolation time | ||
| default = pmin(ref_time, pmax(onset, infector_isolation_time)) | ||
| ) | ||
| } | ||
| ] | ||
|
|
||
| # Chop out unneeded sample columns | ||
| prob_samples[ | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clarify all call paths that enforce the cross-check.
The docs currently mention only
scenario_sim(), but this validation is also enforced viaoutbreak_model(). Please document both entrypoints to avoid ambiguity for API users.✏️ Proposed doc fix
Also applies to: 149-151
🤖 Prompt for AI Agents
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the same suggestion as the comment above, just in a different document. See above for reasoning on not accepting the recommended change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@joshwlambert, understood — I've noted the reasoning from the earlier comment (thatoutbreak_model()may be moved to internal in a future version, so documentation should favourscenario_sim()as the principal user-facing entry point). Happy to leave the wording as-is.🧠 Learnings used