Case 4: Events

Events are a central concept in MATSim, as they are the only way for feedback from the mobility simulation to the behavioral modules.

Event Types

Event Overview and Order

Overview graphic not available

Event types and order in which they are thrown.

Event Types

The following types of events are currently supported and should be generated by a mobility simulation:

id name data description
0 arrival time, agent-id, link-id An agent arrives at a link at the specified time
2 left link time, agent-id, link-id An agent leaves a link at the specified time. This builds a group together with 5-entered link. An agent moves through the network by entering and leaving link until it reaches its destination link.
3 stuckAndAbort time, agent-id Used for deadlock-prevention. If a deadlock occurs at some place, we solve it be removing some "stuck" agents, aborting them, such that other agents can continue.
4 wait2link time, agent-id After an agent departs, it must wait until it finds a space to enter the road. This is the moment the agent really enters the road. Often at the same time as 6-departure, but not always.
5 entered link time, agent-id, link-id Issued if an agent crosses a node (see 2-left link)
6 departure time, agent-id, link-id when an agent departs at a location
7 actstart time, agent-id, link-id, act-type when an agent starts performing an activity
8 actend time, agent-id, link-id, act-type when an agent ends performing an activity
9 agentMoney time, agent-id, amount an agent earns some amount of money (e.g. -5 if it has to pay a toll)

The following example shows the events of one agent, starting at home and driving to work:

T_GBL   VEH_ID  LEG_NR  LINK_ID FROM_NODE_ID    EVENT_FLAG      DESCRIPTION
21610   1       0       1       0               8               actend home
21610   1       0       1       0               6               departure
21612   1       0       1       0               4               wait2link
21640   1       0       1       0               2               left link
21640   1       0       2       0               5               entered link
21740   1       0       2       0               2               left link
21740   1       0       3       0               5               entered link
21820   1       0       3       0               2               left link
21820   1       0       4       0               5               entered link
21890   1       0       4       0               0               arrival
21890   1       0       4       0               7               actstart work

 

Generating Events

Some remarks about generating events, e.g. in a custom traffic simulation:

  • Events must be in the correct temporal order per agent, but not globally.
    An event e1 at time t1 of agent a1 must not be created after an event e2 at time t2 of the same agent a1 if t1 < t2. However, an event e3 at time t3 of agent a2 can be created after e1, even if t3 < t1. It is still good practice to ensure that all events are chronologically ordered.

Handling Events

All events, that were issued in a simulation-run, should be passed along to an instance of the class org.matsim.evens.Events. This is done by creating a new event and then calling computeEvent() method of your instance of Events.

Example:

Events myEventManager = new Events();
EventLinkEnter test = new EventLinkEnter(time,  agentId,  linkId);
Events.computeEvent(test);

The Events instance will then take the event and forward it to every EventHandler, that wants to receive events of this kind.

To receive events out of the simulation, you have to write your own event-handler as described below.

Building an event handler

Building a new eventhandler that uses already existing events

If you just want to receive any of the already defined events, it is an easy task:

  1. Simlpy write your own EventHandler class, that implements every EventHandler...I interface that you want to get to know about.
  2. Then you have to make a new instance of your handler-class and add it to your Events instance by using Events.addHandler(EventHandlerI handler).
  3. We are ready now, Events will call your EventHandler for every event that he listenes to.

Hazard: Be aware, that if you overload some special EventHandler ...I interfaces and the BasicEventHandlerI than the special interfaces will receive the appropriate events and the handleEvent(BasicEvent event) receives the SAME event a second time. This will get optionally in a later verion.

Remark: Instead of overloading several EventHandler...I interfaces it sometimes might be easier just to overload BasicEventHandlerI and to check the events in an if clause like this:

if(event.getClass() == EventAgentNoRoute.class)  {
  ...
} else if(event.getClass() == EventAgentArrival.class)  {
  ...
} else if(event.getClass() == EventLinkLeft.class)  {
  ...
}

Example:

 

class CountLinkTravelTimes implements
        EventLinkEnterHandlerI,
        EventHandlerLinkLeft {
  public void handleEvent (EventLinkEnter event) {
    ...
    id = event.linkId; // do something with it
    ...
  }
  public void handleEvent (EventLinkLeft event) {
    ...
    id = event.linkId; // do something with it
    ...
  }
}
...
Events myevent = new Events();
CountLinkTravelTimes myhandler = new CountLinkTravelTimes();
myevents.addHandler(myhandler);
EventLinkEnter test = new EventLinkEnter(time,  agentId,  linkId);
Events.computeEvent(test);

