Skip to content

Commit

Permalink
prepare population class
Browse files Browse the repository at this point in the history
  • Loading branch information
rakow committed Jan 5, 2024
1 parent 8c543e7 commit f09443a
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 3 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,15 @@ input/$V/$N-$V-100pct.plans-initial.xml.gz: input/plans-longHaulFreight.xml.gz i

$(sc) prepare fix-subtour-modes --coord-dist 100 --input input/$V/prepare-100pct.plans-adj.xml.gz --output $@

$(sc) prepare population $@ --output $@

$(sc) prepare split-activity-types-duration\
--input $@\
--exclude commercial_start,commercial_end,freight_start,freight_end\
--output $@

$(sc) prepare merge-populations $@ $< --output $@

$(sc) prepare extract-home-coordinates $@ --output $@ --csv input/$V/$N-$V-homes.csv

$(sc) prepare downsample-population $@\
--sample-size 1\
--samples 0.25 0.1 0.01\
Expand Down
10 changes: 9 additions & 1 deletion src/main/java/org/matsim/run/RunLausitzScenario.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,13 @@
import org.matsim.core.config.groups.RoutingConfigGroup;
import org.matsim.core.controler.AbstractModule;
import org.matsim.core.controler.Controler;
import org.matsim.core.scoring.functions.ScoringParametersForPerson;
import org.matsim.run.analysis.CommuterAnalysis;
import org.matsim.run.prepare.PreparePopulation;
import org.matsim.simwrapper.SimWrapperConfigGroup;
import org.matsim.simwrapper.SimWrapperModule;
import picocli.CommandLine;
import playground.vsp.scoring.IncomeDependentUtilityOfMoneyPersonScoringParameters;

