Example #1
0
 def transmission_success(self, person, contact_strength):
     days_infected = self.day - self.infection_start_date[person]
     likelihood = self.serial_interval_distribution[days_infected]
     if person in self.symptomatic_infecteds:
         likelihood *= 1.6
     else:
         likelihood *= 0.8
     return probtools.random_event(1 - (1 - likelihood)**contact_strength)
Example #2
0
 def event(self,etype,person,**kwargs):
     if etype == 'quarantined':
         self.quarantined[person] = True
         self.quarantine_end_day[person] = self.quarantine_days + self.day
         self.quarantine_start_day[person] = self.day
         self.registrar.register_departure(person)
         self._record_state_change(person,'quarantined')
         return
     elif etype == 'dequarantined':
         del self.quarantined[person]
         self.registrar.register_return(person)
         self._record_state_change(person,'dequarantined')
         return
     elif etype == 'removed':
         self.removed[person] = True
         if person in self.symptomatic_infecteds:
             del self.symptomatic_infecteds[person]
         del self.infected[person]
         del self.infection_start_date[person]
         if 'artificial' not in kwargs:
             self.average_transmissions *= self.completed_infections
             self.completed_infections += 1
             self.average_transmissions += self.infection_transmissions[person]
             self.average_transmissions /= self.completed_infections
         self._record_state_change(person,'removed')
         return
     elif etype == 'infected':
         del self.susceptible[person]
         self.infected[person] = True
         self.infection_start_date[person] = self.day
         self.infection_detectable_day[person] = self.day + self.days_indetectable
         self.infection_transmissions[person] = 0
         if probtools.random_event(self.symptomatic_fraction):
             self.symptomatic_infecteds[person] = True
             self.symptomatic_day[person] = self.day + self.incubation_picker.draw()
         self.infection_end_day[person] = self.day + self.recovery_days
         self._record_state_change(person,'infected')
         return
     elif etype == 'new person':
         if person in self.registrar.student_data:
             pstring = 'student ' + str(self.registrar.student_data[person]['cohort'])
         else:
             pstring = 'instructor'
         self.susceptible[person] = True
         self.person_state[person] = ('nonquarantined','susceptible',pstring)
         self.all_individuals[person] = True
         self._record_state_change(person,None)
         if 'infected' in kwargs and kwargs['infected'] == True:
             self.event('infected',person,infected_by=None,message='Initially Infected')
         elif 'removed' in kwargs and kwargs['removed'] == True:
             self.event('infected',person,infected_by=None,artificial=True,message='Infection-Pending Initial Removal')
             self.event('removed',person,artificial=True,message='Initially Removed')
         return
     raise Exception('Unknown event',etype)
Example #3
0
    def execute_main_step(self):
        self.day += 1
        self.registrar.update_query_system()
        self.tests_performed_today = 0
        self.contact_traces_performed_today = 0
        self.positive_tests_today = 0

        if self.quarantining:
            for person in self.all_individuals:
                if probtools.random_event(self.daily_testing_fraction):
                    result = self.testing_queue.add(person,
                                                    abort_if=self.quarantined)
            for person in self.testing_queue:
                test_result = self.get_test_result(
                    person)  # Need to change so that all tests are forced
                if test_result > 0 and person not in self.quarantined:
                    self.event('quarantined',
                               person,
                               message='Quarantined on Positive Test Result')
                if test_result > 0 and self.contact_tracing:
                    self.contact_tracing_queue.add(person)
            for person in self.symptomatic_infecteds:
                if self.day == self.symptomatic_day[person]:
                    if person not in self.quarantined:
                        self.event('quarantined',
                                   person,
                                   message='Quarantined on Reported Symptoms')
                        if self.contact_tracing:
                            self.contact_tracing_queue.add(person)

        to_be_released = {}
        for person in self.quarantined:
            if self.day == self.quarantine_end_day[person]:
                to_be_released[person] = True
        for person in to_be_released:
            self.event('dequarantined',
                       person,
                       message='Released from Quarantine today')
        to_be_removed = {}
        for person in self.infected:
            if self.day == self.infection_end_day[person]:
                to_be_removed[person] = True
        for person in to_be_removed:
            self.event('removed', person, message='Removed from infection')

        if self.contact_tracing:
            for person in self.contact_tracing_queue:
                self.contact_traces_performed_today += 1
                first_trace_day = self.day - self.contact_tracing_days
                post_trace_day = self.day
                if person in self.quarantined:
                    post_trace_day = min(post_trace_day,
                                         self.quarantine_start_day[person] + 1)
                for trace_day in range(first_trace_day, post_trace_day):
                    identified_contacts = self.registrar.query_contacts(
                        person, trace_day - self.day)
                    for found_individual in identified_contacts:
                        if found_individual in self.all_individuals and found_individual not in self.quarantined:
                            actions = probtools.random_threshold({
                                'test':
                                self.contact_tracing_testing_rate,
                                'quarantine':
                                self.contact_tracing_quarantine_rate
                            })
                            if 'test' in actions:
                                self.testing_queue.add(
                                    found_individual,
                                    abort_if=self.quarantined)
                            if 'quarantine' in actions and found_individual not in self.quarantined:
                                self.event(
                                    'quarantined',
                                    found_individual,
                                    message='Quarantined on Contact Trace')

        to_be_infected = {}
        for person in self.infected:
            if person not in self.quarantined:
                contact_information = self.registrar.query_transmit(person)
                for potential_infected in contact_information:
                    if potential_infected in self.susceptible and potential_infected not in self.quarantined and potential_infected not in to_be_infected and self.transmission_success(
                            person, contact_information[potential_infected]):
                        to_be_infected[potential_infected] = person
                        self.infection_transmissions[person] += 1

        for person in to_be_infected:
            self.event('infected',
                       person,
                       infected_by=to_be_infected[person],
                       message='Infection by transmission')

        new_cases_to_create = self.daily_outside_cases
        if type(new_cases_to_create) == list:
            new_cases_to_create = probtools.list_select(new_cases_to_create)
        for index in range(new_cases_to_create):
            person = probtools.list_select(list(self.susceptible.keys()))
            if person is not None and person not in self.quarantined:
                self.event('infected',
                           person,
                           infected_by=None,
                           message='infected by outside source')

        self.recorded_info[
            'tests_performed_today'] = self.tests_performed_today
        self.recorded_info[
            'contact_traces_performed_today'] = self.contact_traces_performed_today
        self.recorded_info['positive_tests_today'] = self.positive_tests_today
        self.recorded_info['day'] = self.day
        self.recorded_info['R'] = self.average_transmissions
        for key, value in self.registrar.get_attendance().items():
            self.recorded_info[key] = value