Skip to content
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

How to handle multiple pathogens/serotypes? #76

Open
confunguido opened this issue Nov 5, 2024 · 2 comments
Open

How to handle multiple pathogens/serotypes? #76

confunguido opened this issue Nov 5, 2024 · 2 comments
Labels
needs discussion Needs discussion before implementation

Comments

@confunguido
Copy link
Collaborator

I think we need an example that handles multiple serotypes, variants, pathogens, etc. Particularly, I am thinking of person properties. For instance, if I want to write a model for the four serotypes of dengue (DENV1, DENV2, DENV3, DENV4), should I set the person property for infection status, heatlh status, and even maybe last time infected as:

define_person_property!(InfectionStatus, [InfectionStatusType, 4])
define_person_property!(LastTimeInfected, [f64, 4])
define_person_property!(HealthStatus, [HealthStatusType, 4])

Another complication is if we don't know the number of circulating pathogens or variants in the population. For instance, if we specify the number of variants from an input file that is unknown at compile-time, I would like to define the person properties in a similar mamner.

define_person_property!(InfectionStatus, [InfectionStatusType, parameters.number_variants])
@confunguido confunguido added the needs discussion Needs discussion before implementation label Nov 5, 2024
@ekr-cfa
Copy link
Collaborator

ekr-cfa commented Nov 17, 2024

define_person_property!(InfectionStatus, [InfectionStatusType, parameters.number_variants])

I don't believe that this is possible with a Rust macro, because the macro is evaluated at compile time, and parameters.number_variants is known at runtime. If you truly don't know until runtime, then I think you need to have a fixed upper bound that is known at compile time and a runtime error if you try to exceed that.

With that said, I tend to think that it's inadvisable to have each of these be different person properties, in part because it doesn't enforce correctness. For instance, you can have InfectionStatus=Never but LastTimeInfected=<something>. Similarly, I don't know what HealthStatus is, but I imagine it's not independent of InfectionStatus. Restricting ourselves to InfectionStatus and LastInfected, I would instead use the type system to enforce only valid configurations, e.g.,

enum InfectionStatus {
   Susceptible,
   Infected {
      time: f64   // infected time
   }, 
   Recovered { 
     infected: f64,  // infected time
     recovered: f64  // recovered time
   }
}

impl Default for InfectionStatus {
    fn default() -> Self {
       InfectionStatus::Susceptible
    }
}

This guarantees that if someone is Infected you have an infection time but not a recovery time, but if you are Recovered, you have both, etc.

And then you would do:

#[derive(Default)]
struct InfectionStatusAllType{
   variants: [InfectionStatus; 4]
}

Followed by:

define_person_property_with_default!(InfectionStatusAll, InfectionStatusAllType, InfectionStatusAllType::default())

@jasonasher
Copy link
Collaborator

For future consideration, one challenge with this approach is that event notifications for these kinds of vector person properties are not as useful as one might want. For example people may want to subscribe to people becoming newly infected and they will have to compare across the arrays to see if this kind of status change has occurred. I think we could at some point consider the concept of a vectorized/array person property - one where there is a vec/array of values for each person and where updates occur at specific index entries and updating the ith entry in that array releases an event than the ith entry has been changed with the old and new values at that index.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs discussion Needs discussion before implementation
Projects
None yet
Development

No branches or pull requests

3 participants