Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
54fa259
generate outline Employment statistics file
andrewbaxter439 Mar 28, 2025
d4f2bf5
add employmetn history filter
andrewbaxter439 Mar 28, 2025
fd4bc98
update to calculate all validation statistics
andrewbaxter439 Mar 28, 2025
e08f682
added collector arguments for employment statistics - default off
andrewbaxter439 Mar 28, 2025
e7fe65a
working employment stats
andrewbaxter439 Mar 28, 2025
ac130ca
bad test
andrewbaxter439 Mar 28, 2025
f884b10
add employment lag1 getters
andrewbaxter439 Mar 28, 2025
27aaad8
workign tests for filtering employed and unemploed
andrewbaxter439 Mar 28, 2025
88c2b5b
working tests for proportions in/out of employment
andrewbaxter439 Mar 28, 2025
b86b138
Update src/test/java/simpaths/data/filters/EmploymentHistoryFilterTes…
andrewbaxter439 Mar 28, 2025
e22c63c
Update src/test/java/simpaths/data/filters/EmploymentHistoryFilterTes…
andrewbaxter439 Mar 28, 2025
87fa2b9
add a config file to only report employment transitions statistics
andrewbaxter439 Mar 28, 2025
8ce401a
added a test class of person with an ID
andrewbaxter439 Mar 25, 2025
a321079
added a test class of Benefit Unit with id
andrewbaxter439 Mar 25, 2025
96d3586
Updated Person test class with seed passed to Innovation object
andrewbaxter439 Mar 28, 2025
fc1f9cf
Merge branch 'feature/flexible-person-bu-test-classes' into feature/1…
andrewbaxter439 Mar 28, 2025
52b25a1
change all persons to test person new class
andrewbaxter439 Mar 28, 2025
411e183
Revert "change all persons to test person new class"
andrewbaxter439 Apr 2, 2025
4e29271
Revert "Merge branch 'feature/flexible-person-bu-test-classes' into f…
andrewbaxter439 Apr 2, 2025
d5ea53a
change filter tests to parameterised tests across person array
andrewbaxter439 Apr 2, 2025
c7a6ccc
simpler tests
andrewbaxter439 Apr 2, 2025
f235d47
Apply suggestions from code review
andrewbaxter439 Apr 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions config/employmentTransStats.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# This file can be used to override defaults for multirun arguments.
# Arguments of the SimPathsMultiRun object overridden by the command-line

maxNumberOfRuns: 1
executeWithGui: false
randomSeed: 606
startYear: 2011
endYear: 2020
popSize: 50000

# Arguments passed to the SimPathsModel
model_args:
# maxAge: 130
# fixTimeTrend: true
# timeTrendStopsIn: 2017
# fixRandomSeed: true
# sIndexTimeWindow: 5
# sIndexAlpha: 2
# sIndexDelta: 0
# savingRate: 0
# initialisePotentialEarningsFromDatabase: true
# useWeights: false
# useSBAMMatching:
# projectMortality: true
# alignFertility: true
# labourMarketCovid19On: false
# projectFormalChildcare: true
# donorPoolAveraging: true
# alignEmployment: false
# projectSocialCare: false
# enableIntertemporalOptimisations: true
# responsesToLowWageOffer: true
# saveImperfectTaxDBMatches: false
# useSavedBehaviour: false
# readGrid: "laptop serial"
# saveBehaviour: true
# employmentOptionsOfPrincipalWorker: 3
# employmentOptionsOfSecondaryWorker: 3
# responsesToEducation: true
# responsesToRetirement: false
# responsesToHealth: true
# responsesToDisability: false
# minAgeForPoorHealth: 50
# responsesToRegion: false

# Arguments that alter processing of the SimPathsMultiRun object
innovation_args:
# randomSeedInnov: false
# intertemporalElasticityInnov: false
# labourSupplyElasticityInnov: true

collector_args:
# calculateGiniCoefficients: false
# exportToDatabase: false
# exportToCSV: true
persistStatistics: false
persistStatistics2: false
persistStatistics3: false
persistPersons: false
persistBenefitUnits: false
persistHouseholds: false
persistEmploymentStatistics: true
# dataDumpStartTime: 0L
# dataDumpTimePeriod: 1.0
27 changes: 27 additions & 0 deletions src/main/java/simpaths/data/filters/EmploymentHistoryFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package simpaths.data.filters;

import microsim.statistics.ICollectionFilter;
import simpaths.model.Person;
import simpaths.model.enums.Gender;
import simpaths.model.enums.Les_c4;

