def __init__(self, model_name = "Agent Relocation Model", location_id_name="grid_id", **kwargs ): self.location_id_name = location_id_name RateBasedModel.__init__(self, model_name=model_name, **kwargs)
def run(self, person_set, household_set, resources=None): index = RateBasedModel.run(self, person_set, resources=resources) logger.log_status("%s births occurred" % (index.size) ) person_ds_name, person_id_name = person_set.get_dataset_name(), person_set.get_id_name()[0] hh_ds_name, hh_id_name = person_set.get_dataset_name(), household_set.get_id_name()[0] max_person_id = person_set[person_id_name].max() + 1 new_person_id = arange(max_person_id, max_person_id+index.size) new_born = {} new_born[person_id_name] = new_person_id new_born[hh_id_name] = person_set[hh_id_name][index] ## this may not generate unique person_no, as person can be deleted from a households #new_born['person_no'] = person_set.compute_variables("person.disaggregate(household.persons) + 1")[index] if 'person_no' in person_set.get_known_attribute_names(): ## this requires person_no to exist, which may not always be the case new_born['person_no'] = person_set.compute_variables("person.disaggregate(household.aggregate(person.person_no, function=maximum)) + 1")[index] #assign new-born the race of the mother new_born['race'] = person_set['race'][index] if 'hispanic' in person_set.get_known_attribute_names(): new_born['hispanic'] = person_set['hispanic'][index] new_born['age'] = zeros(index.size, dtype="int32") if 'gender' in person_set.get_known_attribute_names(): new_born['gender'] = randint(1, 3, size=index.size) if 'sex' in person_set.get_known_attribute_names(): new_born['sex'] = randint(1, 3, size=index.size) ##TODO: better way to assign sex? ##TODO: give better default values #new_born['education'] #new_born['job_id'] #new_born['relation'] logger.log_status("Adding %s records to %s dataset" % (index.size, person_set.get_dataset_name()) ) person_set.add_elements(data=new_born, require_all_attributes=False, change_ids_if_not_unique=True) marriage_status0 = person_set.compute_variables("person.marriage_status == 0") marriage_status0_index = where(marriage_status0 == 1)[0] logger.log_status("%s persons have marriage_status = 0. Will be changed to marriage_status = 6" % (marriage_status0_index.size) ) person_set.modify_attribute('marriage_status', array(marriage_status0_index.size*[6]), marriage_status0_index) ##TODO: for each household that experiences a birth, increase household.persons and household.children by 1 ##A better way is to use household.persons and household.children as computed variables, instead of primary ones if 'persons' in household_set.get_primary_attribute_names(): persons = household_set.compute_variables('_persons = household.number_of_agents(person)') household_set.modify_attribute('persons', persons) if 'children' in household_set.get_primary_attribute_names(): children = household_set.compute_variables('_childrens = household.aggregate(person.age<18)') household_set.modify_attribute('children', children) ##preventing households that experience multiple births in the same year from having newborns with duplicate person_no ##right now, this is a work in progress because households with 3 or more births in a single year (very rare) will still have duplicate person_no if 'person_no' in person_set.get_known_attribute_names(): num_max_person_no = household_set.compute_variables('_num_max_person_no = household.aggregate(person.person_no == person.disaggregate(household.aggregate(person.person_no, function=maximum)))') max_person_id = person_set.compute_variables('_max_person_id = person.person_id == person.disaggregate(household.aggregate(person.person_id, function=maximum))') person_no_to_change = person_set.compute_variables('_to_change = person._max_person_id * person.disaggregate(household._num_max_person_no>1)') index_to_change = where(person_no_to_change==1)[0] if index_to_change.size > 0: person_set.modify_attribute('person_no', person_set.get_attribute('person_no')[index_to_change] + 1, index_to_change)
def run(self, person_set, household_set, resources=None, dataset_pool=None): person_ds_name, person_id_name = person_set.get_dataset_name(), person_set.get_id_name()[0] hh_ds_name, hh_id_name = household_set.get_dataset_name(), household_set.get_id_name()[0] household_set.compute_one_variable_with_unknown_package("age_of_head", dataset_pool=dataset_pool) person_set.compute_one_variable_with_unknown_package("head_of_hh", dataset_pool=dataset_pool) person_set.add_attribute(name='much_younger_than_head', data=person_set.compute_variables('(person.age) < ((person.disaggregate(household.age_of_head))-18)')) person_set.add_attribute(name='same_race_as_head', data=person_set.compute_variables('(person.race) ==(person.disaggregate(household.aggregate(person.head_of_hh * person.race)))')) index = RateBasedModel.run(self, person_set, resources=resources) logger.log_status("%s children will be leaving their homes" % (index.size) ) max_hh_id = household_set.get_attribute(hh_id_name).max() + 1 new_hh_id = arange(max_hh_id, max_hh_id+index.size) person_set.modify_attribute(hh_id_name, new_hh_id, index=index) household_set.add_elements({hh_id_name:new_hh_id}, require_all_attributes=False) person_set.delete_one_attribute('much_younger_than_head') person_set.delete_one_attribute('same_race_as_head') ##Update the household table's persons attribute if 'persons' in household_set.get_primary_attribute_names(): persons = household_set.compute_variables('_persons = household.number_of_agents(person)') household_set.modify_attribute('persons', persons) ##Update the household table's children attribute if 'children' in household_set.get_primary_attribute_names(): children = household_set.compute_variables('_children = household.aggregate(person.age<18)') household_set.modify_attribute('children', children) ##Update the household table's workers attribute if 'workers' in household_set.get_primary_attribute_names(): #init new household_ids with workers = -1. To be initialized by the household workers initialization model. new_household_ids = household_set.compute_variables('(household.household_id > %s)' % (max_hh_id)) initialize_workers = where(new_household_ids == 1)[0] if initialize_workers.size > 0: household_set.modify_attribute('workers', array(initialize_workers.size*[-1]), initialize_workers) ##Assign "head of the household" status if 'head_of_hh' in person_set.get_primary_attribute_names(): person_set.add_attribute(name='head_score', data=person_set.compute_variables('(person.age)*1.0 + 3.0*(person.education) + exp(-sqrt(sqrt(sqrt(.5*(person.person_id)))))')) highest_score = person_set.compute_variables('_high_score = (person.disaggregate(household.aggregate(person.head_score, function=maximum)))*1') head_of_hh = person_set.compute_variables('_head_of_hh = (person.head_score == _high_score)*1') person_set.modify_attribute('head_of_hh', head_of_hh) person_set.delete_one_attribute('head_score') ##Update the age_of_head attribute in the household table to reflect the age of new heads of the household if 'age_of_head' in household_set.get_primary_attribute_names(): age_of_head = household_set.compute_variables('_age_of_head = household.aggregate(person.head_of_hh * person.age)') household_set.modify_attribute('age_of_head', age_of_head) ##Initialize income of households with newly-assigned household_ids (should be only 1-person male households) as -1 if 'income' in household_set.get_primary_attribute_names(): new_household_ids = household_set.compute_variables('(household.household_id > %s)' % (max_hh_id)) initialize_income = where(new_household_ids == 1)[0] if initialize_income.size > 0: household_set.modify_attribute('income', array(initialize_income.size*[-1]), initialize_income)
def run(self, agent_set, append_unplaced_agents_index=True, **kwargs): movers_indices = RateBasedModel.run(self, agent_set, **kwargs) if (agent_set.size() > 0) and append_unplaced_agents_index: # add unplaced agents vn = VariableName(self.location_id_name).get_alias() if vn not in agent_set.get_known_attribute_names(): agent_set.compute_variables(self.location_id_name) self.location_id_name = vn unplaced_agents = where(agent_set.get_attribute(self.location_id_name) <= 0)[0] movers_indices = unique(concatenate((movers_indices, unplaced_agents))) logger.log_status("Number of total movers: " + str(movers_indices.size)) return movers_indices
def run(self, person_set, household_set, resources=None): index = RateBasedModel.run(self, person_set, resources=resources) logger.log_status("%s persons are in the marriage market." % (index.size) ) person_ds_name, person_id_name = person_set.get_dataset_name(), person_set.get_id_name()[0] hh_ds_name, hh_id_name = household_set.get_dataset_name(), household_set.get_id_name()[0] #Flag the pool of individuals that are eligible to get married person_set.add_attribute(name='marriage_eligible', data=zeros(person_set.size(), dtype='b')) person_set['marriage_eligible'][index] = True #Separate the males from the females if 'gender' in person_set.get_primary_attribute_names(): index_eligible_males = where(logical_and(person_set['marriage_eligible'], person_set['gender']==1))[0] index_eligible_females = where(logical_and(person_set['marriage_eligible'], person_set['gender']==2))[0] if 'sex' in person_set.get_primary_attribute_names(): index_eligible_males = where(logical_and(person_set['marriage_eligible'], person_set['sex']==1))[0] index_eligible_females = where(logical_and(person_set['marriage_eligible'], person_set['sex']==2))[0] logger.log_status("There are %s eligible males and %s eligible females." % (index_eligible_males.size,index_eligible_females.size) ) logger.log_status("%s new households will be formed." % (array([index_eligible_females.size,index_eligible_males.size]).min())) max_hh_id = household_set.get_attribute(hh_id_name).max() + 1 person_set.add_attribute(name='unmatched', data=ones(person_set.size(), dtype='b')) if (index_eligible_males.size > 0) and (index_eligible_females.size > 0): #When males>females, females choose mate. When females>=males, males choose mate. if index_eligible_males.size > index_eligible_females.size: gender_that_chooses = 'female' #Create the new household IDs and assign them to the mate choosers (the mate they choose will take on this same household ID) new_hh_id = arange(max_hh_id, max_hh_id+index_eligible_females.size) person_set.modify_attribute('household_id', new_hh_id, index=index_eligible_females) self.mate_match(index_eligible_females, index_eligible_males, person_set, gender_that_chooses) else: gender_that_chooses = 'male' new_hh_id = arange(max_hh_id, max_hh_id+index_eligible_males.size) person_set.modify_attribute('household_id', new_hh_id, index=index_eligible_males) self.mate_match(index_eligible_males, index_eligible_females, person_set, gender_that_chooses) person_set.delete_one_attribute('marriage_eligible') person_set.delete_one_attribute('unmatched') #Remove records from household_set that have no persons left persons = household_set.compute_variables("%s.number_of_agents(%s)" % (hh_ds_name, person_ds_name), resources=resources) index_hh0persons = where(persons==0)[0] if index_hh0persons.size > 0: logger.log_status("Removing %s records without %s from %s dataset" % (index_hh0persons.size, person_ds_name, hh_ds_name) ) household_set.remove_elements(index_hh0persons)
def run(self, person_set, household_set, resources=None): index = RateBasedModel.run(self, person_set, resources=resources) person_ds_name, person_id_name = person_set.get_dataset_name(), person_set.get_id_name()[0] hh_ds_name, hh_id_name = household_set.get_dataset_name(), household_set.get_id_name()[0] #Identify married women that will seek a divorce person_set.add_attribute(name='divorce_seeking', data=zeros(person_set.size(), dtype='b')) person_set['divorce_seeking'][index] = True if 'gender' in person_set.get_primary_attribute_names(): index_divorcing_females = where(logical_and(person_set['divorce_seeking'], person_set['gender']==2))[0] if 'sex' in person_set.get_primary_attribute_names(): index_divorcing_females = where(logical_and(person_set['divorce_seeking'], person_set['sex']==2))[0] logger.log_status("%s women will seek a divorce." % (index_divorcing_females.size) ) #Identify men that will be divorced in the simplest case where there is only 1 married man in the household #Assign new household id's to these men. The woman keeps the house and retains custody of any children. if 'gender' in person_set.get_primary_attribute_names(): married_man = person_set.compute_variables("_married_man = (person.marriage_status == 1)*(person.gender == 1)") num_married_men_in_hh = person_set.compute_variables("_num_married_men = person.disaggregate(household.aggregate(person._married_man))") only_married_man_in_hh = person_set.compute_variables("_only_married_man = (person._num_married_men == 1) * (person.gender == 1) * (person.marriage_status == 1)") woman_getting_divorce = person_set.compute_variables("_woman_getting_divorce = (person.divorce_seeking)*(person.gender==2)*(person.marriage_status == 1)") if 'sex' in person_set.get_primary_attribute_names(): married_man = person_set.compute_variables("_married_man = (person.marriage_status == 1)*(person.sex == 1)") num_married_men_in_hh = person_set.compute_variables("_num_married_men = person.disaggregate(household.aggregate(person._married_man))") only_married_man_in_hh = person_set.compute_variables("_only_married_man = (person._num_married_men == 1) * (person.sex == 1) * (person.marriage_status == 1)") woman_getting_divorce = person_set.compute_variables("_woman_getting_divorce = (person.divorce_seeking)*(person.sex==2)*(person.marriage_status == 1)") num_divorces_in_hh = person_set.compute_variables("_num_divorces = person.disaggregate(household.aggregate(person._woman_getting_divorce))") man1_to_divorce = person_set.compute_variables("(person._only_married_man) * (person._num_divorces > 0)") index_man1_divorce = where(man1_to_divorce == 1)[0] max_hh_id = household_set.get_attribute(hh_id_name).max() + 1 new_hh_id = arange(max_hh_id, max_hh_id+index_man1_divorce.size) person_set.modify_attribute('household_id', new_hh_id, index=index_man1_divorce) household_set.add_elements({hh_id_name:new_hh_id}, require_all_attributes=False) person_set.modify_attribute('marriage_status', array(index_man1_divorce.size*[4]), index_man1_divorce) #Identify men that will be divorced when there is more than 1 married man in the household must_pick_man_to_divorce = where(logical_and(woman_getting_divorce > 0, num_married_men_in_hh > 1))[0] person_set.add_attribute(name='not_divorced', data=ones(person_set.size(), dtype='b')) max_hh_id2 = household_set.get_attribute(hh_id_name).max() + 1 new_hh_id = arange(max_hh_id2, max_hh_id2+must_pick_man_to_divorce.size) household_set.add_elements({hh_id_name:new_hh_id}, require_all_attributes=False) new_hh_id_counter = 0 self.pick_man_to_divorce(must_pick_man_to_divorce, married_man, num_married_men_in_hh, person_set, new_hh_id, new_hh_id_counter) #Set the marriage_status of all divorcing females to divorced. Note that # divorcing females will exceed the number of divorced males in this model, because not all divorcing females lived in the same household as husband (female has marriage_status=2 or there can simply be no male in the household with marriage_status=1) person_set.modify_attribute('marriage_status', array(index_divorcing_females.size*[4]), index_divorcing_females) logger.log_status("Divorces completed") person_set.delete_one_attribute('divorce_seeking') person_set.delete_one_attribute('not_divorced') #Remove records from household_set that have no persons left persons = household_set.compute_variables("%s.number_of_agents(%s)" % (hh_ds_name, person_ds_name), resources=resources) index_hh0persons = where(persons==0)[0] if index_hh0persons.size > 0: logger.log_status("Removing %s records without %s from %s dataset" % (index_hh0persons.size, person_ds_name, hh_ds_name) ) ##Update the household table's persons attribute if 'persons' in household_set.get_primary_attribute_names(): persons = household_set.compute_variables('_persons = household.number_of_agents(person)') household_set.modify_attribute('persons', persons) ##Update the household table's children attribute if 'children' in household_set.get_primary_attribute_names(): children = household_set.compute_variables('_children = household.aggregate(person.age<18)') household_set.modify_attribute('children', children) ##Update the household table's workers attribute if 'workers' in household_set.get_primary_attribute_names(): #init new household_ids with workers = -1. To be initialized by the household workers initialization model. new_household_ids = household_set.compute_variables('(household.household_id > %s)' % (max_hh_id)) initialize_workers = where(new_household_ids == 1)[0] if initialize_workers.size > 0: household_set.modify_attribute('workers', array(initialize_workers.size*[-1]), initialize_workers) ##Assign "head of the household" status if 'head_of_hh' in person_set.get_primary_attribute_names(): person_set.add_attribute(name='head_score', data=person_set.compute_variables('(person.age)*1.0 + 3.0*(person.education) + exp(-sqrt(sqrt(sqrt(.5*(person.person_id)))))')) highest_score = person_set.compute_variables('_high_score = (person.disaggregate(household.aggregate(person.head_score, function=maximum)))*1') head_of_hh = person_set.compute_variables('_head_of_hh = (person.head_score == _high_score)*1') person_set.modify_attribute('head_of_hh', head_of_hh) person_set.delete_one_attribute('head_score') ##Update the age_of_head attribute in the household table to reflect the age of new heads of the household if 'age_of_head' in household_set.get_primary_attribute_names(): age_of_head = household_set.compute_variables('_age_of_head = household.aggregate(person.head_of_hh * person.age)') household_set.modify_attribute('age_of_head', age_of_head) ##Initialize income of households with newly-assigned household_ids (should be only 1-person male households) as -1 if 'income' in household_set.get_primary_attribute_names(): new_household_ids = household_set.compute_variables('(household.household_id > %s)' % (max_hh_id)) initialize_income = where(new_household_ids == 1)[0] if initialize_income.size > 0: household_set.modify_attribute('income', array(initialize_income.size*[-1]), initialize_income)
def run(self, person_set, household_set, resources=None): index = RateBasedModel.run(self, person_set, resources=resources) logger.log_status("%s persons are in the marriage market." % (index.size) ) person_ds_name, person_id_name = person_set.get_dataset_name(), person_set.get_id_name()[0] hh_ds_name, hh_id_name = household_set.get_dataset_name(), household_set.get_id_name()[0] #Flag the pool of individuals that are eligible to get married person_set.add_attribute(name='marriage_eligible', data=zeros(person_set.size(), dtype='b')) person_set['marriage_eligible'][index] = True #Separate the males from the females if 'gender' in person_set.get_primary_attribute_names(): index_eligible_males = where(logical_and(person_set['marriage_eligible'], person_set['gender']==1))[0] index_eligible_females = where(logical_and(person_set['marriage_eligible'], person_set['gender']==2))[0] if 'sex' in person_set.get_primary_attribute_names(): index_eligible_males = where(logical_and(person_set['marriage_eligible'], person_set['sex']==1))[0] index_eligible_females = where(logical_and(person_set['marriage_eligible'], person_set['sex']==2))[0] logger.log_status("There are %s eligible males and %s eligible females." % (index_eligible_males.size,index_eligible_females.size) ) logger.log_status("%s new married couple households will be formed." % (index_eligible_females.size)) max_hh_id = household_set.get_attribute(hh_id_name).max() + 1 person_set.add_attribute(name='unmatched', data=ones(person_set.size(), dtype='b')) person_set.add_attribute(name='one_person_hh', data=person_set.compute_variables('person.disaggregate((household.number_of_agents(person)) == 1)')) person_set.add_attribute(name='single_parent', data=person_set.compute_variables('person.disaggregate(((household.aggregate(person.age > 17)) == 1)*((household.aggregate(person.age < 18)) > 0))')) #Create max # of new household IDs that may be needed (not all will be used because of re-use of existing household_ids) new_hh_id = arange(max_hh_id, max_hh_id+index_eligible_females.size) new_hh_id_counter = 0 self.mate_match(index_eligible_females, index_eligible_males, person_set, household_set, new_hh_id, new_hh_id_counter, hh_id_name, max_hh_id) person_set.delete_one_attribute('single_parent') person_set.delete_one_attribute('one_person_hh') person_set.delete_one_attribute('marriage_eligible') person_set.delete_one_attribute('unmatched') #Remove records from household_set that have no persons left persons = household_set.compute_variables("%s.number_of_agents(%s)" % (hh_ds_name, person_ds_name), resources=resources) index_hh0persons = where(persons==0)[0] if index_hh0persons.size > 0: logger.log_status("Removing %s records without %s from %s dataset" % (index_hh0persons.size, person_ds_name, hh_ds_name) ) household_set.remove_elements(index_hh0persons) ##Update the household table's persons attribute if 'persons' in household_set.get_primary_attribute_names(): persons = household_set.compute_variables('_persons = household.number_of_agents(person)') household_set.modify_attribute('persons', persons) ##Update the household table's children attribute if 'children' in household_set.get_primary_attribute_names(): children = household_set.compute_variables('_children = household.aggregate(person.age<18)') household_set.modify_attribute('children', children) ##Update the household table's workers attribute if 'workers' in household_set.get_primary_attribute_names(): #init new household_ids with workers = -1. To be initialized by the household workers initialization model. new_household_ids = household_set.compute_variables('(household.household_id > %s)' % (max_hh_id)) initialize_workers = where(new_household_ids == 1)[0] if initialize_workers.size > 0: household_set.modify_attribute('workers', array(initialize_workers.size*[-1]), initialize_workers) ##Assign "head of the household" status if 'head_of_hh' in person_set.get_primary_attribute_names(): person_set.add_attribute(name='head_score', data=person_set.compute_variables('(person.age)*1.0 + 3.0*(person.education) + exp(-sqrt(sqrt(sqrt(.5*(person.person_id)))))')) highest_score = person_set.compute_variables('_high_score = (person.disaggregate(household.aggregate(person.head_score, function=maximum)))*1') head_of_hh = person_set.compute_variables('_head_of_hh = (person.head_score == _high_score)*1') person_set.modify_attribute('head_of_hh', head_of_hh) person_set.delete_one_attribute('head_score') ##Update the age_of_head attribute in the household table to reflect the age of new heads of the household if 'age_of_head' in household_set.get_primary_attribute_names(): age_of_head = household_set.compute_variables('_age_of_head = household.aggregate(person.head_of_hh * person.age)') household_set.modify_attribute('age_of_head', age_of_head) ##Initialize income of households with newly-assigned household_ids (should be only 2-person households) as -2 if 'income' in household_set.get_primary_attribute_names(): new_household_ids = household_set.compute_variables('(household.household_id > %s)' % (max_hh_id)) initialize_income = where(new_household_ids == 1)[0] if initialize_income.size > 0: household_set.modify_attribute('income', array(initialize_income.size*[-2]), initialize_income)
def run(self, person_set, household_set, resources=None): person_ds_name = person_set.get_dataset_name() index = RateBasedModel.run(self, person_set, resources=resources) logger.log_status("%s students decide to leave school" % (index.size) ) #Update educational level attained by students, accounting for their age no_school = person_set.compute_variables('_no_school = (person.age > 2) * (person.age < 5)') nursery_to_fourth = person_set.compute_variables('_nurs_to_fourth = (person.age > 4) * (person.age < 10)') fifth_sixth = person_set.compute_variables('_fifth_sixth = (person.age > 9) * (person.age < 12)') seventh_eigth = person_set.compute_variables('_sev_eigth = (person.age > 11) * (person.age < 14)') ninth = person_set.compute_variables('_ninth = (person.age > 13) * (person.age < 15)') tenth = person_set.compute_variables('_tenth = (person.age > 14) * (person.age < 16) * (person.student_status > 1)') eleventh = person_set.compute_variables('_eleventh = (person.age > 15) * (person.age < 17) * (person.student_status > 1)') twelfth = person_set.compute_variables('_twelfth = (person.age > 16) * (person.age < 18) * (person.student_status > 1)') hsgrad = person_set.compute_variables('_hsgrad = (person.age > 17) * (person.age < 19) * (person.student_status > 1)') somecollege = person_set.compute_variables('_somecoll = (person.age > 18) * (person.age < 20) * (person.student_status > 1)') somecollege2 = person_set.compute_variables('_somecoll2 = (person.age > 19) * (person.age < 21) * (person.student_status > 1)') associate = person_set.compute_variables('_assoc = (person.age > 20) * (person.age < 22) * (person.student_status > 1)') bachelors = person_set.compute_variables('_bach = (person.age > 21) * (person.age < 24) * (person.student_status > 1)') masters = person_set.compute_variables('_mast = (person.age > 23) * (person.age < 25) * (person.student_status > 1)') professional = person_set.compute_variables('_prof = (person.age > 24) * (person.age < 28) * (person.student_status > 1)') phd = person_set.compute_variables('_phd = (person.age > 27) * (person.student_status > 1) ') idx_no_school = where(no_school)[0] idx_nursery_to_fourth = where(nursery_to_fourth)[0] idx_fifth_sixth = where(fifth_sixth)[0] idx_seventh_eigth = where(nursery_to_fourth)[0] idx_ninth = where(ninth)[0] idx_tenth = where(tenth)[0] idx_eleventh = where(eleventh)[0] idx_twelfth = where(twelfth)[0] idx_hsgrad = where(hsgrad)[0] idx_somecollege = where(somecollege)[0] idx_somecollege2 = where(somecollege2)[0] idx_associate = where(associate)[0] idx_bachelors = where(bachelors)[0] idx_masters = where(masters)[0] idx_professional = where(professional)[0] idx_phd = where(phd)[0] if idx_no_school.size > 0: person_set.modify_attribute('education', array(idx_no_school.size*[1]), idx_no_school) person_set.modify_attribute('student_status', array(idx_no_school.size*[1]), idx_no_school) if idx_nursery_to_fourth.size > 0: person_set.modify_attribute('education', array(idx_nursery_to_fourth.size*[2]), idx_nursery_to_fourth) person_set.modify_attribute('student_status', array(idx_nursery_to_fourth.size*[2]), idx_nursery_to_fourth) if idx_fifth_sixth.size > 0: person_set.modify_attribute('education', array(idx_fifth_sixth.size*[3]), fifth_sixth) if idx_seventh_eigth.size > 0: person_set.modify_attribute('education', array(idx_seventh_eigth.size*[4]), idx_seventh_eigth) if idx_ninth.size > 0: person_set.modify_attribute('education', array(idx_ninth.size*[5]), idx_ninth) if idx_tenth.size > 0: person_set.modify_attribute('education', array(idx_tenth.size*[6]), idx_tenth) if idx_eleventh.size > 0: person_set.modify_attribute('education', array(idx_eleventh.size*[7]), idx_eleventh) if idx_twelfth.size > 0: person_set.modify_attribute('education', array(idx_twelfth.size*[8]), idx_twelfth) if idx_hsgrad.size > 0: person_set.modify_attribute('education', array(idx_hsgrad.size*[9]), idx_hsgrad) if idx_somecollege.size > 0: person_set.modify_attribute('education', array(idx_somecollege.size*[10]), idx_somecollege) if idx_somecollege2.size > 0: person_set.modify_attribute('education', array(idx_somecollege2.size*[11]), idx_somecollege2) if idx_associate.size > 0: person_set.modify_attribute('education', array(idx_associate.size*[12]), associate) if idx_bachelors.size > 0: person_set.modify_attribute('education', array(idx_bachelors.size*[13]), idx_bachelors) if idx_masters.size > 0: person_set.modify_attribute('education', array(idx_masters.size*[14]), idx_masters) if idx_professional.size > 0: person_set.modify_attribute('education', array(idx_professional.size*[15]), idx_professional) if idx_phd.size > 0: person_set.modify_attribute('education', array(idx_phd.size*[16]), idx_phd) # Change the student_status of those predicted to exit from schooling. Whatever educational level they have reached this year is their final level. person_set['student_status'][index] = 1
def run(self, person_set, household_set, resources=None): person_ds_name = person_set.get_dataset_name() hh_ds_name = household_set.get_dataset_name() index = RateBasedModel.run(self, person_set, resources=resources) logger.log_status("%s deaths occurred (before accounting for adults saved to prevent orphans)" % (index.size) ) #avoid orphaning children before we handle them in an adoption model person_set.add_attribute(name='mortality_flag', data=zeros(person_set.size(), dtype='b')) person_set['mortality_flag'][index] = True #identify such households person_set.compute_variables('is_adult = person.age > 17') household_set.compute_variables('adults = (household.aggregate(person.age>17))') person_set.compute_variables("adult_death = person.mortality_flag * person.is_adult") household_set.compute_variables("adult_deaths = household.aggregate(person.adult_death)") full_adult_mortality = household_set.compute_variables("death_of_all_adults = numpy.logical_and(household.adult_deaths>=1, " + "household.adult_deaths == household.adults)") children_at_risk = household_set.compute_variables("children_at_risk=household.aggregate(numpy.logical_not(person.mortality_flag) * (person.age <= 17)) > 0 ") hh_at_risk = household_set.compute_variables("at_risk = household.death_of_all_adults * household.children_at_risk") idx_hh_at_risk = where(hh_at_risk)[0] if idx_hh_at_risk.size > 0: #sample 1 adult per household to keep for households with children at risk prob_to_keep = person_set.compute_variables("safe_array_divide((person.adult_death).astype('f'), " + "person.disaggregate(household.adult_deaths))") for idx_hh in idx_hh_at_risk: hh_id = household_set['household_id'][idx_hh] ps_of_this_hh = where( logical_and(person_set['household_id'] == hh_id, person_set['adult_death'] ))[0] if ps_of_this_hh.size == 1: person_set['mortality_flag'][ps_of_this_hh] = False else: r = uniform(0,1); cumprob = cumsum(prob_to_keep[ps_of_this_hh]) idx_adult_to_keep = searchsorted(cumprob, r) person_set['mortality_flag'][ps_of_this_hh[idx_adult_to_keep]] = False idx = where( person_set['mortality_flag'] )[0] person_set.delete_one_attribute('mortality_flag') logger.log_status("Removing %s records from %s dataset" % (idx.size, person_set.get_dataset_name()) ) logger.log_status("%s deaths occurred after saving some adults to prevent orphans" % (idx.size) ) person_set.remove_elements(idx) ##remove records from household_set that have no persons left persons = household_set.compute_variables("%s.number_of_agents(%s)" % (hh_ds_name, person_ds_name), resources=resources) index_hh0persons = where(persons==0)[0] if index_hh0persons.size > 0: logger.log_status("Removing %s records without %s from %s dataset" % (index_hh0persons.size, person_ds_name, hh_ds_name) ) household_set.remove_elements(index_hh0persons) ## it would work better to convert them to computed variables ##Update the household table's persons attribute to account for deaths if 'persons' in household_set.get_primary_attribute_names(): persons = household_set.compute_variables('_persons = household.number_of_agents(person)') household_set.modify_attribute('persons', persons) ##Update the household table's children attribute to account for child deaths if 'children' in household_set.get_primary_attribute_names(): children = household_set.compute_variables('_children = household.aggregate(person.age<18)') household_set.modify_attribute('children', children) ##Assign "head of the household" status if 'head_of_hh' in person_set.get_primary_attribute_names(): person_set.add_attribute(name='head_score', data=person_set.compute_variables('(person.age)*1.0 + 3.0*(person.education) + exp(-sqrt(sqrt(sqrt(.5*(person.person_id)))))')) highest_score = person_set.compute_variables('_high_score = (person.disaggregate(household.aggregate(person.head_score, function=maximum)))*1') head_of_hh = person_set.compute_variables('_head_of_hh = (person.head_score == _high_score)*1') person_set.modify_attribute('head_of_hh', head_of_hh) person_set.delete_one_attribute('head_score') ##Update the age_of_head attribute in the household table to reflect the age of new heads of the household and to reflect the aging of existing heads of household. if 'age_of_head' in household_set.get_primary_attribute_names(): age_of_head = household_set.compute_variables('_age_of_head = household.aggregate(person.head_of_hh * person.age)') household_set.modify_attribute('age_of_head', age_of_head) ##When a person's spouse dies, change the person's marriage_status from married to widowed. (This has implications for the household formation model) ##Note that a marriage_status=1 is supposed to indicate being married to a spouse who resides in the same household. In the case of marriage_status=2, which indicates married to a spouse who does not live in the household, we cannot tell when someone's spouse dies. Widowed (marriage_status = 3) includes men. if 'marriage_status' in person_set.get_primary_attribute_names(): widowed = person_set.compute_variables('_last_spouse = (((person.disaggregate(household.aggregate(person.marriage_status == 1)))==1)*1) * ((person.marriage_status == 1)*1)') index_widow = where(widowed==1)[0] if index_widow.size > 0: person_set.modify_attribute('marriage_status', array(index_widow.size*[3]), index_widow)