Building your own specialized event

Building your own specialized event based on an existing event:

Now we have to additionally define a specialized event class, let's say

class EventAgentStuckAndReplanning extends EventAgentStuck {
  private double replanning_probability;
  // some other special things...
}

Now we are ready to receive this Event from all EventHandlerAgentStuckI! We can check for this special event by the means of

if(event.getClass() == EventAgentStuckAndReplanning.class) {...}

If for some reasons we want to write a handler that only receives this special Event StuckAndReplanning, we would have to add a new interface that extends EventHandlerI

e.g.

public interface  EventHandlerAgentSuckAndReplanningI extends EventHandlerI {
  handleEvent(EventAgentSutckAndReplanning event);
}

and ready you are... just implement that interface in your Handler and the handler will start receiveing only the appropriate events!

Building your own specialized event based on nothing at all:

It is simply as above, only that you inherit from BasicEvent. All Events should inherit from BasicEvent, which only defines, that there has to be a time and an agentId. One might think of events that don't even have an agentId, maybe you would leave this field blank (e.g. Integer.MIN_VALUE) or whatever. We included agentId into BasicEvent as the wast majority of events will need an agentID.

Event Types - Future

This article is work-in-progress!

The current event types are less and less suited for describing the simulation output. Especially when activities take place in facilities (instead of links as now) and when public transport is included in the simulation, new event types have to be introduced. This page proposes a new set of events that should be suitable for the future development of MATSim.

Key Concepts of New Events

One of the main concepts are the differentiation between Persons and Vehicles. Persons are part of the population/scenario, specified in the plans/population-file. Vehicles are created (at the moment) within the simulation. The simulation only moves vehicles, never persons. Pedestrians should thus to be enclosed into a "Pedestrian-Vehicle".

Proposed Events

Event Name Attributes Notes
EndActivity person, facility, actType  
EnterVehicle person, vehicle, facility  
DepartureAtFacility vehicle, facitlity  
FacilityToLink vehicle, link  
LinkToIntersection vehicle, link  
IntersectionToLink vehicle, link  
LinkToFacility vehicle, link  
ArrivalAtFacility vehicle, facility  
LeaveVehicle person, vehicle, facility  
StartActivity person, facility, actType  
VehicleStuck vehicle, link  

 

File Format: TXT

The TXT format is the currently most used file format for storing events. It consists of a plain text file with the following header:

T_GBL   VEH_ID  LEG_NR  LINK_ID   FROM_NODE_ID    EVENT_FLAG      DESCRIPTION
  • T_GBL is the time of the event, in seconds after midnight
  • VEH_ID corresponds to the agent-id (there's no such thing like a vehicle-id yet!)
  • LEG_NR unused, set to 0
  • LINK_ID the link of the id the event took place. If not used, set to 0
  • FROM_NODE_ID unused, to to 0
  • EVENT_FLAG the id of the event-type (see Event Types)
  • DESCRIPTION unused, usually set to the name of the event-type (see Event Types)

The fields are separated with tabs. Make sure to also include a tab between EVENT_FLAG and DESCRIPTION, even if the DESCRIPTION is empty!

The following is an example, how an event-file could look like:

T_GBL   VEH_ID  LEG_NR  LINK_ID  FROM_NODE_ID    EVENT_FLAG      DESCRIPTION
21610   1       0       2        0               8               actend h
21620   2       0       3        0               6               departure
21630   3       0       4        0               4               wait2link
21640   4       0       5        0               2               left link
21650   5       0       6        0               5               entered link
21660   6       0       7        0               0               arrival
21670   7       0       8        0               7               actstart w
21680   8       0       9        0               3               stuckAndAbort

 

Parallel Event Handling

When running a MATSim simulation, unused cores can be utilized to make the simulation faster. The event handler which is used by default, is running in the same thread as the simulation. For this reason, the presented 'parallelEventHandling' module can make your simulation much faster.

How to use the 'parallelEventHandling' Module

Parallel event handling can be turned on by inserting the follwing module into the config XML file of MATSim:

<module name="parallelEventHandling">
    <param name="numberOfThreads" value="1" />
</module>

The only required parameter in this module is 'numberOfThreads'. The value of this parameter specifies, how many threads (cores) should be assigned to handling events.

There is an additional optional parameter 'estimatedNumberOfEvents', which can be optimized to your simulation resulting in slightly faster runs. But its usage requires an estimate of the number of events which will occur in one iteration.

<param name="estimatedNumberOfEvents" value="5000000" />

Hints and Pitfalls

  • Don't make any  assumptions on the order, in which the handlers are executed (as they are executed in parallel).
  • Don't write the data in one handler and read that data in a different handler. Although this is possible, special care is required as synchronization between threads is needed for this. Furthermore this could lead to a degradation of the speed up.
  • There is no point in using parallel event handling, if you have just one core available on your machine.
  • Always make sure, that one thread is needed for the single cpu simulation. This means, if you have 4 cores, you can set the parameter 'numberOfThreads' to maximum 3.
  • If 2 handlers have been added to the simulation, then there is no point in assigning 3 threads to parameter ''numberOfThreads', because it won't make the simulation faster (but rather could slow it down in some cases).
  • The number of handlers can be bigger than 'numberOfThreads'. In this case automatically if possible, each thread is assigned the same number of handlers. 
  • If the simulation is quite slow (compared to event handling), you won't be able to make full use of parallel event handling.

The actual speed up you get depends on many factors, especially on those mentioned in 'hints and pitfalls'. Experiments on a 16 core machine with different numbers of handlers have shown that the parallel event handler can reduce the simulation time with a very low overhead.

Further Reading

Some Java specific implementation aspects of JDEQSim and parallelEventHandling are described in the following paper:

Waraich, R.,  D. Charypar, M. Balmer and K.W. Axhausen (2009) Performance improvements for large scale traffic simulation in MATSim, paper presented at the 9th Swiss Transport Research Conference, Ascona, September 2009. Download from here.

 

 

 

 

File Format: XML

Description of the data-format to write (and read) Matsim-Events

Events should be stored in XML-Files.

There is no DTD for Events because each event could use other attributes as needed. As long as it is not possible to defined something like "free additional attributes" for tags in DTD, there will be no DTD for events.xml. Therefore, the events-fileformat ist very simple to reduce the possibility of errors.

The file contains:

  • xml-Header
  • root-tag <events>
  • <event>-tags with only attributes, otherwise empty (<event> is a leaf in the xml/dom-tree)

event-attributes:

The following attributes are required:

  • time, in seconds past midnight
  • type, an identifying string, see also Events

Most events will also have the following attributes:

  • agent, the ID of an agent
  • link, the ID of a link in the network

Additional event-types may define additional attributes.

Example of an events.xml-file:

<?xml version="1.0" encoding="utf-8"?>
<events xml:lang="de-CH">
<event time="21600" type="departure" agent="759062" link="47" /> <!-- time: 06:00, in seconds -->
<event time="22980" type="arrival" agent="759062" link="122" /> <!-- time: 06:23 -->
<event time="21720" type="departure" agent="966916" link="25" />
<event time="22865" type="arrival" agent="966916" link="312" />
</events>

Additional event-attributes:

  • "activity", the number of the activity starting with0
  • "act_type", the type of the activity, e.g. "home", "work"
  • "leg", the leg number starting with 0

Warning: Table 'watchdog' is read only query: INSERT INTO watchdog (uid, type, message, severity, link, location, referer, hostname, timestamp) VALUES (0, 'php', '<em>Table &amp;#039;sessions&amp;#039; is read only\nquery: UPDATE sessions SET uid = 0, cache = 0, hostname = &amp;#039;38.107.179.232&amp;#039;, session = &amp;#039;&amp;#039;, timestamp = 1328356856 WHERE sid = &amp;#039;e972b2ab7dd755a2094beea8ac708f02&amp;#039;</em> in <em>/home01/vsp_access/matsimwww/includes/database.mysql.inc</em> on line <em>174</em>.', 2, '', 'http://matsim.org/book/export/html/17', '', '38.107.179.232', 1328356856) in /home01/vsp_access/matsimwww/includes/database.mysql.inc on line 174