public class EmploymentHistoryFilter implements ICollectionFilter {

private Les_c4 employmentLag1;

public EmploymentHistoryFilter(Les_c4 employmentLag1) {
super();
this.employmentLag1 = employmentLag1;

}

public boolean isFiltered(Object object) {

if (object instanceof Person){
Person person = (Person) object;
return (person.getLes_c4_lag1().equals(employmentLag1));
}
else throw new IllegalArgumentException("Argument passed to EmploymentHistoryFilter must be of object type Person");
}

}
70 changes: 70 additions & 0 deletions src/main/java/simpaths/data/statistics/EmploymentStatistics.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package simpaths.data.statistics;

import jakarta.persistence.Column;
import jakarta.persistence.Id;
import jakarta.persistence.Entity;

import microsim.data.db.PanelEntityKey;
import microsim.statistics.CrossSection;
import microsim.statistics.IDoubleSource;
import microsim.statistics.functions.MeanArrayFunction;
import simpaths.data.filters.EmploymentHistoryFilter;
import simpaths.model.SimPathsModel;
import simpaths.model.enums.Les_c4;
import simpaths.model.Person;

@Entity
public class EmploymentStatistics {

@Id
private PanelEntityKey key = new PanelEntityKey(1L);

@Column(name= "EmpToNotEmp")
private double EmpToNotEmp; // Proportion of employed people becoming unemployed

@Column(name= "NotEmpToEmp")
private double NotEmpToEmp; // Proportion of unemployed people becoming employed


public double getEmpToNotEmp() {
return EmpToNotEmp;
}

public void setEmpToNotEmp(double empToNotEmp) {
EmpToNotEmp = empToNotEmp;
}

public double getNotEmpToEmp() {
return NotEmpToEmp;
}

public void setNotEmpToEmp(double notEmpToEmp) {
NotEmpToEmp = notEmpToEmp;
}

public void update(SimPathsModel model) {

EmploymentHistoryFilter employmentHistoryEmployed = new EmploymentHistoryFilter(Les_c4.EmployedOrSelfEmployed);
EmploymentHistoryFilter employmentHistoryUnemployed = new EmploymentHistoryFilter(Les_c4.NotEmployed);


// Entering employment transition rate
CrossSection.Integer personsNotEmpToEmp = new CrossSection.Integer(model.getPersons(), Person.class, "getEmployed", true);
personsNotEmpToEmp.setFilter(employmentHistoryUnemployed);
// Entering not employed transition rate
CrossSection.Integer personsEmpToNotEmp = new CrossSection.Integer(model.getPersons(), Person.class, "getNonwork", true);
personsEmpToNotEmp.setFilter(employmentHistoryEmployed);


MeanArrayFunction isNotEmpToEmp = new MeanArrayFunction(personsNotEmpToEmp);
isNotEmpToEmp.applyFunction();
setNotEmpToEmp(isNotEmpToEmp.getDoubleValue(IDoubleSource.Variables.Default));

MeanArrayFunction isEmpToNotEmp = new MeanArrayFunction(personsEmpToNotEmp);
isEmpToNotEmp.applyFunction();
setEmpToNotEmp(isEmpToNotEmp.getDoubleValue(IDoubleSource.Variables.Default));



}
}
22 changes: 22 additions & 0 deletions src/main/java/simpaths/experiment/SimPathsCollector.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.util.Map;

import simpaths.data.filters.FlexibleInLabourSupplyFilter;
import simpaths.data.statistics.EmploymentStatistics;
import simpaths.model.BenefitUnit;
import simpaths.model.SimPathsModel;
import simpaths.model.enums.Quintiles;
Expand Down Expand Up @@ -57,6 +58,8 @@ public class SimPathsCollector extends AbstractSimulationCollectorManager implem
@GUIparameter(description="Report alignment adjustments")
private boolean persistStatistics3 = true;

private boolean persistEmploymentStatistics = false;

@GUIparameter(description="Toggle to turn database persistence on/off")
private boolean exportToDatabase = false;

Expand Down Expand Up @@ -91,6 +94,8 @@ public class SimPathsCollector extends AbstractSimulationCollectorManager implem

private Statistics3 stats3;

private EmploymentStatistics statsEmployment;

private GiniPersonalGrossEarnings giniPersonalGrossEarnings;

private GiniEquivalisedHouseholdDisposableIncome giniEquivalisedHouseholdDisposableIncome;
Expand All @@ -115,6 +120,8 @@ public class SimPathsCollector extends AbstractSimulationCollectorManager implem

private DataExport exportStatistics3;

private DataExport exportStatisticsEmployment;

