def test_propaganda(): model = CovidModel() get_parameters().params['risk_tolerance_mean'] = 1.0 propaganda = Propaganda(model, 5) model.add_listener(propaganda) assert get_parameters().params['risk_tolerance_mean'] == 1.0 for i in range(5): model.step() assert get_parameters().params['risk_tolerance_mean'] == 1.0 model.step() assert get_parameters().params['risk_tolerance_mean'] == 0.9 model.step() assert get_parameters().params['risk_tolerance_mean'] == 0.9 model.step() assert get_parameters().params['risk_tolerance_mean'] == 0.9 model.step() assert get_parameters().params['risk_tolerance_mean'] == 0.8 for i in range(2): model.step() assert get_parameters().params['risk_tolerance_mean'] == 0.8 for i in range(7): for j in range(3): model.step() assert (get_parameters().params['risk_tolerance_mean'] - (0.7 - (0.1 * i))) < 0.001 for i in range(100): model.step() assert get_parameters().params['risk_tolerance_mean'] == 0.1
def initialize_individual_properties(self): super().initialize_individual_properties() mean = get_parameters().get('risk_tolerance_mean') stdev = get_parameters().get('risk_tolerance_stdev') self.properties.risk_tolerance = normal_cap(mean, stdev, 0.0, 1.0) mean = get_parameters().get('herding_behavior_mean') stdev = get_parameters().get('herding_behavior_stdev') self.properties.herding_behavior = normal_cap(mean, stdev, 0.0, 1.0)
def initialize_individual_properties(self): super().initialize_individual_properties() mean = get_parameters().get('risk_tolerance_mean') stdev = get_parameters().get('risk_tolerance_stdev') self.properties.risk_tolerance = beta_distribution(mean, stdev) mean = get_parameters().get('herding_behavior_mean') stdev = get_parameters().get('herding_behavior_stdev') self.properties.herding_behavior = beta_distribution(mean, stdev)
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()
def parameter_changed(self): self.mask_user = flip_coin(get_parameters().get('mask_user_rate')) self.isolation_cheater = flip_coin( get_parameters().get('isolation_cheater_rate')) self.immune = flip_coin(get_parameters().get('imune_rate')) if flip_coin(get_parameters().get('weareable_adoption_rate')): self.early_symptom_detection = 1 # number of days else: self.early_symptom_detection = 0
def parameter_changed(self): # When a parameter is changed in the middle of simulation # the user may want to reroll some human's properties self.mask_user = flip_coin(get_parameters().get('mask_user_rate')) self.immune = flip_coin(get_parameters().get('imune_rate')) if flip_coin(get_parameters().get('weareable_adoption_rate')): self.early_symptom_detection = 1 # number of days else: self.early_symptom_detection = 0 self.initialize_individual_properties()
def vaccinate(self): if self.vaccinated(): return shots_taken = len(self.vaccination_days) if flip_coin(get_parameters().get('vaccine_immunization_rate')[shots_taken]): self.immune = True else: symptom_attenuation = get_parameters().get('vaccine_symptom_attenuation')[shots_taken] self.moderate_severity_prob = self.base_moderate_severity_prob * (1 - symptom_attenuation) self.high_severity_prob = self.base_moderate_severity_prob * (1 - symptom_attenuation) self.vaccination_days.append(self.covid_model.global_count.day_count)
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}")
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
def is_isolated(self): if self.is_symptomatic(): return flip_coin(get_parameters().get('symptomatic_isolation_rate')) if isinstance(self, Adult): for policy in get_parameters().get('social_policies'): if policy in SocialPolicyUtil.locked_work_classes and \ self.work_info.work_class in SocialPolicyUtil.locked_work_classes[policy]: return not self.personal_decision(Dilemma.GO_TO_WORK_ON_LOCKDOWN) elif isinstance(self, K12Student): for policy in get_parameters().get('social_policies'): if policy in SocialPolicyUtil.locked_student_ages: lb, ub = SocialPolicyUtil.locked_student_ages[policy] if lb <= self.age <= ub: return True return False
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)
def export_chart(self, fname): self.income.pop(1) df = pd.DataFrame( data={ 'Susceptible': self.susceptible, 'Infected': self.infected, 'Recovered': self.recovered, 'Death': self.death, 'Hospitalization': self.hospitalization, 'Severe': self.icu, 'Income': self.income }) color = { 'Susceptible': 'lightblue', 'Infected': 'gray', 'Recovered': 'lightgreen', 'Death': 'black', 'Hospitalization': 'orange', 'Severe': 'red', 'Income': 'magenta' } fig, ax = plt.subplots() ax.set_title('Contagion Evolution') ax.set_xlim((0, self.cycles_count)) ax.axhline(y=get_parameters().get('icu_capacity'), c="black", ls='--', label='Critical limit') for col in df.columns.values: ax.plot(df.index.values, df[col].values, c=color[col], label=col) ax.set_xlabel("Days") ax.set_ylabel("% of Population") handles, labels = ax.get_legend_handles_labels() ax.legend(handles, labels, loc='upper right') fig.savefig(fname)
def test_AddPolicyInfectedRate(): model = CovidModel() listener = AddPolicyInfectedRate(model, SocialPolicy.LOCKDOWN_ALL, 0.5) model.add_listener(listener) model.global_count.total_population = 10 model.global_count.infected_count = 4 assert SocialPolicy.LOCKDOWN_ALL not in get_parameters( ).params['social_policies'] model.step() assert SocialPolicy.LOCKDOWN_ALL not in get_parameters( ).params['social_policies'] model.global_count.infected_count = 5 model.step() assert SocialPolicy.LOCKDOWN_ALL in get_parameters( ).params['social_policies']
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()
def __init__(self, covid_model): super().__init__(unique_id(), covid_model) self.custom_parameters = {} self.humans = [] self.locations = [] self.container = None self.spreading_rate = get_parameters().get('spreading_rate')
def factory(covid_model, forced_age): # https://docs.google.com/document/d/14C4utmOi4WiBe7hOVtRt-NgMLh37pr_ntou-xUFAOjk/edit #moderate_severity_probs = [ # 0, # normal_ci(0.000243, 0.000832, 13), # normal_ci(0.00622, 0.0213, 50), # normal_ci(0.0204, 0.07, 437), # normal_ci(0.0253, 0.0868, 733), # normal_ci(0.0486, 0.167, 743), # normal_ci(0.0701, 0.24, 790), # normal_ci(0.0987, 0.338, 560), # normal_ci(0.11, 0.376, 263), # normal_ci(0.11, 0.376, 76) #] moderate_severity_probs = [0.05, 0.10, 0.20, 0.30, 0.40, 0.60, 0.80, 0.99, 0.99, 0.99] high_severity_probs = [0.05, 0.10, 0.20, 0.30, 0.40, 0.60, 0.80, 0.99, 0.99, 0.99] death_probs = [0] * 10 death_probs[2] = 0.003 death_probs[0] = death_probs[2] / 9 death_probs[1] = death_probs[2] / 16 death_probs[3] = death_probs[2] * 4 death_probs[4] = death_probs[2] * 10 death_probs[5] = death_probs[2] * 30 death_probs[6] = death_probs[2] * 90 death_probs[7] = death_probs[2] * 220 death_probs[8] = death_probs[2] * 630 death_probs[9] = death_probs[2] * 1000 if forced_age is None: age = int(np.random.beta(2, 5, 1) * 100) else: age = forced_age index = age // 10 msp = moderate_severity_probs[index] hsp = high_severity_probs[index] mfd = flip_coin(death_probs[index]) if age <= 1: human = Infant(covid_model, age, msp, hsp, mfd) elif age <= 4: human = Toddler(covid_model, age, msp, hsp, mfd) elif age <= 18: human = K12Student(covid_model, age, msp, hsp, mfd) elif age <= 64: human = Adult(covid_model, age, msp, hsp, mfd) else: human = Elder(covid_model, age, msp, hsp, mfd) human.strid = f"human_{Human.count}" Human.count += 1 covid_model.global_count.non_infected_count += 1 if human.immune: covid_model.global_count.immune_count += 1 else: covid_model.global_count.susceptible_count += 1 if flip_coin(get_parameters().get('initial_infection_rate')): human.infect() return human
def infect_blob(self, blob_num): count = 0 vectors = self.blob_dict[blob_num] for v in vectors: human = self.vector_to_human[tuple(v)] if flip_coin(get_parameters().get('initial_infection_rate')): human.infect(None) count += 1 print(f"infected {count} agents in community {blob_num}")
def step(self): super().step() # The default behavior for Humans are just stay at home all day. Disease is # evolved in EVENING_AT_HOME if self.is_dead: return if self.covid_model.current_state == SimulationState.EVENING_AT_HOME: self.disease_evolution() if not self.is_infected() and not self.is_dead and flip_coin(get_parameters().get('exogenous_infection_rate')): self.infect(None)
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: self.disease_severity = DiseaseSeverity.LOW self.covid_model.global_count.asymptomatic_count -= 1 self.covid_model.global_count.symptomatic_count += 1 elif self.disease_severity == DiseaseSeverity.LOW: if self.infection_days_count > self.mild_duration: # By the end of this period, either the pacient is already with antibodies at # a level sufficient to cure the disease or the simptoms will get worse and he/she # will require hospitalization if flip_coin(self.moderate_severity_prob): # MODERATE cases requires hospitalization self.disease_severity = DiseaseSeverity.MODERATE self.covid_model.global_count.moderate_severity_count += 1 if not self.covid_model.reached_hospitalization_limit(): self.covid_model.global_count.total_hospitalized += 1 self.hospitalized = True shape = get_parameters().get('hospitalization_period_duration_shape') scale = get_parameters().get('hospitalization_period_duration_scale') self.hospitalization_duration = np.random.gamma(shape, scale) + self.infection_days_count else: self.recover() elif self.disease_severity == DiseaseSeverity.MODERATE: if self.infection_days_count > self.hospitalization_duration: self.recover() else: if flip_coin(self.high_severity_prob): 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 accomodated in a hospital, he/she will die. if not self.hospitalized or self.death_mark: self.die() elif self.disease_severity == DiseaseSeverity.HIGH: if self.death_mark: self.die()
def personal_decision(self, dilemma): answer = False 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) else: answer = False 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) 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) else: assert False for tribe in TribeSelector: self.dilemma_history.history[dilemma][tribe].append(answer) return answer
def create_restaurant_location(self, index, is_bar): if is_bar: bar = Restaurant(normal_cap(100, 20, 50, 200), RestaurantType.BAR, flip_coin(0.5), self.model, 'Restaurant', str(index)) return bar else: if flip_coin(0.5): restaurant_type = RestaurantType.FAST_FOOD rtype = "FASTFOOD" else: restaurant_type = RestaurantType.FANCY rtype = "FANCY" restaurant = Restaurant( normal_cap( get_parameters().params['restaurant_capacity_mean'], get_parameters().params['restaurant_capacity_stdev'], 16, 200), restaurant_type, flip_coin(0.5), self.model, 'Restaurant', str(index)) return restaurant
def main_activity_isolated(self): if self.is_infected(): if self.disease_severity == DiseaseSeverity.MODERATE or \ self.disease_severity == DiseaseSeverity.HIGH: return True if self.is_symptomatic(): ir = get_parameters().get('symptomatic_isolation_rate') if flip_coin(ir): return True if isinstance(self, Adult): for policy in get_parameters().get('social_policies'): if policy in SocialPolicyUtil.locked_work_classes and \ self.work_info.work_class in SocialPolicyUtil.locked_work_classes[policy]: return not self.personal_decision(Dilemma.GO_TO_WORK_ON_LOCKDOWN) elif isinstance(self, K12Student): for policy in get_parameters().get('social_policies'): if policy in SocialPolicyUtil.locked_student_ages: lb, ub = SocialPolicyUtil.locked_student_ages[policy] if self.age >= lb and self.age <= ub: return True return False
def infect(self, index): if not self.immune: self.covid_model.global_count.non_infected_people.pop(index) self.covid_model.global_count.infected_people.append(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 mean = get_parameters().get('latency_period_mean') stdev = get_parameters().get('latency_period_stdev') self.infection_latency = np.random.normal( mean, stdev) - self.early_symptom_detection if self.infection_latency < 1.0: self.infection_latency = 1.0 mean = get_parameters().get('incubation_period_mean') stdev = get_parameters().get('incubation_period_stdev') self.infection_incubation = np.random.normal(mean, stdev) if self.infection_incubation <= self.infection_latency: self.infection_incubation = self.infection_latency + 1 mean = get_parameters().get('disease_period_mean') stdev = get_parameters().get('disease_period_stdev') self.infection_duration = np.random.normal(mean, stdev) if self.infection_duration < (self.infection_incubation + 7): self.infection_duration = self.infection_incubation + 7
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}")
def __init__(self, covid_model, strid_prefix, strid_suffix): super().__init__(unique_id(), covid_model) self.custom_parameters = {} self.humans = [] self.locations = [] self.container = None self.spreading_rate = get_parameters().get('spreading_rate') self.strid = strid_prefix if strid_prefix != '': self.strid += '-' self.strid += type(self).__name__ if strid_suffix != '': self.strid += '-' + strid_suffix
def factory(covid_model, forced_age): # https://docs.google.com/document/d/14C4utmOi4WiBe7hOVtRt-NgMLh37pr_ntou-xUFAOjk/edit moderate_severity_probs = [ 0, normal_cap_ci(0.000243, 0.000832, 13), normal_cap_ci(0.00622, 0.0213, 50), normal_cap_ci(0.0204, 0.07, 437), normal_cap_ci(0.0253, 0.0868, 733), normal_cap_ci(0.0486, 0.167, 743), normal_cap_ci(0.0701, 0.24, 790), normal_cap_ci(0.0987, 0.338, 560), normal_cap_ci(0.11, 0.376, 263), normal_cap_ci(0.11, 0.376, 76) ] high_severity_probs = [0.05, 0.05, 0.05, 0.05, 0.063, 0.122, 0.274, 0.432, 0.709, 0.709] death_probs = [0.002, 0.00006, 0.0003, 0.0008, 0.0015, 0.006, 0.022, 0.051, 0.093, 0.093] if forced_age is None: age = int(np.random.beta(2, 5, 1) * 100) else: age = forced_age index = age // 10 msp = moderate_severity_probs[index] hsp = high_severity_probs[index] mfd = flip_coin(death_probs[index]) if age <= 1: human = Infant(covid_model, age, msp, hsp, mfd) elif age <= 4: human = Toddler(covid_model, age, msp, hsp, mfd) elif age <= 18: human = K12Student(covid_model, age, msp, hsp, mfd) elif age <= 64: human = Adult(covid_model, age, msp, hsp, mfd) else: human = Elder(covid_model, age, msp, hsp, mfd) covid_model.global_count.non_infected_count += 1 if human.immune: covid_model.global_count.immune_count += 1 else: covid_model.global_count.susceptible_count += 1 if flip_coin(get_parameters().get('initial_infection_rate')): human.infect() return human
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}")
def is_wearing_mask(self): mur = get_parameters().get('mask_user_rate') return flip_coin(mur)
def is_contagious(self): if self.is_infected() and self.infection_days_count >= self.infection_latency: if self.is_symptomatic() or flip_coin(get_parameters().get('asymptomatic_contagion_probability')): return True return False
def initialize_individual_properties(self): super().initialize_individual_properties() self.properties.extroversion = normal_cap(get_parameters().get('extroversion_mean'), get_parameters().get('extroversion_stdev'), 0.0, 1.0) self.dilemma_history = DilemmaDecisionHistory()