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