Skip to content

Commit

Permalink
Add support for infectious asymptomatic window (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
atmyers authored Mar 3, 2024
1 parent e58713b commit 61ff132
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 23 deletions.
18 changes: 12 additions & 6 deletions docs/source/usage/how_to_run.rst
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,18 @@ In addition to the ExaEpi inputs, there are also a number of runtime options tha
one entry for each disease strain.
* ``disease.vac_eff`` (`float`, example: ``0.4``)
The vaccine efficacy - the probability of transmission will be multiplied by this factor
* ``disease.incubation_length`` (`int`, default: ``3``)
Length of the incubation period in days. Before this, agents have no symptoms and are not infectious.
* ``disease.infectious_length`` (`int`, default: ``6``)
Length of the infectious period in days. This counter starts once the incubation phase is over. Before tihs, agents are symptomatic and can spread the disease.
* ``disease.symptomatic_length`` (`int`, default: ``5``)
Length of the symptomatic-but-not-infectious stage in days. This counter starts once the infectious phase is complete. During this time agents are symptomatic and may self-withdraw, but they cannot spread the illness.
* ``disease.incubation_length_mean`` (`float`, default: ``3.0``)
Mean length of the incubation period in days. Before this, agents have no symptoms and are not infectious.
* ``disease.infectious_length_mean`` (`float`, default: ``6.0``)
Mean length of the infectious period in days. This counter starts once the incubation phase is over. Before tihs, agents are symptomatic and can spread the disease.
* ``disease.symptomdev_length_mean`` (`float`, default: ``5.0``)
Mean length of the time from exposure until symptoms develop in days. During the symptomatic-but-not-infectious stage agents may self-withdraw, but they cannot spread the illness.
* ``disease.incubation_length_std`` (`float`, default: ``1.0``)
Standard deviation of the incubation period in days.
* ``disease.infectious_length_std`` (`float`, default: ``1.0``)
Standard deviation of the infectious period in days.
* ``disease.symptomdev_length_std`` (`float`, default: ``1.0``)
Standard deviation of the time until symptom development in days.
* ``agents.size`` (`tuple of 2 integers`: e.g. ``(1, 1)``, default: ``(1, 1)``)
This option is deprecated and will removed in a future version of ExaEpi. It controls
the number of cells in the domain when running in `demo` mode. During actual usage,
Expand Down
24 changes: 20 additions & 4 deletions src/AgentContainer.H
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,9 @@ struct RealIdx
disease_counter = 0, /*!< Counter since start of infection */
treatment_timer, /*!< Timer since hospital admission */
prob, /*!< Probability of infection */
incubation_period, /*!< Time until infectious */
infectious_period, /*!< Length of time infectious */
symptomdev_period, /*!< Time until symptoms would develop */
nattribs /*!< number of real-type attribute*/
};
};
Expand Down Expand Up @@ -205,7 +208,8 @@ struct IntIdx
school, /*!< school type (elementary, middle, high, none) */
workgroup, /*!< workgroup ID */
work_nborhood, /*!< work neighborhood ID */
withdrawn, /*!< quarrantine status */
withdrawn, /*!< quarantine status */
symptomatic, /*!< currently symptomatic? */
nattribs /*!< number of integer-type attribute */
};
};
Expand Down Expand Up @@ -284,9 +288,13 @@ public:
h_parm->reduced_inf[i] = reduced_inf[i];
}

pp.query("incubation_length", h_parm->incubation_length);
pp.query("infectious_length", h_parm->infectious_length);
pp.query("symptomatic_length", h_parm->symptomatic_length);
pp.query("incubation_length_mean", h_parm->incubation_length_mean);
pp.query("infectious_length_mean", h_parm->infectious_length_mean);
pp.query("symptomdev_length_mean", h_parm->symptomdev_length_mean);

pp.query("incubation_length_std", h_parm->incubation_length_std);
pp.query("infectious_length_std", h_parm->infectious_length_std);
pp.query("symptomdev_length_std", h_parm->symptomdev_length_std);
}

h_parm->Initialize();
Expand Down Expand Up @@ -329,6 +337,14 @@ public:

std::array<amrex::Long, 5> printTotals ();

const DiseaseParm * getDiseaseParameters_h () const {
return h_parm;
}

const DiseaseParm * getDiseaseParameters_d () const {
return d_parm;
}

protected:

