Пример #1
0
    def __init__(self, scenario):
        if isinstance(scenario, str):
            self.scenario = EpiScenario(scenario)
        elif isinstance(scenario, EpiScenario):
            self.scenario = scenario

        self.modelname = self.scenario.modelname
        self.total_days = 0
        self.r0 = self.scenario.parameters['initial_r0']
        self.beta = None
        self.population = self.scenario.totalpop

        self.susceptible = ProbState(period=0,
                                     count=self.scenario.init_susceptible,
                                     name='susceptible')
        self.incubating = ProbState(period=self.scenario.incubation_period,
                                    count=self.scenario.init_infected,
                                    name='incubating')
        self.infectious = ProbState(period=self.scenario.prediagnosis,
                                    count=self.scenario.init_infectious,
                                    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 self.scenario.subgrouprates.items():
            self.subgroups[key] = AgeGroup(value, name=key)
Пример #2
0
    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
Пример #3
0
class ScenarioDrivenModel:
    def __init__(self, scenario):
        if isinstance(scenario, str):
            self.scenario = EpiScenario(scenario)
        elif isinstance(scenario, EpiScenario):
            self.scenario = scenario

        self.modelname = self.scenario.modelname
        self.total_days = 0
        self.r0 = self.scenario.parameters['initial_r0']
        self.beta = None
        self.population = self.scenario.totalpop

        self.susceptible = ProbState(period=0,
                                     count=self.scenario.init_susceptible,
                                     name='susceptible')
        self.incubating = ProbState(period=self.scenario.incubation_period,
                                    count=self.scenario.init_infected,
                                    name='incubating')
        self.infectious = ProbState(period=self.scenario.prediagnosis,
                                    count=self.scenario.init_infectious,
                                    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 self.scenario.subgrouprates.items():
            self.subgroups[key] = AgeGroup(value, name=key)


#		self.fitness = None

    def run(self):
        self.run_r0_set(self.scenario.r0_date_offsets, self.scenario.r0_values)

    def set_r0(self, value):
        self.r0 = value

    def run_r0_set(self, date_offsets, r0_values):
        self.scenario.hospital_door_aggregator = []
        day_counter = 0
        for itr in range(0, len(date_offsets)):
            self.set_r0(r0_values[itr])
            self.beta = calc_beta(r0_values[itr], self.infectious.period)
            while day_counter < date_offsets[itr]:
                self.step_day()
                day_counter += 1
        self.scenario.hospital_door_aggregator.append(
            self.scenario.hospital_door_aggregator[-1])

    def step_day(self):
        new_infections = calc_infected(self.population, self.beta,
                                       self.susceptible.count,
                                       self.infectious.count)
        #print(f"Day {self.total_days} infections: {new_infections} = {self.beta} * {self.susceptible.count} * {self.infectious.count} / {self.population}")
        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
        if len(self.scenario.hospital_door_aggregator) == 0:
            diagnagg = diagnosed
        else:
            diagnagg = self.scenario.hospital_door_aggregator[-1] + diagnosed
        self.scenario.hospital_door_aggregator.append(diagnagg)

        self.isolated_holding.pending = 0
        subpop_out = []
        for key, agegroup in self.subgroups.items():
            subpop = diagnosed * agegroup.stats.pop_dist
            subpop_out.append(subpop)
            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

    def gather_sums(self):
        time_increments = len(self.susceptible.domain)
        self.scenario.out_susceptible = self.susceptible.domain
        self.scenario.out_incubating = self.incubating.domain
        self.scenario.out_infectious = self.infectious.domain
        self.scenario.sum_isolated = [0] * time_increments
        self.scenario.sum_noncrit = [0] * time_increments
        self.scenario.sum_icu = [0] * time_increments
        self.scenario.sum_icu_vent = [0] * time_increments
        self.scenario.sum_recovered = [0] * time_increments
        self.scenario.sum_deceased = [0] * time_increments
        self.scenario.sum_hospitalized = [0] * time_increments

        for key, value in self.subgroups.items():
            self.scenario.sum_isolated = np.add(self.scenario.sum_isolated,
                                                value.isolated.domain)
            self.scenario.sum_noncrit = np.add(self.scenario.sum_noncrit,
                                               value.h_noncrit.domain)
            self.scenario.sum_icu = np.add(self.scenario.sum_icu,
                                           value.h_icu.domain)
            self.scenario.sum_icu_vent = np.add(self.scenario.sum_icu_vent,
                                                value.h_icu_vent.domain)
            self.scenario.sum_recovered = np.add(self.scenario.sum_recovered,
                                                 value.recovered.domain)
            self.scenario.sum_deceased = np.add(self.scenario.sum_deceased,
                                                value.deceased.domain)

        self.scenario.sum_hospitalized = np.add(self.scenario.sum_hospitalized,
                                                self.scenario.sum_icu)
        self.scenario.sum_hospitalized = np.add(self.scenario.sum_hospitalized,
                                                self.scenario.sum_noncrit)
        self.scenario.sum_hospitalized = np.add(self.scenario.sum_hospitalized,
                                                self.scenario.sum_icu_vent)

        self.scenario.fitset = dict()
        cursor = self.scenario.initial_date
        stoptime = cursor + timedelta(self.total_days)
        itr = 0
        while cursor < stoptime:
            if cursor not in self.scenario.fitset:
                self.scenario.fitset[cursor] = dict()
            self.scenario.fitset[cursor][
                'current_hosp'] = self.scenario.sum_hospitalized[itr]
            self.scenario.fitset[cursor][
                'total_hosp'] = self.scenario.hospital_door_aggregator[itr]
            self.scenario.fitset[cursor][
                'total_deceased'] = self.scenario.sum_deceased[itr]
            itr += 1
            cursor += ONEDAY

    def save_results(self, iteration):
        result = dict()

        result['iteration'] = iteration
        result['fitness'] = self.scenario.fitness
        result['scenario'] = self.scenario.parameters

        result['modelname'] = self.modelname
        result['total_days'] = self.total_days
        result['totalpop'] = self.population
        result['sum_isolated'] = self.scenario.sum_isolated
        result['sum_noncrit'] = self.scenario.sum_noncrit
        result['sum_icu'] = self.scenario.sum_icu
        result['sum_icu_vent'] = self.scenario.sum_icu_vent
        result['sum_recovered'] = self.scenario.sum_recovered
        result['sum_deceased'] = self.scenario.sum_deceased

        with open(f"best_fit{iteration}", "w") as bfi:
            json.dump(result, bfi)

    def actual_curves(self):
        cursor = self.scenario.initial_date
        finaldate = cursor + timedelta(self.total_days)
        act_hosp = []
        act_death = []

        while cursor < finaldate:
            if cursor in COLORADO_ACTUAL:
                act_hosp.append(COLORADO_ACTUAL[cursor]['hospitalized'])
                act_death.append(COLORADO_ACTUAL[cursor]['deceased'])
            else:
                act_hosp.append(None)
                act_death.append(None)
            cursor += ONEDAY
        act_death.append(None)
        act_hosp.append(None)
        return act_hosp, act_death

    def generate_png(self):

        hospitalized = self.scenario.hospital_door_aggregator

        startdate = self.scenario.initial_date
        time_domain = [startdate]
        cursor = startdate
        for _ in range(0, self.total_days):
            cursor += ONEDAY
            time_domain.append(cursor)

    #	time_domain = np.linspace(0, model.total_days, model.total_days + 1)

        fig = plt.figure(facecolor='w')
        # ax = fig.add_subplot(111, axis_bgcolor='#dddddd', axisbelow=True)
        ax = fig.add_subplot(111, axisbelow=True)

        ### Vertical line indicating today
        plt.axvline(x=datetime.today(), alpha=.5, lw=2, label='Today')

        #-------------
        #  Actual numbers, displayed when GA fitting
        #-------------
        act_hosp, act_death = self.actual_curves()
        ###   Actual Hospitalized, as specified in the constants
        ax.plot(time_domain,
                act_hosp,
                color=(0, 0, .5),
                alpha=1,
                lw=2,
                label='Actual Hospitalized',
                linestyle='-')
        ###   Actual Deaths, as specified in the constants
        ax.plot(time_domain,
                act_death,
                color=(0, 0, .5),
                alpha=1,
                lw=2,
                label='Actual Deaths',
                linestyle='-')

        #-------------
        #  Basic SEIR
        #-------------
        ###   Susceptible line, usually too tall
        #		ax.plot(time_domain, self.scenario.out_susceptible, label='Susceptible', color=(0, 0, 1), alpha=.5, lw=2, linestyle='-')
        ###   Exposed: pre-symptomatic, not infectious yet
        #   	ax.plot(time_domain, self.scenario.incubating,      label='Exposed',     color=TABLEAU_ORANGE, alpha=0.1, lw=2, linestyle='-')
        ###   Infectious patients, not isolated
        #   	ax.plot(time_domain, self.scenario.infectious,      label='Infected',    color=TABLEAU_RED, alpha=0.5, lw=2, linestyle='-')
        ###   Recovered/immune, usually too tall
        #   	ax.plot(time_domain, self.scenario.sum_recovered,   label='Recovered',   color=(0, .5, 0), alpha=.5, lw=2, linestyle='--')
        ###   Infected, isolated at home
        #   	ax.plot(time_domain, self.scenario.sum_isolated,    label='Home Iso',    color=TAB_COLORS[8], alpha=.5, lw=2, linestyle='-')
        ###   Deceased
        ax.plot(time_domain,
                self.scenario.sum_deceased,
                label='Deceased',
                color=(.25, .25, 0),
                alpha=.5,
                lw=2,
                linestyle='--')

        #-------------
        #  Hospital Capacities
        #-------------
        #		ax.plot(time_domain, self.scenario.sum_floor, label='Floor Beds',         color=TABLEAU_BLUE, alpha=1, lw=2, linestyle='--')
        #		ax.plot(time_domain, self.scenario.sum_icu,   label='ICU Beds',           color=TABLEAU_GREEN, alpha=1, lw=2, linestyle='--')
        #		ax.plot(time_domain, self.scenario.sum_vent,  label='ICU + Vent Beds',    color=TABLEAU_RED, alpha=1, lw=2, linestyle='--')
        ax.plot(time_domain,
                hospitalized,
                label='Total Hospitalized',
                color=(1, 0, 0),
                alpha=.25,
                lw=2,
                linestyle='-')

        #-------------
        #  Hospital Capacities - DH Specific
        #-------------
        #		ax.plot(time_domain, [86] * (self.total_days + 1) , label='Supply - DH ICU Beds'  , color=(1, 0, 0), alpha=1, lw=1, linestyle='-')
        #		ax.plot(time_domain, [229] * (self.total_days + 1), label='Supply - DH Total Beds', color=(0, 0, 1), alpha=1, lw=1, linestyle='-')

        #-------------
        #  Hospital Capacities - Denver County
        #-------------
        #		ax.plot(time_domain, [695] * (self.total_days + 1) , label='Supply - 5C ICU Beds'  , color=(1, 0, 0), alpha=1, lw=1, linestyle='-')
        #		ax.plot(time_domain, [5907] * (self.total_days + 1), label='Supply - 5C Total Beds', color=(0, 0, 1), alpha=1, lw=1, linestyle='-')
        #		ax.plot(time_domain, [1043] * (self.total_days + 1), label='Supply - 5C ICU Beds'  , color=(1, 0, 0), alpha=1, lw=1, linestyle='-')
        #		ax.plot(time_domain, [8861] * (self.total_days + 1), label='Supply - 5C Total Beds', color=(0, 0, 1), alpha=1, lw=1, linestyle='-')

        #-------------
        #  Hospital Capacities - Five County
        #-------------
        #		ax.plot(time_domain, [255] * (self.total_days + 1) , label='Supply - 5C ICU Beds'  , color=(1, 0, 0), alpha=1, lw=1, linestyle='-')
        #		ax.plot(time_domain, [1000] * (self.total_days + 1), label='Supply - 5C Total Beds', color=(0, 0, 1), alpha=1, lw=1, linestyle='-')
        #		ax.plot(time_domain, [1043] * (self.total_days + 1), label='Supply - 5C ICU Beds'  , color=(1, 0, 0), alpha=1, lw=1, linestyle='-')
        #		ax.plot(time_domain, [4135] * (self.total_days + 1), label='Supply - 5C Total Beds', color=(0, 0, 1), alpha=1, lw=1, linestyle='-')

        # ------------
        # Hospital Capacities - Five County - 50%
        # ------------
        #       ax.plot(time_domain, [348] * (model.total_days + 1) , label='Supply - 5County ICU', color=(0, 0, 1), alpha=1, lw=1, linestyle='--')
        #       ax.plot(time_domain, [2954] * (model.total_days + 1), label='Supply - 5County Tot', color=(1, 0, 0), alpha=1, lw=1, linestyle='-')
        #       ax.plot(time_domain, [521] * (model.total_days + 1) , label='1.5x 5County ICU'    , color=(0, 0, 1), alpha=1, lw=1, linestyle='--')
        #       ax.plot(time_domain, [4430] * (model.total_days + 1), label='1.5x 5County Tot'    , color=(1, 0, 0), alpha=1, lw=1, linestyle='-')

        #make pretty

        # set the style of the axes and the text color
        plt.rcParams['axes.edgecolor'] = '#333F4B'
        plt.rcParams['axes.linewidth'] = 0.8
        plt.rcParams['xtick.color'] = '#333F4B'
        plt.rcParams['ytick.color'] = '#333F4B'
        plt.rcParams['text.color'] = '#333F4B'

        # set axis
        ax.tick_params(axis='both', which='major', labelsize=12)

        ax.set_xlabel('Days')
        ax.set_ylabel('Number')

        chart_title = self.modelname
        plt.title(chart_title, fontsize=14)
        # ax.set_ylim(0,1.2)
        ax.yaxis.set_tick_params(length=4)
        ax.xaxis.set_tick_params(length=4)
        # ax.grid(b=True, which='minor', c='w', lw=1, ls='--')
        ax.grid()
        legend = ax.legend()
        legend.get_frame().set_alpha(0.5)
        for spine in ('top', 'right', 'bottom', 'left'):
            ax.spines[spine].set_visible(False)

        return plt

    def generate_csv(self):

        chart_title = self.modelname
        outfilename = "_".join(
            chart_title.replace("|", " ").replace(":",
                                                  " ").replace(".",
                                                               " ").split())
        # Write a CSV to this directory
        with open(f"{outfilename}.csv", 'w') as outfile:
            for itr in range(0, len(self.scenario.out_susceptible)):
                outfile.write(f"{self.scenario.out_susceptible[itr]:.6f}, "
                              f"{self.scenario.out_incubating[itr]:.6f}, "
                              f"{self.scenario.out_infectious[itr]:.6f}, "
                              f"{self.scenario.sum_isolated[itr]:.6f}, "
                              f"{self.scenario.sum_noncrit[itr]:.6f}, "
                              f"{self.scenario.sum_icu[itr]:.6f}, "
                              f"{self.scenario.sum_icu_vent[itr]:.6f}, "
                              f"{self.scenario.sum_recovered[itr]:.6f}, "
                              f"{self.scenario.sum_deceased[itr]:.6f}, "
                              f"{self.scenario.sum_hospitalized[itr]:.6f}\n")
Пример #4
0
    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()
Пример #5
0
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
Пример #6
0
    def __init__(self, subgroupstats, name=None):

        self.name = name
        self.stats = subgroupstats
        # Variables to store state changes

        # Probability states
        self.isolated = ProbState(TIMINGS['days home isolation'],
                                  name=f"{self.name}: isolated")

        self.nevercrit = ProbState(TIMINGS['days noncrit'],
                                   name=f"{self.name}: nevercrit")
        self.pre_icu = ProbState(TIMINGS['days preicu'],
                                 name=f"{self.name}: pre_icu")
        self.icu_novent = ProbState(TIMINGS['days icu nonvent'],
                                    name=f"{self.name}: icu")
        self.icu_vent = ProbState(TIMINGS['days icu vent'],
                                  name=f"{self.name}: icu_vent")
        self.post_icu = ProbState(TIMINGS['days posticu'],
                                  name=f"{self.name}: post_icu")
        # Recovered and dead are presumed permanent
        self.recovered = ProbState(1000, name=f"{self.name}: recovered")
        self.deceased = ProbState(1000, name=f"{self.name}: deceased")

        self.isolated.add_exit_state(self.recovered, 1)
        self.isolated.normalize_states_over_period()

        self.nevercrit.add_exit_state(self.recovered, 1)
        self.nevercrit.normalize_states_over_period()

        self.pre_icu.add_exit_state(self.icu_novent, self.stats.p_icu_nonvent)
        self.pre_icu.add_exit_state(self.icu_vent, self.stats.p_icu_vent)
        self.pre_icu.normalize_states_over_period()

        self.icu_novent.add_exit_state(self.deceased, self.stats.p_icu_death)
        self.icu_novent.add_exit_state(self.post_icu,
                                       self.stats.p_icu_recovery)
        self.icu_novent.normalize_states_over_period()

        self.icu_vent.add_exit_state(self.deceased, self.stats.p_icu_death)
        self.icu_vent.add_exit_state(self.post_icu, self.stats.p_icu_recovery)
        self.icu_vent.normalize_states_over_period()

        self.post_icu.add_exit_state(self.recovered, 1)
        self.post_icu.normalize_states_over_period()
Пример #7
0
class PathsByAge:
    def __init__(self, subgroupstats, name=None):

        self.name = name
        self.stats = subgroupstats
        # Variables to store state changes

        # Probability states
        self.isolated = ProbState(TIMINGS['days home isolation'],
                                  name=f"{self.name}: isolated")

        self.nevercrit = ProbState(TIMINGS['days noncrit'],
                                   name=f"{self.name}: nevercrit")
        self.pre_icu = ProbState(TIMINGS['days preicu'],
                                 name=f"{self.name}: pre_icu")
        self.icu_novent = ProbState(TIMINGS['days icu nonvent'],
                                    name=f"{self.name}: icu")
        self.icu_vent = ProbState(TIMINGS['days icu vent'],
                                  name=f"{self.name}: icu_vent")
        self.post_icu = ProbState(TIMINGS['days posticu'],
                                  name=f"{self.name}: post_icu")
        # Recovered and dead are presumed permanent
        self.recovered = ProbState(1000, name=f"{self.name}: recovered")
        self.deceased = ProbState(1000, name=f"{self.name}: deceased")

        self.isolated.add_exit_state(self.recovered, 1)
        self.isolated.normalize_states_over_period()

        self.nevercrit.add_exit_state(self.recovered, 1)
        self.nevercrit.normalize_states_over_period()

        self.pre_icu.add_exit_state(self.icu_novent, self.stats.p_icu_nonvent)
        self.pre_icu.add_exit_state(self.icu_vent, self.stats.p_icu_vent)
        self.pre_icu.normalize_states_over_period()

        self.icu_novent.add_exit_state(self.deceased, self.stats.p_icu_death)
        self.icu_novent.add_exit_state(self.post_icu,
                                       self.stats.p_icu_recovery)
        self.icu_novent.normalize_states_over_period()

        self.icu_vent.add_exit_state(self.deceased, self.stats.p_icu_death)
        self.icu_vent.add_exit_state(self.post_icu, self.stats.p_icu_recovery)
        self.icu_vent.normalize_states_over_period()

        self.post_icu.add_exit_state(self.recovered, 1)
        self.post_icu.normalize_states_over_period()

    def get_floor_counts(self):
        retval = []
        for itr in range(0, len(self.nevercrit.domain)):
            val = self.nevercrit.domain[itr] + self.pre_icu.domain[
                itr] + self.post_icu.domain[itr]
            retval.append(val)
        return retval

    def get_icu_counts(self):
        retval = []
        for itr in range(0, len(self.icu_novent.domain)):
            val = self.icu_novent.domain[itr] + self.icu_vent.domain[itr]
            retval.append(val)
        return retval

    # Add N people to the list of infected
    def apply_infections(self, infections):
        inf_float = float(infections)
        n_isolated = inf_float * self.stats.p_selfisolate
        n_nevercrit = inf_float * self.stats.p_nevercrit
        n_pre_icu = inf_float * self.stats.p_pre_icu
        n_icu_vent = inf_float * self.stats.p_urgent_icu_vent
        n_icu_novent = inf_float * self.stats.p_urgent_icu_novent

        #		print(f"Storing infections {self.name}:  {n_nevercrit}, {n_pre_icu}, {n_icu_vent}, {n_icu_novent}")
        self.isolated.store_pending(n_isolated)
        self.nevercrit.store_pending(n_nevercrit)
        self.pre_icu.store_pending(n_pre_icu)
        self.icu_vent.store_pending(n_icu_vent)
        self.icu_novent.store_pending(n_icu_novent)

    def calculate_redistributions(self):
        self.isolated.pass_downstream()
        # self.ed_to_floor.pass_downstream()
        # self.ed_to_icu.pass_downstream()
        self.nevercrit.pass_downstream()
        self.pre_icu.pass_downstream()
        self.icu_novent.pass_downstream()
        self.icu_vent.pass_downstream()
        self.post_icu.pass_downstream()

    def apply_pending(self):
        self.isolated.apply_pending()

        # self.ed_to_floor.apply_pending()
        # self.ed_to_icu.apply_pending()
        self.nevercrit.apply_pending()
        self.pre_icu.apply_pending()
        self.icu_novent.apply_pending()
        self.icu_vent.apply_pending()
        self.post_icu.apply_pending()
        self.recovered.apply_pending()
        self.deceased.apply_pending()
class HospFloorModel:
    def __init__(self, scenario):
        if isinstance(scenario, str):
            self.scenario = EpiScenario(scenario)
        elif isinstance(scenario, EpiScenario):
            self.scenario = scenario

        self.modelname = self.scenario.modelname
        self.total_days = 0
        self.r0 = self.scenario.parameters['initial_r0']
        self.beta = None
        self.population = self.scenario.totalpop

        self.susceptible = ProbState(period=0,
                                     count=self.scenario.init_susceptible,
                                     name='susceptible')
        self.incubating = ProbState(period=self.scenario.incubation_period,
                                    count=self.scenario.init_infected,
                                    name='incubating')
        self.infectious = ProbState(period=self.scenario.prediagnosis,
                                    count=self.scenario.init_infectious,
                                    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 self.scenario.subgrouprates.items():
            self.subgroups[key] = PathsByAge(value, name=key)

        self.fitness = None

    def run(self):
        self.run_r0_set(self.scenario.r0_date_offsets, self.scenario.r0_values)

    def set_r0(self, value):
        self.r0 = value

    def run_r0_set(self, date_offsets, r0_values):
        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)
            print(f"{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} infections: {new_infections} = {self.beta} * {self.susceptible.count} * {self.infectious.count} / {self.population}")

        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
        subpop_out = []
        for key, agegroup in self.subgroups.items():
            subpop = diagnosed * agegroup.stats.pop_dist
            subpop_out.append(subpop)
            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

    def gather_sums(self):
        self.scenario.out_susceptible = self.susceptible.domain
        self.scenario.out_incubating = self.incubating.domain
        self.scenario.out_infectious = self.infectious.domain

        time_increments = len(self.susceptible.domain)
        self.scenario.sum_isolated = [0] * time_increments
        self.scenario.sum_floor = [0] * time_increments
        self.scenario.sum_icu = [0] * time_increments
        self.scenario.sum_vent = [0] * time_increments

        self.scenario.sum_recovered = [0] * time_increments
        self.scenario.sum_deceased = [0] * time_increments
        self.scenario.sum_hospitalized = [0] * time_increments

        for key, value in self.subgroups.items():
            self.scenario.sum_isolated = np.add(self.scenario.sum_isolated,
                                                value.isolated.domain)
            self.scenario.sum_floor = np.add(self.scenario.sum_floor,
                                             value.get_floor_counts())
            self.scenario.sum_icu = np.add(self.scenario.sum_icu,
                                           value.get_icu_counts())
            self.scenario.sum_vent = np.add(self.scenario.sum_vent,
                                            value.icu_vent.domain)
            self.scenario.sum_recovered = np.add(self.scenario.sum_recovered,
                                                 value.recovered.domain)
            self.scenario.sum_deceased = np.add(self.scenario.sum_deceased,
                                                value.deceased.domain)

        self.scenario.sum_hospitalized = np.add(self.scenario.sum_hospitalized,
                                                self.scenario.sum_floor)
        self.scenario.sum_hospitalized = np.add(self.scenario.sum_hospitalized,
                                                self.scenario.sum_icu)

    def calculate_fit(self, ideal):
        initial_offset = (ideal['start'] - self.scenario.initial_date).days
        fitcount = (ideal['end'] - ideal['start']).days
        final_offset = initial_offset + fitcount + 1

        cursor = initial_offset
        fitcur = 0
        hosp = self.scenario.sum_hospitalized
        dead = self.scenario.sum_deceased
        hosp_sum = 0
        hosp_r2 = 0
        dead_sum = 0
        dead_r2 = 0
        while cursor < final_offset:
            hosp_sum += hosp[cursor]
            dead_sum += hosp[cursor]
            hosp_r2 += (hosp[cursor] - ideal['hospitalized'][fitcur])**2
            dead_r2 += (dead[cursor] - ideal['deceased'][fitcur])**2
            fitcur += 1
            cursor += 1

        hosp_hold = math.sqrt(hosp_r2)
        dead_hold = math.sqrt(dead_r2)
        hosp_avg = hosp_sum / fitcount
        dead_avg = dead_sum / fitcount

        self.scenario.fitness = (hosp_hold / hosp_avg) + (dead_hold / dead_avg)

    def save_results(self, iteration):
        result = dict()

        result['iteration'] = iteration
        result['fitness'] = self.fitness
        result['scenario'] = self.scenario.parameters

        result['modelname'] = self.modelname
        result['total_days'] = self.total_days
        result['totalpop'] = self.population
        result['sum_isolated'] = self.scenario.sum_isolated
        result['sum_noncrit'] = self.scenario.sum_noncrit
        result['sum_icu'] = self.scenario.sum_icu
        result['sum_icu_vent'] = self.scenario.sum_icu_vent
        result['sum_recovered'] = self.scenario.sum_recovered
        result['sum_deceased'] = self.scenario.sum_deceased

        with open(f"best_fit{iteration}", "w") as bfi:
            json.dump(result, bfi)

    def actual_curves(self):
        cursor = self.scenario.initial_date
        finaldate = cursor + timedelta(self.scenario.maxdays)
        act_hosp = []
        act_death = []

        while cursor < finaldate:
            if cursor in COLORADO_ACTUAL:
                act_hosp.append(COLORADO_ACTUAL[cursor]['hospitalized'])
                act_death.append(COLORADO_ACTUAL[cursor]['deaths'])
            else:
                act_hosp.append(None)
                act_death.append(None)
            cursor += ONEDAY
        act_death.append(None)
        act_hosp.append(None)
        return act_hosp, act_death

    def generate_png(self):

        startdate = self.scenario.initial_date
        time_domain = [startdate]
        cursor = startdate
        for _ in range(0, self.total_days):
            cursor += ONEDAY
            time_domain.append(cursor)

    #	time_domain = np.linspace(0, model.total_days, model.total_days + 1)

        fig = plt.figure(facecolor='w')
        # ax = fig.add_subplot(111, axis_bgcolor='#dddddd', axisbelow=True)
        ax = fig.add_subplot(111, axisbelow=True)

        ###   Lines for comparison to actual
        act_hosp, act_death = self.actual_curves()
        ###   Actual Hospitalized, as specified in the constants
        ax.plot(time_domain,
                act_hosp,
                color=(0, 0, .5),
                alpha=1,
                lw=2,
                label='Actual Hospitalized',
                linestyle='-')
        ###   Actual Deaths, as specified in the constants
        ax.plot(time_domain,
                act_death,
                color=(0, 0, .5),
                alpha=1,
                lw=2,
                label='Actual Deaths',
                linestyle='-')

        ###   Susceptible line, usually too tall
        #   	ax.plot(time_domain, self.scenario.susceptible, color=(0, 0, 1), alpha=.5, lw=2, label='Susceptible', linestyle='-')
        ###   Recovered/immune, usually too tall
        #   	ax.plot(time_domain, self.scenario.sum_recovered, color=(0, .5, 0), alpha=.5, lw=2, label='Recovered', linestyle='--')

        ###   Infected patients who aren't infectious yet
        #   	ax.plot(time_domain, self.scenario.incubating, color=TABLEAU_ORANGE, alpha=0.1, lw=2, label='Exposed', linestyle='-')
        ###   Infectious patients who don't know they have it
        #   	ax.plot(time_domain, self.scenario.infectious, color=TABLEAU_RED, alpha=0.5, lw=2, label='Infected', linestyle='-')
        ###   Known and unknown infected, isolated at home
        #   	ax.plot(time_domain, self.scenario.sum_isolated, color=TAB_COLORS[8], alpha=.5, lw=2, label='Home Iso', linestyle='-')

        ###   Hospital floor patients
        ax.plot(time_domain,
                self.scenario.sum_floor,
                color=TABLEAU_BLUE,
                alpha=1,
                lw=2,
                label='Noncrit',
                linestyle='--')
        ###   Non-ventilated ICU patients
        ax.plot(time_domain,
                self.scenario.sum_icu,
                color=TABLEAU_GREEN,
                alpha=1,
                lw=2,
                label='ICU',
                linestyle='--')
        ###   Ventilated ICU patients
        ax.plot(time_domain,
                self.scenario.sum_vent,
                color=TABLEAU_RED,
                alpha=1,
                lw=2,
                label='ICU + Ventilator',
                linestyle='--')
        ###   Total hospitalized in all areas
        ax.plot(time_domain,
                self.scenario.sum_hospitalized,
                color=(1, 0, 0),
                alpha=.25,
                lw=2,
                label='Total Hospitalized',
                linestyle='-')
        ###   Deceased
        ax.plot(time_domain,
                self.scenario.sum_deceased,
                color=(0, 0, 0),
                alpha=.5,
                lw=2,
                label='Dead',
                linestyle=':')

        ###   Max non-icu capacity
        #		ax.plot(time_domain, [229] * (self.total_days + 1), color=(0, 0, 1), alpha=1, lw=1, label='229 Floor beds', linestyle='-')
        ###   Max ICU capacity
        #		ax.plot(time_domain, [86] * (self.total_days + 1), color=(1, 0, 0), alpha=1, lw=1, label='86 ICU units', linestyle='-')

        ### Vertical line indicating today
        plt.axvline(x=datetime.today(), alpha=.5, lw=2, label='Today')

        ax.set_xlabel('Days')
        ax.set_ylabel('Number')

        chart_title = self.modelname
        plt.title(chart_title, fontsize=14)
        # ax.set_ylim(0,1.2)
        ax.yaxis.set_tick_params(length=4)
        ax.xaxis.set_tick_params(length=4)
        # ax.grid(b=True, which='minor', c='w', lw=1, ls='--')
        ax.grid()
        legend = ax.legend()
        legend.get_frame().set_alpha(0.5)
        for spine in ('top', 'right', 'bottom', 'left'):
            ax.spines[spine].set_visible(False)

        return plt

    def generate_csv(self):

        chart_title = self.modelname
        outfilename = "_".join(
            chart_title.replace("|", " ").replace(":",
                                                  " ").replace(".",
                                                               " ").split())

        # Write a CSV to this directory
        with open(f"{outfilename}.csv", 'w') as outfile:
            for itr in range(0, len(self.scenario.out_susceptible)):
                outfile.write(f"{self.scenario.out_susceptible[itr]:.6f}, "
                              f"{self.scenario.out_incubating[itr]:.6f}, "
                              f"{self.scenario.out_infectious[itr]:.6f}, "
                              f"{self.scenario.sum_isolated[itr]:.6f}, "
                              f"{self.scenario.sum_floor[itr]:.6f}, "
                              f"{self.scenario.sum_icu[itr]:.6f}, "
                              f"{self.scenario.sum_vent[itr]:.6f}, "
                              f"{self.scenario.sum_recovered[itr]:.6f}, "
                              f"{self.scenario.sum_deceased[itr]:.6f}, "
                              f"{self.scenario.sum_hospitalized[itr]:.6f}\n")
	def __init__(self, subgroupstats, name=None):

		self.name = name
		self.stats = subgroupstats
		# Variables to store state changes

		# Probability states
		if self.name is not None:
			self.isolated = ProbState(14,  name=f"{self.name}: isolated")
		else:
			self.isolated = ProbState(14)
		self.h_noncrit  = ProbState(8)
		self.h_post_icu = ProbState(6)
		self.h_icu      = ProbState(10)
		self.h_icu_vent = ProbState(10)
		self.recovered  = ProbState(1000)
		self.deceased   = ProbState(1000)

		self.isolated.add_exit_state(self.recovered, 1)
		self.isolated.normalize_states_over_period()

		self.h_noncrit.add_exit_state(self.recovered, 1)
		self.h_noncrit.normalize_states_over_period()

		self.h_icu.add_exit_state(self.deceased,   self.stats.p_icu_death)
		self.h_icu.add_exit_state(self.h_post_icu, self.stats.p_icu_recovery)
		self.h_icu.normalize_states_over_period()

		self.h_icu_vent.add_exit_state(self.deceased,   self.stats.p_icu_death)
		self.h_icu_vent.add_exit_state(self.h_post_icu, self.stats.p_icu_recovery)
		self.h_icu_vent.normalize_states_over_period()

		self.h_post_icu.add_exit_state(self.recovered, 1)
		self.h_post_icu.normalize_states_over_period()
class AgeGroup:
	def __init__(self, subgroupstats, name=None):

		self.name = name
		self.stats = subgroupstats
		# Variables to store state changes

		# Probability states
		if self.name is not None:
			self.isolated = ProbState(14,  name=f"{self.name}: isolated")
		else:
			self.isolated = ProbState(14)
		self.h_noncrit  = ProbState(8)
		self.h_post_icu = ProbState(6)
		self.h_icu      = ProbState(10)
		self.h_icu_vent = ProbState(10)
		self.recovered  = ProbState(1000)
		self.deceased   = ProbState(1000)

		self.isolated.add_exit_state(self.recovered, 1)
		self.isolated.normalize_states_over_period()

		self.h_noncrit.add_exit_state(self.recovered, 1)
		self.h_noncrit.normalize_states_over_period()

		self.h_icu.add_exit_state(self.deceased,   self.stats.p_icu_death)
		self.h_icu.add_exit_state(self.h_post_icu, self.stats.p_icu_recovery)
		self.h_icu.normalize_states_over_period()

		self.h_icu_vent.add_exit_state(self.deceased,   self.stats.p_icu_death)
		self.h_icu_vent.add_exit_state(self.h_post_icu, self.stats.p_icu_recovery)
		self.h_icu_vent.normalize_states_over_period()

		self.h_post_icu.add_exit_state(self.recovered, 1)
		self.h_post_icu.normalize_states_over_period()


	# Add N people to the list of infected
	def apply_infections(self, infections):
		inf_float = float(infections)
		self.isolated.store_pending(inf_float * self.stats.p_selfisolate)
		self.h_noncrit.store_pending(inf_float * self.stats.p_nevercrit)
		self.h_icu.store_pending(inf_float * self.stats.p_icu_nonvent)
		self.h_icu_vent.store_pending(inf_float * self.stats.p_icu_vent)

	def calculate_redistributions(self):
		self.isolated.pass_downstream()
		self.h_noncrit.pass_downstream()
		self.h_icu.pass_downstream()
		self.h_icu_vent.pass_downstream()

	def apply_pending(self):
		self.isolated.apply_pending()
		self.h_noncrit.apply_pending()
		self.h_icu.apply_pending()
		self.h_icu_vent.apply_pending()
		self.recovered.apply_pending()
		self.deceased.apply_pending()
Пример #11
0
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
Пример #12
0
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]