class HospitalFullModel: def __init__(self): self.r0 = 2.65 self.total_days = 0 self.population = POP_DENVERMETRO - 1 self.beta = None self.susceptible = ProbState(period=0, count=self.population) self.incubating = ProbState(period=3) self.infectious = ProbState(period=3.8, count=1) self.isolated = ProbState(period=14) self.unhospitalized = ProbState(period=14) self.h_noncritical = ProbState(period=8) self.h_critical = ProbState(period=6) self.h_icu = ProbState(period=10) self.recovered = ProbState(period=10000) self.dead = ProbState(period=10000) self.incubating.add_exit_state(self.infectious, 1) self.incubating.normalize_states_over_period() self.isolated.add_exit_state(self.recovered, 1) self.isolated.normalize_states_over_period() self.unhospitalized.add_exit_state(self.recovered, .25) self.unhospitalized.add_exit_state(self.dead, .75) self.unhospitalized.normalize_states_over_period() self.infectious.add_exit_state(self.isolated, .85) self.infectious.add_exit_state(self.h_noncritical, .11) self.infectious.add_exit_state(self.h_critical, .4) self.infectious.normalize_states_over_period() self.h_noncritical.add_exit_state(self.recovered, 1) self.h_noncritical.normalize_states_over_period() self.h_critical.add_exit_state(self.recovered, 1) self.h_critical.normalize_states_over_period() self.h_icu.add_exit_state(self.recovered, .75) self.h_icu.add_exit_state(self.dead, .25) self.h_icu.normalize_states_over_period() def reset(self): self.total_days = 0 self.susceptible.reset() self.susceptible.count = self.population - 1 self.incubating.reset() self.infectious.reset() self.infectious.count = 1 self.isolated.reset() self.unhospitalized.reset() self.h_noncritical.reset() self.h_critical.reset() self.h_icu.reset() self.recovered.reset() self.dead.reset() def set_r0(self, value): self.r0 = value def set_population(self, value): self.population = value def run_period(self, days): time_domain = np.linspace(0, days, days + 1) # Initial conditions vector init = (self.susceptible.count, self.incubating.count, self.infectious.count, self.isolated.count, self.h_noncritical.count, self.h_critical.count, self.h_icu.count, self.unhospitalized.count, self.recovered.count, self.dead.count) # Integrate the SIR equations over the time grid, t. results = odeint(deriv_seirh, init, time_domain, args=(self, )) (d_susceptible, d_incubating, d_infectious, d_isolated, d_noncritical, d_critical, d_icu, d_unhospitalized, d_recovered, d_dead) = results.T self.total_days += days self.susceptible.extend(d_susceptible) self.incubating.extend(d_incubating) self.infectious.extend(d_infectious) self.isolated.extend(d_isolated) self.h_noncritical.extend(d_noncritical) self.h_critical.extend(d_critical) self.h_icu.extend(d_icu) self.unhospitalized.extend(d_unhospitalized) self.recovered.extend(d_recovered) self.dead.extend(d_dead) def run_period2(self, days): # Integrate the SIR equations over the time grid, t. for _ in range(0, days): self.step_day() def run_r0_set(self, date_offsets, r0_values): self.reset() prev_date = 0 for itr in range(0, len(date_offsets)): self.set_r0(r0_values[itr]) self.beta = calc_beta(self.r0, self.dayspergen) self.recalculate() span = date_offsets[itr] - prev_date + 1 self.run_period2(span) prev_date = date_offsets[itr] if len(self.unhospitalized.domain) != len(self.dead.domain): raise ValueError( f"oops, {len(self.unhospitalized.domain)} != {len(self.dead.domain)}" ) def step_day(self): new_infections = self.beta * self.susceptible.count * self.infectious.count / self.population (new_symptomatic, ) = self.incubating.get_state_redist() new_isolated, new_noncritical, new_critical = self.infectious.get_state_redist( ) (recovered1, ) = self.isolated.get_state_redist() (recovered2, ) = self.h_noncritical.get_state_redist() (new_icu, ) = self.h_critical.get_state_redist() recovered3, dead1 = self.h_icu.get_state_redist() recovered4, dead2 = self.unhospitalized.get_state_redist() d_susceptible = -new_infections d_incubating = new_infections - new_symptomatic d_infectious = new_symptomatic - (new_isolated + new_noncritical + new_critical) d_isolated = new_isolated - recovered1 d_noncritical = new_noncritical - recovered2 d_critical = new_critical - new_icu d_icu = new_icu - (recovered3 + dead1) d_unhospitalized = -(recovered4 + dead2) d_recovered = recovered1 + recovered2 + recovered3 + recovered4 d_dead = dead1 + dead2 (d_noncritical, d_critical, d_icu, d_unhospitalized) = adjust_for_overload(self.h_noncritical.count, self.h_critical.count, self.h_icu.count, d_noncritical, d_critical, d_icu, d_unhospitalized) balances = (d_susceptible + d_incubating + d_infectious + d_isolated + d_noncritical + d_critical + d_icu + d_unhospitalized + d_recovered + d_dead) if int(balances) != 0: raise ValueError(f"balances {balances} != 0") self.susceptible.adjust(d_susceptible) self.incubating.adjust(d_incubating) self.infectious.adjust(d_infectious) self.isolated.adjust(d_isolated) self.h_noncritical.adjust(d_noncritical) self.h_critical.adjust(d_critical) self.h_icu.adjust(d_icu) self.unhospitalized.adjust(d_unhospitalized) self.recovered.adjust(d_recovered) self.dead.adjust(d_dead) self.total_days += 1
class SEIRHModel: def __init__(self): self.r0 = 2.65 self.total_days = 0 self.population = POP_DENVER self.beta = None self.susceptible = ProbState(period=0, count=self.population) self.incubating = ProbState(period=3) self.infectious = ProbState(period=3.8, count=1) self.isolated = ProbState(period=14) self.h_noncritical = ProbState(period=8) self.h_critical = ProbState(period=6) self.h_icu = ProbState(period=10) self.recovered = ProbState(period=10000) self.dead = ProbState(period=10000) self.incubating.add_exit_state(self.infectious, 1) self.incubating.normalize_states_over_period() self.isolated.add_exit_state(self.recovered, 1) self.isolated.normalize_states_over_period() self.infectious.add_exit_state(self.isolated, .85) self.infectious.add_exit_state(self.h_noncritical, .11) self.infectious.add_exit_state(self.h_critical, .4) self.infectious.normalize_states_over_period() self.h_noncritical.add_exit_state(self.recovered, 1) self.h_noncritical.normalize_states_over_period() self.h_critical.add_exit_state(self.recovered, 1) self.h_critical.normalize_states_over_period() self.h_icu.add_exit_state(self.recovered, .75) self.h_icu.add_exit_state(self.dead, .25) self.h_icu.normalize_states_over_period() def reset(self): self.total_days = 0 self.susceptible.reset() self.susceptible.count = self.population - 1 self.incubating.reset() self.infectious.reset() self.infectious.count = 1 self.isolated.reset() self.h_noncritical.reset() self.h_critical.reset() self.h_icu.reset() self.recovered.reset() self.dead.reset() def set_r0(self, value): self.r0 = value def set_population(self, value): self.population = value def recalculate(self): self.beta = calc_beta(self.r0, self.dayspergen) def run_period(self, days): time_domain = np.linspace(0, days, days + 1) # Initial conditions vector init = (self.susceptible.count, self.incubating.count, self.infectious.count, self.isolated.count, self.h_noncritical.count, self.h_critical.count, self.h_icu.count, self.recovered.count, self.dead.count) # Integrate the SIR equations over the time grid, t. results = odeint(deriv_seirh, init, time_domain, args=(self, )) (d_susceptible, d_incubating, d_infectious, d_isolated, d_noncritical, d_critical, d_icu, d_recovered, d_dead) = results.T self.total_days += days self.susceptible.extend(d_susceptible) self.incubating.extend(d_incubating) self.infectious.extend(d_infectious) self.isolated.extend(d_isolated) self.h_noncritical.extend(d_noncritical) self.h_critical.extend(d_critical) self.h_icu.extend(d_icu) self.recovered.extend(d_recovered) self.dead.extend(d_dead) def run_r0_set(self, date_offsets, r0_values): self.reset() prev_date = 0 for itr in range(0, len(date_offsets)): self.set_r0(r0_values[itr]) self.beta = calc_beta(self.r0, self.dayspergen) span = date_offsets[itr] - prev_date + 1 self.run_period(span) prev_date = date_offsets[itr]