5.15. Step 15: School Tracking¶
5.15.1. Model Description¶
At this step we add an optional module for tracking students through the grade system of primary school. The module builds on the school fate model which decides on school entry and graduation. This module then adds information on the pathway. It models age at first entry, grade repetition, temporary school career interruptions, current enrolment and current highest grade attended and passed.
5.15.2. The new Educ1BaseTracking.mpp Module¶
This is an optional module used to track students through a grade system of “School One” - in the current implementation refering to primary school. The number of grades is declared in the range EDUC_ONE_GRADE and can be adapted to different school systems. Students are moved through the grade system by an actor SchoolOneActor. This actor has two events, one at the end of the school season, the other at the beginning of the school season. At the end of each school season it is decided who newly enters the school at grade one, who of the active students passed the attended grade, who graduated, who permanently leaves school, and for all others if enrollment is continued or the school career is interrupted by one year. The module builds on a fate model of school entry and success, thusonly models the careers of those fated to enter school. Those fated to graduate from school at some point pass all grades. Those fated to drop out accordingly do not pass all grades - the distribution of the highest grade attended being a model parameter.
The module is driven by 6 parameters:
- The distribution of school entry ages by year of birth. Even in presence of a legislated school entry age, data in some developing countries reflect a wider range of ages when school is first enterd. This parameter allows to account for that fact and allows for scenarios in which school entry ages become more concentrated toward the legislated age.
- The start of the school year: e.g. 0.666 for September 1st
- The end of the school year: e.g. 0.5 for June 30
- A grade repetition rate. The probability that a grade has to be repeated. Currently the only dimension is calendar year to allow for scenarios of changing grade success rates. More dimensions can be added easily e.g. for accountig for geographical variation, the grade, or individual characteristics.
- A school interruption rate. The probability that the school career is interrupted for a year. Currently the only dimension is calendar year to allow for scenarios of changing retention rates. More dimensions can be added easily e.g. for accountig for geographical variation, the grade, or individual characteristics.
- The distribution of the highest grade attended of dropout students. Currently year of birth is the only dimension allowing for scenarios of changing retention patterns. More dimensions can be added easily e.g. for accountig for geographical variation, or individual characteristics.
Besides grade and period, the school progression parameters have two additional dimensions, one for geographical region, the other for personal characteristics. The levels of these two characteristics are model specific, they are declared in the classifications EDUC_ONE_GEO and EDUC_ONE_GROUP, with the corresponding states educ_one_geo and educ_one_group. Currently only totals are implemented.
As an optional module the module can be added or removed from the model. The only required code change in other modules is the creation of the actor SchoolOneActor in the Simulation() function.
////////////////////////////////////////////////////////////////////////////////////////////////////
// Actor-Sets
////////////////////////////////////////////////////////////////////////////////////////////////////
//EN The School One
actor_set SchoolOneActor asSchoolOneActor;
//EN Potential Students of School One
actor_set Person asPotentialSchoolOneStudent
filter is_alive && educ_one_status != EOS_OUT && educ_one_fate != EOL_LOW;
//EN Students of School One To Be Processed
actor_set Person asPotentialSchoolOneStudentToProcess
filter is_alive && educ_one_to_process;
////////////////////////////////////////////////////////////////////////////////////////////////////
// Types
////////////////////////////////////////////////////////////////////////////////////////////////////
range EDUC_ONE_GRADE { 1, 6 }; //EN Grades School One
range EDUC_ONE_GRADE0 { 0 , 6 }; //EN Grades School One (incl. 0)
range EDUC_ONE_ENTRY_AGE { 5, 8 }; //EN Possible entry ages School One
classification EDUC_ONE_STATUS //EN Current attendance status in School One
{
EOS_NEVER, //EN Never entered
EOS_WAIT, //EN Wait for entry (e.g. school break)
EOS_ATTEND, //EN Currently attending
EOS_PAUSE, //EN Pause
EOS_OUT //EN Left school
};
classification EDUC_ONE_GEO //EN Regional Unit
{
EOG_OO //EN All
};
classification EDUC_ONE_GROUP //EN Population Group
{
E1G_OO //EN All
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// Prameters
////////////////////////////////////////////////////////////////////////////////////////////////////
parameters
{
double StartSchoolOneYear; //EN Start of school year
double EndSchoolOneYear; //EN End of school year
//EN Grade repetition rate
double SchoolOneRepetitionRate[EDUC_ONE_GEO][EDUC_ONE_GROUP][SIM_YEAR_RANGE];
//EN School interruption rate
double SchoolOneInterruptionRate[EDUC_ONE_GEO][EDUC_ONE_GROUP][SIM_YEAR_RANGE];
//EN Distribution entry age
cumrate EducOneEntryAge[EDUC_ONE_GEO][EDUC_ONE_GROUP][YOB_GRAD_PRIMARY][EDUC_ONE_ENTRY_AGE];
//EN Distribution dropout grade
cumrate EducOneDropoutGrade[EDUC_ONE_GEO][EDUC_ONE_GROUP][YOB_GRAD_PRIMARY][EDUC_ONE_GRADE];
};
parameter_group PG_ShoolOneTracking //EN Grade system tracking
{
StartSchoolOneYear, EndSchoolOneYear, EducOneEntryAge,
EducOneDropoutGrade, SchoolOneRepetitionRate,
SchoolOneInterruptionRate
};
parameter_group PG_ShoolOne //EN Primary School
{
PG_SchoolOneFate, PG_ShoolOneTracking
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// Actors
////////////////////////////////////////////////////////////////////////////////////////////////////
actor Person
{
logical educ_one_to_process = { FALSE }; //EN Flag for students to be processed
EDUC_ONE_GRADE0 educ_one_grade_attended = { 0 }; //EN Highest grade attended
EDUC_ONE_GRADE0 educ_one_grade_passed = { 0 }; //EN Highest grade passed
EDUC_ONE_STATUS educ_one_status = { EOS_NEVER }; //EN Primary school status
EDUC_ONE_ENTRY_AGE educ_one_entry_age = { 6 }; //EN Primary school entry age
EDUC_ONE_GRADE educ_one_grade_fate = { 1 }; //EN Highest level attended of dropouts
EDUC_ONE_GEO educ_one_geo = {EOG_OO}; //EN Geographical location
EDUC_ONE_GROUP educ_one_group = {E1G_OO}; //EN Person group
void SetEducOneEntryAgeDroputGrade(); //EN Sample entry age and dropout grade
hook SetEducOneEntryAgeDroputGrade, Start; //EN Hook to Start()
};
actor SchoolOneActor
{
TIME time_start_school_one_year = { TIME_INFINITE}; //EN Next start of school year
TIME time_end_school_one_year = { TIME_INFINITE}; //EN Next end of school year
event timeStartSchoolOneYearEvent, StartSchoolOneYearEvent; //EN Start school year event
event timeEndSchoolOneYearEvent, EndSchoolOneYearEvent; //EN End school year event
};
actor Clock
{
void SetSchoolYearOneClock(); //EN Clock for scheduling school year
hook SetSchoolYearOneClock, StartYearClock; //EN Hooked to Start Year
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// Implementatation Person Functions
////////////////////////////////////////////////////////////////////////////////////////////////////
void Person::SetEducOneEntryAgeDroputGrade()
{
int nAge;
Lookup_EducOneEntryAge(RandUniform(32), (int)educ_one_geo, (int)educ_one_group,
RANGE_POS(YOB_GRAD_PRIMARY,year_of_birth), &nAge);
educ_one_entry_age = MIN(EDUC_ONE_ENTRY_AGE) + nAge;
int nGrade;
Lookup_EducOneDropoutGrade(RandUniform(34), (int)educ_one_geo, (int)educ_one_group,
RANGE_POS(YOB_GRAD_PRIMARY,year_of_birth), &nGrade);
educ_one_grade_fate = MIN(EDUC_ONE_GRADE) + nGrade;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Implementatation SchoolOneActor Functions
////////////////////////////////////////////////////////////////////////////////////////////////////
TIME SchoolOneActor::timeStartSchoolOneYearEvent(){return time_start_school_one_year;}
void SchoolOneActor::StartSchoolOneYearEvent()
{
for (long nJ = 0; nJ < asPotentialSchoolOneStudent->Count(); nJ++)
{
auto prPerson = asPotentialSchoolOneStudent->Item(nJ);
if (prPerson->educ_one_status == EOS_WAIT )
{
prPerson->educ_one_status = EOS_ATTEND ;
prPerson->educ_one_grade_attended = prPerson->educ_one_grade_passed + 1;
}
}
time_start_school_one_year = TIME_INFINITE;
}
TIME SchoolOneActor::timeEndSchoolOneYearEvent(){return time_end_school_one_year;}
void SchoolOneActor::EndSchoolOneYearEvent()
{
// Flag the persons to be processed
for (long nJ = 0; nJ < asPotentialSchoolOneStudent->Count(); nJ++)
{
auto prPerson = asPotentialSchoolOneStudent->Item(nJ);
prPerson->educ_one_to_process = TRUE;
}
// Process all potential students
for (long nJ = 0; nJ < asPotentialSchoolOneStudentToProcess->Count(); nJ++)
{
auto prPerson = asPotentialSchoolOneStudentToProcess->Item(nJ);
bool bIsDropout = (prPerson->educ_one_fate == EOL_MEDIUM );
// Potential Student has not entered school yet or currently in pause
if (prPerson->integer_age == prPerson->educ_one_entry_age || prPerson->educ_one_status == EOS_PAUSE )
{
prPerson->educ_one_status = EOS_WAIT;
}
// Active student in last year
else if (prPerson->educ_one_grade_attended == MAX(EDUC_ONE_GRADE))
{
// Leave school without passing grade if fated school dropout
if ( bIsDropout ) prPerson->educ_one_status = EOS_OUT;
// Leave school as graduate if rate passed
else if (RandUniform(35) > SchoolOneRepetitionRate[prPerson->educ_one_geo]
[prPerson->educ_one_group][RANGE_POS(SIM_YEAR_RANGE, prPerson->calendar_year)])
{
prPerson->educ_one_grade_passed = prPerson->educ_one_grade_attended;
prPerson->educ_one_status = EOS_OUT;
}
// Repeat grade: decide now or after a break
else if (RandUniform(36) < SchoolOneInterruptionRate[prPerson->educ_one_geo]
[prPerson->educ_one_group][RANGE_POS(SIM_YEAR_RANGE, prPerson->calendar_year)])
{
prPerson->educ_one_status = EOS_PAUSE;
}
else prPerson->educ_one_status = EOS_WAIT;
}
// Active student before last year
else if (prPerson->integer_age > prPerson->educ_one_entry_age)
{
// Check if grade passed
if (RandUniform(37) > SchoolOneRepetitionRate[prPerson->educ_one_geo]
[prPerson->educ_one_group][RANGE_POS(SIM_YEAR_RANGE, prPerson->calendar_year)])
{
prPerson->educ_one_grade_passed = prPerson->educ_one_grade_attended;
}
// Dropout reached highest fated grade
if (bIsDropout && prPerson->educ_one_grade_fate == prPerson->educ_one_grade_attended)
{
prPerson->educ_one_status = EOS_OUT;
}
// All others continue now or after a break
else if (RandUniform(38) > SchoolOneInterruptionRate[prPerson->educ_one_geo]
[prPerson->educ_one_group][RANGE_POS(SIM_YEAR_RANGE, prPerson->calendar_year)])
{
prPerson->educ_one_status = EOS_WAIT;
}
else prPerson->educ_one_status = EOS_PAUSE;
}
}
// Unflag all persons
while (asPotentialSchoolOneStudentToProcess->Count() > 0)
{
asPotentialSchoolOneStudentToProcess->Item(0)->educ_one_to_process = FALSE;
}
time_end_school_one_year = TIME_INFINITE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Implementatation Clock Functions
////////////////////////////////////////////////////////////////////////////////////////////////////
void Clock::SetSchoolYearOneClock()
{
asSchoolOneActor->Item(0)->time_start_school_one_year = WAIT(StartSchoolOneYear);
asSchoolOneActor->Item(0)->time_end_school_one_year = WAIT(EndSchoolOneYear);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
table Person SchoolTrackTab //EN School Enrolment
[trigger_changes(calendar_year) && in_projected_time && is_resident && educ_one_status == EOS_ATTEND]
{
{
unit //EN Students
}
* sim_year
* educ_one_grade_attended+
};
actor Person
{
logical track_me = (RandUniform(33)<0.01) ? TRUE : FALSE;
};
track Person
[track_me]
{
integer_age,
educ_one_fate,
educ_one_grade_attended,
educ_one_grade_passed,
educ_one_status,
educ_one_grade_fate
};
5.15.3. Initializations in the Simulation() Function¶
The new actor is created in the Simulation() function.
// Create the School One
auto prSchoolOneActor = new SchoolOneActor();
prSchoolOneActor->Start();