MATSIM
Controler.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * *********************************************************************** *
4  * *
5  * copyright : (C) 2007, 2008 by the members listed in the COPYING, *
6  * LICENSE and WARRANTY file. *
7  * email : info at matsim dot org *
8  * *
9  * *********************************************************************** *
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * See also COPYING, LICENSE and WARRANTY file *
16  * *
17  * *********************************************************************** */
18 
19 package org.matsim.core.controler;
20 
21 import com.google.inject.Key;
22 import com.google.inject.Provider;
23 import com.google.inject.TypeLiteral;
24 import com.google.inject.name.Names;
25 import org.apache.log4j.Logger;
26 import org.apache.logging.log4j.core.layout.PatternLayout;
31 import org.matsim.api.core.v01.Scenario;
35 import org.matsim.core.config.Config;
42 import org.matsim.core.gbl.Gbl;
57 
58 import java.util.*;
59 
67 public final class Controler implements ControlerI, MatsimServices, AllowsConfiguration{
68  // yyyy Design thoughts:
69  // * Seems to me that we should try to get everything here final. Flexibility is provided by the ability to set or add factories. If this is
70  // not sufficient, people should use AbstractController. kai, jan'13
71 
72  public static final String DIRECTORY_ITERS = "ITERS";
73 
74  public enum DefaultFiles {
75  config("config.xml"),
76  configReduced("config_reduced.xml"),
77  network("network.xml"),
78  lanes("lanes.xml"),
79  changeEvents("change_events.xml"),
80  counts("counts.xml"),
81  population("plans.xml"),
82  experiencedPlans("experienced_plans.xml"),
83  households("households.xml"),
84  facilities("facilities.xml"),
85  events("events.xml"),
86  eventsPb("events.pb"),
87  eventsJson("events.ndjson"),
88  transitSchedule("transitSchedule.xml"),
89  transitVehicles("transitVehicles.xml"),
90  vehicles("vehicles.xml"),
91  allVehicles("allVehicles.xml"),
92  linkstats("linkstats.txt"),
93  tripscsv("trips.csv"),
94  personscsv("persons.csv"),
95  legscsv("legs.csv"),
96  ;
97 
98  final String filename;
99 
100  DefaultFiles(String filename) {
101  this.filename = filename;
102  }
103  }
104 
105  static final String OUTPUT_PREFIX = "output_";
106 
107  public static final String DIVIDER = "###################################################";
108 
109  private static final Logger log = Logger.getLogger(Controler.class);
110 
111  public static final PatternLayout DEFAULTLOG4JLAYOUT = PatternLayout.newBuilder().withPattern("%d{ISO8601} %5p %C{1}:%L %m%n").build();
112 
113  private final Config config;
115 
116  private com.google.inject.Injector injector;
117  private boolean injectorCreated = false;
118 
119  @Override
121  return injector.getInstance(IterationStopWatch.class);
122  }
123 
124  // DefaultControlerModule includes submodules. If you want less than what the Controler does
125  // by default, you can leave ControlerDefaultsModule out, look at what it does,
126  // and only include what you want.
127  private List<AbstractModule> modules = Collections.singletonList(new ControlerDefaultsModule());
128 
129  // The module which is currently defined by the sum of the setXX methods called on this Controler.
131 
132  private List<AbstractQSimModule> overridingQSimModules = new LinkedList<>();
133 
134  public static void main(final String[] args) {
135  if ((args == null) || (args.length == 0)) {
136  System.out.println("No argument given!");
137  System.out.println("Usage: Controler config-file [dtd-file]");
138  System.out.println();
139  } else {
140  final Controler controler = new Controler(args);
141  controler.run();
142  }
143  System.exit(0);
144  }
145 
156  public Controler(final String[] args) {
157  this(args.length > 0 ? args[0] : null, null, null);
158  }
159 
160  public Controler(final String configFileName) {
161  this(configFileName, null, null);
162  }
163 
164  public Controler(final Config config) {
165  this(null, config, null);
166  }
167 
168  public Controler(final Scenario scenario) {
169  this(null, null, scenario);
170  }
171 
172  private Controler(final String configFileName, final Config config, Scenario scenario) {
173  if (scenario != null) {
174  // scenario already loaded (recommended):
175  this.config = scenario.getConfig();
177  } else {
178  if (configFileName == null) {
179  // config should already be loaded:
180  if (config == null) {
181  throw new IllegalArgumentException("Either the config or the filename of a configfile must be set to initialize the Controler.");
182  }
183  this.config = config;
184  } else {
185  // else load config:
186  this.config = ConfigUtils.loadConfig(configFileName);
187  }
189 
190  // load scenario:
191  //scenario = ScenarioUtils.createScenario(this.config);
192  //ScenarioUtils.loadScenario(scenario) ;
193  }
194  this.config.parallelEventHandling().makeLocked();
195  this.scenario = scenario;
196  this.overrides = scenario == null ?
197  new ScenarioByConfigModule() :
198  new ScenarioByInstanceModule(this.scenario);
199 
200  this.config.qsim().setLocked();
201  // yy this is awfully ad-hoc. kai, jul'18
202  // yy should probably come even earlier, before the scenario is generated. kai, jul'18
203  }
204 
208  @Override
209  public final void run() {
210  // It is better to keep this line before actually creating the injector, because:
211  // - it actually means "fail if adding new Guice modules"
212  // - adding Guice modules to the Controler from other Guice modules is too late.
213  // This might sound silly, but might, in some cases, happen, through code that
214  // - transformed a StartupListener to a Guice module
215  // - that called methods such as setScoringFunctionFactory(), that redirects to addOverridingModule()
216  // And this happens silently, leading to lots of time and hair lost.
217  // td, nov 16
218  this.injectorCreated = true;
219 
220  this.overrides = AbstractModule.override(Collections.singletonList(this.overrides), new AbstractModule() {
221  @Override
222  public void install() {
223  bind(Key.get(new TypeLiteral<List<AbstractQSimModule>>() {
224  }, Names.named("overrides"))).toInstance(overridingQSimModules);
225  }
226  });
227 
228  // check config consistency just before creating injector; sometimes, we can provide better error messages there:
230  config.checkConsistency();
232 
233  final Set<AbstractModule> standardModules = Collections.singleton(
234  new AbstractModule(){
235  @Override
236  public void install(){
237  install( new NewControlerModule() );
238  install( new ControlerDefaultCoreListenersModule() );
239  for( AbstractModule module : modules ){
240  install( module );
241  }
242  // should not be necessary: created in the controler
243  //install(new ScenarioByInstanceModule(scenario));
244  }
245  }
246  );
247  this.injector = Injector.createInjector( config, AbstractModule.override( standardModules, overrides ) );
248  ControlerI controler = injector.getInstance(ControlerI.class);
249  controler.run();
250  }
251 
252 
253  // ******** --------- *******
254  // The following is the internal interface of the Controler, which
255  // is meant to be called while the Controler is running (not before)..
256  // ******** --------- *******
257 
258  @Override
260  return this.injector.getInstance(com.google.inject.Injector.class).getInstance(Key.get(new TypeLiteral<Map<String, TravelTime>>() {}))
261  .get(TransportMode.car);
262  }
263 
275  @Override
276  public final Provider<TripRouter> getTripRouterProvider() {
277  return this.injector.getProvider(TripRouter.class);
278  }
279 
280  @Override
282  return getTravelDisutilityFactory().createTravelDisutility(this.injector.getInstance(TravelTime.class));
283  }
284 
285  @Override
287  return this.injector.getInstance(LeastCostPathCalculatorFactory.class);
288  }
289 
290  @Override
292  return this.injector.getInstance(ScoringFunctionFactory.class);
293  }
294 
295  @Override
296  public final Config getConfig() {
297  return config;
298  }
299 
300  @Override
301  public final Scenario getScenario() {
302  if (this.injectorCreated) {
303  Gbl.assertNotNull(this.injector);
304  return this.injector.getInstance(Scenario.class);
305  } else {
306  if ( scenario == null ) {
307  log.error( "Trying to get Scenario before it was instanciated.");
308  log.error( "When passing a config file or a config file path to the Controler constructor," );
309  log.error( "Scenario will be loaded first when the run() method is invoked." );
310  throw new IllegalStateException( "Trying to get Scenario before is was instanciated." );
311  }
312  return this.scenario;
313  }
314  }
315 
316 
317  @Override
318  public final EventsManager getEvents() {
319  if (this.injector != null) {
320  return this.injector.getInstance(EventsManager.class);
321  } else {
322  return new EventsManager() {
323  @Override
324  public void processEvent(Event event) {
325  Controler.this.injector.getInstance(EventsManager.class).processEvent(event);
326  }
327 
328  @Override
329  public void addHandler(final EventHandler handler) {
331  @Override
332  public void install() {
333  addEventHandlerBinding().toInstance(handler);
334  }
335  });
336  }
337 
338  @Override
339  public void removeHandler(EventHandler handler) {
340  throw new UnsupportedOperationException();
341  }
342 
343  @Override
344  public void resetHandlers(int iteration) {
345  throw new UnsupportedOperationException();
346  }
347 
348  @Override
349  public void initProcessing() {
350  throw new UnsupportedOperationException();
351  }
352 
353  @Override
354  public void afterSimStep(double time) {
355  throw new UnsupportedOperationException();
356  }
357 
358  @Override
359  public void finishProcessing() {
360  throw new UnsupportedOperationException();
361  }
362  };
363  }
364  }
365 
366  @Override
367  public final com.google.inject.Injector getInjector() {
368  return this.injector;
369  }
370 
375  @Override
376  @Deprecated
377  public final CalcLinkStats getLinkStats() {
378  return this.injector.getInstance(CalcLinkStats.class);
379  }
380 
381  @Override
382  public final VolumesAnalyzer getVolumes() {
383  return this.injector.getInstance(VolumesAnalyzer.class);
384  }
385 
386  @Override
387  public final ScoreStats getScoreStats() {
388  return this.injector.getInstance(ScoreStats.class);
389  }
390 
391  @Override
393  return this.injector.getInstance(com.google.inject.Injector.class).getInstance(Key.get(new TypeLiteral<Map<String, TravelDisutilityFactory>>(){}))
394  .get(TransportMode.car);
395  }
396 
405  @Override
406  @Deprecated // see javadoc above
408  return this.injector.getInstance(StrategyManager.class);
409  }
410 
411  @Override
413  return injector.getInstance(OutputDirectoryHierarchy.class);
414  }
415 
416  @Override
417  public Integer getIterationNumber() {
418  return injector.getInstance(ReplanningContext.class).getIteration();
419  }
420  // ******** --------- *******
421  // The following methods are the outer interface of the Controler. They are used
422  // to set up infrastructure from the outside, before calling run().
423  // ******** --------- *******
424 
425  @Override
426  public void addControlerListener(final ControlerListener controlerListener) {
428  @Override
429  public void install() {
430  addControlerListenerBinding().toInstance(controlerListener);
431  }
432  });
433  }
434 
435  public final void setScoringFunctionFactory(
436  final ScoringFunctionFactory scoringFunctionFactory) {
438  @Override
439  public void install() {
440  this.bindScoringFunctionFactory().toInstance(scoringFunctionFactory);
441  }
442  });
443  }
444 
445  public final void setTerminationCriterion(final TerminationCriterion terminationCriterion) {
447  @Override
448  public void install() {
449  bind(TerminationCriterion.class).toInstance(terminationCriterion);
450  }
451  });
452  }
453 
454  @Override
455  public final Controler addOverridingModule( AbstractModule abstractModule ) {
456  if (this.injectorCreated) {
457  throw new RuntimeException("Too late for configuring the Controler. This can only be done before calling run.");
458  }
459  this.overrides = AbstractModule.override(Collections.singletonList(this.overrides), abstractModule);
460  return this ;
461  }
462 
463  public final void setModules(AbstractModule... modules) {
464  if (this.injectorCreated) {
465  throw new RuntimeException("Too late for configuring the Controler. This can only be done before calling run.");
466  }
467  this.modules = Arrays.asList(modules);
468  }
469 
470  @Override
472  if (this.injectorCreated) {
473  throw new RuntimeException("Too late for configuring the Controler. This can only be done before calling run.");
474  }
475  overridingQSimModules.add(qsimModule);
476  return this ;
477  }
478  @Override
479  public final Controler addQSimModule(AbstractQSimModule qsimModule) {
481  @Override
482  public void install() {
483  installQSimModule(qsimModule);
484  }
485  });
486  return this ;
487  }
488 
492  @Override
495  @Override
496  public void install() {
497  QSimComponentsConfig components = new QSimComponentsConfig();
498  new StandardQSimComponentConfigurator(config).configure(components);
499  configurator.configure(components);
500  bind(QSimComponentsConfig.class).toInstance(components);
501  }
502  });
503  return this ;
504  }
505 }
final Controler addOverridingModule(AbstractModule abstractModule)
Definition: Controler.java:455
final void setScoringFunctionFactory(final ScoringFunctionFactory scoringFunctionFactory)
Definition: Controler.java:435
static final PatternLayout DEFAULTLOG4JLAYOUT
Definition: Controler.java:111
void removeConfigConsistencyChecker(final Class clazz)
Definition: Config.java:536
final EventsManager getEvents()
Definition: Controler.java:318
static Config loadConfig(final String filename, ConfigGroup... customModules)
Controler(final Scenario scenario)
Definition: Controler.java:168
List< AbstractModule > modules
Definition: Controler.java:127
TravelDisutility createTravelDisutility(TravelTime timeCalculator)
final void setModules(AbstractModule... modules)
Definition: Controler.java:463
final TravelTime getLinkTravelTimes()
Definition: Controler.java:259
final TravelDisutilityFactory getTravelDisutilityFactory()
Definition: Controler.java:392
final TravelDisutility createTravelDisutilityCalculator()
Definition: Controler.java:281
Controler(final Config config)
Definition: Controler.java:164
final com.google.inject.Injector getInjector()
Definition: Controler.java:367
List< AbstractQSimModule > overridingQSimModules
Definition: Controler.java:132
final CalcLinkStats getLinkStats()
Definition: Controler.java:377
final Provider< TripRouter > getTripRouterProvider()
Definition: Controler.java:276
static void main(final String[] args)
Definition: Controler.java:134
void addConfigConsistencyChecker(final ConfigConsistencyChecker checker)
Definition: Config.java:522
Controler(final String configFileName, final Config config, Scenario scenario)
Definition: Controler.java:172
final VolumesAnalyzer getVolumes()
Definition: Controler.java:382
QSimConfigGroup qsim()
Definition: Config.java:476
final ScoringFunctionFactory getScoringFunctionFactory()
Definition: Controler.java:291
static void assertNotNull(Object obj)
Definition: Gbl.java:207
final StrategyManager getStrategyManager()
Definition: Controler.java:407
final void setTerminationCriterion(final TerminationCriterion terminationCriterion)
Definition: Controler.java:445
Controler(final String[] args)
Definition: Controler.java:156
static com.google.inject.Injector createInjector(final Config config, Module... modules)
Definition: Injector.java:58
final Controler configureQSimComponents(QSimComponentsConfigurator configurator)
Definition: Controler.java:493
static final String DIRECTORY_ITERS
Definition: Controler.java:72
void addControlerListener(final ControlerListener controlerListener)
Definition: Controler.java:426
ParallelEventHandlingConfigGroup parallelEventHandling
Definition: Config.java:71
Controler(final String configFileName)
Definition: Controler.java:160
IterationStopWatch getStopwatch()
Definition: Controler.java:120
final LeastCostPathCalculatorFactory getLeastCostPathCalculatorFactory()
Definition: Controler.java:286
final Controler addQSimModule(AbstractQSimModule qsimModule)
Definition: Controler.java:479
final Controler addOverridingQSimModule(AbstractQSimModule qsimModule)
Definition: Controler.java:471
static AbstractModule override(final Iterable<? extends AbstractModule > modules, final AbstractModule abstractModule)
com.google.inject.Injector injector
Definition: Controler.java:116
OutputDirectoryHierarchy getControlerIO()
Definition: Controler.java:412