MATSIM
PopulationUtils.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: matsim
3  * PopulationUtils.java
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2010 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.population;
22 
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.PipedInputStream;
26 import java.io.PipedOutputStream;
27 import java.io.UncheckedIOException;
28 import java.util.ArrayList;
29 import java.util.Collections;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Random;
34 import java.util.SortedMap;
35 import java.util.TreeMap;
36 
37 import org.apache.logging.log4j.LogManager;
38 import org.apache.logging.log4j.Logger;
39 import org.matsim.api.core.v01.Coord;
40 import org.matsim.api.core.v01.Id;
41 import org.matsim.api.core.v01.Scenario;
54 import org.matsim.core.config.Config;
58 import org.matsim.core.gbl.Gbl;
75 import org.matsim.core.utils.io.IOUtils;
81 import org.matsim.vehicles.Vehicle;
84 
88 public final class PopulationUtils {
89  private static final Logger log = LogManager.getLogger(PopulationUtils.class);
91 
95  @Deprecated
96  public static final String SUBPOPULATION_ATTRIBUTE_NAME = "subpopulation";
97 
98 
102  private PopulationUtils() {
103  }
104 
112  public static Population createPopulation(Config config) {
113  return createPopulation(config, null);
114  }
115 
125  public static Population createPopulation(Config config, Network network) {
126  return createPopulation(config.plans(), network);
127  }
128 
129  public static Population createPopulation(PlansConfigGroup plansConfigGroup, Network network) {
130  // yyyy my intuition would be to rather get this out of a standard scenario. kai, jun'16
131  RouteFactories routeFactory = new RouteFactories();
132  String networkRouteType = plansConfigGroup.getNetworkRouteType();
133  RouteFactory factory;
134  if (PlansConfigGroup.NetworkRouteType.LinkNetworkRoute.equals(networkRouteType)) {
135  factory = new LinkNetworkRouteFactory();
136  } else if (PlansConfigGroup.NetworkRouteType.MediumCompressedNetworkRoute.equals(networkRouteType) && network != null) {
137  factory = new MediumCompressedNetworkRouteFactory();
138  } else if (PlansConfigGroup.NetworkRouteType.HeavyCompressedNetworkRoute.equals(networkRouteType) && network != null) {
139  factory = new HeavyCompressedNetworkRouteFactory(network, TransportMode.car);
140  } else if (PlansConfigGroup.NetworkRouteType.CompressedNetworkRoute.equals(networkRouteType) && network != null) {
141  factory = new HeavyCompressedNetworkRouteFactory(network, TransportMode.car);
142  } else {
143  throw new IllegalArgumentException("The type \"" + networkRouteType + "\" is not a supported type for network routes.");
144  }
145  routeFactory.setRouteFactory(NetworkRoute.class, factory);
146  return new PopulationImpl(new PopulationFactoryImpl(routeFactory));
147  }
148 
149  public static Leg unmodifiableLeg(Leg leg) {
150  return new UnmodifiableLeg(leg);
151  }
152 
153  public static void resetRoutes(final Plan plan) {
154  // loop over all <leg>s, remove route-information
155  // routing is done after location choice
156  for (PlanElement pe : plan.getPlanElements()) {
157  if (pe instanceof Leg) {
158  ((Leg) pe).setRoute(null);
159  }
160  }
161  }
162 
163  static class UnmodifiableLeg implements Leg {
164  private final Leg delegate;
165 
166  public UnmodifiableLeg(Leg leg) {
167  this.delegate = leg;
168  }
169 
170  @Override
171  public String getMode() {
172  return this.delegate.getMode();
173  }
174 
175  @Override
176  public void setMode(String mode) {
177  throw new UnsupportedOperationException();
178  }
179 
180  @Override
181  public String getRoutingMode() {
182  return this.delegate.getRoutingMode();
183  }
184 
185  @Override
186  public void setRoutingMode(String routingMode) {
187  throw new UnsupportedOperationException();
188  }
189 
190  @Override
191  public Route getRoute() {
192  // route should be unmodifiable. kai
193  return this.delegate.getRoute();
194  }
195 
196  @Override
197  public void setRoute(Route route) {
198  throw new UnsupportedOperationException();
199  }
200 
201  @Override
202  public OptionalTime getDepartureTime() {
203  return this.delegate.getDepartureTime();
204  }
205 
206  @Override
207  public void setDepartureTime(double seconds) {
208  throw new UnsupportedOperationException();
209  }
210 
211  @Override
212  public void setDepartureTimeUndefined() {
213  throw new UnsupportedOperationException();
214  }
215 
216  @Override
217  public OptionalTime getTravelTime() {
218  return this.delegate.getTravelTime();
219  }
220 
221  @Override
222  public void setTravelTime(double seconds) {
223  throw new UnsupportedOperationException();
224  }
225 
226  @Override
227  public void setTravelTimeUndefined() {
228  throw new UnsupportedOperationException();
229  }
230 
231  @Override
232  public String toString() {
233  return this.delegate.toString();
234  }
235 
236  @Override
237  public Attributes getAttributes() {
238  // attributes should be made unmodifiable
239  return delegate.getAttributes();
240  }
241  }
242 
244  return new UnmodifiableActivity(act);
245  }
246 
247  static class UnmodifiableActivity implements Activity {
248  private final Activity delegate;
249 
250  public UnmodifiableActivity(Activity act) {
251  this.delegate = act;
252  }
253 
254  @Override
255  public OptionalTime getEndTime() {
256  return this.delegate.getEndTime();
257  }
258 
259  @Override
260  public void setEndTime(double seconds) {
261  throw new UnsupportedOperationException();
262  }
263 
264  @Override
265  public void setEndTimeUndefined() {
266  throw new UnsupportedOperationException();
267  }
268 
269  @Override
270  public String getType() {
271  return this.delegate.getType();
272  }
273 
274  @Override
275  public void setType(String type) {
276  throw new UnsupportedOperationException();
277  }
278 
279  @Override
280  public Coord getCoord() {
281  return this.delegate.getCoord();
282  }
283 
284  @Override
285  public OptionalTime getStartTime() {
286  return this.delegate.getStartTime();
287  }
288 
289  @Override
290  public void setStartTime(double seconds) {
291  throw new UnsupportedOperationException();
292  }
293 
294  @Override
295  public void setStartTimeUndefined() {
296  throw new UnsupportedOperationException();
297  }
298 
299  @Override
300  public OptionalTime getMaximumDuration() {
301  return this.delegate.getMaximumDuration();
302  }
303 
304  @Override
305  public void setMaximumDuration(double seconds) {
306  throw new UnsupportedOperationException();
307  }
308 
309  @Override
310  public void setMaximumDurationUndefined() {
311  throw new UnsupportedOperationException();
312  }
313 
314  @Override
315  public Id<Link> getLinkId() {
316  return this.delegate.getLinkId();
317  }
318 
319  @Override
320  public Id<ActivityFacility> getFacilityId() {
321  return this.delegate.getFacilityId();
322  }
323 
324  @Override
325  public String toString() {
326  return this.delegate.toString();
327  }
328 
329  @Override
330  public void setLinkId(Id<Link> id) {
331  throw new UnsupportedOperationException();
332  }
333 
334  @Override
335  public void setFacilityId(Id<ActivityFacility> id) {
336  throw new UnsupportedOperationException();
337  }
338 
339  @Override
340  public void setCoord(Coord coord) {
341  throw new RuntimeException("not implemented");
342  }
343 
344  @Override
345  public Attributes getAttributes() {
346  // attributes should be made unmodifiable
347  return delegate.getAttributes();
348  }
349  }
350 
355  public static Plan unmodifiablePlan(Plan plan) {
356  return new UnmodifiablePlan(plan);
357  }
358 
359  static class UnmodifiablePlan implements Plan {
360  private final Plan delegate;
361  private final List<PlanElement> unmodifiablePlanElements;
362 
363  public UnmodifiablePlan(Plan plan) {
364  this.delegate = plan;
365  List<PlanElement> tmp = new ArrayList<>();
366  for (PlanElement pe : plan.getPlanElements()) {
367  if (pe instanceof Activity) {
368  tmp.add(unmodifiableActivity((Activity) pe));
369  } else if (pe instanceof Leg) {
370  tmp.add(unmodifiableLeg((Leg) pe));
371  }
372  }
373  this.unmodifiablePlanElements = Collections.unmodifiableList(tmp);
374  }
375 
376  @Override
377  public void addActivity(Activity act) {
378  throw new UnsupportedOperationException();
379  }
380 
381  @Override
382  public String getType() {
383  return delegate.getType();
384  }
385 
386  @Override
387  public void setType(String type) {
388  throw new UnsupportedOperationException();
389  }
390 
391  @Override
392  public Id<Plan> getId() {
393  return this.delegate.getId();
394  }
395 
396  @Override
397  public void setPlanId(Id<Plan> planId) {
398  throw new UnsupportedOperationException();
399  }
400 
401  @Override
402  public int getIterationCreated() {
403  return this.delegate.getIterationCreated();
404  }
405 
406  @Override
407  public void setIterationCreated(int iteration) {
408  throw new UnsupportedOperationException();
409  }
410 
411  @Override
412  public String getPlanMutator() {
413  return this.delegate.getPlanMutator();
414  }
415 
416  @Override
417  public void setPlanMutator(String planMutator) {
418  throw new UnsupportedOperationException();
419  }
420 
421  @Override
422  public void addLeg(Leg leg) {
423  throw new UnsupportedOperationException();
424  }
425 
426  @Override
427  public Map<String, Object> getCustomAttributes() {
428  return delegate.getCustomAttributes();
429  }
430 
431  @Override
432  public Person getPerson() {
433  return delegate.getPerson();
434  }
435 
436  @Override
437  public List<PlanElement> getPlanElements() {
438  return this.unmodifiablePlanElements;
439  }
440 
441  @Override
442  public Double getScore() {
443  return delegate.getScore();
444  }
445 
446  @Override
447  public void setPerson(Person person) {
448  throw new UnsupportedOperationException();
449  }
450 
451  @Override
452  public void setScore(Double score) {
453  throw new UnsupportedOperationException();
454  }
455 
456  @Override
457  public Attributes getAttributes() {
458  // TODO yyyy should be made unmodifiable. kai, jan'17
459  return delegate.getAttributes();
460  }
461  }
462 
466  public static SortedMap<Id<Person>, Person> getSortedPersons(final Population population) {
467  return new TreeMap<>(population.getPersons());
468  }
469 
473  public static void sortPersons(final Population population) {
474  Map<Id<Person>, Person> map = (Map<Id<Person>, Person>) population.getPersons();
475 
476  if (map instanceof SortedMap) return;
477 
478  Map<Id<Person>, Person> treeMap = new TreeMap<>(map);
479  map.clear();
480  map.putAll(treeMap);
481  }
482 
483  private static int missingFacilityCnt = 0;
484 
485  @Deprecated // use decideOnLinkIdForActivity. kai, sep'18
487  // the following might eventually become configurable by config. kai, feb'16
488  if (act.getFacilityId() == null) {
489  final Id<Link> linkIdFromActivity = act.getLinkId();
490  Gbl.assertNotNull(linkIdFromActivity);
491  return linkIdFromActivity;
492  } else {
493  ActivityFacility facility = facs.getFacilities().get(act.getFacilityId());
494  if (facility == null || facility.getLinkId() == null) {
495  if (facility == null) {
496  if (missingFacilityCnt < 10) {
497  log.warn("we have a facility ID for an activity, but can't find the facility; this should not really happen. Falling back on link ID.");
498  missingFacilityCnt++;
499  if (missingFacilityCnt == 10) {
500  log.warn(Gbl.FUTURE_SUPPRESSED);
501  }
502  }
503  }
504  final Id<Link> linkIdFromActivity = act.getLinkId();
505  Gbl.assertIf(linkIdFromActivity != null);
506  return linkIdFromActivity;
507  } else {
508  return facility.getLinkId();
509  }
510  // yy sorry about this mess, I am just trying to make explicit which seems to have been the logic so far implicitly. kai, feb'16
511  }
512  }
513 
514  @Deprecated // use "decideOnCoord..."
516  return computeCoordFromActivity(act, facs, null, config);
517  }
518 
519  @Deprecated // use "decideOnCoord..."
520  public static Coord computeCoordFromActivity(Activity act, ActivityFacilities facs, Network network, Config config) {
521  // the following might eventually become configurable by config. kai, feb'16
522  if (act.getFacilityId() == null) {
523  if (act.getCoord() != null) {
524  return act.getCoord();
525  } else {
526  Gbl.assertNotNull(network);
527  Link link = network.getLinks().get(act.getLinkId());
528  return link.getCoord();
529  }
530  } else {
531  Gbl.assertIf(facs != null);
532  ActivityFacility facility = facs.getFacilities().get(act.getFacilityId());
533  Gbl.assertIf(facility != null);
534  return facility.getCoord();
535  }
536  }
537 
541  public static List<Activity> getActivities(Plan plan, StageActivityHandling stageActivityHandling) {
542  return TripStructureUtils.getActivities(plan, stageActivityHandling);
543  }
544 
548  public static List<Leg> getLegs(Plan plan) {
549  return TripStructureUtils.getLegs(plan);
550  }
551 
558  public static double calculateSimilarity(List<Leg> legs1, List<Leg> legs2, Network network,
559  double sameModeReward, double sameRouteReward) {
560  // yyyy should be made configurable somehow (i.e. possibly not a static method any more). kai, apr'15
561 
562  // yy kwa points to:
563  // Schüssler, N. and K.W. Axhausen (2009b) Accounting for similarities in destination choice modelling: A concept, paper presented at the 9th Swiss Transport Research Conference, Ascona, October 2009.
564  // und
565  // Joh, Chang-Hyeon, Theo A. Arentze and Harry J. P. Timmermans (2001).
566  // A Position-Sensitive Sequence Alignment Method Illustrated for Space-Time Activity-Diary Data¹, Environment and Planning A 33(2): 313­338.
567 
568  // Mahdieh Allahviranloo has some work on activity pattern similarity (iatbr'15)
569 
570  double simil = 0.;
571  Iterator<Leg> it1 = legs1.iterator();
572  Iterator<Leg> it2 = legs2.iterator();
573  for (; it1.hasNext() && it2.hasNext(); ) {
574  Leg leg1 = it1.next();
575  Leg leg2 = it2.next();
576  if (leg1.getMode().equals(leg2.getMode())) {
577  simil += sameModeReward;
578  } else {
579  continue;
580  // don't look for route overlap if different mode. Makes sense for totally different modes,
581  // but maybe not so obvious for similar modes such as "car" and "ride". kai, jul'18
582  }
583  // the easy way for the route is to not go along the links but just check for overlap.
584  Route route1 = leg1.getRoute();
585  Route route2 = leg2.getRoute();
586  // currently only for network routes:
587  NetworkRoute nr1, nr2;
588  if (route1 instanceof NetworkRoute) {
589  nr1 = (NetworkRoute) route1;
590  } else {
591  simil += sameModeReward;
592  // ("no route" is interpreted as "same route". One reason is that otherwise plans
593  // with routes always receive higher penalties than plans without routes in the diversity
594  // increasing plans remover, which clearly is not what one wants. kai, jul'18)
595  continue; // next leg
596  }
597  if (route2 instanceof NetworkRoute) {
598  nr2 = (NetworkRoute) route2;
599  } else {
600  simil += sameModeReward;
601  continue; // next leg
602  }
603  simil += sameRouteReward * (RouteUtils.calculateCoverage(nr1, nr2, network) + RouteUtils.calculateCoverage(nr2, nr1, network)) / 2;
604  }
605  return simil;
606  }
607 
613  public static double calculateSimilarity(List<Activity> activities1, List<Activity> activities2, double sameActivityTypePenalty,
614  double sameActivityLocationPenalty, double actTimeParameter) {
615  // yyyy should be made configurable somehow (i.e. possibly not a static method any more). kai, apr'15
616 
617  // yy kwa points to:
618  // Schüssler, N. and K.W. Axhausen (2009b) Accounting for similarities in destination choice modelling: A concept, paper presented at the 9th Swiss Transport Research Conference, Ascona, October 2009.
619  // und
620  // Joh, Chang-Hyeon, Theo A. Arentze and Harry J. P. Timmermans (2001).
621  // A Position-Sensitive Sequence Alignment Method Illustrated for Space-Time Activity-Diary Data¹, Environment and Planning A 33(2): 313­338.
622 
623  // Mahdieh Allahviranloo has some work on activity pattern similarity (iatbr'15)
624 
625  double simil = 0.;
626  Iterator<Activity> it1 = activities1.iterator();
627  Iterator<Activity> it2 = activities2.iterator();
628  for (; it1.hasNext() && it2.hasNext(); ) {
629  Activity act1 = it1.next();
630  Activity act2 = it2.next();
631 
632  // activity type
633  if (act1.getType().equals(act2.getType())) {
634  simil += sameActivityTypePenalty;
635  }
636 
637  // activity location
638  if (act1.getCoord().equals(act2.getCoord())) {
639  simil += sameActivityLocationPenalty;
640  }
641 
642  // activity end times
643  if (act1.getEndTime().isUndefined() && act2.getEndTime().isUndefined()) {
644  // both activities have no end time, no need to compute a similarity penalty
645  } else {
646  // both activities have an end time, comparing the end times
647 
648  // 300/ln(2) means a penalty of 0.5 for 300 sec difference
649  double delta = Math.abs(act1.getEndTime().seconds() - act2.getEndTime().seconds());
650  simil += actTimeParameter * Math.exp(-delta / (300 / Math.log(2)));
651  }
652 
653  }
654 
655  // a positive value is interpreted as a penalty
656  return simil;
657  }
658 
671  @Deprecated
672  public static boolean equalPopulation(final Population s1, final Population s2) {
673  try {
674  try (InputStream inputStream1 = openPopulationInputStream(s1); InputStream inputStream2 = openPopulationInputStream(s2)) {
675  return IOUtils.isEqual(inputStream1, inputStream2);
676  }
677  } catch (IOException e) {
678  throw new UncheckedIOException(e);
679  }
680  }
681 
688  private static InputStream openPopulationInputStream(final Population s1) {
689  try {
690  final PipedInputStream in = new PipedInputStream();
691  final PipedOutputStream out = new PipedOutputStream(in);
692  new Thread(new Runnable() {
693  @Override
694  public void run() {
695  final PopulationWriter writer = new PopulationWriter(s1);
696  try {
697  writer.write(out);
698  } catch (UncheckedIOException e) {
699  // Writer will throw an IOException when pipe is closed from the other side (like "broken pipe" in UNIX)
700  // This is expected. Don't even log anything.
701  // Other exceptions (from the Writer) are not caught
702  // but written to the console.
703  }
704  }
705  }).start();
706  return in;
707  } catch (IOException e) {
708  throw new UncheckedIOException(e);
709  }
710  }
711 
713  List<PlanElement> planElements = plan.getPlanElements();
714  int indexOfLastCarLegOfDay = -1;
715  for (int i = planElements.size() - 1; i >= 0; i--) {
716  if (planElements.get(i) instanceof Leg leg) {
717  if (leg.getMode().equalsIgnoreCase(TransportMode.car)) {
718  indexOfLastCarLegOfDay = i;
719  break;
720  }
721 
722  }
723  }
724 
725  for (int i = indexOfLastCarLegOfDay + 1; i < planElements.size(); i++) {
726  if (planElements.get(i) instanceof Activity act) {
727  return act;
728  }
729  }
730  return null;
731  }
732 
734  List<PlanElement> planElements = plan.getPlanElements();
735  int indexOfFirstCarLegOfDay = -1;
736  for (int i = 0; i < planElements.size(); i++) {
737  if (planElements.get(i) instanceof Leg leg) {
738  if (leg.getMode().equalsIgnoreCase(TransportMode.car)) {
739  indexOfFirstCarLegOfDay = i;
740  break;
741  }
742 
743  }
744  }
745  for (int i = indexOfFirstCarLegOfDay - 1; i >= 0; i--) {
746  if (planElements.get(i) instanceof Activity act) {
747  return act;
748  }
749  }
750  return null;
751  }
752 
753  public static boolean hasCarLeg(Plan plan) {
754  List<PlanElement> planElements = plan.getPlanElements();
755  for (int i = 0; i < planElements.size(); i++) {
756  if (planElements.get(i) instanceof Leg leg) {
757  if (leg.getMode().equalsIgnoreCase(TransportMode.car)) {
758  return true;
759  }
760 
761  }
762  }
763  return false;
764  }
765 
766  public static PopulationFactory getFactory() {
767  // to make this private, would have to get rid of things like getFactory().createPerson(..) .
768  // But I am not sure if this really makes a lot of sense, because this static default factory is easier to change into
769  // pop.getFactory() than anothing else. kai, jun'16
770 
771  // Scenario scenario = ScenarioUtils.createScenario( ConfigUtils.createConfig() ) ;
772  // return scenario.getPopulation().getFactory() ;
773  // the above is too slow. kai, jun'16
774 
775  // return new PopulationFactoryImpl( new RouteFactoryImpl() ) ;
776  return populationFactory;
777  }
778 
779  // --- plain factories:
780 
781  public static Plan createPlan(Person person) {
782  Plan plan = getFactory().createPlan();
783  plan.setPerson(person);
784  return plan;
785  }
786 
787  public static Plan createPlan() {
788  return getFactory().createPlan();
789  }
790 
791  public static Activity createActivityFromLinkId(String type, Id<Link> linkId) {
792  return getFactory().createActivityFromLinkId(type, linkId);
793  }
794 
795  public static Activity createInteractionActivityFromLinkId(String type, Id<Link> linkId) {
796  return getFactory().createInteractionActivityFromLinkId(type, linkId);
797  }
798 
799  public static Activity createActivityFromFacilityId(String type, Id<ActivityFacility> facilityId) {
800  return getFactory().createActivityFromActivityFacilityId(type, facilityId);
801  }
802 
805  }
806 
807  public static Activity createActivityFromCoord(String type, Coord coord) {
808  return getFactory().createActivityFromCoord(type, coord);
809  }
810 
811  public static Activity createInteractionActivityFromCoord(String type, Coord coord) {
812  return getFactory().createInteractionActivityFromCoord(type, coord);
813  }
814 
815  public static Activity createActivityFromCoordAndLinkId(String type, Coord coord, Id<Link> linkId) {
816  Activity act = getFactory().createActivityFromCoord(type, coord);
817  act.setLinkId(linkId);
818  return act;
819  }
820 
821  public static Activity createInteractionActivityFromCoordAndLinkId(String type, Coord coord, Id<Link> linkId) {
823  act.setLinkId(linkId);
824  return act;
825  }
826 
828  if (activity instanceof InteractionActivity) {
829  return createActivity(activity);
830  } else {
831  return activity;
832  }
833  }
834 
835  public static Leg createLeg(String transportMode) {
836  return getFactory().createLeg(transportMode);
837  }
838 
839  // createAndAdd methods:
840 
841  public static Activity createAndAddActivityFromFacilityId(Plan plan, String type, Id<ActivityFacility> facilityId) {
842  Activity act = getFactory().createActivityFromActivityFacilityId(type, facilityId);
843  plan.addActivity(act);
844  return act;
845  }
846 
847  public static Activity createAndAddActivityFromCoord(Plan plan, String type, Coord coord) {
848  Activity act = getFactory().createActivityFromCoord(type, coord);
849  plan.addActivity(act);
850  act.setCoord(coord);
851  return act;
852  }
853 
854  public static Activity createAndAddActivityFromLinkId(Plan plan, String type, Id<Link> linkId) {
855  Activity act = getFactory().createActivityFromLinkId(type, linkId);
856  plan.addActivity(act);
857  act.setLinkId(linkId);
858  return act;
859  }
860 
861  public static Leg createAndAddLeg(Plan plan, String mode) {
862  verifyCreateLeg(plan);
863  Leg leg = getFactory().createLeg(mode);
864  plan.addLeg(leg);
865  return leg;
866  }
867 
868  private static void verifyCreateLeg(Plan plan) throws IllegalStateException {
869  if (plan.getPlanElements().size() == 0) {
870  throw new IllegalStateException("The order of 'acts'/'legs' is wrong in some way while trying to create a 'leg'.");
871  }
872  }
873 
874  public static Activity createAndAddActivity(Plan plan, String type) {
875  Activity act = new ActivityImpl(type);
876  // (can't do this from the factory since factory method only exists with coord or with linkId. kai, jun'16)
877  plan.addActivity(act);
878  return act;
879  }
880 
881  public static Activity createStageActivityFromCoordLinkIdAndModePrefix(final Coord interactionCoord, final Id<Link> interactionLink, String modePrefix) {
882  Activity act = createInteractionActivityFromCoordAndLinkId(ScoringConfigGroup.createStageActivityType(modePrefix), interactionCoord, interactionLink);
883 // act.setMaximumDuration(0.0); // obsolete since this is hard-coded in InteractionActivity
884  return act;
885  }
886 
887 
888  // --- static copy methods:
889 
896  public static void copyFromTo(final Plan in, final Plan out) {
897  /*
898  * By default 'false' to be backwards compatible. As a result, InteractionActivities will be converted to ActivityImpl.
899  */
900  copyFromTo(in, out, false);
901  }
902 
903  public static void copyFromTo(final Plan in, final Plan out, final boolean withInteractionActivities) {
904  out.getPlanElements().clear();
905  out.setScore(in.getScore());
906  out.setType(in.getType());
907  for (PlanElement pe : in.getPlanElements()) {
908  if (pe instanceof Activity) {
909  /*
910  * So far, we do not use the check for StageActivityTypeIdentifier.isStageActivity(...). It Would convert ActivityImpl to InteractionActivities.
911  * However, there are pieces of code in use, e.g. in the share mobility contrib, where "interaction activities" need to be modeled as ActivityImpl
912  * since their duration is != 0 or they have a defined start time.
913  */
914  if (withInteractionActivities && (pe instanceof InteractionActivity /* || StageActivityTypeIdentifier.isStageActivity(((Activity) pe).getType())*/)) {
915  out.getPlanElements().add(createInteractionActivity((Activity) pe));
916  } else {
917  out.getPlanElements().add(createActivity((Activity) pe));
918  }
919  } else if (pe instanceof Leg) {
920  out.getPlanElements().add(createLeg((Leg) pe));
921  } else {
922  throw new IllegalArgumentException("unrecognized plan element type discovered");
923  }
924  }
926  }
927 
928  public static void copyFromTo(Leg in, Leg out) {
929  out.setMode(in.getMode());
931  in.getDepartureTime().ifDefinedOrElse(out::setDepartureTime, out::setDepartureTimeUndefined);
932  in.getTravelTime().ifDefinedOrElse(out::setTravelTime, out::setTravelTimeUndefined);
933  if (in.getRoute() != null) {
934  out.setRoute(in.getRoute().clone());
935  }
937  }
938 
939  public static void copyFromTo(Activity act, Activity newAct) {
940  Coord coord = act.getCoord() == null ? null : new Coord(act.getCoord().getX(), act.getCoord().getY());
941  // (we don't want to copy the coord ref, but rather the contents!)
942  newAct.setCoord(coord);
943  newAct.setType(act.getType());
944  newAct.setLinkId(act.getLinkId());
945  act.getStartTime().ifDefinedOrElse(newAct::setStartTime, newAct::setStartTimeUndefined);
946  act.getEndTime().ifDefinedOrElse(newAct::setEndTime, newAct::setEndTimeUndefined);
947  act.getMaximumDuration().ifDefinedOrElse(newAct::setMaximumDuration, newAct::setMaximumDurationUndefined);
948  newAct.setFacilityId(act.getFacilityId());
949 
951  }
952 
953  // --- copy factories:
954 
955  public static Activity createActivity(Activity act) {
957 
958  copyFromTo(act, newAct);
959  // (this ends up setting type and linkId again)
960 
961  return newAct;
962  }
963 
966 
967  copyFromTo(act, newAct);
968  // (this ends up setting type and linkId again)
969 
970  return newAct;
971  }
972 
983  public static Leg createLeg(Leg leg) {
984  Leg newLeg = createLeg(leg.getMode());
985 
986  copyFromTo(leg, newLeg);
987  // (this ends up setting mode again)
988 
989  return newLeg;
990  }
991 
992  // --- positional methods:
993 
994  public static Activity getFirstActivity(Plan plan) {
995  return (Activity) plan.getPlanElements().get(0);
996  }
997 
998  public static Activity getLastActivity(Plan plan) {
999  return (Activity) plan.getPlanElements().get(plan.getPlanElements().size() - 1);
1000  }
1001 
1002  public static Activity getNextActivity(Plan plan, Leg leg) {
1003  int index = getActLegIndex(plan, leg);
1004  if (index != -1) {
1005  return (Activity) plan.getPlanElements().get(index + 1);
1006  }
1007  return null;
1008  }
1009 
1010  public static int getActLegIndex(Plan plan, PlanElement pe) {
1011  if ((pe instanceof Leg) || (pe instanceof Activity)) {
1012  for (int i = 0; i < plan.getPlanElements().size(); i++) {
1013  if (plan.getPlanElements().get(i).equals(pe)) {
1014  return i;
1015  }
1016  }
1017  return -1;
1018  }
1019  throw new IllegalArgumentException("Method call only valid with a Leg or Act instance as parameter!");
1020  }
1021 
1022  public static Leg getNextLeg(Plan plan, Activity act) {
1023  int index = PopulationUtils.getActLegIndex(plan, act);
1024  if ((index < plan.getPlanElements().size() - 1) && (index != -1)) {
1025  return (Leg) plan.getPlanElements().get(index + 1);
1026  }
1027  return null;
1028  }
1029 
1030  public static Activity getPreviousActivity(Plan plan, Leg leg) {
1031  int index = PopulationUtils.getActLegIndex(plan, leg);
1032  if (index != -1) {
1033  return (Activity) plan.getPlanElements().get(index - 1);
1034  }
1035  return null;
1036  }
1037 
1038  public static Leg getPreviousLeg(Plan plan, Activity act) {
1039  int index = PopulationUtils.getActLegIndex(plan, act);
1040  if (index != -1) {
1041  return (Leg) plan.getPlanElements().get(index - 1);
1042  }
1043  return null;
1044  }
1045 
1046  // --- remove methods:
1047 
1054  public static void removeLeg(Plan plan, int index) {
1055  if ((index % 2 == 0) || (index < 1) || (index >= plan.getPlanElements().size() - 1)) {
1056  log.warn(plan + "[index=" + index + " is wrong. nothing removed]");
1057  } else {
1058  if (index != plan.getPlanElements().size() - 2) {
1059  // not the last leg
1060  Leg next_leg = (Leg) plan.getPlanElements().get(index + 2);
1061  next_leg.setDepartureTimeUndefined();
1062  next_leg.setTravelTimeUndefined();
1063  next_leg.setRoute(null);
1064  }
1065  plan.getPlanElements().remove(index + 1); // following act
1066  plan.getPlanElements().remove(index); // leg
1067  }
1068 
1069  }
1070 
1071  public static void removeActivity(Plan plan, int index) {
1072  if ((index % 2 != 0) || (index < 0) || (index > plan.getPlanElements().size() - 1)) {
1073  log.warn(plan + "[index=" + index + " is wrong. nothing removed]");
1074  } else if (plan.getPlanElements().size() == 1) {
1075  log.warn(plan + "[index=" + index + " only one act. nothing removed]");
1076  } else {
1077  if (index == 0) {
1078  // remove first act and first leg
1079  plan.getPlanElements().remove(index + 1); // following leg
1080  plan.getPlanElements().remove(index); // act
1081  } else if (index == plan.getPlanElements().size() - 1) {
1082  // remove last act and last leg
1083  plan.getPlanElements().remove(index); // act
1084  plan.getPlanElements().remove(index - 1); // previous leg
1085  } else {
1086  // remove an in-between act
1087  Leg prev_leg = (Leg) plan.getPlanElements().get(index - 1); // prev leg;
1088  prev_leg.setDepartureTimeUndefined();
1089  prev_leg.setTravelTimeUndefined();
1090  prev_leg.setRoute(null);
1091 
1092  plan.getPlanElements().remove(index + 1); // following leg
1093  plan.getPlanElements().remove(index); // act
1094  }
1095  }
1096  }
1097 
1098  // --- insert method(s):
1099 
1108  public static void insertLegAct(Plan plan, int pos, Leg leg, Activity act) {
1109  if (pos < plan.getPlanElements().size()) {
1110  Object o = plan.getPlanElements().get(pos);
1111  if (!(o instanceof Leg)) {
1112  throw new IllegalArgumentException("Position to insert leg and act is not valid (act instead of leg at position).");
1113  }
1114  } else if (pos > plan.getPlanElements().size()) {
1115  throw new IllegalArgumentException("Position to insert leg and act is not valid.");
1116  }
1117  plan.getPlanElements().add(pos, act);
1118  plan.getPlanElements().add(pos, leg);
1119  }
1120 
1121  public static void changePersonId(Person person, Id<Person> id) {
1122  if (person instanceof PersonImpl) {
1123  ((PersonImpl) person).changeId(id);
1124  } else {
1125  throw new RuntimeException("wrong implementation of interface Person");
1126  }
1127  }
1128 
1129  public static void printPlansCount(Population population) {
1130  log.info(" person # " + population.getPersons().size());
1131  }
1132 
1133  public static void printPlansCount(StreamingPopulationReader reader) {
1134  reader.printPlansCount();
1135  }
1136 
1137  public static void writePopulation(Population population, String filename) {
1138  new PopulationWriter(population).write(filename);
1139  }
1140 
1142  if (act.getFacilityId() != null) {
1143  final ActivityFacility facility = sc.getActivityFacilities().getFacilities().get(act.getFacilityId());
1144  if (facility == null) {
1145  throw new RuntimeException("facility ID given but not in facilities container");
1146  }
1147  Gbl.assertNotNull(facility.getLinkId());
1148  return facility.getLinkId();
1149  }
1150  Gbl.assertNotNull(act.getLinkId());
1151  return act.getLinkId();
1152  }
1153 
1155  Id<ActivityFacility> facilityId;
1156  try {
1157  facilityId = act.getFacilityId();
1158  } catch (Exception ee) {
1159  facilityId = null;
1160  }
1161  // some people prefer throwing exceptions over using null
1162 
1163  if (facilityId != null) {
1164  final ActivityFacility facility = sc.getActivityFacilities().getFacilities().get(facilityId);
1165  Gbl.assertNotNull(facility);
1166  Gbl.assertNotNull(facility.getCoord());
1167  return facility.getCoord();
1168  }
1169 
1170  if (act.getCoord() != null) {
1171  return act.getCoord();
1172  }
1173 
1175  Link link = sc.getNetwork().getLinks().get(act.getLinkId());
1176  Gbl.assertNotNull(link);
1177  Coord fromCoord = link.getFromNode().getCoord();
1178  Coord toCoord = link.getToNode().getCoord();
1180  return new Coord(fromCoord.getX() + rel * (toCoord.getX() - fromCoord.getX()), fromCoord.getY() + rel * (toCoord.getY() - fromCoord.getY()));
1181  }
1182 
1183  public static void sampleDown(Population pop, double sample) {
1184  final Random rnd = MatsimRandom.getLocalInstance();
1185  log.info("population size before downsampling=" + pop.getPersons().size());
1186  pop.getPersons().values().removeIf(person -> rnd.nextDouble() >= sample);
1187  log.info("population size after downsampling=" + pop.getPersons().size());
1188  }
1189 
1190  public static void readPopulation(Population population, String filename) {
1192  scenario.setPopulation(population);
1193  new PopulationReader(scenario).readFile(filename);
1194  // (yyyy population reader uses network to retrofit some missing geo information such as route lenth.
1195  // In my opinion, that should be done in prepareForSim, not in the parser. It is commented as such
1196  // in the PopulationReader class. kai, nov'18)
1197  }
1198 
1199  public static Population readPopulation(String filename) {
1201  readPopulation(population, filename);
1202  return population;
1203  }
1204 
1208  @Deprecated
1209  public static boolean comparePopulations(Population population1, Population population2) {
1210  return PopulationUtils.equalPopulation(population1, population2);
1211  }
1212 
1213  // ---
1214 
1218  public static Object getPersonAttribute(HasPlansAndId<?, ?> person, String key) {
1219  if (person == null) {
1220  return null;
1221  }
1222  // (This was originally "if person instanceof Attributable then ...". Since HasPlansAndId now implements Attributable, this is in
1223  // principle always fulfilled. However, if person==null, then person instanceof Attributable also fails. kai, jul'22)
1224 
1225  return person.getAttributes().getAttribute(key);
1226  }
1227 
1231  public static void putPersonAttribute(HasPlansAndId<?, ?> person, String key, Object value) {
1232  person.getAttributes().putAttribute(key, value);
1233  }
1234 
1238  public static Object removePersonAttribute(Person person, String key) {
1239  return person.getAttributes().removeAttribute(key);
1240  }
1241 
1245  public static void removePersonAttributes(Person person, Population population) {
1246  //population.getPersonAttributes().removeAllAttributesDirectly( person.getId().toString() );
1247  person.getAttributes().clear();
1248  }
1249 
1250  public static String getSubpopulation(HasPlansAndId<?, ?> person) {
1251  if (person == null) {
1252  return null;
1253  }
1254  // (This originally delegated to getPersonAttribute. See comment there. kai, jul'22)
1255 
1256  return (String) person.getAttributes().getAttribute(SUBPOPULATION_ATTRIBUTE_NAME);
1257  }
1258 
1259  public static void putSubpopulation(HasPlansAndId<?, ?> person, String subpopulation) {
1260  putPersonAttribute(person, SUBPOPULATION_ATTRIBUTE_NAME, subpopulation);
1261  }
1262 
1263  public static void removeSubpopulation(Person person) {
1264  person.getAttributes().removeAttribute(SUBPOPULATION_ATTRIBUTE_NAME);
1265  }
1266 
1267  public static Population getOrCreateAllpersons(Scenario scenario) {
1268  Population map = (Population) scenario.getScenarioElement("allpersons");
1269  if (map == null) {
1270  log.info("adding scenario element for allpersons container");
1271  map = new PopulationImpl(scenario.getPopulation().getFactory());
1272  scenario.addScenarioElement("allpersons", map);
1273  }
1274  return map;
1275  }
1276 
1277  private static int tryStdCnt = 5;
1278 
1279  public static Person findPerson(Id<Person> personId, Scenario scenario) {
1280  Person person = getOrCreateAllpersons(scenario).getPersons().get(personId);
1281  if (person == null) {
1282  if (tryStdCnt > 0) {
1283  tryStdCnt--;
1284  log.info("personId=" + personId + " not in allPersons; trying standard population container ...");
1285  if (tryStdCnt == 0) {
1286  log.info(Gbl.FUTURE_SUPPRESSED);
1287  }
1288  }
1289  person = scenario.getPopulation().getPersons().get(personId);
1290  }
1291  if (person == null) {
1292  log.info("unable to find person for personId=" + personId + "; will return null");
1293  }
1294  return person;
1295  }
1296 
1302  public static void insertVehicleTypesIntoPersonAttributes(Person person, Map<String, Id<VehicleType>> modeToVehicleType) {
1303  VehicleUtils.insertVehicleTypesIntoPersonAttributes(person, modeToVehicleType);
1304  }
1305 
1314  public static void insertVehicleIdsIntoPersonAttributes(Person person, Map<String, Id<Vehicle>> modeToVehicle) {
1315  VehicleUtils.insertVehicleIdsIntoPersonAttributes(person, modeToVehicle);
1316  }
1317 
1325  public static void checkRouteModeAndReset(Population population, Network network) {
1326  PersonRouteCheck personRouteChecker = new PersonRouteCheck(network);
1327  population.getPersons().values().forEach(
1328  personRouteChecker::run
1329  );
1330  }
1331 }
static Activity createAndAddActivity(Plan plan, String type)
Map< Id< ActivityFacility >, ? extends ActivityFacility > getFacilities()
static void removeSubpopulation(Person person)
static Activity getPreviousActivity(Plan plan, Leg leg)
Activity createActivityFromActivityFacilityId(String actType, Id< ActivityFacility > activityFacilityId)
static Activity createActivityFromCoord(String type, Coord coord)
static Activity createInteractionActivity(Activity act)
static boolean isEqual(InputStream first, InputStream second)
Definition: IOUtils.java:474
static Activity getNextActivity(Plan plan, Leg leg)
static final PopulationFactory populationFactory
static void assertIf(boolean flag)
Definition: Gbl.java:207
static void insertVehicleTypesIntoPersonAttributes(Person person, Map< String, Id< VehicleType >> modeToVehicleType)
Map< String, Object > getCustomAttributes()
static boolean equalPopulation(final Population s1, final Population s2)
void ifDefinedOrElse(DoubleConsumer action, Runnable undefinedAction)
void setRouteFactory(final Class<? extends Route > routeClass, final RouteFactory factory)
static void insertLegAct(Plan plan, int pos, Leg leg, Activity act)
static void removePersonAttributes(Person person, Population population)
static boolean comparePopulations(Population population1, Population population2)
static void printPlansCount(StreamingPopulationReader reader)
static Population readPopulation(String filename)
static Activity getFirstActivityAfterLastCarLegOfDay(Plan plan)
static List< Activity > getActivities(final Plan plan, final StageActivityHandling stageActivityHandling)
static void removeActivity(Plan plan, int index)
static Activity createAndAddActivityFromCoord(Plan plan, String type, Coord coord)
void addScenarioElement(String name, Object o)
static Person findPerson(Id< Person > personId, Scenario scenario)
Activity createActivityFromLinkId(String actType, Id< Link > linkId)
static Object removePersonAttribute(Person person, String key)
static Coord computeCoordFromActivity(Activity act, ActivityFacilities facs, Config config)
static void insertVehicleIdsIntoPersonAttributes(Person person, Map< String, Id< Vehicle >> modeToVehicle)
static< T extends Attributable > void copyAttributesFromTo(T from, T to)
static Activity createActivityFromLinkId(String type, Id< Link > linkId)
static Activity createInteractionActivityFromCoordAndLinkId(String type, Coord coord, Id< Link > linkId)
final void setPopulation(Population population)
static Activity createAndAddActivityFromFacilityId(Plan plan, String type, Id< ActivityFacility > facilityId)
static int getActLegIndex(Plan plan, PlanElement pe)
static Activity convertInteractionToStandardActivity(Activity activity)
static MutableScenario createMutableScenario(final Config config)
static void copyFromTo(Activity act, Activity newAct)
static void changePersonId(Person person, Id< Person > id)
static Population createPopulation(PlansConfigGroup plansConfigGroup, Network network)
static final String FUTURE_SUPPRESSED
Definition: Gbl.java:44
Map< Id< Person >,? extends Person > getPersons()
Object getScenarioElement(String name)
static Leg createAndAddLeg(Plan plan, String mode)
static Id< Link > computeLinkIdFromActivity(Activity act, ActivityFacilities facs, Config config)
static void removeLeg(Plan plan, int index)
Activity createInteractionActivityFromActivityFacilityId(String actType, Id< ActivityFacility > activityFacilityId)
static void putPersonAttribute(HasPlansAndId<?, ?> person, String key, Object value)
static Leg getNextLeg(Plan plan, Activity act)
static void insertVehicleTypesIntoPersonAttributes(Person person, Map< String, Id< VehicleType >> modeToVehicleType)
static Activity createInteractionActivityFromCoord(String type, Coord coord)
static void copyFromTo(final Plan in, final Plan out)
static double calculateSimilarity(List< Activity > activities1, List< Activity > activities2, double sameActivityTypePenalty, double sameActivityLocationPenalty, double actTimeParameter)
static void setRoutingMode(Leg leg, String mode)
static Activity createActivityFromFacilityId(String type, Id< ActivityFacility > facilityId)
static void printPlansCount(Population population)
static Activity createInteractionActivityFromFacilityId(String type, Id< ActivityFacility > facilityId)
static Object getPersonAttribute(HasPlansAndId<?, ?> person, String key)
static void insertVehicleIdsIntoPersonAttributes(Person person, Map< String, Id< Vehicle >> modeToVehicle)
static Population createPopulation(Config config)
static String getSubpopulation(HasPlansAndId<?, ?> person)
static InputStream openPopulationInputStream(final Population s1)
static Population getOrCreateAllpersons(Scenario scenario)
static void sampleDown(Population pop, double sample)
void addActivity(final Activity act)
static Leg createLeg(String transportMode)
List< PlanElement > getPlanElements()
static double calculateSimilarity(List< Leg > legs1, List< Leg > legs2, Network network, double sameModeReward, double sameRouteReward)
final PlansConfigGroup plans()
Definition: Config.java:415
static void readPopulation(Population population, String filename)
boolean equals(final Object other)
Definition: Coord.java:107
static SortedMap< Id< Person >, Person > getSortedPersons(final Population population)
static void assertNotNull(Object obj)
Definition: Gbl.java:212
static Population createPopulation(Config config, Network network)
Activity createInteractionActivityFromCoord(String actType, Coord coord)
static void copyFromTo(final Plan in, final Plan out, final boolean withInteractionActivities)
Map< Id< Link >, ? extends Link > getLinks()
static Activity createInteractionActivityFromLinkId(String type, Id< Link > linkId)
static Activity createActivityFromCoordAndLinkId(String type, Coord coord, Id< Link > linkId)
static void checkRouteModeAndReset(Population population, Network network)
static Id< Link > decideOnLinkIdForActivity(Activity act, Scenario sc)
static List< Activity > getActivities(Plan plan, StageActivityHandling stageActivityHandling)
Id< ActivityFacility > getFacilityId()
static Activity createAndAddActivityFromLinkId(Plan plan, String type, Id< Link > linkId)
static Coord computeCoordFromActivity(Activity act, ActivityFacilities facs, Network network, Config config)
final void readFile(final String filename)
Activity createActivityFromCoord(String actType, Coord coord)
ActivityFacilities getActivityFacilities()
static Coord decideOnCoordForActivity(Activity act, Scenario sc)
static void putSubpopulation(HasPlansAndId<?, ?> person, String subpopulation)
Activity createInteractionActivityFromLinkId(String actType, Id< Link > linkId)
static Activity createActivity(Activity act)
static double calculateCoverage(NetworkRoute route1, NetworkRoute route2, Network network)
static Leg getPreviousLeg(Plan plan, Activity act)
static Activity createStageActivityFromCoordLinkIdAndModePrefix(final Coord interactionCoord, final Id< Link > interactionLink, String modePrefix)
static Activity getFirstActivityOfDayBeforeDepartingWithCar(Plan plan)
void setFacilityId(final Id< ActivityFacility > id)
final GlobalConfigGroup global()
Definition: Config.java:395
static List< Leg > getLegs(final Plan plan)
static void writePopulation(Population population, String filename)
static void sortPersons(final Population population)
static Activity unmodifiableActivity(Activity act)
static Config createConfig(final String context)
static void resetRoutes(final Plan plan)