Beispiel #1
0
 def tick(self):
     v = get_parameters().get('risk_tolerance_mean') - 0.1
     if v < 0.1:
         v = 0.1
     logger().debug(f'Global risk_tolerance change to {v}')
     change_parameters(risk_tolerance_mean=v)
     self.model.reroll_human_properties()
Beispiel #2
0
 def invite_friends_to_restaurant(self):
     shape = self.properties.risk_tolerance * get_parameters().get('typical_restaurant_event_size')
     event_size = np.random.gamma(shape, 1)
     logger().debug(f"Restaurant event size of {self} is {event_size}")
     accepted = [self]
     for human in self.tribe[TribeSelector.FRIEND]:
         if human != self and human.personal_decision(Dilemma.ACCEPT_FRIEND_INVITATION_TO_RESTAURANT):
             accepted.append(human)
             if len(accepted) >= event_size:
                 break
     if len(accepted) == 1:
         return
     outdoor = flip_coin(linear_rescale(self.properties.risk_tolerance, 0, 0.5))
     if flip_coin(linear_rescale(self.work_info.base_income, 0, 1 / 5)):
         restaurant_type = RestaurantType.FANCY
     else:
         restaurant_type = RestaurantType.FAST_FOOD
     event = self.work_district.get_available_restaurant(len(accepted), outdoor, restaurant_type)
     if event is not None and not outdoor:
         event = self.work_district.get_available_restaurant(len(accepted), True, restaurant_type)
     if event is None:
         return
     event.available -= len(accepted)
     for human in accepted:
         human.social_event = (self, event)
Beispiel #3
0
 def spread_infection(self):
     if len(self.humans) > 0:
         logger().info(f"{self} is spreading infection amongst {len(self.humans)} humans")
     for h1 in self.humans:
         if h1.is_infected() and not h1.is_hospitalized() and not h1.is_isolated():
             for h2 in self.humans:
                 if h1 != h2:
                     self.check_spreading(h1, h2)
Beispiel #4
0
 def spread_infection(self):
     if len(self.humans) > 0:
         logger().info(f"{self} is spreading infection amongst {len(self.humans)} humans")
     for h1 in self.humans:
         for h2 in self.humans:
             if h1 != h2:
                 if h1.social_event == h2.social_event or \
                         flip_coin(0.25 * self.get_parameter('allowed_restaurant_capacity')):
                     self.check_spreading(h1, h2)
Beispiel #5
0
 def spread_infection(self):
     if len(self.humans) > 0:
         logger().info(
             f"{self} is spreading infection amongst {len(self.humans)} humans"
         )
     for h1 in self.humans:
         for h2 in self.humans:
             if h1 != h2:
                 self.check_spreading(h1, h2)
Beispiel #6
0
 def disease_evolution(self):
     # https://media.tghn.org/medialibrary/2020/06/ISARIC_Data_Platform_COVID-19_Report_8JUN20.pdf
     # https://www.ecdc.europa.eu/en/covid-19/latest-evidence
     if self.is_infected():
         self.infection_days_count += 1
         if self.disease_severity == DiseaseSeverity.ASYMPTOMATIC:
             if self.infection_days_count >= self.infection_incubation:
                 logger().info(f"{self} evolved from ASYMPTOMATIC to LOW")
                 self.disease_severity = DiseaseSeverity.LOW
                 self.covid_model.global_count.asymptomatic_count -= 1
                 self.covid_model.global_count.symptomatic_count += 1
                 day = self.covid_model.global_count.day_count
                 if day not in self.covid_model.global_count.new_symptomatic_count:
                     self.covid_model.global_count.new_symptomatic_count[day] = 0
                 self.covid_model.global_count.new_symptomatic_count[day] += 1
         elif self.disease_severity == DiseaseSeverity.LOW:
             if self.infection_days_count > self.infection_incubation + self.mild_duration:
                 # By the end of this period, either the patient is already with antibodies at
                 # a level sufficient to cure the disease or the symptoms will get worse and he/she
                 # will require hospitalization
                 if self.death_mark or flip_coin(self.moderate_severity_prob):
                     # MODERATE cases requires hospitalization
                     logger().info(f"{self} evolved from LOW to MODERATE")
                     self.disease_severity = DiseaseSeverity.MODERATE
                     self.covid_model.global_count.moderate_severity_count += 1
                     if not self.covid_model.reached_hospitalization_limit():
                         self.hospitalize()
                     else:
                         logger().info(f"{self} couldn't be hospitalized (hospitalization limit reached)")
                 else:
                     self.recover()
         elif self.disease_severity == DiseaseSeverity.MODERATE:
             if self.infection_days_count >= self.infection_incubation + self.mild_duration + self.hospitalization_duration:
                 if self.death_mark or flip_coin(self.high_severity_prob):
                     logger().info(f"{self} evolved from MODERATE to HIGH")
                     self.disease_severity = DiseaseSeverity.HIGH
                     self.covid_model.global_count.moderate_severity_count -= 1
                     self.covid_model.global_count.high_severity_count += 1
                     # If the disease evolves to HIGH and the person could not
                     # be accommodated in a hospital, he/she will die.
                     if not self.hospitalized or self.covid_model.reached_icu_limit():
                         self.die()
                     else:
                         shape = get_parameters().get('icu_period_duration_shape')
                         scale = get_parameters().get('icu_period_duration_scale')
                         self.icu_duration = np.random.gamma(shape, scale)
                         self.has_been_icu = True
                         logger().debug(f"ICU duration of {self} is {self.icu_duration}")
                 else:
                     self.recover()
         elif self.disease_severity == DiseaseSeverity.HIGH:
             if self.infection_days_count >= self.infection_incubation + self.mild_duration +\
             self.hospitalization_duration + self.icu_duration:
                 if self.death_mark:
                     self.die()
                 else:
                     self.recover()
