Step 9: Male Childlessness

Model Description

At this step we add a module for setting the fate of male childlessness. Based on information from the starting population and a cohort parameter by education, lifetime childlessness is decided at the begin of the simulation or - for those born in the simulation - early in life before entering fertile age.

The new MaleChildlessness.mpp Module

This module decides the lifetime-fate of male childlessness based on two pieces of information: (1) living with children in the starting population file, and (2) a parameter of male cohort childlessness by education fate. Men currently living with children are assumed to be parents, thus not childless. In a second step, men from the starting population who are currently not living with children a status is assigned randomly in order to meet the cohort targets. For those born in the simulation, the status is assigned by sampling according the cohort parameter. This assignment happens at the first birthday, as at this time the final education fate is known.



////////////////////////////////////////////////////////////////////////////////////////////////////
// Actor Sets
////////////////////////////////////////////////////////////////////////////////////////////////////

//EN Men fated to stay childless by year of birth and education
actor_set Person asMenNeverFather[year_of_birth][birth1_group] filter never_father && sex == MALE;

////////////////////////////////////////////////////////////////////////////////////////////////////
// Parameters
////////////////////////////////////////////////////////////////////////////////////////////////////

parameters
{
    //EN Male cohort childlessness
    double MaleCohortChildlessness[YOB_MALEFERT][BIRTH1_GROUP];
};

parameter_group PG_MaleChildlessness        //EM Male Childlessness
{
    MaleCohortChildlessness
};

////////////////////////////////////////////////////////////////////////////////////////////////////
// Actor states and functions
////////////////////////////////////////////////////////////////////////////////////////////////////

actor Person
{
    logical never_father = { TRUE };            //EN Person fated never to become father
    void    SetEverFatherFate();                //EN Set fate of ever becoming father
    hook    SetEverFatherFate, BirthdayEvent;   //EN Decide at 1st birthday (education fate known)
};

actor Clock
{
    void ImputeEverFather();                    //EN Person is father
    hook ImputeEverFather, ImputeIsMother;      //EN To be run immediately after female imputation
};

////////////////////////////////////////////////////////////////////////////////////////////////////
// Implementation
////////////////////////////////////////////////////////////////////////////////////////////////////

void Person::SetEverFatherFate()
{
    if (person_type != PT_START && integer_age == 1 && sex==MALE)
    {
        never_father = (RandUniform(21)
            < MaleCohortChildlessness[RANGE_POS(YOB_MALEFERT, year_of_birth)][birth1_group]);
    }
}

void Clock::ImputeEverFather()
{
    if (clock_year == MIN(SIM_YEAR_RANGE))
    {
        int nPopSize;
        int nPersons[SIZE(YOB_START15)][SIZE(BIRTH1_GROUP)];
        int nExpected[SIZE(YOB_START15)][SIZE(BIRTH1_GROUP)];
        int nRecorded[SIZE(YOB_START15)][SIZE(BIRTH1_GROUP)];
        // initialize with 0
        for (int nJ = 0; nJ < SIZE(YOB_START15); nJ++)
        {
            for (int nGroup = 0; nGroup < SIZE(BIRTH1_GROUP); nGroup++)
            {
                nPersons[nJ][nGroup] = 0; nExpected[nJ][nGroup] = 0; nRecorded[nJ][nGroup] = 0;
            }
        }
        // assign status is_father where there are children in hh
        // count men and known fathers by yob
        nPopSize = asAllPersons->Count();
        for (int nI = 0; nI < nPopSize; nI++)
        {
            auto prPerson = asAllPersons->Item(nI);
            if (WITHIN(YOB_START15, prPerson->year_of_birth) && prPerson->sex == MALE)
            {
                int nYOB = prPerson->year_of_birth - MIN(YOB_START15);
                nPersons[nYOB][prPerson->birth1_group] = nPersons[nYOB][prPerson->birth1_group] + 1;
                if (prPerson->linked_kids > 0 || (prPerson->lSpouse && prPerson->lSpouse->linked_kids >0))
                {
                    nRecorded[nYOB][prPerson->birth1_group] = nRecorded[nYOB][prPerson->birth1_group] + 1;
                    prPerson->never_father = FALSE;
                }
            }
            else if (prPerson->sex == MALE) // those below 15
            {
                prPerson->never_father = (RandUniform(20) < MaleCohortChildlessness[RANGE_POS(YOB_MALEFERT, prPerson->year_of_birth)][prPerson->birth1_group]);
            }
        }
        //calculate expected number of fathers by yob
        for (int nGroup = 0; nGroup < SIZE(BIRTH1_GROUP); nGroup++)
        {
            for (int nJ = 0; nJ < SIZE(YOB_START15); nJ++)
            {
                nExpected[nJ][nGroup] = round(nPersons[nJ][nGroup] * (1 - MaleCohortChildlessness[RANGE_POS(YOB_MALEFERT, nJ+MIN(YOB_START15))][nGroup]));
            }
        }
        //randomly choose childless men to (ever) become fathers in order to meet target numbers
        for (int nGroup = 0; nGroup < SIZE(BIRTH1_GROUP); nGroup++)
        {
            for (int nJ = 0; nJ < SIZE(YOB_START15); nJ++)
            {
                if (nExpected[nJ][nGroup] > nRecorded[nJ][nGroup])
                {
                    for (int nI = 0; nI < nExpected[nJ][nGroup] - nRecorded[nJ][nGroup]; nI++)
                    {
                        if (asMenNeverFather[RANGE_POS(ALL_YEAR_RANGE, MIN(YOB_START15) + nJ)][nGroup]->Count() > 0)
                        {
                            auto prFather = asMenNeverFather[RANGE_POS(ALL_YEAR_RANGE, MIN(YOB_START15) + nJ)][nGroup]->GetRandom(RandUniform(19));
                            prFather->never_father = FALSE;
                        }
                    }
                }
            }
        }
    }
 }

table Person TabIsFather //EN Is ever Father
[sex == MALE && calendar_year > 2010 && integer_age>1]
{
    {
        duration(never_father,FALSE) / duration()
    }
    * year_of_birth
    * educ_fate +
};

Update of a version specific age-range in _CountryContext.mpp


range YOB_MALEFERT{ 1920, 2050 };               //EN Year of birth
//