예제 #1
0
 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)
예제 #2
0
    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)
예제 #3
0
    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)
예제 #4
0
 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
예제 #5
0
    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)
예제 #6
0
    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)
예제 #7
0
    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)
예제 #8
0
    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
예제 #9
0
    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)