Beispiel #7
0
 def get_available_restaurant(self, people_count, outdoor, restaurant_type):
     for location in self.locations:
         if isinstance(location, Restaurant) and \
                 location.restaurant_type == restaurant_type and \
                 location.is_outdoor == outdoor and \
                 ((location.capacity - location.available) + people_count) <= \
                 location.capacity * self.get_parameter('allowed_restaurant_capacity'):
             return location
     logger().info("No restaurant is available")
     return None
Beispiel #8
0
 def die(self):
     logger().info(f"{self} died")
     self.covid_model.global_count.symptomatic_count -= 1
     self.disease_severity = DiseaseSeverity.DEATH
     self.covid_model.global_count.high_severity_count -= 1
     self.covid_model.global_count.infected_count -= 1
     self.covid_model.global_count.death_count += 1
     if self.hospitalized:
         self.leave_hospital()
     self.is_dead = True
Beispiel #9
0
 def hospitalize(self):
     self.hospitalized = True
     self.has_been_hospitalized = True
     if self.hospital_district is not None:
         self.hospital = self.hospital_district.get_available_hospital()
         self.hospital.patients.append(self)
     self.covid_model.global_count.total_hospitalized += 1
     logger().info(f"{self} is now hospitalized")
     shape = get_parameters().get('hospitalization_period_duration_shape')
     scale = get_parameters().get('hospitalization_period_duration_scale')
     self.hospitalization_duration = np.random.gamma(shape, scale)
     logger().debug(f"Hospital duration of {self} is {self.hospitalization_duration}")
Beispiel #10
0
 def infect(self):
     # https://www.acpjournals.org/doi/10.7326/M20-0504
     # https://media.tghn.org/medialibrary/2020/06/ISARIC_Data_Platform_COVID-19_Report_8JUN20.pdf
     # https://www.ecdc.europa.eu/en/covid-19/latest-evidence
     if not self.immune and not self.is_infected():
         # Evolve disease severity based in this human's specific
         # attributes and update global counts
         logger().info(f"Infected {self}")
         self.covid_model.global_count.infected_count += 1
         self.covid_model.global_count.non_infected_count -= 1
         self.covid_model.global_count.susceptible_count -= 1
         self.infection_status = InfectionStatus.INFECTED
         self.disease_severity = DiseaseSeverity.ASYMPTOMATIC
         self.covid_model.global_count.asymptomatic_count += 1
         shape = get_parameters().get('latency_period_shape')
         scale = get_parameters().get('latency_period_scale')
         self.infection_latency = np.random.gamma(shape, scale) - self.early_symptom_detection
         logger().debug(f"Infection latency of {self} is {self.infection_latency}")
         if self.infection_latency < 1.0:
             self.infection_latency = 1.0
         shape = get_parameters().get('incubation_period_shape')
         scale = get_parameters().get('incubation_period_scale')
         self.infection_incubation = self.infection_latency + np.random.gamma(shape, scale)
         logger().debug(f"Infection incubation of {self} is {self.infection_incubation}")
         shape = get_parameters().get('mild_period_duration_shape')
         scale = get_parameters().get('mild_period_duration_scale')
         self.mild_duration = np.random.gamma(shape, scale) + self.infection_incubation
         logger().debug(f"Mild duration of {self} is {self.mild_duration}")