import javax.annotation.Nullable;
import java.util.Set;
Expand All @@ -35,7 +38,7 @@
CreateNetworkFromSumo.class, CreateTransitScheduleFromGtfs.class, TrajectoryToPlans.class, GenerateShortDistanceTrips.class,
MergePopulations.class, ExtractRelevantFreightTrips.class, DownSamplePopulation.class, ExtractHomeCoordinates.class, CleanNetwork.class,
CreateLandUseShp.class, ResolveGridCoordinates.class, FixSubtourModes.class, AdjustActivityToLinkDistances.class, XYToLinks.class,
SplitActivityTypesDuration.class, CreateCountsFromBAStData.class
SplitActivityTypesDuration.class, CreateCountsFromBAStData.class, PreparePopulation.class
})
@MATSimApplication.Analysis({
LinkStats.class, CheckPopulation.class, CommuterAnalysis.class,
Expand Down Expand Up @@ -114,9 +117,14 @@ protected void prepareControler(Controler controler) {
controler.addOverridingModule(new AbstractModule() {
@Override
public void install() {

bind(ScoringParametersForPerson.class).to(IncomeDependentUtilityOfMoneyPersonScoringParameters.class).asEagerSingleton();

addControlerListenerBinding().to(ModeChoiceCoverageControlerListener.class);

addTravelTimeBinding(TransportMode.ride).to(networkTravelTime());
addTravelDisutilityFactoryBinding(TransportMode.ride).to(carTravelDisutilityFactoryKey());

}

});
Expand Down
143 changes: 143 additions & 0 deletions src/main/java/org/matsim/run/prepare/PreparePopulation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package org.matsim.run.prepare;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.Coord;
import org.matsim.api.core.v01.population.*;
import org.matsim.application.MATSimAppCommand;
import org.matsim.application.prepare.population.ExtractHomeCoordinates;
import org.matsim.core.population.PersonUtils;
import org.matsim.core.population.PopulationUtils;
import org.matsim.core.router.TripStructureUtils;
import picocli.CommandLine;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.SplittableRandom;

@CommandLine.Command(
name = "population",
description = "Prepares person attributes and plans."
)
public class PreparePopulation implements MATSimAppCommand {

private static final Logger log = LogManager.getLogger(PreparePopulation.class);

private final SplittableRandom rnd = new SplittableRandom(1234);

@CommandLine.Parameters(arity = "1", paramLabel = "INPUT", description = "Path to input population")
private Path input;

@CommandLine.Option(names = "--output", description = "Path to output population", required = true)
private Path output;

public static void main(String[] args) {
new PreparePopulation().execute(args);
}

private static double round(double x) {
return BigDecimal.valueOf(x).setScale(2, RoundingMode.HALF_UP).doubleValue();
}

@Override
public Integer call() throws Exception {

if (!Files.exists(input)) {
log.error("Input population does not exist: {}", input);
return 2;
}


Population population = PopulationUtils.readPopulation(input.toString());


population.getPersons().values().forEach(this::prepare);


PopulationUtils.writePopulation(population, output.toString());

return 0;
}

/**
* This step runs before any other steps.
*/
private void prepare(Person person) {


List<Activity> activities = TripStructureUtils.getActivities(person.getSelectedPlan(), TripStructureUtils.StageActivityHandling.ExcludeStageActivities);
for (Activity act : activities) {
// Reduce unnecessary precision
if (act.getCoord() != null) {
act.setCoord(new Coord(round(act.getCoord().getX()), round(act.getCoord().getY())));
}
}

// Set car availability to "never" for agents below 18 years old
// Standardize the attribute "age"
String avail = "always";
Object age = person.getAttributes().getAttribute("microm:modeled:age");
if (age != null) {
PersonUtils.setAge(person, (int) age);
person.getAttributes().removeAttribute("microm:modeled:age");
if ((int) age < 18) {
avail = "never";
}
}

// Replace with standardized car availability attribute
PersonUtils.setCarAvail(person, avail);
person.getAttributes().removeAttribute("sim_carAvailability");

// Standardize the attribute "sex"
Object sex = person.getAttributes().getAttribute("microm:modeled:sex");
if (sex != null) {
PersonUtils.setSex(person, (String) sex);
person.getAttributes().removeAttribute("microm:modeled:sex");
}

// Assign income to person (skip the freight agents)
if (person.getId().toString().startsWith("freight")) {
return;
}

ExtractHomeCoordinates.setHomeCoordinate(person);

String incomeGroupString = (String) person.getAttributes().getAttribute("householdIncome");
String householdSizeString = (String) person.getAttributes().getAttribute("householdSize");
int incomeGroup = 0;
double householdSize = 1;
if (incomeGroupString != null && householdSizeString != null) {
incomeGroup = Integer.parseInt(incomeGroupString);
householdSize = Double.parseDouble(householdSizeString);
}

double income = switch (incomeGroup) {
case 1 -> 500 / householdSize;
case 2 -> (rnd.nextInt(400) + 500) / householdSize;
case 3 -> (rnd.nextInt(600) + 900) / householdSize;
case 4 -> (rnd.nextInt(500) + 1500) / householdSize;
case 5 -> (rnd.nextInt(1000) + 2000) / householdSize;
case 6 -> (rnd.nextInt(1000) + 3000) / householdSize;
case 7 -> (rnd.nextInt(1000) + 4000) / householdSize;
case 8 -> (rnd.nextInt(1000) + 5000) / householdSize;
case 9 -> (rnd.nextInt(1000) + 6000) / householdSize;
case 10 -> (Math.abs(rnd.nextGaussian()) * 1000 + 7000) / householdSize;
default -> 2364;
// Average monthly household income per Capita (2021). See comments below for details
// Average Gross household income: 4734 Euro
// Average household size: 83.1M persons /41.5M households = 2.0 persons / household
// Average household income per capita: 4734/2.0 = 2364 Euro
// Source (Access date: 21 Sep. 2021):
// https://www.destatis.de/EN/Themes/Society-Environment/Income-Consumption-Living-Conditions/Income-Receipts-Expenditure/_node.html
// https://www.destatis.de/EN/Themes/Society-Environment/Population/Households-Families/_node.html
// https://www.destatis.de/EN/Themes/Society-Environment/Population/Current-Population/_node.html;jsessionid=E0D7A060D654B31C3045AAB1E884CA75.live711
};
PersonUtils.setIncome(person, (int) income);

}

}

0 comments on commit f09443a

Please sign in to comment.