MATSIM
ExperiencedPlansServiceImpl.java
Go to the documentation of this file.
1 
2 /* *********************************************************************** *
3  * project: org.matsim.*
4  * ExperiencedPlansServiceImpl.java
5  * *
6  * *********************************************************************** *
7  * *
8  * copyright : (C) 2019 by the members listed in the COPYING, *
9  * LICENSE and WARRANTY file. *
10  * email : info at matsim dot org *
11  * *
12  * *********************************************************************** *
13  * *
14  * This program is free software; you can redistribute it and/or modify *
15  * it under the terms of the GNU General Public License as published by *
16  * the Free Software Foundation; either version 2 of the License, or *
17  * (at your option) any later version. *
18  * See also COPYING, LICENSE and WARRANTY file *
19  * *
20  * *********************************************************************** */
21 
22  package org.matsim.core.scoring;
23 
24 import com.google.inject.Inject;
25 import org.apache.logging.log4j.LogManager;
26 import org.apache.logging.log4j.Logger;
27 import org.matsim.api.core.v01.Id;
28 import org.matsim.api.core.v01.IdMap;
29 import org.matsim.api.core.v01.Scenario;
30 import org.matsim.api.core.v01.population.*;
31 import org.matsim.core.config.Config;
36 
37 import java.util.Map;
38 
39 class ExperiencedPlansServiceImpl implements ExperiencedPlansService, EventsToLegs.LegHandler, EventsToActivities.ActivityHandler {
40 
41  private final static Logger log = LogManager.getLogger(ExperiencedPlansServiceImpl.class);
42 
43  @Inject private Config config;
44  @Inject private Population population;
45  @Inject(optional = true) private ScoringFunctionsForPopulation scoringFunctionsForPopulation;
46 
47  private final IdMap<Person, Plan> agentRecords = new IdMap<>(Person.class);
48 
49  @Inject
50  ExperiencedPlansServiceImpl(ControlerListenerManager controlerListenerManager, EventsToActivities eventsToActivities, EventsToLegs eventsToLegs) {
51  controlerListenerManager.addControlerListener(new IterationStartsListener() {
52  @Override
53  public void notifyIterationStarts(IterationStartsEvent event) {
54  for (Person person : population.getPersons().values()) {
55  agentRecords.put(person.getId(), PopulationUtils.createPlan());
56  }
57  }
58  });
59  eventsToActivities.addActivityHandler(this);
60  eventsToLegs.addLegHandler(this);
61  }
62 
63  ExperiencedPlansServiceImpl(EventsToActivities eventsToActivities, EventsToLegs eventsToLegs, Scenario scenario) {
64  this.population = scenario.getPopulation();
65 
66  for (Person person : population.getPersons().values()) {
67  agentRecords.put(person.getId(), PopulationUtils.createPlan());
68  }
69  eventsToActivities.addActivityHandler(this);
70  eventsToLegs.addLegHandler(this);
71  this.config = scenario.getConfig();
72  }
73 
74  @Override
75  synchronized public void handleLeg(PersonExperiencedLeg o) {
76  // Has to be synchronized because the thing which sends Legs and the thing which sends Activities can run
77  // on different threads. Will go away when/if we get a more Actor or Reactive Streams like event infrastructure.
78  Id<Person> agentId = o.getAgentId();
79  Leg leg = o.getLeg();
80  Plan plan = agentRecords.get(agentId);
81  if (plan != null) {
82  plan.addLeg(leg);
83  }
84  }
85 
86  @Override
87  synchronized public void handleActivity(PersonExperiencedActivity o) {
88  // Has to be synchronized because the thing which sends Legs and the thing which sends Activities can run
89  // on different threads. Will go away when/if we get a more Actor or Reactive Streams like event infrastructure.
90  Id<Person> agentId = o.getAgentId();
91  Activity activity = o.getActivity();
92  Plan plan = agentRecords.get(agentId);
93  if (plan != null) {
94  agentRecords.get(agentId).addActivity(activity);
95  }
96  }
97 
98  @Override
99  public void writeExperiencedPlans(String iterationFilename) {
100 // finishIteration(); // already called somewhere else in pgm flow.
101  Population tmpPop = PopulationUtils.createPopulation(config);
102  for (Map.Entry<Id<Person>, Plan> entry : this.agentRecords.entrySet()) {
103  Person person = PopulationUtils.getFactory().createPerson(entry.getKey());
104  Plan plan = entry.getValue();
105  person.addPlan(plan);
106  tmpPop.addPerson(person);
107  }
108  new PopulationWriter(tmpPop, null).write(iterationFilename);
109  // I removed the "V5" here in the assumption that it is better to move along with future format changes. If this is
110  // undesired, please change back but could you then please also add a comment why you prefer this. Thanks.
111  // kai, jan'16
112  }
113  @Override
114  public final void finishIteration() {
115  // I separated this from "writeExperiencedPlans" so that it can be called separately even when nothing is written. Can't say
116  // if the design might be better served by an iteration ends listener. kai, feb'17
117  for (Map.Entry<Id<Person>, Plan> entry : this.agentRecords.entrySet()) {
118  Plan plan = entry.getValue();
119  if (scoringFunctionsForPopulation != null) {
120  plan.setScore(scoringFunctionsForPopulation.getScoringFunctionForAgent(entry.getKey()).getScore());
121  if (plan.getScore().isNaN()) {
122  log.warn("score is NaN; plan:" + plan.toString());
123  }
124  }
125  }
126  }
127 
128  @Override
129  public IdMap<Person, Plan> getExperiencedPlans() {
130  return this.agentRecords;
131  }
132 
133 }
void addActivity(final Activity act)