Beispiel #11
0
 def recover(self):
     logger().info(f"{self} is recovered after a disease of severity {self.disease_severity}")
     self.covid_model.global_count.recovered_count += 1
     if self.disease_severity == DiseaseSeverity.MODERATE:
         self.covid_model.global_count.moderate_severity_count -= 1
     elif self.disease_severity == DiseaseSeverity.HIGH:
         self.covid_model.global_count.high_severity_count -= 1
     self.covid_model.global_count.infected_count -= 1
     if self.hospitalized:
         self.leave_hospital()
     self.infection_status = InfectionStatus.RECOVERED
     self.disease_severity = DiseaseSeverity.ASYMPTOMATIC
     self.covid_model.global_count.symptomatic_count -= 1
     self.covid_model.global_count.asymptomatic_count += 1
     self.immune = True
Beispiel #12
0
def build_district(name, model, population_size, building_capacity,
                   unit_capacity, occupacy_rate, contagion_probability):
    logger().info(
        f"Building district {name} contagion_probability = {contagion_probability}"
    )
    district = District(name, model, '', name)
    building_count = math.ceil(
        math.ceil(population_size / unit_capacity) * (1 / occupacy_rate) /
        building_capacity)
    for i in range(building_count):
        building = HomogeneousBuilding(building_capacity, model, name, str(i))
        for j in range(building_capacity):
            unit = BuildingUnit(unit_capacity,
                                model,
                                name,
                                str(i) + '-' + str(j),
                                contagion_probability=contagion_probability)
            building.locations.append(unit)
        district.locations.append(building)
    return district
Beispiel #13
0
 def get_available_restaurant(self, people_count, outdoor, restaurant_type,
                              favorites):
     #print ("favorites")
     #print (favorites)
     #for location in self.locations:
     for location in favorites:
         #print("location.strid")
         #print (location.strid)
         #print(isinstance(location, Restaurant))
         #print(location.restaurant_type == restaurant_type))
         #print(location.is_outdoor == outdoor)
         #print(        ((location.capacity - location.available) + people_count) <= \
         #location.capacity * self.get_parameter('allowed_restaurant_capacity') )
         if isinstance(location, Restaurant) and \
                 location.restaurant_type == restaurant_type and \
                 location.is_outdoor == outdoor and \
                 ((location.capacity - location.available) + people_count) <= \
                 location.capacity * self.get_parameter('allowed_restaurant_capacity'):
             return location
     logger().info("No restaurant is available")
     return None
Beispiel #14
0
    def infect(self, unit=None):
        # https://www.acpjournals.org/doi/10.7326/M20-0504
        # https://media.tghn.org/medialibrary/2020/06/ISARIC_Data_Platform_COVID-19_Report_8JUN20.pdf
        # https://www.ecdc.europa.eu/en/covid-19/latest-evidence
        if not self.immune and not self.is_infected():
            # Evolve disease severity based in this human's specific
            # attributes and update global counts
            logger().info(f"Infected {self}")

            # Commented because covid_model doesn't have `hrf`
            #vec = self.covid_model.hrf.feature_vector[self]
            #blob = self.covid_model.hrf.vector_to_blob[vec]
            #if blob is not None:
            #    self.covid_model.actual_infections["blob"].append(blob)
            #    self.covid_model.actual_infections["strid"].append(self.strid)
            #    self.covid_model.actual_infections["unit"].append(unit.strid if unit is not None else None)
            #    self.covid_model.actual_infections["day"].append(self.covid_model.global_count.day_count)

            self.covid_model.global_count.infected_count += 1
            self.covid_model.global_count.non_infected_count -= 1
            self.covid_model.global_count.susceptible_count -= 1
            self.infection_status = InfectionStatus.INFECTED
            self.disease_severity = DiseaseSeverity.ASYMPTOMATIC
            self.covid_model.global_count.asymptomatic_count += 1
            shape = get_parameters().get('latency_period_shape')
            scale = get_parameters().get('latency_period_scale')
            self.infection_latency = np.random.gamma(shape, scale) - self.early_symptom_detection
            if self.infection_latency < 1.0:
                self.infection_latency = 1.0
            logger().debug(f"Infection latency of {self} is {self.infection_latency}")
            shape = get_parameters().get('incubation_period_shape')
            scale = get_parameters().get('incubation_period_scale')
            self.infection_incubation = np.random.gamma(shape, scale)
            logger().debug(f"Infection incubation of {self} is {self.infection_incubation}")
            shape = get_parameters().get('mild_period_duration_shape')
            scale = get_parameters().get('mild_period_duration_scale')
            self.mild_duration = np.random.gamma(shape, scale)
            logger().debug(f"Mild duration of {self} is {self.mild_duration}")