DiseaseParm* h_parm; /*!< Disease parameters */
Expand Down
29 changes: 19 additions & 10 deletions src/AgentContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -804,8 +804,9 @@ void AgentContainer::updateStatus (MultiFab& disease_stats /*!< Community-wise d
auto counter_ptr = soa.GetRealData(RealIdx::disease_counter).data();
auto timer_ptr = soa.GetRealData(RealIdx::treatment_timer).data();
auto prob_ptr = soa.GetRealData(RealIdx::prob).data();
//auto& aos = ptile.GetArrayOfStructs();
//auto pstruct_ptr = aos.data();
auto incubation_period_ptr = soa.GetRealData(RealIdx::incubation_period).data();
auto infectious_period_ptr = soa.GetRealData(RealIdx::infectious_period).data();

auto ds_arr = disease_stats[mfi].array();

struct DiseaseStats
Expand All @@ -818,8 +819,6 @@ void AgentContainer::updateStatus (MultiFab& disease_stats /*!< Community-wise d
};
};

auto* lparm = d_parm;

// Track hospitalization, ICU, ventilator, and fatalities
Real CHR[] = {.0104, .0104, .070, .28, 1.0}; // sick -> hospital probabilities
Real CIC[] = {.24, .24, .24, .36, .35}; // hospital -> ICU probabilities
Expand All @@ -835,11 +834,11 @@ void AgentContainer::updateStatus (MultiFab& disease_stats /*!< Community-wise d
}
else if (status_ptr[i] == Status::infected) {
counter_ptr[i] += 1;
if (counter_ptr[i] < lparm->incubation_length) {
if (counter_ptr[i] < incubation_period_ptr[i]) {
// incubation phase
return;
}
if (counter_ptr[i] == lparm->incubation_length) {
if (counter_ptr[i] == amrex::Math::ceil(incubation_period_ptr[i])) {
// decide if hospitalized
Real p_hosp = CHR[age_group_ptr[i]];
if (amrex::Random(engine) < p_hosp) {
Expand Down Expand Up @@ -929,7 +928,7 @@ void AgentContainer::updateStatus (MultiFab& disease_stats /*!< Community-wise d
}
}
else { // not hospitalized, recover once not infectious
if (counter_ptr[i] == lparm->incubation_length + lparm->infectious_length) {
if (counter_ptr[i] >= (incubation_period_ptr[i] + infectious_period_ptr[i])) {
status_ptr[i] = Status::immune;
}
}
Expand Down Expand Up @@ -1057,6 +1056,11 @@ void AgentContainer::infectAgents ()
auto status_ptr = soa.GetIntData(IntIdx::status).data();
auto counter_ptr = soa.GetRealData(RealIdx::disease_counter).data();
auto prob_ptr = soa.GetRealData(RealIdx::prob).data();
auto incubation_period_ptr = soa.GetRealData(RealIdx::incubation_period).data();
auto infectious_period_ptr = soa.GetRealData(RealIdx::infectious_period).data();
auto symptomdev_period_ptr = soa.GetRealData(RealIdx::symptomdev_period).data();

auto* lparm = d_parm;

amrex::ParallelForRNG( np,
[=] AMREX_GPU_DEVICE (int i, amrex::RandomEngine const& engine) noexcept
Expand All @@ -1067,6 +1071,9 @@ void AgentContainer::infectAgents ()
if (amrex::Random(engine) < prob_ptr[i]) {
status_ptr[i] = Status::infected;
counter_ptr[i] = 0.0;
incubation_period_ptr[i] = amrex::RandomNormal(lparm->incubation_length_mean, lparm->incubation_length_std, engine);
infectious_period_ptr[i] = amrex::RandomNormal(lparm->infectious_length_mean, lparm->infectious_length_std, engine);
symptomdev_period_ptr[i] = amrex::RandomNormal(lparm->symptomdev_length_mean, lparm->symptomdev_length_std, engine);
return;
}
}
Expand Down Expand Up @@ -1196,6 +1203,8 @@ void AgentContainer::interactAgentsHomeWork ( MultiFab& /*mask_behavior*/ /*!< M
auto workgroup_ptr = soa.GetIntData(IntIdx::workgroup).data();
auto prob_ptr = soa.GetRealData(RealIdx::prob).data();
auto counter_ptr = soa.GetRealData(RealIdx::disease_counter).data();
auto incubation_period_ptr = soa.GetRealData(RealIdx::incubation_period).data();
//auto symptomdev_period_ptr = soa.GetRealData(RealIdx::symptomdev_period).data();

auto* lparm = d_parm;
amrex::ParallelFor( bins_ptr->numItems(), [=] AMREX_GPU_DEVICE (int ii) noexcept
Expand All @@ -1208,7 +1217,7 @@ void AgentContainer::interactAgentsHomeWork ( MultiFab& /*mask_behavior*/ /*!< M
AMREX_ALWAYS_ASSERT( (Long) i < np);
if (status_ptr[i] == Status::immune) { return; }
if (status_ptr[i] == Status::dead) { return; }
if (status_ptr[i] == Status::infected && counter_ptr[i] < lparm->incubation_length) { return; } // incubation stage
if (status_ptr[i] == Status::infected && counter_ptr[i] < incubation_period_ptr[i]) { return; } // incubation stage
//amrex::Real i_mask = mask_arr(home_i_ptr[i], home_j_ptr[i], 0);
for (unsigned int jj = cell_start; jj < cell_stop; ++jj) {
auto j = inds[jj];
Expand All @@ -1217,11 +1226,11 @@ void AgentContainer::interactAgentsHomeWork ( MultiFab& /*mask_behavior*/ /*!< M
//amrex::Real j_mask = mask_arr(home_i_ptr[j], home_j_ptr[j], 0);
if (status_ptr[j] == Status::immune) {continue;}
if (status_ptr[j] == Status::dead) {continue;}
if (status_ptr[j] == Status::infected && counter_ptr[j] < lparm->incubation_length) { continue; } // incubation stage
if (status_ptr[j] == Status::infected && counter_ptr[j] < incubation_period_ptr[j]) { continue; } // incubation stage

if (status_ptr[j] == Status::infected &&
(status_ptr[i] != Status::infected && status_ptr[i] != Status::dead)) {
if (counter_ptr[j] < lparm->incubation_length) { continue; }
if (counter_ptr[j] < incubation_period_ptr[j]) { continue; }
// j can infect i
amrex::Real infect = lparm->infect;
infect *= lparm->vac_eff;
Expand Down
10 changes: 7 additions & 3 deletions src/DiseaseParm.H
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,13 @@ struct DiseaseParm
amrex::Real Child_compliance, /*!< Child compliance with masking ?? */
Child_HH_closure; /*!< Multiplier for household contacts during school closure */

int incubation_length = 3; /*!< Incubation period of disease (in days) */
int infectious_length = 6; /*!< Number of days person is infectious */
int symptomatic_length = 5; /*!< Number of days person is symptomatic */ //note, this does not affect the model yet
amrex::Real incubation_length_mean = 3.0; /*!< mean time (in days) until infectious*/
amrex::Real infectious_length_mean = 6.0; /*!< mean time (in days) agents are infectious */
amrex::Real symptomdev_length_mean = 5.0; /*!< mean time (in days) until symptoms show */

amrex::Real incubation_length_std = 1.0; /*!< std dev (in days) for the above*/
amrex::Real infectious_length_std = 1.0; /*!< std dev (in days) for the above */
amrex::Real symptomdev_length_std = 1.0; /*!< std dev (in days) for the above */

void Initialize ();

Expand Down
9 changes: 9 additions & 0 deletions src/Initialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,16 @@ namespace Initialization

auto status_ptr = soa.GetIntData(IntIdx::status).data();
auto counter_ptr = soa.GetRealData(RealIdx::disease_counter).data();
auto incubation_period_ptr = soa.GetRealData(RealIdx::incubation_period).data();
auto infectious_period_ptr = soa.GetRealData(RealIdx::infectious_period).data();
auto symptomdev_period_ptr = soa.GetRealData(RealIdx::symptomdev_period).data();

//auto unit_arr = unit_mf[mfi].array();
auto comm_arr = comm_mf[mfi].array();
auto bx = mfi.tilebox();

const auto* lparm = pc.getDiseaseParameters_d();

Gpu::DeviceScalar<int> num_infected_d(num_infected);
int* num_infected_p = num_infected_d.dataPtr();
amrex::ParallelForRNG(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k, amrex::RandomEngine const& engine) noexcept
Expand Down Expand Up @@ -310,6 +316,9 @@ namespace Initialization
} else {
status_ptr[pindex] = Status::infected;
counter_ptr[pindex] = 0;
incubation_period_ptr[pindex] = amrex::RandomNormal(lparm->incubation_length_mean, lparm->incubation_length_std, engine);
infectious_period_ptr[pindex] = amrex::RandomNormal(lparm->infectious_length_mean, lparm->infectious_length_std, engine);
symptomdev_period_ptr[pindex] = amrex::RandomNormal(lparm->symptomdev_length_mean, lparm->symptomdev_length_std, engine);
++ni;
}
}
Expand Down

0 comments on commit 61ff132

Please sign in to comment.