protected MultiTraceFunction.Double fGiniPersonalGrossEarningsNational;

protected Map<Region, MultiTraceFunction.Double> fGiniPersonalGrossEarningsRegionalMap;
Expand Down Expand Up @@ -150,6 +157,7 @@ public enum Processes {
DumpStatistics,
DumpStatistics2,
DumpStatistics3,
DumpStatisticsEmployment
}


Expand Down Expand Up @@ -218,6 +226,13 @@ public void onEvent(Enum<?> type) {
log.error(e.getMessage());
}
break;
case DumpStatisticsEmployment:
statsEmployment.update(model);
try {
exportStatisticsEmployment.export();
} catch (Exception e) {
log.error(e.getMessage());
}
}
}

Expand All @@ -234,6 +249,7 @@ public void buildObjects() {
stats = new Statistics();
stats2 = new Statistics2();
stats3 = new Statistics3();
statsEmployment = new EmploymentStatistics();

//For export to database or .csv files.
if(persistPersons)
Expand All @@ -248,6 +264,8 @@ public void buildObjects() {
exportStatistics2 = new DataExport(stats2, exportToDatabase, exportToCSV);
if (persistStatistics3)
exportStatistics3 = new DataExport(stats3, exportToDatabase, exportToCSV);
if (persistEmploymentStatistics)
exportStatisticsEmployment = new DataExport(statsEmployment, exportToDatabase, exportToCSV);


if (calculateGiniCoefficients) {
Expand Down Expand Up @@ -308,6 +326,10 @@ public void buildSchedule() {
getEngine().getEventQueue().scheduleRepeat(new SingleTargetEvent(this, Processes.DumpStatistics3), model.getStartYear() + dataDumpStartTime, ordering, dataDumpTimePeriod);
}

if (persistEmploymentStatistics) {
getEngine().getEventQueue().scheduleRepeat(new SingleTargetEvent(this, Processes.DumpStatisticsEmployment), model.getStartYear() + dataDumpStartTime, ordering, dataDumpTimePeriod);
}

if (persistPersons) {
getEngine().getEventQueue().scheduleRepeat(new SingleTargetEvent(this, Processes.DumpPersons), model.getStartYear() + dataDumpStartTime, ordering, dataDumpTimePeriod);
}
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/simpaths/model/Person.java
Original file line number Diff line number Diff line change
Expand Up @@ -3964,6 +3964,14 @@ public int getNonwork() {
return (Les_c4.NotEmployed.equals(les_c4)) ? 1 : 0;
}

public int getEmployed_Lag1() {
return (Les_c4.EmployedOrSelfEmployed.equals(les_c4_lag1)) ? 1 : 0;
}

public int getNonwork_Lag1() {
return (Les_c4.NotEmployed.equals(les_c4_lag1)) ? 1 : 0;
}

public void setRegionLocal(Region region) {
regionLocal = region;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package simpaths.data.filters;

import org.junit.jupiter.api.*;
import simpaths.model.Person;
import simpaths.model.enums.Les_c4;


import static org.junit.jupiter.api.Assertions.*;

@DisplayName("Test filtering by employment history")
class EmploymentHistoryFilterTest {

private static Person createTestPerson(
Les_c4 les_c4_lag1
) {
Person testPerson = new Person(true);
testPerson.setLes_c4_lag1(les_c4_lag1);

return testPerson;
}

@Test
@DisplayName("Employed filter only returns true for employed or self-employed persons")
void employedOrSelfEmployed() {
EmploymentHistoryFilter filter = new EmploymentHistoryFilter(Les_c4.EmployedOrSelfEmployed);
assertTrue(filter.isFiltered(createTestPerson(Les_c4.EmployedOrSelfEmployed)));
assertFalse(filter.isFiltered(createTestPerson(Les_c4.NotEmployed)));
assertFalse(filter.isFiltered(createTestPerson(Les_c4.Student)));
assertFalse(filter.isFiltered(createTestPerson(Les_c4.Retired)));
}

@Test
@DisplayName("Unemployed filter only returns true for unemployed persons")
void unEmployed() {
EmploymentHistoryFilter filter = new EmploymentHistoryFilter(Les_c4.NotEmployed);
assertFalse(filter.isFiltered(createTestPerson(Les_c4.EmployedOrSelfEmployed)));
assertTrue(filter.isFiltered(createTestPerson(Les_c4.NotEmployed)));
assertFalse(filter.isFiltered(createTestPerson(Les_c4.Student)));
assertFalse(filter.isFiltered(createTestPerson(Les_c4.Retired)));
}


}
Loading