MATSIM
QSimConfigGroup.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * SimulationConfigGroup.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.config.groups;
22 
23 import org.apache.logging.log4j.LogManager;
24 import org.apache.logging.log4j.Logger;
29 import org.matsim.core.utils.misc.Time;
31 
32 import jakarta.validation.constraints.Positive;
33 import jakarta.validation.constraints.PositiveOrZero;
34 import java.util.*;
35 import java.util.stream.Collectors;
36 
41 public final class QSimConfigGroup extends ReflectiveConfigGroup {
42 
43 
44  private final static Logger log = LogManager.getLogger(QSimConfigGroup.class);
45 
46  public static final String GROUP_NAME = "qsim";
47 
48  private static final String START_TIME = "startTime";
49  private static final String END_TIME = "endTime";
50  private static final String TIME_STEP_SIZE = "timeStepSize";
51  private static final String SNAPSHOT_PERIOD = "snapshotperiod";
52  // measure so that comments remain consistent between Simulation and QSim. kai, aug'10
53  /* package */ final static String REMOVE_STUCK_VEHICLES_STRING =
54  "Boolean. `true': stuck vehicles are removed, aborting the plan; `false': stuck vehicles are forced into the next link. `false' is probably the better choice.";
55  private static final String FLOW_CAPACITY_FACTOR = "flowCapacityFactor";
56  private static final String STORAGE_CAPACITY_FACTOR = "storageCapacityFactor";
57  private static final String STUCK_TIME = "stuckTime";
58  private static final String REMOVE_STUCK_VEHICLES = "removeStuckVehicles";
59  private static final String NOTIFY_ABOUT_STUCK_VEHICLES = "notifyAboutStuckVehicles";
60  /* package */ final static String NOTIFY_ABOUT_STUCK_VEHICLES_STRING =
61  "Boolean. `true': when a vehicle is moved to the next link because the stuck time is exceeded, a PersonStuckAndContinueEvent is thrown.";
62  private static final String NUMBER_OF_THREADS = "numberOfThreads";
63  private static final String TRAFFIC_DYNAMICS = "trafficDynamics";
64  private static final String SIM_STARTTIME_INTERPRETATION = "simStarttimeInterpretation";
65  private static final String USE_PERSON_ID_FOR_MISSING_VEHICLE_ID = "usePersonIdForMissingVehicleId";
66  private static final String SIM_ENDTIME_INTERPRETATION = "simEndtimeInterpretation";
67  /* package */ final static String STUCK_TIME_STRING =
68  "time in seconds. Time after which the frontmost vehicle on a link is called `stuck' if it does not move.";
69  private static final String FILTER_SNAPSHOTS = "filterSnapshots";
70  private static final String LINK_DYNAMICS = "linkDynamics";
72 
73  public enum StarttimeInterpretation {maxOfStarttimeAndEarliestActivityEnd, onlyUseStarttime}
74 
75  public enum EndtimeInterpretation {minOfEndtimeAndMobsimFinished, onlyUseEndtime}
76 
77  private static final String NODE_OFFSET = "nodeOffset";
78 
79 
82  @Positive
83  private double timeStepSize = 1.0;
84  @PositiveOrZero
85  private double snapshotPeriod = 0; // off, no snapshots
86  @Positive
87  private double flowCapFactor = 1.0;
88  @Positive
89  private double storageCapFactor = 1.0;
90  @Positive
91  private double stuckTime = 10;
92  private boolean removeStuckVehicles = false;
93  private boolean notifyAboutStuckVehicles = false;
94  private boolean usePersonIdForMissingVehicleId = true;
95  @Positive
96  private int numberOfThreads = 1;
97  // private static final String CREATING_VEHICLES_FOR_ALL_NETWORK_MODES = "creatingVehiclesForAllNetworkModes";
98 // private boolean creatingVehiclesForAllNetworkModes = true;
99  // ---
100  private static final String IS_SEEP_MODE_STORAGE_FREE = "isSeepModeStorageFree";
101  private FilterSnapshots filterSnapshots = FilterSnapshots.no; // include all vehicles by default
102 
104 
105  //Vehicles of size (in PCU) smaller than or equal to this threshold will be allowed to enter the buffer even
106  //if flowcap_accumulate <= 0.
107  //The default value is 0.0 meaning that all vehicles of non-zero sizes will be let into buffer only
108  //if flowcap_accumulate > 0.
109  //
110  //Flow capacity easing prevents buses from waiting long time for entering the buffer in sub-sampled scenarios
111  //For instance, for 10% scenario, a car (representing 10 cars) has a size of 1.0 PCU, a bus (representing 1 bus)
112  //has a size of 0.3 PCU, and link flow capacities are reduced to about 0.1 of the original capacity.
113  //(1) If pcuThresholdForFlowCapacityEasing == 0, all buses moving just behind private cars wait long times before
114  //entering the buffer (recovering the flow capacity accumulator in a 10% scenario takes approx. 10 times longer than
115  //in the 100% scenario).
116  //(2) If pcuThresholdForFlowCapacityEasing == 0.3, buses at the front of the queue immediately enter the buffer
117  //(once they arrive at the end of a link). If they (one or more buses) have been queued behind a private car,
118  //they all leave the link at the same time as the preceding private car.
119  private double pcuThresholdForFlowCapacityEasing = 0.0;
120 
121  // ---
122  private static final String VEHICLE_BEHAVIOR = "vehicleBehavior";
123 
124  public enum VehicleBehavior {teleport, wait, exception}
125 
127  // ---
128  private static final String SNAPSHOT_STYLE = "snapshotStyle";
129 
130  public enum SnapshotStyle {
131  equiDist, queue, withHoles, withHolesAndShowHoles,
132  kinematicWaves /*kinematicWaves and withHoles produce same snapshots Amit Mar'17*/
133  }
134 
136 
137  // ---
138  private static final String MAIN_MODE = "mainMode";
140 
141 
142  // ---
143  public enum LinkDynamics {FIFO, PassingQ, SeepageQ}
144 
146  private Collection<String> mainModes = Collections.singletonList(TransportMode.car);
147 
148  // ---
149  private double nodeOffset = 0;
150  private float linkWidth = 30;
151 
152  public static final String LINK_WIDTH = "linkWidth";
153 
154  // ---
155  private final static String FAST_CAPACITY_UPDATE = "usingFastCapacityUpdate";
156  private boolean usingFastCapacityUpdate = true;
157  // ---
158  private static final String VEHICLES_SOURCE = "vehiclesSource";
160  private Collection<String> seepModes = Collections.singletonList(TransportMode.bike);
161  // ---
162 
163  @Override
164  public final Map<String, String> getComments() {
165  Map<String, String> map = super.getComments();
166  {
167  StringBuilder options = new StringBuilder();
168  for (SnapshotStyle style : SnapshotStyle.values()) {
169  options.append(style.toString());
170  options.append(' ');
171  }
172  map.put(SNAPSHOT_STYLE, "snapshotStyle. One of: " + options);
173  }
174  map.put(NUMBER_OF_THREADS, "Number of threads used for the QSim. "
175  + "Note that this setting is independent from the \"global\" threads setting. "
176  + "In contrast to earlier versions, the non-parallel special version is no longer there.");
177  map.put(REMOVE_STUCK_VEHICLES, REMOVE_STUCK_VEHICLES_STRING);
178  map.put(STUCK_TIME, STUCK_TIME_STRING);
179  map.put(NOTIFY_ABOUT_STUCK_VEHICLES, NOTIFY_ABOUT_STUCK_VEHICLES_STRING);
180  {
181  StringBuilder options = new StringBuilder(60);
182  for (TrafficDynamics dyn : TrafficDynamics.values()) {
183  options.append(dyn).append(' ');
184  }
185  map.put(TRAFFIC_DYNAMICS, "options: " + options);
186  }
187  {
188  StringBuilder options = new StringBuilder(60);
190  options.append(ii).append(' ');
191  }
192  map.put(SIM_STARTTIME_INTERPRETATION, "Options: " + options);
193  }
194  {
195  StringBuilder options = new StringBuilder(60);
196  for (VehicleBehavior behav : VehicleBehavior.values()) {
197  options.append(behav).append(' ');
198  }
199  map.put(VEHICLE_BEHAVIOR, "Defines what happens if an agent wants to depart, but the specified vehicle is not available. " +
200  "One of: " + options);
201  }
202  map.put(MAIN_MODE, "[comma-separated list] Defines which modes are congested modes. Technically, these are the modes that " +
203  "the departure handler of the netsimengine handles. Effective cell size, effective lane width, flow capacity " +
204  "factor, and storage capacity factor need to be set with diligence. Need to be vehicular modes to make sense.");
207  map.put(NODE_OFFSET, "Shortens a link in the visualization, i.e. its start and end point are moved into towards the center. Does not affect traffic flow. ");
208  map.put(LINK_WIDTH, "The (initial) width of the links of the network. Use positive floating point values. This is used only for visualisation.");
209  {
210  StringBuilder stb = new StringBuilder();
211  for (LinkDynamics ld : LinkDynamics.values()) {
212  stb.append(" ").append(ld.toString());
213  }
214  map.put(LINK_DYNAMICS, "default: FIFO; options:" + stb);
215  }
216  map.put(USE_PERSON_ID_FOR_MISSING_VEHICLE_ID, "If a route does not reference a vehicle, agents will use the vehicle with the same id as their own.");
217  map.put(FAST_CAPACITY_UPDATE, "If false, the qsim accumulates fractional flows up to one flow unit in every time step. If true, "
218  + "flows are updated only if an agent wants to enter the link or an agent is added to buffer. "
219  + "Default is true.");
220  map.put(USE_LANES, "Set this parameter to true if lanes should be used, false if not.");
221  {
222  StringBuilder stb = new StringBuilder();
223  for (VehiclesSource src : VehiclesSource.values()) {
224  stb.append(" ").append(src.toString());
225  }
226  map.put(VEHICLES_SOURCE, "If vehicles should all be the same default vehicle, or come from the vehicles file, "
227  + "or something else. Possible values: " + stb);
228  }
229  map.put(SEEP_MODE, "If link dynamics is set as " + LinkDynamics.SeepageQ + ", set a seep mode. Default is bike.");
230  map.put(IS_SEEP_MODE_STORAGE_FREE, "If link dynamics is set as " + LinkDynamics.SeepageQ + ", set to true if seep mode do not consumes any space on the link. Default is false.");
231  map.put(IS_RESTRICTING_SEEPAGE, "If link dynamics is set as " + LinkDynamics.SeepageQ + ", set to false if all seep modes should perform seepage. Default is true (better option).");
232  map.put(FILTER_SNAPSHOTS, "If set to " + FilterSnapshots.withLinkAttributes + " snapshots will only be generated for links which include " + SnapshotWritersModule.GENERATE_SNAPSHOT_FOR_LINK_KEY + " as attribute key. Default is no filtering.");
233 // map.put(CREATING_VEHICLES_FOR_ALL_NETWORK_MODES, "If set to true, creates a vehicle for each person corresponding to every network mode. However, " +
234 // "this will be overridden if vehicle source is "+ VehiclesSource.fromVehiclesData+".");
235 
236  return map;
237  }
238 
239  private boolean isSeepModeStorageFree = false;
240 
242 
243  // ---
244  public enum NodeTransition {
249  moveVehByVehDeterministicPriorities_nodeBlockedWhenSingleOutlinkFull
250  /* note: moveVehByVehDeterministicPriorities is not implemented for the case when the node is not blocked
251  * as soon as a single outlink is full
252  * theresa, jun'20
253  */
254  }
256 
257  // ---
258 
259  public QSimConfigGroup() {
260  super(GROUP_NAME);
261  }
262 
263  @StringSetter(MAIN_MODE)
264  private void setMainModes(String value) {
265  Set<String> modes = Arrays.stream(value.split(",")).map(String::trim).collect(Collectors.toSet());
266  setMainModes(modes);
267  }
268 
269  @StringSetter(SNAPSHOT_PERIOD)
270  private void setSnapshotPeriod(String value) {
272  }
273 
274  @StringSetter(TIME_STEP_SIZE)
275  private void setTimeStepSize(String value) {
277  }
278 
279  @StringSetter(END_TIME)
280  private void setEndTime(String value) {
281  this.endTime = Time.parseOptionalTime(value);
282  }
283 
284  @StringSetter(START_TIME)
285  private void setStartTime(String value) {
286  this.startTime = Time.parseOptionalTime(value);
287  }
288 
290  private String getMainModesAsString() {
291  return CollectionUtils.setToString(new HashSet<>(getMainModes()));
292  }
293 
295  private String getSnapshotPeriodAsString() {
296  return Time.writeTime(getSnapshotPeriod());
297  }
298 
300  private String getTimeStepSizeAsString() {
301  return Time.writeTime(getTimeStepSize());
302  }
303 
304 
306  private String getEndTimeAsString() {
307  return Time.writeTime(getEndTime());
308  }
309 
310 
312  private String getStartTimeAsString() {
313  return Time.writeTime(getStartTime());
314  }
315 
317  public String getFilterSnapshotsAsString() {
318  return filterSnapshots.toString();
319  }
320 
322  return filterSnapshots;
323  }
324 
326  public void setFilterSnapshots(String value) {
327  this.filterSnapshots = FilterSnapshots.valueOf(value);
328  }
329 
330  public void setFilterSnapshots(FilterSnapshots value) {
331  this.filterSnapshots = value;
332  }
333 
335  public final boolean isUsingFastCapacityUpdate() {
336  return this.usingFastCapacityUpdate;
337  }
338 
339  public void setStartTime(final double startTime) {
340  this.startTime = OptionalTime.defined(startTime);
341  }
342 
344  return this.startTime;
345  }
346 
347  public void setEndTime(final double endTime) {
348  this.endTime = OptionalTime.defined(endTime);
349  }
350 
352  return this.endTime;
353  }
354 
358  public void setTimeStepSize(final double seconds) {
359  this.timeStepSize = seconds;
360  }
361 
362  public double getTimeStepSize() {
363  return this.timeStepSize;
364  }
365 
366  public void setSnapshotPeriod(final double snapshotPeriod) {
367  this.snapshotPeriod = snapshotPeriod;
368  }
369 
370  public double getSnapshotPeriod() {
371  return this.snapshotPeriod;
372  }
373 
375  public void setFlowCapFactor(final double flowCapFactor) {
377  }
378 
380  public double getFlowCapFactor() {
381  return this.flowCapFactor;
382  }
383 
385  public void setStorageCapFactor(final double val) {
386  this.storageCapFactor = val;
387  }
388 
390  public double getStorageCapFactor() {
391  return this.storageCapFactor;
392  }
393 
395  public void setStuckTime(final double stuckTime) {
396  this.stuckTime = stuckTime;
397  }
398 
400  public double getStuckTime() {
401  return this.stuckTime;
402  }
403 
405  public void setRemoveStuckVehicles(final boolean removeStuckVehicles) {
407  }
408 
410  public boolean isRemoveStuckVehicles() {
411  return this.removeStuckVehicles;
412  }
413 
417  }
418 
420  public boolean isNotifyAboutStuckVehicles() {
421  return this.notifyAboutStuckVehicles;
422  }
423 
425  public final void setUsingFastCapacityUpdate(boolean val) {
426  this.usingFastCapacityUpdate = val;
427  }
428 
431  return this.snapshotStyle;
432  }
433 
435  public void setSnapshotStyle(final SnapshotStyle style) {
436  this.snapshotStyle = style;
437  }
438 
445  }
446 
452  public enum TrafficDynamics {
454  @Deprecated
456  kinematicWaves // MATSim-630; previously, the switch was InflowConstraint.maxflowFromFdiag. Amit Jan 2017.
457  }
458 
472  @Deprecated
474  @Deprecated
475  MAX_CAP_FOR_ONE_LANE}
476 
478  public void setTrafficDynamics(final TrafficDynamics str) {
479  this.trafficDynamics = str;
480  }
481 
484  return this.trafficDynamics;
485  }
486 
488  public int getNumberOfThreads() {
489  return this.numberOfThreads;
490  }
491 
493  public void setNumberOfThreads(final int numberOfThreads) {
494  if ( numberOfThreads < 1 ) {
495  throw new IllegalArgumentException( "Number of threads must be strictly positive, got "+numberOfThreads );
496  }
498  }
499 
503  }
504 
507  this.simStarttimeInterpretation = str;
508  }
509 
513  }
514 
517  this.simEndtimeInterpretation = str;
518  }
519 
521  public void setVehicleBehavior(VehicleBehavior value) {
522  this.vehicleBehavior = value;
523  }
524 
527  return this.vehicleBehavior;
528  }
529 
530  public void setMainModes(Collection<String> mainModes) {
531  this.mainModes = mainModes;
532  }
533 
534  public Collection<String> getMainModes() {
535  return mainModes;
536  }
537  // ---
538  private static final String INSERTING_WAITING_VEHICLES_BEFORE_DRIVING_VEHICLES = "insertingWaitingVehiclesBeforeDrivingVehicles";
540  "decides if waiting vehicles enter the network after or before the already driving vehicles were moved. Default: false";
542  // (yyyyyy switch this default to true; false has really weird consequences sometimes (vehicles waiting for hours in driveway;
543  // and this is not included into decongestion approach. kai/ihab, aug'18)
544 
551  }
552 
553  public enum FilterSnapshots {no, withLinkAttributes}
554 
555  // ---
557  public double getNodeOffset() {
558  return nodeOffset;
559  }
560 
562  public void setNodeOffset(double nodeOffset) {
563  this.nodeOffset = nodeOffset;
564  }
565 
567  public float getLinkWidthForVis() {
568  return this.linkWidth;
569  }
570 
572  public void setLinkWidthForVis(final float linkWidth) {
573  this.linkWidth = linkWidth;
574  }
575 
578  return this.linkDynamics ;
579  }
580 
583  this.linkDynamics = linkDynamics ;
584  }
585 
589  }
590 
592  public void setUsePersonIdForMissingVehicleId(boolean value) {
593  this.usePersonIdForMissingVehicleId = value;
594  }
595 
597  public final void setVehiclesSource( VehiclesSource source ) {
598  // yyyy This setting triggers behavior in PrepareForSim, the result of which is also used by the router. A better place for this switch might be in the vehicles config group. kai, may'21
599  testForLocked();
600  this.vehiclesSource = source ;
601  }
604  // yyyy This setting triggers behavior in PrepareForSim, the result of which is also used by the router. A better place for this switch might be in the vehicles config group. kai, may'21
605  return this.vehiclesSource ;
606  }
607 
608  private static final String USE_LANES="useLanes" ;
609  private boolean useLanes = false;
610 
612  public boolean isUseLanes() {
613  return this.useLanes;
614  }
615 
617  public void setUseLanes(final boolean useLanes) {
618  this.useLanes = useLanes;
619  }
620 
621  // ---
622  private static final String SEEP_MODE = "seepMode";
623 
624  public enum VehiclesSource {defaultVehicle, modeVehicleTypesFromVehiclesData, fromVehiclesData}
625 
627  private String getSeepModesAsString() {
628  return CollectionUtils.setToString(new HashSet<>(getSeepModes()));
629  }
630 
632  private void setSeepModes(String value) {
633  Set<String> modes = Arrays.stream(value.split(",")).map(String::trim).collect(Collectors.toSet());
634  setSeepModes(modes);
635  }
636 
637  public Collection<String> getSeepModes() {
638  return seepModes;
639  }
640  public void setSeepModes(Collection<String> seepModes) {
641  this.seepModes = seepModes;
642  }
643  // ---
645  public boolean isSeepModeStorageFree() {
646  // yyyyyy replace boolean by something more expressive. kai, aug'18
647  return isSeepModeStorageFree;
648  }
652  }
653  // ---
654  private static final String IS_RESTRICTING_SEEPAGE = "isRestrictingSeepage";
655  private boolean isRestrictingSeepage = true;
657  public boolean isRestrictingSeepage() {
658  // yyyyyy replace boolean by something more expressive. kai, aug'18
659  return isRestrictingSeepage;
660  }
664  }
665  // ---
666  private boolean usingTravelTimeCheckInTeleportation = false ;
668  // yyyyyy this should better become a threshold number! kai, aug'16
670  }
671  public boolean setUsingTravelTimeCheckInTeleportation( boolean val ) {
672  // yyyyyy this should better become a threshold number! kai, aug'16
673  return this.usingTravelTimeCheckInTeleportation = val ;
674  }
675 
676  static final String PCU_THRESHOLD_FOR_FLOW_CAPACITY_EASING = //
677  "Flow capacity easing is activated for vehicles of size equal or smaller than the specified threshold. "
678  + "Introduced to minimise the chances of buses being severely delayed in downsampled scenarios";
679 
680 
683  }
684 
689  this.pcuThresholdForFlowCapacityEasing = pcuThresholdForFlowCapacityEasing;
690  }
691 
693  return nodeTransitionLogic;
694  }
695 
697  this.nodeTransitionLogic = nodeTransitionLogic;
698  }
699 
701  return this.inflowCapacitySetting;
702  }
703 
705  this.inflowCapacitySetting = inflowCapacitySetting;
706  }
707 
709 // public boolean isCreatingVehiclesForAllNetworkModes() {
710 // // yyyy do we really need this switch? Quite in general, please try to avoid boolean switches. kai, may'18
711 // return creatingVehiclesForAllNetworkModes;
712 // }
713 
715 // public void setCreatingVehiclesForAllNetworkModes(boolean creatingVehiclesForAllNetworkModes) {
716 // // yyyy do we really need this switch? Quite in general, please try to avoid boolean switches. kai, may'18
717 // this.creatingVehiclesForAllNetworkModes = creatingVehiclesForAllNetworkModes;
718 // }
719 
720 }
void setTrafficDynamics(final TrafficDynamics str)
void setPcuThresholdForFlowCapacityEasing(double pcuThresholdForFlowCapacityEasing)
void setNodeTransitionLogic(NodeTransition nodeTransitionLogic)
void setSeepModes(Collection< String > seepModes)
static String setToString(final Set< String > values)
void setRestrictingSeepage(boolean isRestrictingSeepage)
void setFlowCapFactor(final double flowCapFactor)
void setInflowCapacitySetting(InflowCapacitySetting inflowCapacitySetting)
void setRemoveStuckVehicles(final boolean removeStuckVehicles)
void setMainModes(Collection< String > mainModes)
void setSimEndtimeInterpretation(EndtimeInterpretation str)
void setSeepModeStorageFree(boolean isSeepModeStorageFree)
static final OptionalTime parseOptionalTime(final String time)
Definition: Time.java:167
static final double parseTime(final String time)
Definition: Time.java:163
StarttimeInterpretation getSimStarttimeInterpretation()
void setNotifyAboutStuckVehicles(final boolean notifyAboutStuckVehicles)
static final String writeTime(final double seconds, final String timeformat)
Definition: Time.java:80
static OptionalTime defined(double seconds)
void setSnapshotPeriod(final double snapshotPeriod)
final void setVehiclesSource(VehiclesSource source)
void setNumberOfThreads(final int numberOfThreads)
static final String INSERTING_WAITING_VEHICLES_BEFORE_DRIVING_VEHICLES
void setLinkDynamics(LinkDynamics linkDynamics)
void setSnapshotStyle(final SnapshotStyle style)
void setSimStarttimeInterpretation(StarttimeInterpretation str)
static final String INSERTING_WAITING_VEHICLES_BEFORE_DRIVING_VEHICLES_CMT