Skip to content

Commit

Permalink
make plan creation method public
Browse files Browse the repository at this point in the history
  • Loading branch information
rakow committed Aug 7, 2024
1 parent ce81ea2 commit d9f763f
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 127 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public class RunOpenBerlinCalibration extends MATSimApplication {
* Flexible activities, which need to be known for location choice and during generation.
* A day can not end on a flexible activity.
*/
public static final Set<String> FLEXIBLE_ACTS = Set.of("shop_daily", "shop_other", "leisure", "dining");
public static final Set<String> FLEXIBLE_ACTS = Set.of("shop_daily", "shop_other", "shopping", "leisure", "dining");
private static final Logger log = LogManager.getLogger(RunOpenBerlinCalibration.class);
@CommandLine.Mixin
private final SampleOptions sample = new SampleOptions(25, 10, 3, 1);
Expand Down
254 changes: 128 additions & 126 deletions src/main/java/org/matsim/prepare/population/RunActivitySampling.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,129 +71,10 @@ public static void main(String[] args) {
new RunActivitySampling().execute(args);
}

@Override
public Integer call() throws Exception {

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

matcher = new PersonMatcher("idx", personsPath);

try (CSVParser parser = csv.createParser(activityPath)) {
readActivities(parser);
}

ctxs = ThreadLocal.withInitial(() -> new Context(new SplittableRandom(seed)));
factory = population.getFactory();

ParallelPersonAlgorithmUtils.run(population, 8, this);

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

double atHome = 0;
for (Person person : population.getPersons().values()) {
List<Leg> legs = TripStructureUtils.getLegs(person.getSelectedPlan());
if (legs.isEmpty())
atHome++;
}

int size = population.getPersons().size();
double mobile = (size - atHome) / size;

log.info("Processed {} persons, mobile persons: {}%", size, 100 * mobile);

return 0;
}

private void readActivities(CSVParser csv) {

String currentId = null;
List<CSVRecord> current = null;

int i = 0;
for (CSVRecord r : csv) {

String pId = r.get("p_id");

if (!Objects.equals(pId, currentId)) {
if (current != null)
activities.put(currentId, current);

currentId = pId;
current = new ArrayList<>();
}

current.add(r);
i++;
}

if (current != null && !current.isEmpty()) {
activities.put(currentId, current);
}

log.info("Read {} activities for {} persons", i, activities.size());
}


@Override
public void run(Person person) {

SplittableRandom rnd = ctxs.get().rnd;

String idx = matcher.matchPerson(person, rnd);
CSVRecord row = matcher.getPerson(idx);

copyAttributes(row, person);

String mobile = row.get("mobile_on_day");

// ensure mobile agents have a valid plan
switch (mobile.toLowerCase()) {

case "true" -> {
List<CSVRecord> activities = this.activities.get(idx);

if (activities == null)
throw new AssertionError("No activities for mobile person " + idx);

if (activities.size() == 0)
throw new AssertionError("Activities for mobile agent can not be empty.");

person.removePlan(person.getSelectedPlan());
Plan plan = createPlan(Attributes.getHomeCoord(person), activities, rnd);

person.addPlan(plan);
person.setSelectedPlan(plan);
}

case "false" -> {
// Keep the stay home plan
}

default -> throw new AssertionError("Invalid mobile_on_day attribute " + mobile);
}
}

/**
* Copy attributes from csv record to person.
*/
public void copyAttributes(CSVRecord row, Person person) {
PersonUtils.setCarAvail(person, row.get("car_avail").equals("True") ? "always" : "never");
PersonUtils.setLicence(person, row.get("driving_license").toLowerCase());
PersonUtils.setIncome(person, Math.max(499, Double.parseDouble(row.get("income"))));

person.getAttributes().putAttribute(Attributes.BIKE_AVAIL, row.get("bike_avail").equals("True") ? "always" : "never");
person.getAttributes().putAttribute(Attributes.PT_ABO_AVAIL, row.get("pt_abo_avail").equals("True") ? "always" : "never");

person.getAttributes().putAttribute(Attributes.EMPLOYMENT, row.get("employment"));
person.getAttributes().putAttribute(Attributes.RESTRICTED_MOBILITY, row.get("restricted_mobility").equals("True"));
person.getAttributes().putAttribute(Attributes.ECONOMIC_STATUS, row.get("economic_status"));
person.getAttributes().putAttribute(Attributes.HOUSEHOLD_SIZE, Integer.parseInt(row.get("n_persons")));
}

/**
* Randomize the duration slightly, depending on total duration.
*/
private static int randomizeDuration(int minutes, SplittableRandom rnd) {
static int randomizeDuration(int minutes, SplittableRandom rnd) {
if (minutes <= 10)
return minutes * 60;

Expand All @@ -207,13 +88,9 @@ private static int randomizeDuration(int minutes, SplittableRandom rnd) {
}

/**
* Create plan for a person using given id.
* Create daily plan from a list of entries.
*/
public Plan createPlan(Coord homeCoord, String personId) {
return createPlan(homeCoord, activities.get(personId), ctxs.get().rnd);
}

private Plan createPlan(Coord homeCoord, List<CSVRecord> activities, SplittableRandom rnd) {
public static Plan createPlan(Coord homeCoord, List<CSVRecord> activities, SplittableRandom rnd, PopulationFactory factory) {
Plan plan = factory.createPlan();

Activity a = null;
Expand Down Expand Up @@ -321,6 +198,131 @@ private Plan createPlan(Coord homeCoord, List<CSVRecord> activities, SplittableR
return plan;
}

@Override
public Integer call() throws Exception {

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

matcher = new PersonMatcher("idx", personsPath);

try (CSVParser parser = csv.createParser(activityPath)) {
readActivities(parser);
}

ctxs = ThreadLocal.withInitial(() -> new Context(new SplittableRandom(seed)));
factory = population.getFactory();

ParallelPersonAlgorithmUtils.run(population, 8, this);

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

double atHome = 0;
for (Person person : population.getPersons().values()) {
List<Leg> legs = TripStructureUtils.getLegs(person.getSelectedPlan());
if (legs.isEmpty())
atHome++;
}

int size = population.getPersons().size();
double mobile = (size - atHome) / size;

log.info("Processed {} persons, mobile persons: {}%", size, 100 * mobile);

return 0;
}

private void readActivities(CSVParser csv) {

String currentId = null;
List<CSVRecord> current = null;

int i = 0;
for (CSVRecord r : csv) {

String pId = r.get("p_id");

if (!Objects.equals(pId, currentId)) {
if (current != null)
activities.put(currentId, current);

currentId = pId;
current = new ArrayList<>();
}

current.add(r);
i++;
}

if (current != null && !current.isEmpty()) {
activities.put(currentId, current);
}

log.info("Read {} activities for {} persons", i, activities.size());
}

@Override
public void run(Person person) {

SplittableRandom rnd = ctxs.get().rnd;

String idx = matcher.matchPerson(person, rnd);
CSVRecord row = matcher.getPerson(idx);

copyAttributes(row, person);

String mobile = row.get("mobile_on_day");

// ensure mobile agents have a valid plan
switch (mobile.toLowerCase()) {

case "true" -> {
List<CSVRecord> activities = this.activities.get(idx);

if (activities == null)
throw new AssertionError("No activities for mobile person " + idx);

if (activities.size() == 0)
throw new AssertionError("Activities for mobile agent can not be empty.");

person.removePlan(person.getSelectedPlan());
Plan plan = createPlan(Attributes.getHomeCoord(person), activities, rnd, factory);

person.addPlan(plan);
person.setSelectedPlan(plan);
}

case "false" -> {
// Keep the stay home plan
}

default -> throw new AssertionError("Invalid mobile_on_day attribute " + mobile);
}
}

/**
* Copy attributes from csv record to person.
*/
public void copyAttributes(CSVRecord row, Person person) {
PersonUtils.setCarAvail(person, row.get("car_avail").equals("True") ? "always" : "never");
PersonUtils.setLicence(person, row.get("driving_license").toLowerCase());
PersonUtils.setIncome(person, Math.max(499, Double.parseDouble(row.get("income"))));

person.getAttributes().putAttribute(Attributes.BIKE_AVAIL, row.get("bike_avail").equals("True") ? "always" : "never");
person.getAttributes().putAttribute(Attributes.PT_ABO_AVAIL, row.get("pt_abo_avail").equals("True") ? "always" : "never");

person.getAttributes().putAttribute(Attributes.EMPLOYMENT, row.get("employment"));
person.getAttributes().putAttribute(Attributes.RESTRICTED_MOBILITY, row.get("restricted_mobility").equals("True"));
person.getAttributes().putAttribute(Attributes.ECONOMIC_STATUS, row.get("economic_status"));
person.getAttributes().putAttribute(Attributes.HOUSEHOLD_SIZE, Integer.parseInt(row.get("n_persons")));
}

/**
* Create plan for a person using given id.
*/
public Plan createPlan(Coord homeCoord, String personId) {
return createPlan(homeCoord, activities.get(personId), ctxs.get().rnd, factory);
}

private record Context(SplittableRandom rnd) {
}

Expand Down

0 comments on commit d9f763f

Please sign in to comment.