Skip to content

Commit

Permalink
Read FOI specific values for age groups to attempt infection
Browse files Browse the repository at this point in the history
  • Loading branch information
confunguido committed Oct 22, 2024
1 parent 5ddb70f commit 95f726e
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 32 deletions.
2 changes: 1 addition & 1 deletion examples/births-deaths/demographics_report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use ixa::{
use std::path::PathBuf;
use std::path::Path;
use serde::{Deserialize, Serialize};
use crate::population_loader::{Age, AgeGroupType};
use crate::population_manager::{Age, AgeGroupType};
use crate::Parameters;

#[derive(Serialize, Deserialize, Clone)]
Expand Down
8 changes: 4 additions & 4 deletions examples/births-deaths/input.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
"max_time": 200.0,
"seed": 123,
"birth_rate": 0.1,
"age_groups": [
{"min_age": 0, "max_age": 1, "group_name": "newborn", "foi": 0.2},
{"min_age": 1, "max_age": 65, "group_name": "general", "foi": 0.1},
{"min_age": 65, "max_age": 200, "group_name": "oldadult", "foi": 0.15}
"foi_groups": [
{"group_name": "NewBorn", "foi": 0.2},
{"group_name": "General", "foi": 0.1},
{"group_name": "OldAdult", "foi": 0.15}
],
"infection_duration": 5.0,
"output_file": "incidence",
Expand Down
22 changes: 7 additions & 15 deletions examples/births-deaths/main.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,17 @@
use ixa::people::ContextPeopleExt;
use ixa::random::ContextRandomExt;
use ixa::{
context::Context, define_person_property, define_person_property_with_default,
context::Context,
global_properties::ContextGlobalPropertiesExt,
};
use std::path::Path;

mod parameters_loader;
mod population_loader;
mod population_manager;
mod demographics_report;
mod transmission_manager;

use crate::parameters_loader::Parameters;

use serde::{Deserialize, Serialize};

#[derive(Debug, Hash, Eq, PartialEq, Clone, Copy, Serialize, Deserialize)]
pub enum InfectionStatus {
S,
I,
R,
}
define_person_property_with_default!(InfectionStatusType, InfectionStatus, InfectionStatus::S);

fn main() {
let mut context = Context::new();
let current_dir = Path::new(file!()).parent().unwrap();
Expand All @@ -34,8 +24,9 @@ fn main() {
context.init_random(parameters.seed);

demographics_report::init(&mut context);
population_loader::init(&mut context);

population_manager::init(&mut context);
transmission_manager::init(&mut context);

context.add_plan(parameters.max_time, |context| {
context.shutdown();
});
Expand All @@ -47,3 +38,4 @@ fn main() {
}
}
}

15 changes: 8 additions & 7 deletions examples/births-deaths/parameters_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ use ixa::define_global_property;
use ixa::error::IxaError;
use serde::{Deserialize, Serialize};

use crate::population_manager::AgeGroupRisk;

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct AgeGroups {
pub min_age: f64,
pub max_age: f64,
pub group_name: String,
pub struct FoiAgeGroups {
pub group_name: AgeGroupRisk,
pub foi: f64,
}

Expand All @@ -21,15 +21,16 @@ pub struct ParametersValues {
pub max_time: f64,
pub seed: u64,
pub birth_rate: f64,
pub age_groups: Vec<AgeGroups>,
pub foi_groups: Vec<FoiAgeGroups>,
pub infection_duration: f64,
pub output_file: String,
pub demographic_output_file: String,
}
define_global_property!(Parameters, ParametersValues);

//define_global_property!(Foi, HashMap);
pub fn init_parameters(context: &mut Context, file_path: &Path) -> Result<(), IxaError> {
let parameters_json = context.load_parameters_from_json::<ParametersValues>(file_path)?;
context.set_global_property_value(Parameters, parameters_json);
context.set_global_property_value(Parameters, parameters_json.clone());
Ok(())
}

Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,25 @@ use ixa::context::Context;
use ixa::global_properties::ContextGlobalPropertiesExt;
use ixa::people::{ContextPeopleExt, PersonId};
use ixa::random::ContextRandomExt;
use ixa::{define_derived_person_property, define_person_property};
use ixa::{define_derived_person_property, define_global_property, define_person_property, define_person_property_with_default};
use std::collections::HashMap;
use serde::Deserialize;
use crate::parameters_loader::Parameters;
use ixa::random::define_rng;
define_rng!(PeopleRng);
static MAX_AGE: u8 = 100;
use std::fmt;
use rand_distr::Exp;
#[derive(Deserialize, Copy, Clone, PartialEq, Eq, Debug)]
use serde::Serialize;

#[derive(Debug, Hash, Eq, PartialEq, Clone, Copy, Serialize, Deserialize)]
pub enum InfectionStatus {
S,
I,
R,
}

#[derive(Deserialize, Serialize, Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub enum AgeGroupRisk {
NewBorn,
General,
Expand All @@ -23,6 +33,12 @@ impl fmt::Display for AgeGroupRisk {
}
}

define_global_property!(Foi, HashMap<AgeGroupRisk, f64>);
define_person_property_with_default!(
InfectionStatusType,
InfectionStatus,
InfectionStatus::S
);

define_person_property!(Age, u8);
define_person_property!(Alive, bool);
Expand All @@ -41,7 +57,6 @@ define_derived_person_property!(
}
);


fn schedule_birth(context: &mut Context) {
let parameters = context.get_global_property_value(Parameters).clone();

Expand All @@ -51,7 +66,6 @@ fn schedule_birth(context: &mut Context) {

let next_birth_event = context.get_current_time() +
context.sample_distr(PeopleRng, Exp::new(parameters.birth_rate).unwrap());
println!("Next birth event: {:?}", next_birth_event);
context.add_plan(next_birth_event,
move |context| {
schedule_birth(context);
Expand Down Expand Up @@ -80,6 +94,17 @@ fn schedule_birth(context: &mut Context) {

pub fn init(context: &mut Context) {
let parameters = context.get_global_property_value(Parameters).clone();

let foi_map = parameters
.foi_groups
.clone()
.into_iter()
.map(|x| (x.group_name,x.foi))
.collect::<HashMap<AgeGroupRisk, f64>>();


context.set_global_property_value(Foi, foi_map.clone());

for _ in 0..parameters.population {
let person = context.add_person();
let age = context.sample_range(PeopleRng, 0..(MAX_AGE));
Expand All @@ -89,5 +114,4 @@ pub fn init(context: &mut Context) {

// Plan for births and deaths
context.add_plan(0.0, |context| {schedule_birth(context)});

}
62 changes: 62 additions & 0 deletions examples/births-deaths/transmission_manager.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use ixa::context::Context;
use ixa::define_rng;
use ixa::global_properties::ContextGlobalPropertiesExt;
use ixa::people::ContextPeopleExt;
use ixa::random::ContextRandomExt;

use crate::population_manager::InfectionStatus;
use crate::population_manager::InfectionStatusType;
use crate::population_manager::AgeGroupRisk;
use crate::population_manager::Foi;
use crate::Parameters;
use rand_distr::Exp;

define_rng!(TransmissionRng);

//Attempt infection for specific age group risk (meaning diferent forces of infection)
fn attempt_infection(context: &mut Context, age_group: AgeGroupRisk) {
let population_size: usize = context.get_current_population();

let person_to_infect =
context.get_person_id(context.sample_range(TransmissionRng, 0..population_size));

let person_status: InfectionStatus =
context.get_person_property(person_to_infect, InfectionStatusType);
let parameters = context.get_global_property_value(Parameters).clone();
let foi = *context
.get_global_property_value(Foi)
.get(&age_group)
.unwrap();

println!("Attempting infection for age group: {:?} with foi: {:?}", age_group, foi);

if matches!(person_status, InfectionStatus::S) {
context.set_person_property(person_to_infect, InfectionStatusType, InfectionStatus::I);
}

#[allow(clippy::cast_precision_loss)]
let next_attempt_time = context.get_current_time()
+ context.sample_distr(TransmissionRng, Exp::new(foi).unwrap())
/ population_size as f64;

if next_attempt_time <= parameters.max_time {
context.add_plan(next_attempt_time, move |context| {
attempt_infection(context, age_group);
});
}
}

pub fn init(context: &mut Context) {
// Need to convert to a more efficient way
context.add_plan(0.0, |context| {
attempt_infection(context, AgeGroupRisk::NewBorn);
});

context.add_plan(0.0, |context| {
attempt_infection(context, AgeGroupRisk::General);
});

context.add_plan(0.0, |context| {
attempt_infection(context, AgeGroupRisk::OldAdult);
});
}

0 comments on commit 95f726e

Please sign in to comment.