MATSIM
PlanCalcScoreConfigGroup.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * CharyparNagelScoringConfigGroup.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 java.util.Arrays;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.LinkedHashMap;
29 import java.util.Map;
30 import java.util.Set;
31 
32 import org.apache.logging.log4j.LogManager;
33 import org.apache.logging.log4j.Logger;
36 import org.matsim.core.config.Config;
39 import org.matsim.core.gbl.Gbl;
41 import org.matsim.core.utils.misc.Time;
42 import org.matsim.pt.PtConstants;
43 
59 public final class PlanCalcScoreConfigGroup extends ConfigGroup {
60 
61  private static final Logger log = LogManager.getLogger(PlanCalcScoreConfigGroup.class);
62 
63  public static final String GROUP_NAME = "planCalcScore";
64 
65  private static final String LEARNING_RATE = "learningRate";
66  private static final String BRAIN_EXP_BETA = "BrainExpBeta";
67  private static final String PATH_SIZE_LOGIT_BETA = "PathSizeLogitBeta";
68  private static final String LATE_ARRIVAL = "lateArrival";
69  private static final String EARLY_DEPARTURE = "earlyDeparture";
70  private static final String PERFORMING = "performing";
71 
72  private static final String WAITING = "waiting";
73  private static final String WAITING_PT = "waitingPt";
74 
75  private static final String WRITE_EXPERIENCED_PLANS = "writeExperiencedPlans";
76 
77  private static final String MARGINAL_UTL_OF_MONEY = "marginalUtilityOfMoney";
78 
79  private static final String UTL_OF_LINE_SWITCH = "utilityOfLineSwitch";
80 
82 
83  private boolean usesDeprecatedSyntax = false ;
84 
86  super(GROUP_NAME);
87 
89 
90  // what follows now has weird consequences:
91  // * the material is added to the ScoringParameterSet of the default subpopulation
92  // * if someone uses the following in the config.xml:
93  // < ... planCalcScore ... >
94  // <... modeParams ... >
95  // < ... mode ... abc ... />
96  // then abc will be _added_ to the modes info below (same for activities)
97  // * if, however, someone uses in the config.xml:
98  // < ... planCalcScore ... >
99  // < ... scoringParameters ... >
100  // <... modeParams ... >
101  // < ... mode ... abc ... />
102  // (= fully hierarchical format), then the default modes will be removed before adding mode abc. The reason for this is that the second
103  // syntax clears the scoring params for the default subpopulation.
104 
105  // Unfortunately, it continues:
106  // * Normally, we need a "clear defaults with first configured entry" (see PlansCalcRouteConfigGroup). Otherwise, we fail the write-read
107  // test: Assume we end up with a config that has _less_ material than the defaults. Then we write this to file, and read it back in. If
108  // the defaults are not cleared, they would now be fully there.
109  // * The reason why this works here is that all the material is written out with the fully hierarchical format. I.e. it actually clears the
110  // defaults when being read it.
111 
112  // I am not sure if it can stay the way it is right now; took me several hours to understand it (and fix a problem we had not by
113  // trial-and-error but by understanding the root cause). Considerations:
114  // * Easiest would be to not have defaults. However, defaults are helpful in particular to avoid that everybody uses different parameters.
115  // * We could also have the "manual addition triggers clearing" logic. In PlansCalcRouteConfigGroup I now have this with a warning, which
116  // can be switched off with a switch. I find this a good solution; I am, however, not 100% certain that it is robust since that switch is a
117  // "state" while "clearing the defaults" is an action, and I am not sure if they can be mapped into each other in all cases.
118  // * We could, together with the previous point, disallow the not fully hierarchical format.
119 
120  // kai, dec'19
121 
128 
129  this.addActivityParams( new ActivityParams("dummy").setTypicalDuration(2. * 3600. ) );
130  // (this is there so that an empty config prints out at least one activity type, so that the explanations of this
131  // important concept show up e.g. in defaultConfig.xml, created from the GUI. kai, jul'17
132 // params.setScoringThisActivityAtAll(false); // no longer minimal when included here. kai, jun'18
133 
134  // yyyyyy find better solution for this. kai, dec'15
135  // Probably no longer needed; see checkConsistency method. kai, jan'21
138  // (need this for self-programmed pseudo pt. kai, nov'16)
144  // (bushwhacking_walk---network_walk---bushwhacking_walk)
145  }
146 
147  public static ActivityParams createStageActivityParams( String mode ) {
149  }
150 
151  // ---
152 
153  private static final String USING_OLD_SCORING_BELOW_ZERO_UTILITY_DURATION = "usingOldScoringBelowZeroUtilityDuration";
154 
159  private boolean memorizingExperiencedPlans = false;
160 
164  public static final String EXPERIENCED_PLAN_KEY = "experiencedPlan";
165  public static final String DEFAULT_SUBPOPULATION = "default";
166 
167  // ---
168  private static final String FRACTION_OF_ITERATIONS_TO_START_SCORE_MSA = "fractionOfIterationsToStartScoreMSA";
169 
170  public static String createStageActivityType( String mode ){
171  return mode + " interaction";
172  }
173 
174  // ---
175 
176  @Override
177  public String getValue(final String key) {
178  throw new IllegalArgumentException(key + ": getValue access disabled; use direct getter");
179  }
180 
181  private static final String msg = " is deprecated config syntax; please use the more " +
182  "modern hierarchical format; your output_config.xml " +
183  "will be in the correct version; the old version will fail eventually, since we want to reduce the " +
184  "workload on this backwards compatibility (look into " +
185  "PlanCalcScoreConfigGroup or PlanCalcRouteConfigGroup if you want to know what we mean).";
186 
187  @Override
188  public void addParam(final String key, final String value) {
189  testForLocked();
190  if (key.startsWith("monetaryDistanceCostRate")) {
191  throw new RuntimeException("Please use monetaryDistanceRate (without `cost'). Even better, use config v2, "
192  + "mode-parameters (see output of any recent run), and mode-specific monetary " + "distance rate.");
193  } else if (WAITING_PT.equals(key)) {
194  setMarginalUtlOfWaitingPt_utils_hr(Double.parseDouble(value));
195  }
196 
197  // backward compatibility: underscored
198  else if (key.startsWith("activityType_")) {
199  log.warn( key + msg );
200  usesDeprecatedSyntax = true ;
201 
202  ActivityParams actParams = getActivityTypeByNumber(key.substring("activityType_".length()));
203 
204  actParams.setActivityType(value);
205  getScoringParameters(null).removeParameterSet(actParams);
206  addActivityParams(actParams);
207  } else if (key.startsWith("activityPriority_")) {
208  log.warn( key + msg );
209  usesDeprecatedSyntax = true ;
210  ActivityParams actParams = getActivityTypeByNumber(key.substring("activityPriority_".length()));
211  actParams.setPriority(Double.parseDouble(value));
212  } else if (key.startsWith("activityTypicalDuration_")) {
213  log.warn( key + msg );
214  usesDeprecatedSyntax = true ;
215  ActivityParams actParams = getActivityTypeByNumber(key.substring("activityTypicalDuration_".length()));
216  actParams.typicalDuration = Time.parseOptionalTime(value);
217  } else if (key.startsWith("activityMinimalDuration_")) {
218  log.warn( key + msg );
219  usesDeprecatedSyntax = true ;
220  ActivityParams actParams = getActivityTypeByNumber(key.substring("activityMinimalDuration_".length()));
221  actParams.minimalDuration = Time.parseOptionalTime(value);
222  } else if (key.startsWith("activityOpeningTime_")) {
223  log.warn( key + msg );
224  usesDeprecatedSyntax = true ;
225  ActivityParams actParams = getActivityTypeByNumber(key.substring("activityOpeningTime_".length()));
226  actParams.openingTime=Time.parseOptionalTime(value);
227  } else if (key.startsWith("activityLatestStartTime_")) {
228  log.warn( key + msg );
229  usesDeprecatedSyntax = true ;
230  ActivityParams actParams = getActivityTypeByNumber(key.substring("activityLatestStartTime_".length()));
231  actParams.latestStartTime = Time.parseOptionalTime(value);
232  } else if (key.startsWith("activityEarliestEndTime_")) {
233  log.warn( key + msg );
234  usesDeprecatedSyntax = true ;
235  ActivityParams actParams = getActivityTypeByNumber(key.substring("activityEarliestEndTime_".length()));
236  actParams.earliestEndTime = Time.parseOptionalTime(value);
237  } else if (key.startsWith("activityClosingTime_")) {
238  log.warn( key + msg );
239  usesDeprecatedSyntax = true ;
240  ActivityParams actParams = getActivityTypeByNumber(key.substring("activityClosingTime_".length()));
241  actParams.closingTime = Time.parseOptionalTime(value);
242  } else if (key.startsWith("scoringThisActivityAtAll_")) {
243  log.warn( key + msg );
244  usesDeprecatedSyntax = true ;
245  ActivityParams actParams = getActivityTypeByNumber(key.substring("scoringThisActivityAtAll_".length()));
246  actParams.setScoringThisActivityAtAll(Boolean.parseBoolean(value));
247  } else if (key.startsWith("traveling_")) {
248  log.warn( key + msg );
249  usesDeprecatedSyntax = true ;
250  ModeParams modeParams = getOrCreateModeParams(key.substring("traveling_".length()));
251  modeParams.setMarginalUtilityOfTraveling(Double.parseDouble(value));
252  } else if (key.startsWith("marginalUtlOfDistance_")) {
253  log.warn( key + msg );
254  usesDeprecatedSyntax = true ;
255  ModeParams modeParams = getOrCreateModeParams(key.substring("marginalUtlOfDistance_".length()));
256  modeParams.setMarginalUtilityOfDistance(Double.parseDouble(value));
257  } else if (key.startsWith("monetaryDistanceRate_")) {
258  log.warn( key + msg );
259  usesDeprecatedSyntax = true ;
260  ModeParams modeParams = getOrCreateModeParams(key.substring("monetaryDistanceRate_".length()));
261  modeParams.setMonetaryDistanceRate(Double.parseDouble(value));
262  } else if ("monetaryDistanceRateCar".equals(key)) {
263  log.warn( key + msg );
264  usesDeprecatedSyntax = true ;
266  modeParams.setMonetaryDistanceRate(Double.parseDouble(value));
267  } else if ("monetaryDistanceRatePt".equals(key)) {
268  log.warn( key + msg );
269  usesDeprecatedSyntax = true ;
271  modeParams.setMonetaryDistanceRate(Double.parseDouble(value));
272  } else if (key.startsWith("constant_")) {
273  log.warn( key + msg );
274  usesDeprecatedSyntax = true ;
275  ModeParams modeParams = getOrCreateModeParams(key.substring("constant_".length()));
276  modeParams.setConstant(Double.parseDouble(value));
277  }
278 
279  // backward compatibility: "typed" traveling
280  else if ("traveling".equals(key)) {
281  log.warn( key + msg );
282  usesDeprecatedSyntax = true ;
283  this.getModes().get(TransportMode.car).setMarginalUtilityOfTraveling(Double.parseDouble(value));
284  } else if ("travelingPt".equals(key)) {
285  log.warn( key + msg );
286  usesDeprecatedSyntax = true ;
287  this.getModes().get(TransportMode.pt).setMarginalUtilityOfTraveling(Double.parseDouble(value));
288  } else if ("travelingWalk".equals(key)) {
289  log.warn( key + msg );
290  usesDeprecatedSyntax = true ;
291  this.getModes().get(TransportMode.walk).setMarginalUtilityOfTraveling(Double.parseDouble(value));
292  } else if ("travelingOther".equals(key)) {
293  log.warn( key + msg );
294  usesDeprecatedSyntax = true ;
295  this.getModes().get(TransportMode.other).setMarginalUtilityOfTraveling(Double.parseDouble(value));
296  } else if ("travelingBike".equals(key)) {
297  log.warn( key + msg );
298  usesDeprecatedSyntax = true ;
299  this.getModes().get(TransportMode.bike).setMarginalUtilityOfTraveling(Double.parseDouble(value));
300  }
301 
302  // backward compatibility: "typed" util of distance
303  else if ("marginalUtlOfDistanceCar".equals(key)) {
304  log.warn( key + msg );
305  usesDeprecatedSyntax = true ;
306  this.getModes().get(TransportMode.car).setMarginalUtilityOfDistance(Double.parseDouble(value));
307  } else if ("marginalUtlOfDistancePt".equals(key)) {
308  log.warn( key + msg );
309  usesDeprecatedSyntax = true ;
310  this.getModes().get(TransportMode.pt).setMarginalUtilityOfDistance(Double.parseDouble(value));
311  } else if ("marginalUtlOfDistanceWalk".equals(key)) {
312  log.warn( key + msg );
313  usesDeprecatedSyntax = true ;
314  this.getModes().get(TransportMode.walk).setMarginalUtilityOfDistance(Double.parseDouble(value));
315  } else if ("marginalUtlOfDistanceOther".equals(key)) {
316  log.warn( key + msg );
317  usesDeprecatedSyntax = true ;
318  this.getModes().get(TransportMode.other).setMarginalUtilityOfDistance(Double.parseDouble(value));
319  }
320 
321  // backward compatibility: "typed" constants
322  else if ("constantCar".equals(key)) {
323  log.warn( key + msg );
324  usesDeprecatedSyntax = true ;
325  getModes().get(TransportMode.car).setConstant(Double.parseDouble(value));
326  } else if ("constantWalk".equals(key)) {
327  log.warn( key + msg );
328  usesDeprecatedSyntax = true ;
329  getModes().get(TransportMode.walk).setConstant(Double.parseDouble(value));
330  } else if ("constantOther".equals(key)) {
331  log.warn( key + msg );
332  usesDeprecatedSyntax = true ;
333  getModes().get(TransportMode.other).setConstant(Double.parseDouble(value));
334  } else if ("constantPt".equals(key)) {
335  log.warn( key + msg );
336  usesDeprecatedSyntax = true ;
337  getModes().get(TransportMode.pt).setConstant(Double.parseDouble(value));
338  } else if ("constantBike".equals(key)) {
339  log.warn( key + msg );
340  usesDeprecatedSyntax = true ;
341  getModes().get(TransportMode.bike).setConstant(Double.parseDouble(value));
342  }
343 
344  // old-fashioned scoring parameters: default subpopulation
345  else if (Arrays
346  .asList(LATE_ARRIVAL, EARLY_DEPARTURE, PERFORMING, MARGINAL_UTL_OF_MONEY, UTL_OF_LINE_SWITCH, WAITING)
347  .contains(key)) {
348 // log.warn( key + msg );
349 // usesDeprecatedSyntax = true ;
350  // this is the stuff with the default subpopulation
351 
352  getScoringParameters(null).addParam(key, value);
353  }
354 
355  else {
356  delegate.addParam(key, value);
357  }
358  }
359 
360  /* for the backward compatibility nonsense */
361  private final Map<String, ActivityParams> activityTypesByNumber = new HashMap<>();
362 
363  private ActivityParams getActivityTypeByNumber(final String number) {
364  ActivityParams actType = this.activityTypesByNumber.get(number);
365  if ((actType == null)) {
366  // not sure what this means, but I found it so...
367  // TD, sep'14
368  actType = new ActivityParams(number);
369  this.activityTypesByNumber.put(number, actType);
370  addParameterSet(actType);
371  }
372  return actType;
373  }
374 
375  public ModeParams getOrCreateModeParams(String modeName) {
376  return getScoringParameters(null).getOrCreateModeParams(modeName);
377  }
378 
379  @Override
380  public Map<String, String> getParams() {
381  return delegate.getParams();
382  }
383 
384  @Override
385  public final Map<String, String> getComments() {
386  Map<String, String> map = super.getComments();
387  map.put(FRACTION_OF_ITERATIONS_TO_START_SCORE_MSA,
388  "fraction of iterations at which MSA score averaging is started. The matsim theory department "
389  + "suggests to use this together with switching off choice set innovation (where a similar switch exists), but it has not been tested yet.");
390  map.put(USING_OLD_SCORING_BELOW_ZERO_UTILITY_DURATION,
391  "There used to be a plateau between duration=0 and duration=zeroUtilityDuration. "
392  + "This caused durations to evolve to zero once they were below zeroUtilityDuration, causing problems. Only use this switch if you need to be "
393  + "backwards compatible with some old results. (changed nov'13)");
394  map.put(PERFORMING,
395  "[utils/hr] marginal utility of doing an activity. normally positive. also the opportunity cost of "
396  + "time if agent is doing nothing. MATSim separates the resource value of time from the direct (dis)utility of travel time, see, e.g., "
397  + "Boerjesson and Eliasson, TR-A 59 (2014) 144-158.");
398  map.put(LATE_ARRIVAL,
399  "[utils/hr] utility for arriving late (i.e. after the latest start time). normally negative");
400  map.put(EARLY_DEPARTURE,
401  "[utils/hr] utility for departing early (i.e. before the earliest end time). Normally negative. Probably "
402  + "implemented correctly, but not tested.");
403  map.put(WAITING,
404  "[utils/hr] additional marginal utility for waiting. normally negative. this comes on top of the opportunity cost of time. Probably "
405  + "implemented correctly, but not tested.");
406  map.put(WAITING_PT,
407  "[utils/hr] additional marginal utility for waiting for a pt vehicle. normally negative. this comes on top of the opportunity cost "
408  + "of time. Default: if not set explicitly, it is equal to traveling_pt!!!");
409  map.put(BRAIN_EXP_BETA,
410  "logit model scale parameter. default: 1. Has name and default value for historical reasons "
411  + "(see Bryan Raney's phd thesis).");
412  map.put(LEARNING_RATE,
413  "new_score = (1-learningRate)*old_score + learningRate * score_from_mobsim. learning rates "
414  + "close to zero emulate score averaging, but slow down initial convergence");
415  map.put(UTL_OF_LINE_SWITCH, "[utils] utility of switching a line (= transfer penalty). Normally negative");
416  map.put(MARGINAL_UTL_OF_MONEY,
417  "[utils/unit_of_money] conversion of money (e.g. toll, distance cost) into utils. Normall positive (i.e. toll/cost/fare are processed as negative amounts of money).");
418  map.put(WRITE_EXPERIENCED_PLANS,
419  "write a plans file in each iteration directory which contains what each agent actually did, and the score it received.");
420 
421  return map;
422  }
423 
424  /*
425  *
426  * @returns a list of all Activities over all Subpopulations (if existent)
427  */
428  public Collection<String> getActivityTypes() {
429  if (getScoringParameters(null) != null)
430  return getScoringParameters(null).getActivityParamsPerType().keySet();
431  else{
432  Set<String> activities = new HashSet<>();
433  getScoringParametersPerSubpopulation().values().forEach(item -> activities.addAll(item.getActivityParamsPerType().keySet()));
434  return activities;
435  }
436  }
437 
438  /*
439  *
440  * @returns a list of all Modes over all Subpopulations (if existent)
441  */
442  public Collection<String> getAllModes() {
443  if (getScoringParameters(null) != null) {
444  return getScoringParameters(null).getModes().keySet();
445 
446  } else {
447  Set<String> modes = new HashSet<>();
448  getScoringParametersPerSubpopulation().values().forEach(item -> modes.addAll(item.getModes().keySet()));
449  return modes;
450  }
451 
452  }
453 
454  public Collection<ActivityParams> getActivityParams() {
455  if (getScoringParameters(null) != null)
457  else if (getScoringParameters(DEFAULT_SUBPOPULATION) != null)
458  return getScoringParameters(DEFAULT_SUBPOPULATION).getActivityParams();
459  else
460  throw new RuntimeException("Default subpopulation is not defined");
461  }
462 
463  public Map<String, ModeParams> getModes() {
464  if (getScoringParameters(null) != null)
465  return getScoringParameters(null).getModes();
466  else if (getScoringParameters(DEFAULT_SUBPOPULATION) != null)
467  return getScoringParameters(DEFAULT_SUBPOPULATION).getModes();
468  else
469  throw new RuntimeException("Default subpopulation is not defined");
470  }
471 
472 
473 
474  public Map<String, ScoringParameterSet> getScoringParametersPerSubpopulation() {
475  final Collection<ScoringParameterSet> parameters = (Collection<ScoringParameterSet>) getParameterSets(
477  final Map<String, ScoringParameterSet> map = new LinkedHashMap<>();
478 
479  for (ScoringParameterSet pars : parameters) {
480  if (this.isLocked()) {
481  pars.setLocked();
482  }
483  map.put(pars.getSubpopulation(), pars);
484  }
485 
486  return map;
487  }
488 
489  /* direct access */
490 
492  if (getScoringParameters(null) != null)
494  else if (getScoringParameters(DEFAULT_SUBPOPULATION) != null)
495  return getScoringParameters(DEFAULT_SUBPOPULATION).getMarginalUtlOfWaitingPt_utils_hr();
496  else
497  throw new RuntimeException("Default subpopulation is not defined");
498 
499  }
500 
501  public void setMarginalUtlOfWaitingPt_utils_hr(double val) {
503  }
504 
505  public ActivityParams getActivityParams(final String actType) {
506  if (getScoringParameters(null) != null)
507  return getScoringParameters(null).getActivityParams(actType);
508  else if (getScoringParameters(DEFAULT_SUBPOPULATION) != null)
509  return getScoringParameters(DEFAULT_SUBPOPULATION).getActivityParams(actType);
510  else
511  throw new RuntimeException("Default subpopulation is not defined");
512 
513  }
514 
515  public ScoringParameterSet getScoringParameters(String subpopulation) {
517  // If no config parameters defined for a specific subpopulation,
518  // use the ones of the "default" subpopulation
519  return params != null ? params : getScoringParametersPerSubpopulation().get(null);
520  }
521 
522  public ScoringParameterSet getOrCreateScoringParameters(String subpopulation) {
524 
525  if (params == null) {
526  params = new ScoringParameterSet(subpopulation);
527  this.addScoringParameters(params);
528  }
529 
530  return params;
531  }
532 
533  @Override
534  public void addParameterSet(final ConfigGroup set) {
535  switch (set.getName()) {
538  break;
539  case ModeParams.SET_TYPE:
540  addModeParams((ModeParams) set);
541  break;
544  break;
545  default:
546  throw new IllegalArgumentException(set.getName());
547  }
548  }
549 
551  final ScoringParameterSet previous = this.getScoringParameters(params.getSubpopulation());
552 
553  if (previous != null) {
554  log.info("scoring parameters for subpopulation " + previous.getSubpopulation() + " were just replaced.");
555 
556  final boolean removed = removeParameterSet(previous);
557  if (!removed)
558  throw new RuntimeException("problem replacing scoring params ");
559  }
560 
561  super.addParameterSet(params);
562  }
563 
564  public void addModeParams(final ModeParams params) {
565  getScoringParameters(null).addModeParams(params);
566  }
567 
570  }
571 
573  uniform, relative
574  };
575 
576  /* parameter set handling */
577  @Override
578  public ConfigGroup createParameterSet(final String type) {
579  switch (type) {
581  return new ActivityParams();
582  case ModeParams.SET_TYPE:
583  return new ModeParams();
585  return new ScoringParameterSet();
586  default:
587  throw new IllegalArgumentException(type);
588  }
589  }
590 
591  @Override
592  protected void checkParameterSet(final ConfigGroup module) {
593  switch (module.getName()) {
595  if (!(module instanceof ScoringParameterSet)) {
596  throw new RuntimeException("wrong class for " + module);
597  }
598  final String s = ((ScoringParameterSet) module).getSubpopulation();
599  if (getScoringParameters(s) != null) {
600  throw new IllegalStateException("already a parameter set for subpopulation " + s);
601  }
602  break;
603  default:
604  throw new IllegalArgumentException(module.getName());
605  }
606  }
607 
608  @Override
609  protected final void checkConsistency(final Config config) {
610  super.checkConsistency(config);
611 
612  if ( usesDeprecatedSyntax && !config.global().isInsistingOnDeprecatedConfigVersion() ) {
613  throw new RuntimeException( msg ) ;
614  }
615 
616  if (getScoringParametersPerSubpopulation().size()>1){
618  throw new RuntimeException("Using several subpopulations in "+PlanCalcScoreConfigGroup.GROUP_NAME+" requires defining a \""+PlanCalcScoreConfigGroup.DEFAULT_SUBPOPULATION+" \" subpopulation."
619  + " Otherwise, crashes can be expected.");
620  }
621  }
622 // if (!config.plansCalcRoute().getAccessEgressType().equals(PlansCalcRouteConfigGroup.AccessEgressType.none)) {
623 
624  // there are modes such as pt or drt that need interaction params even without accessEgress switched on. The policy so far was that
625  // they had to define them by themselves. For drt, this needs to be done manually (adjustDrtConfigGroup) since it is not a core
626  // contrib. At least from a user perspective, it will be easier if they are all generated here. Result of current variant is that they are now also generated
627  // for situations where accessEgress routing is not switched on. Since, in general, our data model assumes that there is always
628  // access/egress, I think that this is acceptable. kai, jan'21
629 
630  // adding the interaction activities that result from access/egress routing. this is strictly speaking not a consistency
631  // check, but I don't know a better place where to add this. kai, jan'18
632 
633  for (ScoringParameterSet scoringParameterSet : this.getScoringParametersPerSubpopulation().values()) {
634 
635  for (String mode : config.plansCalcRoute().getNetworkModes()) {
636  createAndAddInteractionActivity( scoringParameterSet, mode );
637  }
638  // (In principle, the for loop following next should be sufficient, i.e. taking the necessary modes from scoring.
639  // There is, however, a test that checks if all network modes from planCalcRoute have
640  // interaction activities. So we rather satisfy it than changing the test. kai, jan'21
641 
642  for( String mode : scoringParameterSet.getModes().keySet() ){
643  createAndAddInteractionActivity( scoringParameterSet, mode );
644  }
645  }
646 // }
647 
648  for (ActivityParams params : this.getActivityParams()) {
649  if (params.isScoringThisActivityAtAll() && params.getTypicalDuration().isUndefined()) {
650  throw new RuntimeException("In activity type=" + params.getActivityType()
651  + ", the typical duration is undefined. This will lead to errors that are difficult to debug, "
652  + "so rather aborting here.");
653  }
654  }
655 
656  }
657  private static void createAndAddInteractionActivity( ScoringParameterSet scoringParameterSet, String mode ){
658  String interactionActivityType = createStageActivityType( mode );
659  ActivityParams set = scoringParameterSet.getActivityParamsPerType().get( interactionActivityType );
660  if( set == null ){
661 // (we do not want to overwrite this if the use has already set it with other params!)
662  scoringParameterSet.addActivityParams( createStageActivityParams( mode ) );
663  }
664  }
665 
666  public boolean isMemorizingExperiencedPlans() {
667  return this.memorizingExperiencedPlans;
668  }
669 
670  public void setMemorizingExperiencedPlans(boolean memorizingExperiencedPlans) {
671  this.memorizingExperiencedPlans = memorizingExperiencedPlans;
672  }
673 
674  public double getLearningRate() {
675  return delegate.getLearningRate();
676  }
677 
678  public void setLearningRate(double learningRate) {
679  delegate.setLearningRate(learningRate);
680  }
681 
682  public double getBrainExpBeta() {
683  return delegate.getBrainExpBeta();
684  }
685 
686  public void setBrainExpBeta(double brainExpBeta) {
687  delegate.setBrainExpBeta(brainExpBeta);
688  }
689 
690  public double getPathSizeLogitBeta() {
691  return delegate.getPathSizeLogitBeta();
692  }
693 
694  public void setPathSizeLogitBeta(double beta) {
695  delegate.setPathSizeLogitBeta(beta);
696  }
697 
698  public double getLateArrival_utils_hr() {
699 
700  if (getScoringParameters(null) != null)
702  else if (getScoringParameters(DEFAULT_SUBPOPULATION) != null)
703  return getScoringParameters(DEFAULT_SUBPOPULATION).getLateArrival_utils_hr();
704  else
705  throw new RuntimeException("Default subpopulation is not defined");
706 
707  }
708 
709  public void setLateArrival_utils_hr(double lateArrival) {
711  }
712 
713  public double getEarlyDeparture_utils_hr() {
714  if (getScoringParameters(null) != null)
716  else if (getScoringParameters(DEFAULT_SUBPOPULATION) != null)
717  return getScoringParameters(DEFAULT_SUBPOPULATION).getEarlyDeparture_utils_hr();
718  else
719  throw new RuntimeException("Default subpopulation is not defined");
720 
721  }
722 
723  public void setEarlyDeparture_utils_hr(double earlyDeparture) {
724  getScoringParameters(null).setEarlyDeparture_utils_hr(earlyDeparture);
725  }
726 
727  public double getPerforming_utils_hr() {
728  if (getScoringParameters(null) != null)
730  else if (getScoringParameters(DEFAULT_SUBPOPULATION) != null)
731  return getScoringParameters(DEFAULT_SUBPOPULATION).getPerforming_utils_hr();
732  else
733  throw new RuntimeException("Default subpopulation is not defined");
734 
735  }
736 
737  public void setPerforming_utils_hr(double performing) {
739  }
740 
741  public double getMarginalUtilityOfMoney() {
742  if (getScoringParameters(null) != null)
744  else if (getScoringParameters(DEFAULT_SUBPOPULATION) != null)
745  return getScoringParameters(DEFAULT_SUBPOPULATION).getMarginalUtilityOfMoney();
746  else
747  throw new RuntimeException("Default subpopulation is not defined");
748 
749  }
750 
751  public void setMarginalUtilityOfMoney(double marginalUtilityOfMoney) {
752  getScoringParameters(null).setMarginalUtilityOfMoney(marginalUtilityOfMoney);
753  }
754 
755  public double getUtilityOfLineSwitch() {
756  if (getScoringParameters(null) != null)
758  else if (getScoringParameters(DEFAULT_SUBPOPULATION) != null)
759  return getScoringParameters(DEFAULT_SUBPOPULATION).getUtilityOfLineSwitch();
760  else
761  throw new RuntimeException("Default subpopulation is not defined");
762 
763  }
764 
765  public void setUtilityOfLineSwitch(double utilityOfLineSwitch) {
766  getScoringParameters(null).setUtilityOfLineSwitch(utilityOfLineSwitch);
767  }
768 
771  }
772 
773  public void setUsingOldScoringBelowZeroUtilityDuration(boolean usingOldScoringBelowZeroUtilityDuration) {
774  delegate.setUsingOldScoringBelowZeroUtilityDuration(usingOldScoringBelowZeroUtilityDuration);
775  }
776 
777  public boolean isWriteExperiencedPlans() {
778  return delegate.isWriteExperiencedPlans();
779  }
780 
781  public void setWriteExperiencedPlans(boolean writeExperiencedPlans) {
782  delegate.setWriteExperiencedPlans(writeExperiencedPlans);
783  }
784 
786  if (getScoringParameters(null) != null)
788  else if (getScoringParameters(DEFAULT_SUBPOPULATION) != null)
789  return getScoringParameters(DEFAULT_SUBPOPULATION).getMarginalUtlOfWaiting_utils_hr();
790  else
791  throw new RuntimeException("Default subpopulation is not defined");
792 
793  }
794 
795  public void setMarginalUtlOfWaiting_utils_hr(double waiting) {
797  }
798 
799  public void setFractionOfIterationsToStartScoreMSA(Double val) {
801  }
802 
804  return delegate.getFractionOfIterationsToStartScoreMSA();
805  }
806 
807  @Override
808  public final void setLocked() {
809  super.setLocked();
810  this.delegate.setLocked();
811  }
812 
814  // CLASSES
816  public static class ActivityParams extends ReflectiveConfigGroup implements MatsimParameters {
817  // in normal pgm execution, code will presumably lock instance of PlanCalcScoreConfigGroup, but not instance of
818  // ActivityParams. I will try to pass the locked setting through the getters. kai, jun'15
819 
820  public final static String SET_TYPE = "activityParams";
821 
822  // ---
823 
824  private static final String TYPICAL_DURATION_SCORE_COMPUTATION = "typicalDurationScoreComputation";
826 
827  // --- typical duration:
828 
829  public static final String TYPICAL_DURATION = "typicalDuration";
830  public static final String TYPICAL_DURATION_CMT = "typical duration of activity. needs to be defined and non-zero. in sec.";
831 
835  @StringGetter(TYPICAL_DURATION)
836  private String getTypicalDurationString() {
838  }
839 
844  return this.typicalDuration;
845  }
846 
850  @StringSetter(TYPICAL_DURATION)
852  testForLocked();
853  this.typicalDuration = Time.parseOptionalTime(typicalDuration);
854  return this;
855  }
856 
861  testForLocked();
862  this.typicalDuration = OptionalTime.defined(typicalDuration);
863  return this ;
864  }
865 
866  // --- activity type:
867 
868  public static final String ACTIVITY_TYPE = "activityType";
869  private String type;
870  public static final String ACVITITY_TYPE_CMT = "all activity types that occur in the plans file need to be defined by their own sections here";
871 
875  @StringGetter(ACTIVITY_TYPE)
876  public String getActivityType() {
877  return this.type;
878  }
879 
883  @StringSetter(ACTIVITY_TYPE)
884  public void setActivityType(final String type) {
885  testForLocked();
886  this.type = type;
887  }
888 
889  // ---
890 
891  private double priority = 1.0;
898 
899  public ActivityParams() {
900  super(SET_TYPE);
901  }
902 
903  public ActivityParams(final String type) {
904  super(SET_TYPE);
905  this.type = type;
906  }
907 
908  @Override
909  public Map<String, String> getComments() {
910  final Map<String, String> map = super.getComments();
911  // ---
912  StringBuilder str = new StringBuilder();
913  str.append("method to compute score at typical duration. Options: | ");
915  str.append(value.name());
916  str.append(" | ");
917  }
918  str.append("Use ");
919  str.append(TypicalDurationScoreComputation.uniform.name());
920  str.append(" for backwards compatibility (all activities same score; higher proba to drop long acts).");
921  map.put(TYPICAL_DURATION_SCORE_COMPUTATION, str.toString());
922  // ---
924  // ---
925  return map;
926  }
927 
931  }
932 
935  testForLocked();
937  return this ;
938  }
939 
940  @StringGetter("priority")
941  public double getPriority() {
942  return this.priority;
943  }
944 
945  @StringSetter("priority")
946  public ActivityParams setPriority(final double priority) {
947  testForLocked();
948  this.priority = priority;
949  return this ;
950  }
951 
952  @StringGetter("minimalDuration")
953  private String getMinimalDurationString() {
954  return Time.writeTime(minimalDuration);
955  }
956 
958  return minimalDuration;
959  }
960 
961  @StringSetter("minimalDuration")
962  private ActivityParams setMinimalDuration(final String minimalDuration) {
963  testForLocked();
964  this.minimalDuration = Time.parseOptionalTime(minimalDuration);
965  return this;
966  }
967 
968  private static int minDurCnt = 0;
969 
971  testForLocked();
972  if (minDurCnt < 1) {
973  minDurCnt++;
974  log.warn(
975  "Setting minimalDuration different from zero is discouraged. It is probably implemented correctly, "
976  + "but there is as of now no indication that it makes the results more realistic. KN, Sep'08"
977  + Gbl.ONLYONCE);
978  }
979  this.minimalDuration = OptionalTime.defined(minimalDuration);
980  return this ;
981  }
982 
983  @StringGetter("openingTime")
984  private String getOpeningTimeString() {
985  return Time.writeTime(this.openingTime);
986  }
987 
989  return openingTime;
990  }
991 
992  @StringSetter("openingTime")
993  private ActivityParams setOpeningTime(final String openingTime) {
994  testForLocked();
995  this.openingTime =Time.parseOptionalTime(openingTime);
996  return this ;
997  }
998 
1000  testForLocked();
1001  this.openingTime = OptionalTime.defined(openingTime);
1002  return this ;
1003  }
1004 
1005  @StringGetter("latestStartTime")
1006  private String getLatestStartTimeString() {
1007  return Time.writeTime(latestStartTime);
1008  }
1009 
1011  return this.latestStartTime;
1012  }
1013 
1014  @StringSetter("latestStartTime")
1016  testForLocked();
1018  return this ;
1019  }
1020 
1022  testForLocked();
1023  this.latestStartTime = OptionalTime.defined(latestStartTime);
1024  return this ;
1025  }
1026 
1027  @StringGetter("earliestEndTime")
1028  private String getEarliestEndTimeString() {
1029  return Time.writeTime(earliestEndTime);
1030  }
1031 
1033  return earliestEndTime;
1034  }
1035 
1036  @StringSetter("earliestEndTime")
1038  testForLocked();
1040  return this ;
1041  }
1042 
1044  testForLocked();
1045  this.earliestEndTime = OptionalTime.defined(earliestEndTime);
1046  return this ;
1047  }
1048 
1049  @StringGetter("closingTime")
1050  private String getClosingTimeString() {
1051  return Time.writeTime(closingTime);
1052  }
1053 
1055  return closingTime;
1056  }
1057 
1058  @StringSetter("closingTime")
1060  testForLocked();
1062  return this ;
1063  }
1064 
1066  testForLocked();
1067  this.closingTime = OptionalTime.defined(closingTime);
1068  return this ;
1069  }
1070 
1071  // ---
1072 
1073  static final String SCORING_THIS_ACTIVITY_AT_ALL = "scoringThisActivityAtAll";
1074 
1075  private boolean scoringThisActivityAtAll = true;
1076 
1077  @StringGetter(SCORING_THIS_ACTIVITY_AT_ALL)
1078  public boolean isScoringThisActivityAtAll() {
1079  return scoringThisActivityAtAll;
1080  }
1081 
1082  @StringSetter(SCORING_THIS_ACTIVITY_AT_ALL)
1084  testForLocked();
1086  return this ;
1087  }
1088  }
1089 
1090  public static class ModeParams extends ReflectiveConfigGroup implements MatsimParameters {
1091 
1092  final static String SET_TYPE = "modeParams";
1093 
1094  private static final String MONETARY_DISTANCE_RATE = "monetaryDistanceRate";
1095  private static final String MONETARY_DISTANCE_RATE_CMT = "[unit_of_money/m] conversion of distance into money. Normally negative.";
1096 
1097  private static final String MARGINAL_UTILITY_OF_TRAVELING = "marginalUtilityOfTraveling_util_hr";
1098 
1099  private static final String CONSTANT = "constant";
1100  private static final String CONSTANT_CMT = "[utils] alternative-specific constant. Normally per trip, but that is probably buggy for multi-leg trips.";
1101 
1102  public static final String MODE = "mode";
1103 
1104  private static final String DAILY_MONETARY_CONSTANT = "dailyMonetaryConstant";
1105  private static final String DAILY_MONETARY_CONSTANT_CMT = "[unit_of_money/day] Fixed cost of mode, per day.";
1106 
1107  private static final String DAILY_UTILITY_CONSTANT = "dailyUtilityConstant";
1108 
1109  private String mode = null;
1110  private double traveling = -6.0;
1111  private double distance = 0.0;
1112  private double monetaryDistanceRate = 0.0;
1113  private double constant = 0.0;
1114  private double dailyMonetaryConstant = 0.0;
1115  private double dailyUtilityConstant = 0.0;
1116 
1117  // @Override public String toString() {
1118  // String str = super.toString();
1119  // str += "[mode=" + mode + "]" ;
1120  // str += "[const=" + constant + "]" ;
1121  // str += "[beta_trav=" + traveling + "]" ;
1122  // str += "[beta_dist=" + distance + "]" ;
1123  // return str ;
1124  // }
1125 
1126  public ModeParams(final String mode) {
1127  super(SET_TYPE);
1128  setMode(mode);
1129  }
1130 
1131  ModeParams() {
1132  super(SET_TYPE);
1133  }
1134 
1135  @Override
1136  public Map<String, String> getComments() {
1137  final Map<String, String> map = super.getComments();
1138  map.put(MARGINAL_UTILITY_OF_TRAVELING,
1139  "[utils/hr] additional marginal utility of traveling. normally negative. this comes on top "
1140  + "of the opportunity cost of time");
1141  map.put("marginalUtilityOfDistance_util_m",
1142  "[utils/m] utility of traveling (e.g. walking or driving) per m, normally negative. this is "
1143  + "on top of the time (dis)utility.");
1144  map.put(MONETARY_DISTANCE_RATE, MONETARY_DISTANCE_RATE_CMT);
1145  map.put(CONSTANT, CONSTANT_CMT );
1146  map.put(DAILY_UTILITY_CONSTANT, "[utils] daily utility constant. "
1147  + "default=0 to be backwards compatible");
1148  map.put(DAILY_MONETARY_CONSTANT, DAILY_MONETARY_CONSTANT_CMT ) ;
1149  return map;
1150  }
1151 
1152  @StringSetter(MODE)
1153  public ModeParams setMode(final String mode) {
1154  testForLocked();
1155  this.mode = mode;
1156  return this ;
1157  }
1158  @StringGetter(MODE)
1159  public String getMode() {
1160  return mode;
1161  }
1162  // ---
1163  @StringSetter(MARGINAL_UTILITY_OF_TRAVELING)
1164  public ModeParams setMarginalUtilityOfTraveling(double traveling) {
1165  testForLocked();
1166  this.traveling = traveling;
1167  return this ;
1168  }
1169  @StringGetter(MARGINAL_UTILITY_OF_TRAVELING)
1170  public double getMarginalUtilityOfTraveling() {
1171  return this.traveling;
1172  }
1173  // ---
1174  @StringGetter("marginalUtilityOfDistance_util_m")
1175  public double getMarginalUtilityOfDistance() {
1176  return distance;
1177  }
1178  @StringSetter("marginalUtilityOfDistance_util_m")
1179  public ModeParams setMarginalUtilityOfDistance(double distance) {
1180  testForLocked();
1181  this.distance = distance;
1182  return this ;
1183  }
1184 
1188  // ---
1189  @StringGetter(CONSTANT)
1190  public double getConstant() {
1191  return this.constant;
1192  }
1196  @StringSetter(CONSTANT)
1197  public ModeParams setConstant(double constant) {
1198  testForLocked();
1199  this.constant = constant;
1200  return this ;
1201  }
1202  // ---
1206  @StringGetter(MONETARY_DISTANCE_RATE)
1207  public double getMonetaryDistanceRate() {
1208  return this.monetaryDistanceRate;
1209  }
1210 
1214  @StringSetter(MONETARY_DISTANCE_RATE)
1215  public ModeParams setMonetaryDistanceRate(double monetaryDistanceRate) {
1216  testForLocked();
1217  this.monetaryDistanceRate = monetaryDistanceRate;
1218  return this ;
1219  }
1223  @StringGetter(DAILY_MONETARY_CONSTANT)
1224  public double getDailyMonetaryConstant() {
1225  return dailyMonetaryConstant;
1226  }
1227 
1231  @StringSetter(DAILY_MONETARY_CONSTANT)
1232  public ModeParams setDailyMonetaryConstant(double dailyMonetaryConstant) {
1233  this.dailyMonetaryConstant = dailyMonetaryConstant;
1234  return this ;
1235  }
1236 
1237  @StringGetter(DAILY_UTILITY_CONSTANT)
1238  public double getDailyUtilityConstant() {
1239  return dailyUtilityConstant;
1240  }
1241 
1242  @StringSetter(DAILY_UTILITY_CONSTANT)
1243  public ModeParams setDailyUtilityConstant(double dailyUtilityConstant) {
1244  this.dailyUtilityConstant = dailyUtilityConstant;
1245  return this ;
1246  }
1247 
1248 
1249  }
1250 
1251  public static class ScoringParameterSet extends ReflectiveConfigGroup {
1252  public static final String SET_TYPE = "scoringParameters";
1253 
1254  private ScoringParameterSet(final String subpopulation) {
1255  this();
1256  this.subpopulation = subpopulation;
1257  }
1258 
1260  super(SET_TYPE);
1261  }
1262 
1263  private String subpopulation = null;
1264 
1265  private double lateArrival = -18.0;
1266  private double earlyDeparture = -0.0;
1267  private double performing = +6.0;
1268 
1269  private double waiting = -0.0;
1270 
1271  private double marginalUtilityOfMoney = 1.0;
1272 
1273  private double utilityOfLineSwitch = -1;
1274 
1275  private Double waitingPt = null; // if not actively set by user, it will
1276  // later be set to "travelingPt".
1277 
1279  public double getLateArrival_utils_hr() {
1280  return lateArrival;
1281  }
1282 
1284  public void setLateArrival_utils_hr(double lateArrival) {
1285  testForLocked();
1286  this.lateArrival = lateArrival;
1287  }
1288 
1290  public double getEarlyDeparture_utils_hr() {
1291  return earlyDeparture;
1292  }
1293 
1295  public void setEarlyDeparture_utils_hr(double earlyDeparture) {
1296  testForLocked();
1297  this.earlyDeparture = earlyDeparture;
1298  }
1299 
1301  public double getPerforming_utils_hr() {
1302  return performing;
1303  }
1304 
1306  public void setPerforming_utils_hr(double performing) {
1307  this.performing = performing;
1308  }
1309 
1311  public double getMarginalUtilityOfMoney() {
1312  return marginalUtilityOfMoney;
1313  }
1314 
1316  public void setMarginalUtilityOfMoney(double marginalUtilityOfMoney) {
1317  testForLocked();
1318  this.marginalUtilityOfMoney = marginalUtilityOfMoney;
1319  }
1320 
1322  public double getUtilityOfLineSwitch() {
1323  return utilityOfLineSwitch;
1324  }
1325 
1327  public void setUtilityOfLineSwitch(double utilityOfLineSwitch) {
1328  testForLocked();
1329  this.utilityOfLineSwitch = utilityOfLineSwitch;
1330  }
1331 
1334  return this.waiting;
1335  }
1336 
1338  public void setMarginalUtlOfWaiting_utils_hr(final double waiting) {
1339  testForLocked();
1340  this.waiting = waiting;
1341  }
1342 
1343  @StringGetter("subpopulation")
1344  public String getSubpopulation() {
1345  return subpopulation;
1346  }
1347 
1351  @StringSetter("subpopulation")
1352  public void setSubpopulation(String subpopulation) {
1353  // TODO: handle case of default subpopulation
1354  if (this.subpopulation != null) {
1355  throw new IllegalStateException(
1356  "cannot change subpopulation in a scoring parameter set, as it is used for indexing.");
1357  }
1358 
1359  this.subpopulation = subpopulation;
1360  }
1361 
1364  return waitingPt != null ? waitingPt
1365  : this.getModes().get(TransportMode.pt).getMarginalUtilityOfTraveling();
1366  }
1367 
1369  public void setMarginalUtlOfWaitingPt_utils_hr(final Double waitingPt) {
1370  this.waitingPt = waitingPt;
1371  }
1372 
1373  /* parameter set handling */
1374  @Override
1375  public ConfigGroup createParameterSet(final String type) {
1376  switch (type) {
1377  case ActivityParams.SET_TYPE:
1378  return new ActivityParams();
1379  case ModeParams.SET_TYPE:
1380  return new ModeParams();
1381  default:
1382  throw new IllegalArgumentException(type);
1383  }
1384  }
1385 
1386  @Override
1387  protected void checkParameterSet(final ConfigGroup module) {
1388  switch (module.getName()) {
1389  case ActivityParams.SET_TYPE:
1390  if (!(module instanceof ActivityParams)) {
1391  throw new RuntimeException("wrong class for " + module);
1392  }
1393  final String t = ((ActivityParams) module).getActivityType();
1394  if (getActivityParams(t) != null) {
1395  throw new IllegalStateException("already a parameter set for activity type " + t);
1396  }
1397  break;
1398  case ModeParams.SET_TYPE:
1399  if (!(module instanceof ModeParams)) {
1400  throw new RuntimeException("wrong class for " + module);
1401  }
1402  final String m = ((ModeParams) module).getMode();
1403  if (getModes().get(m) != null) {
1404  throw new IllegalStateException("already a parameter set for mode " + m);
1405  }
1406  break;
1407  default:
1408  throw new IllegalArgumentException(module.getName());
1409  }
1410  }
1411 
1412  public Collection<String> getActivityTypes() {
1413  return this.getActivityParamsPerType().keySet();
1414  }
1415 
1416  public Collection<ActivityParams> getActivityParams() {
1417  Collection<ActivityParams> collection = (Collection<ActivityParams>) getParameterSets(
1419  for (ActivityParams params : collection) {
1420  if (this.isLocked()) {
1421  params.setLocked();
1422  }
1423  }
1424  return collection;
1425  }
1426 
1427  public Map<String, ActivityParams> getActivityParamsPerType() {
1428  final Map<String, ActivityParams> map = new LinkedHashMap<>();
1429 
1430  for (ActivityParams pars : getActivityParams()) {
1431  map.put(pars.getActivityType(), pars);
1432  }
1433 
1434  return map;
1435  }
1436 
1437  public ActivityParams getActivityParams(final String actType) {
1438  return this.getActivityParamsPerType().get(actType);
1439  }
1440 
1441  public ActivityParams getOrCreateActivityParams(final String actType) {
1442  ActivityParams params = this.getActivityParamsPerType().get(actType);
1443 
1444  if (params == null) {
1445  params = new ActivityParams(actType);
1446  addActivityParams(params);
1447  }
1448 
1449  return params;
1450  }
1451 
1452  public Map<String, ModeParams> getModes() {
1453  final Collection<ModeParams> modes = (Collection<ModeParams>) getParameterSets(ModeParams.SET_TYPE);
1454  final Map<String, ModeParams> map = new LinkedHashMap<>();
1455 
1456  for (ModeParams pars : modes) {
1457  if (this.isLocked()) {
1458  pars.setLocked();
1459  }
1460  map.put(pars.getMode(), pars);
1461  }
1462  if (this.isLocked()) {
1463  return Collections.unmodifiableMap(map);
1464  } else {
1465  return map;
1466  }
1467  }
1468 
1469  public ModeParams getOrCreateModeParams(String modeName) {
1470  ModeParams modeParams = getModes().get(modeName);
1471  if (modeParams == null) {
1472  modeParams = new ModeParams(modeName);
1473  addParameterSet(modeParams);
1474  }
1475  return modeParams;
1476  }
1477 
1478  public void addModeParams(final ModeParams params) {
1479  final ModeParams previous = this.getModes().get(params.getMode());
1480 
1481  if (previous != null) {
1482  final boolean removed = removeParameterSet(previous);
1483  if (!removed)
1484  throw new RuntimeException("problem replacing mode params ");
1485  log.info("mode parameters for mode " + previous.getMode() + " were just overwritten.");
1486  }
1487 
1488  super.addParameterSet(params);
1489  }
1490 
1492  final ActivityParams previous = this.getActivityParams(params.getActivityType());
1493 
1494  if (previous != null) {
1495  if (previous.getActivityType().equals(PtConstants.TRANSIT_ACTIVITY_TYPE)) {
1496  log.error("ERROR: Activity parameters for activity type " + previous.getActivityType()
1497  + " were just overwritten. This happens most "
1498  + "likely because you defined them in the config file and the Controler overwrites them. Or the other way "
1499  + "round. pt interaction has problems, but doing what you are doing here will just cause "
1500  + "other (less visible) problem. Please take the effort to discuss with the core team "
1501  + "what needs to be done. kai, nov'12");
1502  } else {
1503  log.info("activity parameters for activity type " + previous.getActivityType()
1504  + " were just overwritten.");
1505  }
1506 
1507  final boolean removed = removeParameterSet(previous);
1508  if (!removed)
1509  throw new RuntimeException("problem replacing activity params ");
1510  }
1511 
1512  super.addParameterSet(params);
1513  }
1514 
1521  @Override
1522  public void checkConsistency(Config config) {
1523  super.checkConsistency(config);
1524 
1525 
1526  boolean hasOpeningAndClosingTime = false;
1527  boolean hasOpeningTimeAndLatePenalty = false;
1528 
1529 
1530  // This cannot be done in ActivityParams (where it would make more
1531  // sense),
1532  // because some global properties are also checked
1533  for (ActivityParams actType : this.getActivityParams()) {
1534  if (actType.isScoringThisActivityAtAll()) {
1535  // (checking consistency only if activity is scored at all)
1536 
1537  if (actType.getOpeningTime().isDefined() && actType.getClosingTime().isDefined()) {
1538  hasOpeningAndClosingTime = true;
1539 
1540  if (actType.getOpeningTime().seconds() == 0. && actType.getClosingTime().seconds() > 24. * 3600 - 1) {
1541  log.error("it looks like you have an activity type with opening time set to 0:00 and closing "
1542  + "time set to 24:00. This is most probably not the same as not setting them at all. "
1543  + "In particular, activities which extend past midnight may not accumulate scores.");
1544  }
1545  }
1546  if (actType.getOpeningTime().isDefined() && (getLateArrival_utils_hr() < -0.001)) {
1547  hasOpeningTimeAndLatePenalty = true;
1548  }
1549  }
1550  }
1551  if (!hasOpeningAndClosingTime && !hasOpeningTimeAndLatePenalty) {
1552  log.info("NO OPENING OR CLOSING TIMES DEFINED!\n\n"
1553  + "There is no activity type that has an opening *and* closing time (or opening time and late penalty) defined.\n"
1554  + "This usually means that the activity chains can be shifted by an arbitrary\n"
1555  + "number of hours without having an effect on the score of the plans, and thus\n"
1556  + "resulting in wrong results / traffic patterns.\n"
1557  + "If you are using MATSim without time adaptation, you can ignore this warning.\n\n");
1558  }
1559  if (this.getMarginalUtlOfWaiting_utils_hr() != 0.0) {
1560  log.warn("marginal utl of wait set to: " + this.getMarginalUtlOfWaiting_utils_hr()
1561  + ". Setting this different from zero is "
1562  + "discouraged since there is already the marginal utility of time as a resource. The parameter was also used "
1563  + "in the past for pt routing; if you did that, consider setting the new "
1564  + "parameter waitingPt instead.");
1565  }
1566  }
1567 
1568  }
1569 
1570  private static class ReflectiveDelegate extends ReflectiveConfigGroup {
1573  }
1574 
1575  private double learningRate = 1.0;
1576  private double brainExpBeta = 1.0;
1577  private double pathSizeLogitBeta = 1.0;
1578 
1579  private boolean writeExperiencedPlans = false;
1580 
1581  private Double fractionOfIterationsToStartScoreMSA = null;
1582 
1583  private boolean usingOldScoringBelowZeroUtilityDuration = false;
1584 
1587  return fractionOfIterationsToStartScoreMSA;
1588  }
1589 
1591  public void setFractionOfIterationsToStartScoreMSA(Double fractionOfIterationsToStartScoreMSA) {
1592  testForLocked();
1593  this.fractionOfIterationsToStartScoreMSA = fractionOfIterationsToStartScoreMSA;
1594  }
1595 
1597  public double getLearningRate() {
1598  return learningRate;
1599  }
1600 
1602  public void setLearningRate(double learningRate) {
1603  testForLocked();
1604  this.learningRate = learningRate;
1605  }
1606 
1608  public double getBrainExpBeta() {
1609  return brainExpBeta;
1610  }
1611 
1613  public void setBrainExpBeta(double brainExpBeta) {
1614  testForLocked();
1615  this.brainExpBeta = brainExpBeta;
1616  }
1617 
1619  public double getPathSizeLogitBeta() {
1620  return pathSizeLogitBeta;
1621  }
1622 
1624  public void setPathSizeLogitBeta(double beta) {
1625  testForLocked();
1626  if (beta != 0.) {
1627  log.warn("Setting pathSizeLogitBeta different from zero is experimental. KN, Sep'08");
1628  }
1629  this.pathSizeLogitBeta = beta;
1630  }
1631 
1634  return usingOldScoringBelowZeroUtilityDuration;
1635  }
1636 
1638  public void setUsingOldScoringBelowZeroUtilityDuration(boolean usingOldScoringBelowZeroUtilityDuration) {
1639  // should be disabled like in the following. kai, may'22
1640 // if ( usingOldScoringBelowZeroUtilityDuration ) {
1641 // throw new RuntimeException( "using old scoringBelowZeroUtility duration is no longer possible. Use matsim version 14.0 " +
1642 // "or older if you truly need this for backwards compatibility." )
1643 // }
1644  testForLocked();
1645  this.usingOldScoringBelowZeroUtilityDuration = usingOldScoringBelowZeroUtilityDuration;
1646  }
1647 
1649  public boolean isWriteExperiencedPlans() {
1650  return writeExperiencedPlans;
1651  }
1652 
1654  public void setWriteExperiencedPlans(boolean writeExperiencedPlans) {
1655  testForLocked();
1656  this.writeExperiencedPlans = writeExperiencedPlans;
1657  }
1658 
1659  }
1660 }
ScoringParameterSet getOrCreateScoringParameters(String subpopulation)
static final String ONLYONCE
Definition: Gbl.java:42
void addParameterSet(final ConfigGroup set)
ScoringParameterSet getScoringParameters(String subpopulation)
ActivityParams setScoringThisActivityAtAll(boolean scoringThisActivityAtAll)
PlansCalcRouteConfigGroup plansCalcRoute()
Definition: Config.java:443
static final String TRANSIT_ACTIVITY_TYPE
void setUsingOldScoringBelowZeroUtilityDuration(boolean usingOldScoringBelowZeroUtilityDuration)
static final OptionalTime parseOptionalTime(final String time)
Definition: Time.java:167
void setMemorizingExperiencedPlans(boolean memorizingExperiencedPlans)
final Map< String, ? extends Collection<? extends ConfigGroup > > getParameterSets()
static final String writeTime(final double seconds, final String timeformat)
Definition: Time.java:80
static OptionalTime defined(double seconds)
void setUsingOldScoringBelowZeroUtilityDuration(boolean usingOldScoringBelowZeroUtilityDuration)
Map< String, ScoringParameterSet > getScoringParametersPerSubpopulation()
final void addParam(final String param_name, final String value)
ActivityParams setTypicalDurationScoreComputation(TypicalDurationScoreComputation str)
final TreeMap< String, String > params
boolean removeParameterSet(final ConfigGroup set)
void setFractionOfIterationsToStartScoreMSA(Double fractionOfIterationsToStartScoreMSA)
final GlobalConfigGroup global()
Definition: Config.java:399
static void createAndAddInteractionActivity(ScoringParameterSet scoringParameterSet, String mode)