class AgeAdjustedModel: 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 - 1, name='susceptible') self.incubating = ProbState(period=3, name='incubating') self.infectious = ProbState(period=3.8, count=1, name='infectious') self.isolated_holding = ProbState(period=90, name='isolated_holding') self.incubating.add_exit_state(self.infectious, 1) self.incubating.normalize_states_over_period() self.infectious.add_exit_state(self.isolated_holding, 1) self.infectious.normalize_states_over_period() self.subgroups = dict() for key, value in AGE_DISTRIBUTION.items(): self.subgroups[key] = AgeGroup(SubgroupRates(ICD[key], value), name=key) self.sum_isolated = None self.sum_noncrit = None self.sum_icu = None self.sum_icu_vent = None self.sum_recovered = None self.sum_deceased = None def gather_sums(self): # print(f"base:{len(self.susceptible.domain)}") self.sum_isolated = [0] * len(self.susceptible.domain) self.sum_noncrit = [0] * len(self.susceptible.domain) self.sum_icu = [0] * len(self.susceptible.domain) self.sum_icu_vent = [0] * len(self.susceptible.domain) self.sum_recovered = [0] * len(self.susceptible.domain) self.sum_deceased = [0] * len(self.susceptible.domain) # print(f"final isolated 0-9:{len(self.subgroups['0-9'].isolated.domain)} {self.subgroups['0-9'].isolated.pending}, {self.subgroups['0-9'].isolated.count}") for key, value in self.subgroups.items(): # print(f"adding isolated {key}: {self.sum_isolated} {value.isolated.domain}") self.sum_isolated = np.add(self.sum_isolated, value.isolated.domain) self.sum_noncrit = np.add(self.sum_noncrit, value.h_noncrit.domain) self.sum_icu = np.add(self.sum_icu, value.h_icu.domain) self.sum_icu_vent = np.add(self.sum_icu_vent, value.h_icu_vent.domain) self.sum_recovered = np.add(self.sum_recovered, value.recovered.domain) self.sum_deceased = np.add(self.sum_deceased, value.deceased.domain) 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.subgroups = dict() for key, value in AGE_DISTRIBUTION.items(): self.subgroups[key] = AgeGroup(SubgroupRates(ICD[key], value), name=key) def set_r0(self, value): self.r0 = value def set_population(self, value): self.population = value def run_period(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() day_counter = 0 for itr in range(0, len(date_offsets)): self.set_r0(r0_values[itr]) self.beta = calc_beta(self.r0, self.dayspergen) while day_counter < date_offsets[itr]: self.step_day() day_counter += 1 def step_day(self): new_infections = self.beta * self.susceptible.count * self.infectious.count / self.population # print(f"Day {self.total_days}, {self.beta} * {self.susceptible.count} * {self.infectious.count} / {self.population} = {new_infections}") self.susceptible.store_pending(-new_infections) self.incubating.store_pending(new_infections) self.incubating.pass_downstream() self.infectious.pass_downstream() diagnosed = self.isolated_holding.pending self.isolated_holding.pending = 0 for key, agegroup in self.subgroups.items(): subpop = diagnosed * agegroup.stats.pop_dist agegroup.apply_infections(subpop) agegroup.calculate_redistributions() self.susceptible.apply_pending() self.incubating.apply_pending() self.infectious.apply_pending() for key, agegroup in self.subgroups.items(): agegroup.apply_pending() self.total_days += 1
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]