def get_comorbidity(self, person): age_index = self._get_age_index(person) if person.sex == "m": comorbidity_idx = random_choice_numba( self.comorbidities_idx, self.male_comorbidities_probabilities[age_index] ) else: comorbidity_idx = random_choice_numba( self.comorbidities_idx, self.female_comorbidities_probabilities[age_index], ) comorbidity = self.comorbidities[comorbidity_idx] if comorbidity == "no_condition": return None return comorbidity
def roll_activity_dice(poisson_parameters, delta_time, n_activities): total_poisson_parameter = np.sum(poisson_parameters) does_activity = random() < (1.0 - np.exp(-total_poisson_parameter * delta_time)) if does_activity: poisson_parameters_normalized = poisson_parameters / total_poisson_parameter return random_choice_numba(np.arange(0, n_activities), poisson_parameters_normalized) return None
def generate_comorbidity(person, comorbidity_data): if comorbidity_data is not None: male_co = comorbidity_data[0] female_co = comorbidity_data[1] ages = np.array(male_co.columns).astype(int) column_index = 0 for idx, i in enumerate(ages): if person.age <= i: break else: column_index = idx if column_index != 0: column_index += 1 if person.sex == "m": comorbidity = random_choice_numba( male_co.index.values.astype(str), male_co[male_co.columns[column_index]].values, ) if comorbidity == "no_condition": comorbidity = None return comorbidity elif person.sex == "f": comorbidity = random_choice_numba( female_co.index.values.astype(str), female_co[female_co.columns[column_index]].values, ) if comorbidity == "no_condition": comorbidity = None return comorbidity else: return None
def _assign_lockdown_status( self, probabilities_by_sector: dict, lockdown_tags: List[str], lockdown_tags_idx: List[int], person: Person, ): """ Assign lockdown_status in proportion to definitions in the policy config """ # value = np.random.choice(values, 1, p=probs)[0] idx = random_choice_numba(lockdown_tags_idx, probabilities_by_sector[person.sector]) # Currently all people definitely not furloughed or key are assigned a 'random' tag which allows for # them to dynamically be sent to work. For now we fix this so that the same 1/5 people go to work once a week # rather than a 1/5 chance that a person with a 'random' tag goes to work. # If commented out then people will be correctly assigned random tag for going to work randomly # if value == "random" and self.lockdown_status_random[idx] == 0: # value = "furlough" person.lockdown_status = lockdown_tags[idx]
def get_subgroup_for_person_and_housemates(self, person: Person, to_send_abroad: dict = None): """ Main function of the Leisure class. For every possible activity a person can do, we chech the Poisson parameter lambda = probability / day * deltat of that activty taking place. We then sum up the Poisson parameters to decide whether a person does any activity at all. The relative weight of the Poisson parameters gives then the specific activity a person does. If a person ends up going to a social venue, we do a second check to see if his/her entire household accompanies him/her. The social venue subgroups are attached to the involved people, but they are not added to the subgroups, since it is possible they change their plans if a policy is in place or they have other responsibilities. The function returns None if no activity takes place. Parameters ---------- person an instance of person """ if person.residence.group.spec == "care_home": return prob_age_sex = self.get_activity_probabilities_for_person( person=person) if random() < prob_age_sex["does_activity"]: activity_idx = random_choice_numba( arr=np.arange(0, len(prob_age_sex["activities"])), prob=np.array(list(prob_age_sex["activities"].values())), ) activity = list(prob_age_sex["activities"].keys())[activity_idx] activity_distributor = self.leisure_distributors[activity] leisure_subgroup_type = activity_distributor.get_leisure_subgroup_type( person) if "visits" in activity: residence_type = "_".join(activity.split("_")[:-1]) if residence_type not in person.residence.group.residences_to_visit: return else: candidates = person.residence.group.residences_to_visit[ residence_type] else: candidates = person.area.social_venues[activity] candidates_length = len(candidates) if candidates_length == 0: return elif candidates_length == 1: group = candidates[0] else: group = candidates[randint(0, candidates_length - 1)] if group is None: return elif group.external: subgroup = ExternalSubgroup( subgroup_type=leisure_subgroup_type, group=group) else: subgroup = group[leisure_subgroup_type] self.send_household_with_person_if_necessary( person, subgroup, prob_age_sex["drags_household"][activity], to_send_abroad=to_send_abroad, ) if activity == "household_visits": group.make_household_residents_stay_home( to_send_abroad=to_send_abroad) group.being_visited = True person.subgroups.leisure = subgroup return subgroup
def weighted_random_choice(self) -> "ModeOfTransport": """ Randomly choose a mode of transport, weighted by usage in this region. """ idx = random_choice_numba(self.modes_idx, self.weights) return self.modes[idx]