Beispiel #15
0
 def spread_infection(self):
     if len(self.patients) > 0:
         logger().info(f"{self} is spreading infection patients -> workers")
         print(f"{self} is spreading infection patients -> workers")
         for worker in humans:
             for patient in patients:
                 if not flip_coin(r):
                     continue
                 logger().debug(
                     f"Check to see if patient {patient} can infect worker {worker} in {self}"
                 )
                 print(
                     f"Check to see if patient {patient} can infect worker {worker} in {self}"
                 )
                 if not worker.is_infected():
                     logger().debug(
                         f"contagion_probability = {self.get_parameter('contagion_probability')}"
                     )
                     if flip_coin(
                             self.get_parameter('contagion_probability')):
                         if worker.strid not in self.covid_model.global_count.infection_info:
                             self.covid_model.global_count.infection_info[
                                 worker.strid] = self
                         logger().debug(
                             f"Infection succeeded - {patient} has infected {worker} in {self} with contagion "
                             f"probability {self.get_parameter('contagion_probability')}"
                         )
                         print(
                             f"Infection succeeded - {patient} has infected {worker} in {self} with contagion "
                             f"probability {self.get_parameter('contagion_probability')}"
                         )
                         patient.count_infected_humans += 1
                         worker.infect(patient)
                     else:
                         logger().debug(
                             f"Infection failed - {self} didn't pass contagion_probability check with contagion "
                             f"probability {self.get_parameter('contagion_probability')}"
                         )
                         print(
                             f"Infection failed - {self} didn't pass contagion_probability check with contagion "
                             f"probability {self.get_parameter('contagion_probability')}"
                         )
                 else:
                     logger().debug(
                         f"Infection failed - infectee {worker} is already infected"
                     )
                     print(
                         f"Infection failed - infectee {worker} is already infected"
                     )
     super().spread_infection()  # amongst workers only
Beispiel #16
0
    def personal_decision(self, dilemma):
        if dilemma == Dilemma.GO_TO_WORK_ON_LOCKDOWN:
            if self.work_info.work_class == WorkClasses.RETAIL:
                pd = flip_coin(self.properties.risk_tolerance)
                hd = self.dilemma_history.herding_decision(self, dilemma, TribeSelector.FRIEND,
                                                           get_parameters().get('min_behaviors_to_copy'))
                answer = self._standard_decision(pd, hd)
                logger().debug(f'{self}({self.unique_id}) had risk tolerance of {self.properties.risk_tolerance} in decision to work retail, making a personal decision of {pd} but a herding decision of {hd}')
            else:
                answer = False
            if answer:
                logger().info(f"{self} decided to get out to work on lockdown")
        elif dilemma == Dilemma.INVITE_FRIENDS_TO_RESTAURANT:
            if self.social_event is not None or self.is_symptomatic():
                # don't update dilemma_history since it's a compulsory decision
                return False
            rt = self.properties.risk_tolerance
            if SocialPolicy.SOCIAL_DISTANCING in get_parameters().get('social_policies'):
                rt = rt * rt
            k = 3  # TODO parameter
            d = self.covid_model.global_count.infected_count / self.covid_model.global_count.total_population
            rt = rt * math.exp(-k * d)
            pd = flip_coin(rt)
            hd = self.dilemma_history.herding_decision(self,dilemma, TribeSelector.FRIEND,
                    get_parameters().get('min_behaviors_to_copy'))
            answer = self._standard_decision(pd, hd)
            logger().debug(f'{self}({self.unique_id}) had risk tolerance of {rt} in decision to invite, making a personal decision of {pd} but a herding decision of {hd} and answer of {answer}')
            

            if answer: logger().info(f"{self} decided to invite friends to a restaurant")
        elif dilemma == Dilemma.ACCEPT_FRIEND_INVITATION_TO_RESTAURANT:
            if self.social_event is not None or self.is_symptomatic():
                # don't update dilemma_history since it's a compulsory decision
                return False
            rt = self.properties.risk_tolerance
            if SocialPolicy.SOCIAL_DISTANCING in get_parameters().get('social_policies'):
                rt = rt * rt
            k = 3  # TODO parameter
            d = self.covid_model.global_count.infected_count / self.covid_model.global_count.total_population
            rt = rt * math.exp(-k * d)
            pd = flip_coin(rt)
            hd = self.dilemma_history.herding_decision(self,dilemma, TribeSelector.FRIEND,
                    get_parameters().get('min_behaviors_to_copy'))
            answer = self._standard_decision(pd, hd)
            logger().debug(f'{self}({self.unique_id}) had risk tolerance of {rt} in decision to accept invite, making a personal decision of {pd} but a herding decision of {hd} and answer of {answer}')
            
            if answer:
                logger().info(f"{self} decided to accept an invitation to go to a restaurant")
        else:
            assert False
        for tribe in TribeSelector:
            self.dilemma_history.history[dilemma][tribe].append(answer)
        return answer
