MATSIM
ExternalModule.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * ExternalModule.java
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2007 by the members listed in the COPYING, *
8  * LICENSE and WARRANTY file. *
9  * email : info at matsim dot org *
10  * *
11  * *********************************************************************** *
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * See also COPYING, LICENSE and WARRANTY file *
18  * *
19  * *********************************************************************** */
20 
21 package org.matsim.core.replanning.modules;
22 
23 import java.util.HashMap;
24 import java.util.Map;
25 
26 import org.matsim.api.core.v01.Id;
27 import org.matsim.api.core.v01.Scenario;
34 import org.matsim.core.config.Config;
45 
59 public class ExternalModule implements PlanStrategyModule {
60 
61  interface ExeRunnerDelegate {
62  public boolean invoke();
63  }
64 
65  private static final String SCENARIO = "scenario";
66  private static final String SCENARIO_INPUT_PLANS_FILENAME = "inputPlansFilename";
67  private static final String SCENARIO_WORKING_PLANS_FILENAME = "workingPlansFilename";
68  private static final String SCENARIO_WORKING_EVENTS_TXT_FILENAME = "workingEventsTxtFilename";
69  private static final String SCENARIO_NETWORK_FILENAME = "networkFilename";
70 
71  private static final String ExternalInFileName = "plans.in.xml";
72  private static final String ExternalOutFileName = "plans.out.xml";
73  private static final String ExternalConfigFileName = "config.xml";
74 
75  private final Scenario scenario;
76  private final ExeRunnerDelegate exeRunnerDelegate;
77  private String modulePrefix = "";
78  private String outFileRoot = "";
79 
81 
82  private int currentIteration = -1;
83 
85 
86  private Map<Id<Person>, Plan> plansToMutate = new HashMap<>();
87 
88  public ExternalModule(final String exePath, final String moduleId, final OutputDirectoryHierarchy controler, final Scenario scenario) {
89  this.modulePrefix = moduleId + "_";
90  this.controler = controler;
91  this.outFileRoot = controler.getTempPath() + "/";
92  this.scenario = scenario;
93  this.exeRunnerDelegate = new ExeRunnerDelegate() {
94  @Override
95  public boolean invoke() {
96  String cmd = exePath + " " + outFileRoot + modulePrefix + ExternalConfigFileName;
97  String logfilename = controler.getIterationFilename(currentIteration, modulePrefix + "stdout.log");
98  return (ExeRunner.run(cmd, logfilename, 3600) == 0);
99  }
100  };
101  }
102 
103  ExternalModule(ExeRunnerDelegate exeRunnerDelegate, final String moduleId, final OutputDirectoryHierarchy controler, final Scenario scenario) {
104  this.modulePrefix = moduleId + "_";
105  this.controler = controler;
106  this.outFileRoot = controler.getTempPath() + "/";
107  this.scenario = scenario;
108  this.exeRunnerDelegate = exeRunnerDelegate;
109  }
110 
111  @Override
112  public void prepareReplanning(ReplanningContext replanningContext) {
113  this.currentIteration = replanningContext.getIteration();
114  this.exportPopulation = ScenarioUtils.createScenario(ConfigUtils.createConfig()).getPopulation();
115  }
116 
117  @Override
118  public void handlePlan(final Plan plan) {
119  // Creating a dummy population which only contains the plans which are passed here.
120  // I need to copy the plans because I am not supposed to add a plan to a different Person.
121  // I also need to memorize the plans which are passed here, because I am supposed to mutate them.
122 
123  final Person personWithOnlySelectedPlan = this.exportPopulation.getFactory().createPerson(plan.getPerson().getId());
124  final Plan planForNewPerson = PopulationUtils.createPlan(personWithOnlySelectedPlan);
125  PopulationUtils.copyFromTo(plan, planForNewPerson);
126  personWithOnlySelectedPlan.addPlan(planForNewPerson);
127  this.exportPopulation.addPerson(personWithOnlySelectedPlan);
128  this.plansToMutate.put(plan.getPerson().getId(), plan);
129  }
130 
131  @Override
132  public void finishReplanning() {
135  boolean successful = this.exeRunnerDelegate.invoke();
136  if (successful) {
138  } else {
139  throw new RuntimeException("External Replanning exited with error.");
140  }
141  }
142 
143  private void exportPopulation() {
144  String filename = this.outFileRoot + this.modulePrefix + ExternalInFileName;
145  PopulationWriter plansWriter = new PopulationWriter(exportPopulation, scenario.getNetwork());
146  plansWriter.write(filename);
147  }
148 
149  private void prepareExternalExeConfig() {
150  Config extConfig;
151  String configFileName = this.scenario.getConfig().replanning().getExternalExeConfigTemplate();
152  if (configFileName == null) {
153  extConfig = new Config();
154  } else {
155  extConfig = new Config();
156  ConfigReader reader = new ConfigReader(extConfig);
157  reader.readFile(configFileName);
158  }
159  // Change scenario config according to given output- and input-filenames: events, plans, network
160  extConfig.setParam(SCENARIO, SCENARIO_INPUT_PLANS_FILENAME, this.outFileRoot + "/" + this.modulePrefix + ExternalInFileName);
161  extConfig.setParam(SCENARIO, SCENARIO_WORKING_PLANS_FILENAME, this.outFileRoot + "/" + this.modulePrefix + ExternalOutFileName);
162  extConfig.setParam(SCENARIO, SCENARIO_WORKING_EVENTS_TXT_FILENAME, this.controler.getIterationFilename(this.currentIteration - 1, "events.txt"));
163  String networkFilename = this.scenario.getConfig().findParam("network", "inputNetworkFile");
164  extConfig.setParam(SCENARIO, SCENARIO_NETWORK_FILENAME, networkFilename);
165  new ConfigWriter(extConfig).write(this.outFileRoot + this.modulePrefix + ExternalConfigFileName);
166  }
167 
170  MatsimReader plansReader = new PopulationReader(dummyScenario);
171  Population plans = dummyScenario.getPopulation();
172  plansReader.readFile(this.outFileRoot + this.modulePrefix + ExternalOutFileName);
173  new UpdatePlansAlgo().run(plans);
174  }
175 
176  private class UpdatePlansAlgo extends AbstractPersonAlgorithm {
177  @Override
178  public void run(final Person dummyPerson) {
179  Plan newPlan = dummyPerson.getPlans().get(0);
180  Plan planToMutate = plansToMutate.get(dummyPerson.getId());
181  planToMutate.getPlanElements().clear();
182  PopulationUtils.copyFromTo(newPlan, planToMutate);
183  }
184  }
185 
186 }
void readFile(final String filename, final String dtdFilename)
final void setParam(final String moduleName, final String paramName, final String value)
Definition: Config.java:381
final String getIterationFilename(final int iteration, final String filename)
final void write(final String filename)
static int run(final String cmd, final String stdoutFileName, final int timeout)
Definition: ExeRunner.java:56
final String findParam(final String moduleName, final String paramName)
Definition: Config.java:346
static void copyFromTo(final Plan in, final Plan out)
ExternalModule(final String exePath, final String moduleId, final OutputDirectoryHierarchy controler, final Scenario scenario)
List< PlanElement > getPlanElements()
final ReplanningConfigGroup replanning()
Definition: Config.java:427
void prepareReplanning(ReplanningContext replanningContext)
static Scenario createScenario(final Config config)
static Config createConfig(final String context)
abstract List<? extends T > getPlans()