MATSIM
VspConfigConsistencyCheckerImpl.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: matsim
3  * VspConfigConsistencyCheckerImpl.java
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2011 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.config.consistency;
22 
23 import org.apache.logging.log4j.Level;
24 import org.apache.logging.log4j.LogManager;
25 import org.apache.logging.log4j.Logger;
27 import org.matsim.core.config.Config;
28 import org.matsim.core.config.groups.*;
38 import org.matsim.pt.PtConstants;
39 
40 import java.util.Collection;
41 import java.util.Map;
42 import java.util.Set;
43 
49 
50  private static final Logger log = LogManager.getLogger(VspConfigConsistencyCheckerImpl.class);
51 
53  // empty. only here to find out where it is called.
54  }
55 
56  @Override
57  public void checkConsistency(Config config) {
58  Level lvl ;
59 
60  switch( config.vspExperimental().getVspDefaultsCheckingLevel() ){
61  case ignore -> {
62  log.info( "NOT running vsp config consistency check because vsp defaults checking level is set to IGNORE" );
63  return;
64  }
65  case info -> lvl = Level.INFO;
66  case warn -> lvl = Level.WARN;
67  case abort -> lvl = Level.WARN;
68  default -> throw new RuntimeException( "not implemented" );
69  }
70  log.info("running checkConsistency ...");
71 
72  boolean problem = false ; // ini
73 
74  // yy: sort the config groups alphabetically
75 
76  // === controler:
77 
78  problem = checkControlerConfigGroup( config, lvl, problem );
79 
80  // === facilities:
81 
82  //noinspection ReassignedVariable
83  problem = checkFacilitiesConfigGroup( config, lvl, problem );
84 
85  // === global:
86 
87  problem = checkGlobalConfigGroup( config, lvl, problem );
88 
89  // === location choice:
90 
91  problem = checkLocationChoiceConfigGroup( config, problem );
92 
93  // === planCalcScore:
94 
95  problem = checkPlanCalcScoreConfigGroup( config, lvl, problem );
96 
97  // === plans:
98 
99  problem = checkPlansConfigGroup( config, lvl, problem );
100 
101  // === plansCalcRoute:
102 
103  checkPlansCalcScoreConfigGroup( config, lvl );
104 
105  // === qsim:
106 
107  problem = checkQsimConfigGroup( config, lvl, problem );
108 
109  // === strategy:
110 
111  problem = checkStrategyConfigGroup( config, lvl, problem );
112 
113  // === travelTimeCalculator:
114 
116 
117  // === interaction between config groups:
118  boolean containsModeChoice = false ;
119  for ( StrategySettings settings : config.replanning().getStrategySettings() ) {
120  if ( settings.getStrategyName().contains("Mode") ) {
121  containsModeChoice = true ;
122  }
123  }
124 
125  // added jun'16
128  && containsModeChoice
129  && config.qsim().getMainModes().size() > 1 )
130  {
131  problem = true ;
132  log.log( lvl, "You can't use more than one main (=vehicular) mode while using the agent ID as missing vehicle ID ... "
133  + "because in this case the person can only have one vehicle and thus cannot switch to a different vehicle type." ) ;
134  }
135 
136  // === zzz:
137 
139  String str = "found a situation that leads to vsp-abort. aborting ..." ;
140  System.out.flush() ;
141  log.fatal( str ) ;
142  throw new RuntimeException( str ) ;
143  }
144 
145  }
146 // private boolean checkSubtourModeChoiceConfigGroup( Config config, Level lvl, boolean problem ){
147 // if ( config.subtourModeChoice().considerCarAvailability() ) {
149 // log.log( lvl, "you are considering car abailability; vsp config is not doing that. Instead, we are using a daily monetary constant for car.");
150 // }
151 // return problem;
152 // }
153 // private boolean checkModeChoiceConfigGroup( Config config, Level lvl, boolean problem ){
154 // if ( !config.changeMode().getIgnoreCarAvailability() ) {
156 // log.log( lvl, "you are considering car abailability; vsp config is not doing that. Instead, we are using a daily monetary constant for car.");
157 // }
158 // return problem;
159 // }
160  private static boolean checkGlobalConfigGroup( Config config, Level lvl, boolean problem ){
161  if ( config.global().isInsistingOnDeprecatedConfigVersion() ) {
162  problem = true ;
163  System.out.flush();
164  log.log( lvl, "you are insisting on config v1. vsp default is using v2." ) ;
165  }
166  return problem;
167  }
168  private static void checkTravelTimeCalculatorConfigGroup( Config config, Level lvl ){
169  // added feb'19
170  if ( !config.travelTimeCalculator().getSeparateModes() ) {
171  System.out.flush() ;
172  log.log( lvl, "travelTimeCalculator is not analyzing different modes separately; vsp default is to do that. Otherwise, you are using the same travel times " +
173  "for, say, bike and car.") ;
174  }
175  }
176  private static boolean checkStrategyConfigGroup( Config config, Level lvl, boolean problem ){
177  boolean found = false ;
178  Collection<StrategySettings> settingsColl = config.replanning().getStrategySettings();
179  for ( StrategySettings settings : settingsColl ) {
180  if ( settings.getStrategyName().equalsIgnoreCase("ChangeExpBeta") ) {
181  found = true ;
182  }
183  }
184  if ( !found ) {
185  problem = true ;
186  System.out.flush() ;
187  log.log( lvl, "You have no strategy configured that uses ChangeExpBeta. vsp default is to use ChangeExpBeta at least in one strategy." );
188  }
189 
190  // added may'16
191  if ( config.replanning().getFractionOfIterationsToDisableInnovation()==Double.POSITIVE_INFINITY ) {
192  problem = true ;
193  System.out.flush() ;
194  log.log( lvl, "You have not set fractionOfIterationsToDisableInnovation; vsp default is to set this to 0.8 or similar. Add the following config lines:" ) ;
195  log.log( lvl, "<module name=\"strategy\">" );
196  log.log( lvl, " <param name=\"fractionOfIterationsToDisableInnovation\" value=\"0.8\" />" );
197  log.log( lvl, "</module>" );
198  }
199 
200  // added nov'15
201  boolean usingTimeMutator = false ;
202  for ( StrategySettings it : config.replanning().getStrategySettings() ) {
203  if ( DefaultStrategy.TimeAllocationMutator.equals( it.getName() ) ) {
204  usingTimeMutator = true ;
205  break ;
206  }
207  }
208  if ( usingTimeMutator ) {
209  // added before nov'12
210  if ( config.timeAllocationMutator().getMutationRange() < 7200 ) {
211  problem = true ;
212  System.out.flush() ;
213  log.log( lvl, "timeAllocationMutator mutationRange < 7200; vsp default is 7200. This means you have to add the following lines to your config file: " ) ;
214  log.log( lvl, "<module name=\"TimeAllocationMutator\">" );
215  log.log( lvl, " <param name=\"mutationRange\" value=\"7200.0\" />" );
216  log.log( lvl, "</module>" );
217  }
218  // added jan'14
219  if ( config.timeAllocationMutator().isAffectingDuration() ) {
220  // problem = true ;
221  System.out.flush() ;
222  log.log( lvl, "timeAllocationMutator is affecting duration; vsp default is to not do that. This will be more strictly" +
223  " enforced in the future. This means you have to add the following lines to your config file: ") ;
224  log.log( lvl, "<module name=\"TimeAllocationMutator\">" );
225  log.log( lvl, " <param name=\"affectingDuration\" value=\"false\" />" );
226  log.log( lvl, "</module>" );
227  }
228  }
229 
230  // added jun'22
231  boolean usingSMC = false ;
232  for ( StrategySettings it : config.replanning().getStrategySettings() ) {
233  if ( DefaultStrategy.SubtourModeChoice.equals( it.getName() ) ) {
234  usingSMC = true ;
235  break ;
236  }
237  }
238  if (usingSMC) {
239  if ( config.subtourModeChoice().getProbaForRandomSingleTripMode() < 0.2) {
240  problem = true;
241  System.out.flush();
242  log.log( lvl, "SubTourModeChoice 'probaForRandomSingleTripMode' is very small and below 0.2. Recommendation is, to set this to a value around 0.5." );
243  }
244  }
245  return problem;
246  }
247  private static boolean checkQsimConfigGroup( Config config, Level lvl, boolean problem ){
248  // jun'23
250  log.log( lvl, "found qsim.vehiclesSource=defaultVehicle; vsp should use one of the other settings or talk to kai");
251  }
252  if ( config.qsim().getLinkDynamics() != QSimConfigGroup.LinkDynamics.PassingQ && config.qsim().getMainModes().contains(TransportMode.bike) ) {
253  log.log( lvl, "found qsim.linkDynamics=" + config.qsim().getLinkDynamics() + "; vsp should use PassingQ or talk to kai");
254  }
255 
256  // added jun'16
257  if ( config.qsim().getUsePersonIdForMissingVehicleId() ) {
258  log.log( lvl, "found qsim.usePersonIdForMissingVehicleId==true; vsp should set this to false or talk to kai" ) ;
259  }
260 
261  // added feb'16
262  if ( !config.qsim().isUsingTravelTimeCheckInTeleportation() ) {
263  log.log( lvl, "found `qsim.usingTravelTimeCheckInTeleporation==false'; vsp should try out `true' and report." ) ;
264  }
265 
266  // added apr'15
267 // if ( !config.qsim().isUsingFastCapacityUpdate() ) {
268 // log.log( lvl, " found 'qsim.usingFastCapacityUpdate==false'; vsp should try out `true' and report. ") ;
269 // }
270  switch( config.qsim().getTrafficDynamics() ) {
271  case kinematicWaves:
272  break;
273  case withHoles:
274  case queue:
275  default:
276  log.log( lvl, " found 'qsim.trafficDynamics==" + config.qsim().getTrafficDynamics() + "'; vsp standard is`"
277  + TrafficDynamics.kinematicWaves + "'." ) ;
278  break;
279  }
280 
281  if ( config.qsim()!=null && config.qsim().isRemoveStuckVehicles() ) {
282  problem = true ;
283  System.out.flush() ;
284  log.log( lvl, "found that the qsim is removing stuck vehicles. vsp default is setting this to false." );
285  }
286 
287  return problem;
288  }
289  private static void checkPlansCalcScoreConfigGroup( Config config, Level lvl ){
290  }
291  private static boolean checkPlansConfigGroup( Config config, Level lvl, boolean problem ){
292  // added before nov'12
293  if ( !config.plans().isRemovingUnneccessaryPlanAttributes() ) {
294  problem = true ;
295  System.out.flush() ;
296  log.log( lvl, "You are not removing unnecessary plan attributes; vsp default is to do that." ) ;
297  }
298 
301  // added jan'13
303  problem = true;
304  // added before nov'12
305  if( config.transit().isUseTransit()) {
306  problem = true;
307  System.out.flush() ;
308  log.error("You are using " + config.plans().getActivityDurationInterpretation() + " as activityDurationInterpretation in " +
309  "conjunction with the matsim transit module. This is not working at all as pt interaction activities never have an end time and " +
310  "thus will never end!");
311  }
312  }
313 
314  // added jan'13
316  problem = true ;
317  System.out.flush() ;
318  log.log( lvl, "You are using ActivityDurationInterpretation " + config.plans().getActivityDurationInterpretation() + " ; vsp default is to use " +
320  "This means you have to add the following lines into the vspExperimental section of your config file: ") ;
321  log.log( lvl, " <param name=\"activityDurationInterpretation\" value=\"" + PlansConfigGroup.ActivityDurationInterpretation.tryEndTimeThenDuration + "\" />" ) ;
322  log.log( lvl, "Please report if this causes odd results (this will simplify many code maintenance issues, but is unfortunately not well tested)." ) ;
323  }
324  return problem;
325  }
326  private static boolean checkPlanCalcScoreConfigGroup( Config config, Level lvl, boolean problem ){
327  // use beta_brain=1 // added as of nov'12
328  if ( config.scoring().getBrainExpBeta() != 1. ) {
329  problem = true ;
330  System.out.flush() ;
331  log.log( lvl, "You are using a brainExpBeta != 1; vsp default is 1. (Different values may cause conceptual " +
332  "problems during paper writing.) This means you have to add the following lines to your config file: ") ;
333  log.log( lvl, "<module name=\"planCalcScore\">" );
334  log.log( lvl, " <param name=\"BrainExpBeta\" value=\"1.0\" />" );
335  log.log( lvl, "</module>" );
336  }
337 
338  // added aug'13:
339  if ( config.scoring().getMarginalUtlOfWaiting_utils_hr() != 0. ) {
340  problem = true ;
341  System.out.flush() ;
342  log.log( lvl, "found marginal utility of waiting != 0. vsp default is setting this to 0. " ) ;
343  }
344 
345  // added apr'15:
346  for ( ActivityParams params : config.scoring().getActivityParams() ) {
347  if ( PtConstants.TRANSIT_ACTIVITY_TYPE.equals( params.getActivityType() ) ) {
348  // they have typicalDurationScoreComputation==relative, but are not scored anyways. benjamin/kai, nov'15
349  continue ;
350  }
351  switch( params.getTypicalDurationScoreComputation() ) {
352  case relative:
353  break;
354  case uniform:
355 // problem = true ;
356  log.log( lvl, "found `typicalDurationScoreComputation == uniform' for activity type " + params.getActivityType() + "; vsp should use `relative'. " ) ;
357  break;
358  default:
359  throw new RuntimeException("unexpected setting; aborting ... ") ;
360  }
361  }
362  for ( ModeParams params : config.scoring().getModes().values() ) {
363  if ( params.getMonetaryDistanceRate() > 0. ) {
364  problem = true ;
365  System.out.flush() ;
366  log.error("found monetary distance rate for mode " + params.getMode() + " > 0. You probably want a value < 0 here.\n" ) ;
367  }
368  if ( params.getMonetaryDistanceRate() < -0.01 ) {
369  System.out.flush() ;
370  log.error("found monetary distance rate for mode " + params.getMode() + " < -0.01. -0.01 per meter means -10 per km. You probably want to divide your value by 1000." ) ;
371  }
372  }
373 
374  if ( config.scoring().getModes().get(TransportMode.car ) != null && config.scoring().getModes().get(TransportMode.car ).getMonetaryDistanceRate() > 0 ) {
375  problem = true ;
376  }
377  final ModeParams modeParamsPt = config.scoring().getModes().get(TransportMode.pt );
378  if ( modeParamsPt!=null && modeParamsPt.getMonetaryDistanceRate() > 0 ) {
379  problem = true ;
380  System.out.flush() ;
381  log.error("found monetary distance rate pt > 0. You probably want a value < 0 here." ) ;
382  }
383  if ( config.scoring().getMarginalUtilityOfMoney() < 0. ) {
384  problem = true ;
385  System.out.flush() ;
386  log.error("found marginal utility of money < 0. You almost certainly want a value > 0 here. " ) ;
387  }
388 
389  // added feb'16
391  log.log( lvl, "found `PlansCalcRouteConfigGroup.AccessEgressType.none'; vsp should use `accessEgressModeToLink' or " +
392  "some other value or talk to Kai." ) ;
393  }
394  // added oct'17:
396  problem = true ;
397  System.out.flush() ;
398  log.log( lvl, "You are not setting fractionOfIterationsToStartScoreMSA; vsp default is to set this to something like 0.8. " +
399  "This means you have to add the following lines to your config file: ") ;
400  log.log( lvl, "<module name=\"planCalcScore\">" );
401  log.log( lvl, " <param name=\"fractionOfIterationsToStartScoreMSA\" value=\"0.8\" />" );
402  log.log( lvl, "</module>" );
403  }
404 
405  // added apr'21:
406  for( Map.Entry<String, ScoringConfigGroup.ScoringParameterSet> entry : config.scoring().getScoringParametersPerSubpopulation().entrySet() ){
407  for( ActivityParams activityParam : entry.getValue().getActivityParams() ){
408  if( activityParam.getMinimalDuration().isDefined() ){
409  log.log( lvl, "Vsp default is to not define minimal duration. Activity type=" + activityParam.getActivityType() + "; subpopulation=" + entry.getKey() );
410  }
411  }
412  }
413 
414  // added may'23
415  for ( ModeParams params : config.scoring().getModes().values() ){
417  if( params.getMarginalUtilityOfTraveling() != 0. && !params.getMode().equals( TransportMode.ride ) && !params.getMode().equals( TransportMode.bike ) ){
418  log.log( lvl, "You are setting the marginal utility of traveling with mode " + params.getMode() + " to " + params.getMarginalUtilityOfTraveling()
419  + ". VSP standard is to set this to zero. Please document carefully why you are using a value different from zero, e.g. by showing distance distributions." );
420  }
421  }
422  if ( params.getMode().equals( TransportMode.walk ) && params.getConstant() != 0. ) {
423  problem = true;
424  log.log( lvl, "You are setting the alternative-specific constant for the walk mode to " + params.getConstant()
425  + ". Values different from zero cause problems here because the ASC is also used for access/egress modes" );
426  }
427  }
428  return problem;
429  }
430  private static boolean checkLocationChoiceConfigGroup( Config config, boolean problem ){
431  boolean usingLocationChoice = false ;
432  if ( config.getModule("locationchoice" )!=null ) {
433  usingLocationChoice = true ;
434  }
435 
436  if ( usingLocationChoice ) {
437  final String samplePercent = config.findParam("locationchoice", "destinationSamplePercent" );
438  if ( samplePercent!=null && !samplePercent.equals("100.") ) {
439  problem = true ;
440  System.out.flush() ;
441  log.error("vsp will not accept location choice destination sample percent other than 100 until the corresponding warning in " +
442  "DestinationSampler is resolved. kai, jan'13") ;
443  }
444 // if ( !config.locationchoice().getProbChoiceExponent().equals("1.") ) {
445 // // problem = true ;
446 // log.error("vsp will not accept location choice prob choice exponents other than 1 until the corresponding warning in " +
447 // "ChoiceSet is resolved. kai, jan'13") ;
448 // }
450  problem = true ;
451  System.out.flush() ;
452  log.error("vsp will not accept location choice without including opportunity cost of time into the approximation. kai,jan'13") ;
453  }
454  }
455  return problem;
456  }
457  private static boolean checkFacilitiesConfigGroup( Config config, Level lvl, boolean problem ){
458  // 2023-05:
460 // problem = true;
461  System.out.flush();
462  log.log( lvl, "vsp should move away from facilitiesSource=FacilitiesSource.none" );
463  }
464  return problem;
465  }
466  private static boolean checkControlerConfigGroup( Config config, Level lvl, boolean problem ){
467  Set<EventsFileFormat> formats = config.controller().getEventsFileFormats();
468  if ( !formats.contains( EventsFileFormat.xml ) ) {
469  problem = true ;
470  System.out.flush() ;
471  log.log( lvl, "did not find xml as one of the events file formats. vsp default is using xml events.");
472  }
473 
474  // may'21
475  switch ( config.controller().getRoutingAlgorithmType() ) {
476  case Dijkstra:
477  case AStarLandmarks:
478  log.log( lvl, "you are not using SpeedyALT as routing algorithm. vsp default (since may'21) is to use SpeedeALT.") ;
479  System.out.flush();
480  break;
481  case SpeedyALT:
482  break;
483  }
484 
485  if ( config.controller().getWritePlansInterval() <= 0 ) {
486  problem = true ;
487  System.out.flush() ;
488  log.log( lvl, "found writePlansInterval==0. vsp default is to write plans at least once (for simwrapper).") ;
489  }
490 
491  if ( config.controller().getWriteTripsInterval() <= 0 ) {
492  problem = true ;
493  System.out.flush() ;
494  log.log( lvl, "found writeTripsInterval==0. vsp default is to write trips at least once (for simwrapper).") ;
495  }
496 
497  return problem;
498  }
499 
500 }
static boolean checkGlobalConfigGroup(Config config, Level lvl, boolean problem)
static final String TRANSIT_ACTIVITY_TYPE
static boolean checkControlerConfigGroup(Config config, Level lvl, boolean problem)
final ScoringConfigGroup scoring()
Definition: Config.java:407
final String findParam(final String moduleName, final String paramName)
Definition: Config.java:346
final FacilitiesConfigGroup facilities()
Definition: Config.java:423
TravelTimeCalculatorConfigGroup travelTimeCalculator()
Definition: Config.java:431
VspExperimentalConfigGroup vspExperimental()
Definition: Config.java:443
final String getValue(final String param_name)
TransitConfigGroup transit()
Definition: Config.java:451
TimeAllocationMutatorConfigGroup timeAllocationMutator()
Definition: Config.java:463
static boolean checkPlanCalcScoreConfigGroup(Config config, Level lvl, boolean problem)
final PlansConfigGroup plans()
Definition: Config.java:415
QSimConfigGroup qsim()
Definition: Config.java:447
RoutingConfigGroup routing()
Definition: Config.java:439
static boolean checkStrategyConfigGroup(Config config, Level lvl, boolean problem)
SubtourModeChoiceConfigGroup subtourModeChoice()
Definition: Config.java:471
CheckingOfMarginalUtilityOfTravellng getCheckingOfMarginalUtilityOfTravellng()
static boolean checkPlansConfigGroup(Config config, Level lvl, boolean problem)
final ReplanningConfigGroup replanning()
Definition: Config.java:427
static boolean checkQsimConfigGroup(Config config, Level lvl, boolean problem)
final ControllerConfigGroup controller()
Definition: Config.java:399
final ConfigGroup getModule(final String moduleName)
Definition: Config.java:301
final GlobalConfigGroup global()
Definition: Config.java:395
StrategySettings getStrategySettings(final Id< StrategySettings > index, final boolean createIfMissing)
static boolean checkFacilitiesConfigGroup(Config config, Level lvl, boolean problem)
PlansConfigGroup.ActivityDurationInterpretation getActivityDurationInterpretation()
Map< String, ScoringParameterSet > getScoringParametersPerSubpopulation()