Beispiel #17
0
sc7_model.add_listener(
    RemovePolicy(sc7_model, SocialPolicy.LOCKDOWN_OFFICE, 90))
sc7_model.add_listener(
    RemovePolicy(sc7_model, SocialPolicy.LOCKDOWN_ELEMENTARY_SCHOOL, 90))
sc7_model.add_listener(
    RemovePolicy(sc7_model, SocialPolicy.LOCKDOWN_MIDDLE_SCHOOL, 90))
sc7_model.add_listener(
    RemovePolicy(sc7_model, SocialPolicy.LOCKDOWN_HIGH_SCHOOL, 120))
scenario[sc]['parameters'] = sc7_parameters
scenario[sc]['model'] = sc7_model

################################################################################
# Simulation of all scenarios

for sc in scenario:
    # for sc in [1]:
    # print("--------------------------------------------------------------------------------")
    print(f"Running scenario {sc}")
    set_parameters(scenario[sc]['parameters'])
    model = scenario[sc]['model']
    debug = DebugUtils(model)
    logger().model = model
    model.reset_randomizer(seed)
    statistics = BasicStatistics(model)
    model.add_listener(statistics)
    for i in range(simulation_cycles):
        model.step()
    statistics.export_chart("scenario" + str(sc) + ".png")
    statistics.export_csv("scenario" + str(sc) + ".csv")
# debug.print_infection_status()
Beispiel #18
0
    def check_spreading(self, h1, h2):
        if h1.is_infected():
            logger().debug(f"Check to see if {h1} can infect {h2} in {self}")
            if h1.is_contagious() and not h2.is_infected():
                if flip_coin(self.get_parameter('contagion_probability')):
                    me = self.get_parameter('mask_efficacy')
                    if not h1.is_wearing_mask() or (h1.is_wearing_mask()
                                                    and not flip_coin(me)):
                        if h2.strid not in self.covid_model.global_count.infection_info:
                            self.covid_model.global_count.infection_info[
                                h2.strid] = self
                        logger().debug(
                            f"Infection succeeded - {h1} has infected {h2} in {self} with contagion "
                            f"probability {self.get_parameter('contagion_probability')}"
                        )

                        h2.infect()
                    else:
                        if h1.is_wearing_mask():
                            logger().debug(
                                f"Infection failed - infector {h1} wearing mask"
                            )
                        if h2.is_wearing_mask():
                            logger().debug(
                                f"Infection failed - infectee {h2} wearing mask"
                            )
                else:
                    logger().debug(
                        f"Infection failed - {self} didn't pass contagion_probability check with contagion "
                        f"probability {self.get_parameter('contagion_probability')}"
                    )
            else:
                if not h1.is_contagious():
                    logger().debug(
                        f"Infection failed - infector {h1} is not contagious")
                if h2.is_infected():
                    logger().debug(
                        f"Infection failed - infectee {h2} is already infected"
                    )