The developer guide
Choose a topic of interest to read more:
In addition to the resources listed below, the Downloads page also includes important information about getting the source code of MATSim.
Most people will only need the information in "Using Eclipse".
You must have the following software installed and ready to use:
The following steps were tested with the following combination of tools: Java 1.6 Update 15, Eclipse 3.6 SR 1, Subclipse 1.6.2, M2Eclipse 0.12.0.
The main MATSim project includes the API and core implementation of MATSim. It includes everything to start with the basic functionality offered by MATSim and is required in any case.
https://matsim.svn.sourceforge.net/svnroot/matsim". If it does not yet exist, create it.matsim/trunk" and click "next".

The project will be checked out, which may take some minutes. The status of the checkout can be observed in the Progress-View of Eclipse.
After the project appears in Eclipse:
This will convert your project into a Maven/Java project. The first time, Maven may download some required dependencies which can take some minutes. Progress can be observed in the Maven Console View. After that, the project is ready to use.
The "Contributions" provide stable extensions provided by different developers. Some specialized features are not available in the main MATSim project, but must be loaded separately from the contributions.
To check out the contributions, proceed as for the main MATSim project, but this time select the folder "contrib/trunk".

Choose again "Check out as a project in the workspace" and name it "contrib".
After the checkout has finished, right-click on the project and choose "Maven > Enable Dependency Management". After this, materialize the contributions into own projects, i.e. each contribution should become a separate project in Eclipse (at the time of this writing, there is only one contribution named "sna"). To do this, follow these hints.
The "Playgrounds" provide a place for experimental, often unstable code, for each developer. You should only add the Playgrounds to Eclipse if you plan to develop code for MATSim yourself.
Proceed as for the main MATSim project (or for the contributions), but this time select the folder "playgrounds/trunk" to check out and name the project "playgrounds". After the checkout, enable the Maven Dependency Management and materialize the different playgrounds into separate projects. At the time of this writing, there are about 40 playgrounds, so you should see like 40 additional projects in eclipse.
As each contribution and each playground is a separate project in Eclipse, you may end up with quite a large number of projects in Eclipse you likely will not use much (e.g. the playgrounds of other people). While you could remove those projects, it may be better to just close them if you do not need them. Also, to gain some better overview, you can e.g. create a Working set that contains all the playgrounds.
To do this, select menu "File > New > Other ... > Java > Java Working Set".
Name it "matsim-playgrounds", and all the playground projects to it.
After that, in the Package Explorer, click the little triangle in the upper right and select "Top Level Elements > Working Sets".
Now you can easily hide all the many projects so they do not clutter your view.
In the end, you should have the following projects in Eclipse:
matsimcontrib (only if you checked out the contributions)playgrounds (only if you checked out the playgrounds)To use the OTFVis visualizer, one has to configure the path to the native libraries. To do so, go the the Java Build Path settings of the main MATSim project and set the "Native library location" within the Maven Dependencies to the correct directory according to your operating systems. The native libraries are located in libs/jogl-1.1.1/<system-dependent>/lib.

If you get a warning about Eclipse and JDK, you need to configure Eclipse to use a JDK.
Since Eclipse 3.5 it may happen that the code does not compile, even if everything is correctly set up, with the following error message:
Access restriction: The type <<some class name>> is not accessible due to restriction on required library <<some jar file on your system>>
In that case, go to Project Properties, Java Build Path, Libraries. Make sure that the Java version you use is not set to an "Execution environment", but to an "Alternate JRE". After that, the project should compile. It looks like the Eclipse compiler is overly strict when set to an execution environment, forbidding the access to classes that may not be available on all Java installations, but actually are on all major distributions. [Source]

Please note that the way how to install plugins differs from each version of Eclipse to the next one. The following description is for Eclipse 3.5.
http://m2eclipse.sonatype.org/sites/m2e
To make sure the plugin was correctly installed, create a new project using menu "File > New > Project...". There should be a new section "Maven" with several options in it to create Projects based on Maven. Select the option "New Maven Project" and click "Next".
If a warning appears "Maven Integration for Eclipse JDK Warning", you have to configure Eclipse to run on a JDK.
If no warning appears, you're installation/configuration should be complete.
Click "Cancel" to leave the "New Maven Project" dialog.
Please note that the way how to install plugins differs from each version of Eclipse to the next one. The following description is for Eclipse 3.5 - 4.2. See http://subclipse.tigris.org/servlets/ProjectProcess?pageID=p4wYuA for more detailed information by the plugin provider.
http://subclipse.tigris.org/update_1.6.xhttp://subclipse.tigris.org/update_1.8.x
To verify that the integration works, try the following steps:
https://matsim.svn.sourceforge.net/svnroot/matsimmatsim/trunk.
While Subclipse includes everything it needs to run on Windows 32-bit, it has some additional dependencies on Linux and Mac OS X. Especially, Subclipse requires that you have the correct version of Subversion installed on your machine along some libraries to make Subversion usable by Subclipse. Please have a look at the detailed information provided directly by the Subclipse team. For Windows 7 64-bit, see these informations.
Maven allows hierarchical project structures, where one projects can contain one or more modules – which are essentially independent projects. MATSim uses such so-called "multi-module projects" for the Contributions and Playgrounds. Eclipse can generate for each module a project, so you can specify which modules (e.g. contributions, playgrounds) you really need and you will not have to care about the other projects.
To create an Eclipse project for a Maven module (e.g. a specific Contribution or specific Playground), follow these steps:

To create an Eclipse project for a Maven module (e.g. a specific Contribution or specific Playground), follow these steps:

If you have Eclipse Projects representing Maven Modules you no longer need, you can simply delete the Projects in Eclipse's Project Explorer like you delete any other project. Just make sure the option "Delete project contents on disk" is not activated.
Maven requires Eclipse using a JDK, i.e. Java Development Kit, instead of a Java Runtime Environment (JRE). The main difference is that a JDK also contains a Java Compiler and other tools to develop Java Code, while the JRE is only able to run compiled Java applications.
To check with what Java version (JRE or JDK) Eclipse is running, do the following:
Help > About Eclipse". (On the Mac, it's in the Eclipse-menu, not the Help-menu)Installation Details".Configuration"-vm". The line following it shows which Java binary is used.Depending on the name and location of the used Java binary one can figure out if a JRE or a JDK is used:
C:\Program Files\Java\jre6\bin\client\jvm.dll) it is a JREIf no JDK is used for eclipse, change it:
eclipse.ini in a text editor.-vmargs"-vmargs", add two lines:-vm".C:\Program Files\Java\jdk1.6.0_31\bin\javaw.exe" on Windows)You must have the following software installed and ready to use:
The following steps were tested with the following combination of tools: Java 1.6 Update 24, Eclipse 3.7, Subclipse 1.6.18.
The main MATSim project includes the API and core implementation of MATSim. It includes everything to start with the basic functionality offered by MATSim and is required in any case.
https://matsim.svn.sourceforge.net/svnroot/matsim". If it does not yet exist, create it.matsim/trunk" and click "next".

The project will be checked out, which may take some minutes. The status of the checkout can be observed in the Progress-View of Eclipse.
After the project appears in Eclipse:
This will convert your project into a Maven/Java project. The first time, Maven may download some required dependencies which can take some minutes. Progress can be observed in the Maven Console View. After that, the project is ready to use.
The "Contributions" provide stable extensions provided by different developers. Some specialized features are not available in the main MATSim project, but must be loaded separately from the contributions.
To check out the contributions, proceed as for the main MATSim project, but this time select the folder "contrib/trunk".

Choose again "Check out as a project in the workspace" and name it "contrib".
After the checkout has finished, right-click on the project and choose "Configure > Convert to Maven Project". After this, materialize the contributions into own projects, i.e. each contribution should become a separate project in Eclipse (at the time of this writing, there is only one contribution named "sna"). To do this, follow these hints.
Please note that the contribs project itself is not a Java project, but just a generic Eclipse project that holds a bunch of files. After materializing the projects you need, you could actually close the contribs project in Eclipse (right-click on project > Close Project). But do not delete it!
The "Playgrounds" provide a place for experimental, often unstable code, for each developer. You should only add the Playgrounds to Eclipse if you plan to develop code for MATSim yourself.
Proceed as for the main MATSim project (or for the contributions), but this time select the folder "playgrounds/trunk" to check out and name the project "playgrounds". After the checkout, convert it to a Maven Project and materialize the different playgrounds into separate projects. At the time of this writing, there are about 40 playgrounds, so you should see like 40 additional projects in Eclipse. As there are so many playgrounds, for most people it is advised to only materialize those projects that they really need. Otherwise, your computer will have to compile many many playgrounds that you don't need at all, which might take quite some time.
As with the contribs project, note that the playground project itself is not a Java project, but just a generic Eclipse project that holds a bunch of files. After materializing the playgrounds you need, you could actually close the playground project in Eclipse (right-click on project > Close Project). But do not delete it!
As each contribution and each playground is a separate project in Eclipse, you may end up with quite a large number of projects in Eclipse you likely will not use much (e.g. the playgrounds of other people). While you could remove those projects, it may be better to just close them if you do not need them. Also, to gain some better overview, you can e.g. create a Working set that contains all the playgrounds.
To do this, select menu "File > New > Other ... > Java > Java Working Set".
Name it "matsim-playgrounds", and all the playground projects to it.
After that, in the Package Explorer, click the little triangle in the upper right and select "Top Level Elements > Working Sets".
Now you can easily hide all the many projects so they do not clutter your view.
In the end, you should have the following projects in Eclipse:
matsimcontrib (only if you checked out the contributions)playgrounds (only if you checked out the playgrounds)To use the OTFVis visualizer, one has to configure the path to the native libraries. To do so, go the the Java Build Path settings of the main MATSim project and set the "Native library location" within the Maven Dependencies to the correct directory according to your operating systems. The native libraries are located in libs/jogl-1.1.1/<system-dependent>/lib.

If you get a warning about Eclipse and JDK, you need to configure Eclipse to use a JDK.
Since Eclipse 3.5 it may happen that the code does not compile, even if everything is correctly set up, with the following error message:
Access restriction: The type <<some class name>> is not accessible due to restriction on required library <<some jar file on your system>>
In that case, go to Project Properties, Java Build Path, Libraries. Make sure that the Java version you use is not set to an "Execution environment", but to an "Alternate JRE". After that, the project should compile. It looks like the Eclipse compiler is overly strict when set to an execution environment, forbidding the access to classes that may not be available on all Java installations, but actually are on all major distributions. [Source]

You must have the following software installed and ready to use:
The following steps were tested with the following combination of tools: Java 1.6 Update 31, Eclipse 4.2, Subversive 1.0.0.
The main MATSim project includes the API and core implementation of MATSim. It includes everything to start with the basic functionality offered by MATSim and is required in any case.
https://svn.code.sf.net/p/matsim/code/". If it does not yet exist, create it.matsim/trunk" and click "next".

The project will be checked out, which may take some minutes. The status of the checkout can be observed in the Progress-View of Eclipse.
After the project appears in Eclipse:
This will convert your project into a Maven/Java project. The first time, Maven may download some required dependencies which can take some minutes. Progress can be observed in the Maven Console View. After that, the project is ready to use.
The "Contributions" provide stable extensions provided by different developers. Some specialized features are not available in the main MATSim project, but must be loaded separately from the contributions.
To check out the contributions, proceed as for the main MATSim project, but this time select the folder "contrib/trunk".

Choose again "Check out as a project in the workspace" and name it "contrib".
After the checkout has finished, right-click on the project and choose "Configure > Convert to Maven Project". After this, materialize the contributions into own projects, i.e. each contribution should become a separate project in Eclipse (at the time of this writing, there is only one contribution named "sna"). To do this, follow these hints.
Please note that the contribs project itself is not a Java project, but just a generic Eclipse project that holds a bunch of files. After materializing the projects you need, you could actually close the contribs project in Eclipse (right-click on project > Close Project). But do not delete it!
The "Playgrounds" provide a place for experimental, often unstable code, for each developer. You should only add the Playgrounds to Eclipse if you plan to develop code for MATSim yourself.
Proceed as for the main MATSim project (or for the contributions), but this time select the folder "playgrounds/trunk" to check out and name the project "playgrounds". After the checkout, convert it to a Maven Project and materialize the different playgrounds into separate projects. At the time of this writing, there are about 40 playgrounds, so you should see like 40 additional projects in Eclipse. As there are so many playgrounds, for most people it is advised to only materialize those projects that they really need. Otherwise, your computer will have to compile many many playgrounds that you don't need at all, which might take quite some time.
As with the contribs project, note that the playground project itself is not a Java project, but just a generic Eclipse project that holds a bunch of files. After materializing the playgrounds you need, you could actually close the playground project in Eclipse (right-click on project > Close Project). But do not delete it!
As each contribution and each playground is a separate project in Eclipse, you may end up with quite a large number of projects in Eclipse you likely will not use much (e.g. the playgrounds of other people). While you could remove those projects, it may be better to just close them if you do not need them. Also, to gain some better overview, you can e.g. create a Working set that contains all the playgrounds.
To do this, select menu "File > New > Other ... > Java > Java Working Set".
Name it "matsim-playgrounds", and all the playground projects to it.
After that, in the Package Explorer, click the little triangle in the upper right and select "Top Level Elements > Working Sets".
Now you can easily hide all the many projects so they do not clutter your view.
In the end, you should have the following projects in Eclipse:
matsimcontrib (only if you checked out the contributions)playgrounds (only if you checked out the playgrounds)To use the OTFVis visualizer, one has to configure the path to the native libraries. To do so, go the the Java Build Path settings of the main MATSim project and set the "Native library location" within the Maven Dependencies to the correct directory according to your operating systems. The native libraries are located in libs/jogl-1.1.1/<system-dependent>/lib.

If you get a warning about Eclipse and JDK, you need to configure Eclipse to use a JDK.
Since Eclipse 3.5 it may happen that the code does not compile, even if everything is correctly set up, with the following error message:
Access restriction: The type <<some class name>> is not accessible due to restriction on required library <<some jar file on your system>>
In that case, go to Project Properties, Java Build Path, Libraries. Make sure that the Java version you use is not set to an "Execution environment", but to an "Alternate JRE". After that, the project should compile. It looks like the Eclipse compiler is overly strict when set to an execution environment, forbidding the access to classes that may not be available on all Java installations, but actually are on all major distributions. [Source]

We strongly advise developers to use Maven in combination with an IDE, e.g. Eclipse, to develop for MATSim. But there are still situations when Eclipse is not available, for example if you need to run MATSim remotely on a server. These guidelines merely give some hints, how MATSim can be checked out and compiled on the command line, without giving too much information, assuming the reader already has experience and feels safe on the command line.
# Checking out the Code mkdir sandbox cd sandbox svn co https://svn.code.sf.net/p/matsim/code/matsim/trunk matsim svn co https://svn.code.sf.net/p/matsim/code/contrib/trunk contrib svn co https://svn.code.sf.net/p/matsim/code/playgrounds/trunk playgrounds # compile, test and install main MATSim project # installation in the local Maven repository is required for Contributions and Playgrounds to compile. cd matsim mvn install -DskipTests=true cd .. # compile, test, install the Contributions. # installation in the local Maven repository is required because of dependencies from Playgrounds. cd contrib mvn install -DskipTests=true cd .. # compile the playgrounds cd playgrounds mvn compile cd .. # if your playground depends on other playgrounds, those playgrounds must be installed as well: cd playgrounds mvn -fae install -DskipTests=true cd .. # run the Controler with some config-file, and give it 200MB of RAM # mvn exec:java automatically sets the classpath to include all dependencies cd matsim export MAVEN_OPTS=-Xmx200m mvn exec:java -Dexec.mainClass="org.matsim.run.Controler" -Dexec.args="/path/to/config.xml" # alternative call to start the Controler: # mvn exec:exec substitutes the argument "%classpath" with the actual classpath that includes all dependencies mvn exec:exec -Dexec.executable="java" -Dexec.outputFile=/path/to/logfile.log -Dexec.args="-Xmx200m -cp %classpath org.matsim.run.Controler /path/to/config.xml"
If Maven is not installed on the machine, download maven and unzip it in a local directory. After that, instead of the simple mvn-command you can use /path/to/your/apache-maven/bin/mvn to run the above commands.
mvn clean mvn source:jar mvn -Prelease -DskipTests=true
The above commands create a variety of artifacts in ./target/ that could be used in a release. Most importantly, it creates a matsim-*-release.zip with can easily be used to distribute MATSim.
I advise against using "jar-with-dependencies" as releases, as the meta-information (most importantly license-information form third-parties) is destroyed with that mechanism.
# create *and install* the matsim release cd matsim mvn clean mvn source:jar mvn install -DskipTests=true mvn -Prelease -DskipTests=true # install all contribs, they could be required as a dependency cd ../contribs mvn clean mvn install -DskipTests=true # clean again, so the following jars will be created with the release profile mvn clean mvn source:jar cd myContrib mvn -Prelease -DskipTests=true cd ../anotherContrib mvn -Prelease -DskipTests=true
The Manifest for the release-jars may be special and must be configured in the plugin-configuration in the pom, thus the release profile ("-Prelease") is used for the generation of the final zip. This is also the reason why it is important to clean before building the release, as Maven might not recompile the jar when just the profile changes, leading to missing entries in the Manifest of the packaged jar-file.
To see the content of the generated zip file, use the following command to unzip it:
unzip target/matsim-0.1.0-SNAPSHOT-release.zip -d target/release
Adding revision information and timestamp is possible with the buildnumber-plugin, but it needs quite some customization. Using the buildnumber-properties in filtered files seems only to work if the buildnumber-plugin is NOT configured in a profile, but in the main part of the pom.
calling "java -jar target/matsim-x.y.z-release.jar" should show useful build information (revision number and timestamp)
We highly recommend the two versions above (see Using Eclipse and With Maven on the Command Line). Nevertheless, sometimes one has to pack his own development as a self-executable file that can be started on the command line, since some machines do neither have Maven nor it is allowed to compile/build code there. In such a case it is useful to assemble your playground (or contribution) to a single jar file.
In Eclipse Galileo, the MATSim project and your playground (or contribution) is set up as explained in here.
First, MATSim needs to be packaged as a library in your local Maven repository. For this, create a new Run Configuration: Select Menu Run > Run Configurations..., click on "Maven Build", and press the "New" Button. Configure the build as in the screenshot shown below: Choose the MATSim-project as the base directory, use "install" as the only goal, and add the parameter "skipTests" with the value "true" (Note: The checkbox "Skip Tests" has not the same effect as this parameter, so do not use it!).

After you run that configuration (the first time, Maven might download some additional plugins first), you should see the following final log messages in the "Console" View of Eclipse:
[INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ [INFO] Total time: 31 seconds [INFO] Finished at: Fri Jan 08 13:00:14 CET 2010 [INFO] Final Memory: 4M/14M [INFO] ------------------------------------------------------------------------
MATSim is now placed in your local Maven repository at "[path/to/your/home/dir]/.m2/repository/org/matsim/matsim/0.2.0-SNAPSHOT/". There, you should find the following files:
matsim-0.2.0-SNAPSHOT-tests.jar
matsim-0.2.0-SNAPSHOT.jar
matsim-0.2.0-SNAPSHOT.pom
maven-metadata-local.xml
repeat the above steps for installing MATSim, but this time run the install first on the contrib project, then on the playground project. For this, change the Base directory to the corresponding projects.
If the above is done, you now are able to package your playground (or contribution) with all dependent libraries (including MATSim) into one Jar file. This can then be copied and used on any machine that has only JVM installed.
Right-click on your playground (or your contrib) project and choose "Run As > Run Configurations...".

Define a new Configuration by right-click on "Maven Build", select "New" and set up the new configuration as shown in the Figure above (instead of "balmermi", use the name of your playground in the base directory). Run that Configuration whenever you want to create the Jar.
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 18.523s
[INFO] Finished at: Mon Jun 28 09:41:47 CEST 2010
[INFO] Final Memory: 10M/81M
[INFO] ------------------------------------------------------------------------
If the final log messages in the "Console" View of Eclipse looks like the above the Jar is created and can be found at "[path/to/your/workspace]/playgrounds/[yourPlayground]/target/[yourPlayground]-0.2.0-SNAPSHOT-jar-with-dependencies.jar".
Finally, copy the final Jar file to the machine where you want to run your process and start it via:
java -Xms123m -Xmx456m -cp [yourPlayground]-0.2.0-SNAPSHOT-jar-with-dependencies.jar playground.[yourPlayground].[xyz].[yourMainClass] [arguments]
[[might be easier to just ignore this section until the problem acutally happens]]
moved, see here.
We observed several times that Eclipse freezes when enabling the maven dependency manager for the first time. If this happens, we suggest the following: (i) kill Eclipse (ii) start Eclipse again (iii) disable maven dependency management (right click on project, Maven > Disable Dependency Management) (iv) enable maven dependency management again. In the second try, things usually work.
mvn phasename -DskipTests option (former: -Dmaven.test.skip=true option)mvn assembly:assembly I am still learning git myself. There are many aspects to it I have absolutely no clue about. This is the workflow I am trying and researching. I limit myself to things related to our use case, i.e. using git locally while tracking the SVN repository. This seems to be a good general git text.
git svn clone -s https://svn.code.sf.net/p/matsim/code/matsim matsimgit svn rebasegit branch * master
git branch my-feature git branch * master my-feature
git checkout my-feature git branch master * my-feature
git status # On branch master # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: examples/tutorial/config/example1-config.xml # modified: src/main/java/org/matsim/ptproject/qsim/QSim.java # modified: src/main/java/org/matsim/ptproject/qsim/qnetsimengine/QLinkImpl.java # no changes added to commit (use "git add" and/or "git commit -a")
git add .git status# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: examples/tutorial/config/example1-config.xml# modified: src/main/java/org/matsim/ptproject/qsim/QSim.java# modified: src/main/java/org/matsim/ptproject/qsim/qnetsimengine/QLinkImpl.java#
git commitgit svn dcommitgit svn dcommit directly from the feature branch, and not to previously merge it into master and git svn dcommit it from there. I can afterwards git checkout master again and call git svn rebase there to update the master (or any other local branch). It will even "recognize" my commits when they come back down from the SVN as the "same" commits I did locally. Some documentation even explicitly advises against committing something to the SVN which is the product of a local merge, as git and SVN are not similar enough for that to make sense in some circumstances. If we start working with a remote git repository, it'll be a whole different story (and a normal case).git bisect, which is an incredibly cool feature.git svn clone about the layout of our SVN repository, which seems to be non-standard (with the subdirectories matsim, playgrounds ...).Kirill Müller provided the following solution:
# initialize repository git svn init https://svn.code.sf.net/p/matsim/code matsim-full cd matsim-full # activate sparse checkout git config core.sparsecheckout true # select directories for checkout echo matsim/trunk/ >> .git/info/sparse-checkout echo playgrounds/trunk/ >> .git/info/sparse-checkout echo contrib/trunk/ >> .git/info/sparse-checkout # do the actual checkout git svn fetch # have some coffee, finish a paper, go home, ... # loading checkout into work directory git svn rebase -l # check the size, this may increase over time du -hs . # 1.3G .
To use a checked out repository (either way) in Eclipse:
From an empty workspace, say: Import -> Maven -> Existing Maven Projects. Select the local git repository as the directory. Select all projects. Press OK. You now have matsim an possibly all the contrib and playground projects in your workspace.
Now, make them known to the EGit plugin for Eclipse. Select all projects (at once), say: Team->Share Project. Select git. Leave everything selected, including the checkbox all the way up ("Look for git repository in parent directories."). Hit finish. That's it.
What are the concepts MATSim is built upon?
MATSIM-T consists of several (logically seperated parts). All modules are based on MATSIM-DB which contains all available data points needed for modeling agents and their demand.
World-DB, Network-DB, Facilities-DB, etc... describes the scenario and aggregated information like OD-matrices and so on. MATSIM-FUSION fuse those diverse data into a well deformed data sturture stored into memory.
Based on the scenario information MATSIM-INI them models each individual in the scenario including individual initial demand, called plans (i.e. for a day). The Agents are stored into Agent-DB which refers to the given scenario information of the other databases of MATSIM-DB.
In MATSIM-EA the individual demand of each agent will be optimized using an iterative process. The process steps consists of:
By iterating these steps the overall performance of the system (sum of scores of each plan of each agent) increase until a stable state is reached.
The result are optimized demand of each agent and - as a side effect - the exact description of the last execution of this individual demand. Therefore, at every point in time, we know where and agent is and what it is doing at that time.
These very precice information can then be aggregated via MATSIM-ANALYSIS to extract desired information like traffic volumes, departure histograms, system relaxations, location occupation, and so on.
In fact the process steps are (typically) split up into two to three main parts:
The reason lies into the fact that some parts of MATSim are implemented in C++ while other parts are written in JAVA. The MATSim core has been fully ported to JAVA; in consequence, C++ modules are optional.
Because of the flexible data parsing and data writing functionality of MATSim-T, also external modeling application and modules can be used for MATSim-T.
The Figure shows a typical MATSim-T process. An external synthetic population generation program by Martin Frick was used to create the individuals of the scenario. With other base information about the scenario all those data a filled into MATSim-DB. With MATSim-FUSION modules these data points are connected in an appropriate way such they can now be used to add initial demand for each person of the given population. The resulting Agent-DB (and also the Network-DB) are exported into well defined XML data files. To optimize the demand, these data are then read into another Agent-DB written in C++. After the optimization process of MATSim-EA the resulting demand and the resulting MATSim-EXEC description are written into files again which can be used for analysis.
The most important rules:
The following chapters contain more information for writing code for MATSim.
As the project is growing, we need a minimal set of guidelines to insure the stability of the MATSim project and its further development. I try to keep this list as short as possible.
if statements and other stuff. A notable exception are line lengths (we have no problem with lines up to 132 characters).org.matsim.* do not reference other classes outside of the org.matsim.*-package except for classes provided by libraries in the libs directory. Especially, org.matsim.*-classes must not reference playground-classes. Also playground classes must not depend on code within src/test/java.mvn compile test-compile from the command line within the project top-level directory./* *********************************************************************** *
* project: org.matsim.*
* *
* *********************************************************************** *
* *
* copyright : (C) ${year} by the members listed in the COPYING, *
* LICENSE and WARRANTY file. *
* email : info at matsim dot org *
* *
* *********************************************************************** *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* See also COPYING, LICENSE and WARRANTY file *
* *
* *********************************************************************** */
${filecomment}
${package_declaration}
${typecomment}
${type_declaration}
examples, which is maintained by Michael Balmer and Marcel Rieser – please contact them if you want to add your own examples to this directory.getTravTime() >> getTravelTime()getDist() >> getDistance()Id is an abbreviation for Identifier, the 'd' is thus usually a lowercase letter.create*(), e.g. createLink(). newLink()Abstract, e.g. AbstractPersonAlgorithm.I like SomeInterfaceIImpl, if no more specific class-name is suitable, e.g. PlanImpl implements Plan.
You have some cool features or ideas you want to implement and provide to the MATSim community? Then become a contributor! We grant commit rights to people we know personally (e.g. students from affiliated universities) or to people that can convince us that they are doing (or planning to do) nice things with MATSim. As MATSim is a fairly large project with an extensive API where coding mistakes can affect quite a lot of users, we try to guide new contributors closely to help them feel comfortable with their commits quickly. By default, people with commit rights get their own playground where they are allowed to commit their code. Commit rights for other playgrounds, contributions or even the core are given by the respective maintainers of the packages.
To become a contributor, follow those steps:
If will then add your account to the MATSim project and create a playground.
org.matsim.* unless you are the maintainer of a package/module in org.matsim.*, then you can also commit to this package. Only a small group of persons has the right to commit code to org.matsim.core.*, if you're not one of them, do not commit code in there. Talk to one of the core committers if you need changes or want to contribute code into the core.org.matsim.*, run first the test cases before committing and make sure there are no test failures.test/input/*. See the detailed discussion of this topic.KDE has a nice list of additional recommendations for committing code to a repository. The list seems mostly reasonable also for our project, but we don't want to regulate too much, but hope for people's sanity when committing code.
MATSim generally uses XML files to store data and configuration. There are separate files for configuration, network, demand, and other data. All the different file formats are based on either DTDs (Document Type Descriptions) or XML Schemas, which can be used to validate the XML-files against. The DTD-files and XML schemas are available at http://matsim.org/files/dtd/ and usually contain some documentation about the meaning of the XML-tags in comments.
Some questions occurred about committing data to the MATSim project on SourceForge. To clarify, what kind of data is allowed to commit and where to put it, here a short guideline:
src" and its subdirectories. Do not commit any data files under "src"!config.xml" files are allowed under "src/playground/<username>".test/src", you are allowed to add required data to "test/input" or "test/scenario". Then please follow the following constraints:
test/scenario".test/input" or "test/scenario". Note that bigger files may be compressed with gzip since MATSim supports reading and writing gzipped files with org.matsim.utils.io.IOUtils.getBufferedReader() and IOUtils.getBufferedWriter() respectively.test/input" or "test/scenario". Remember: SourceForge is public to everyone!So, to make it short: You are not allowed to add any data to the SourceForge repository except:
config.xml-files in your playgroundtest/input/<name of your test>" or "test/scenario/…".Our main reason to have tests is to ensure we do not loose existing functionality when adding new functionality. Another reason, hopefully getting less important, is to figure out what influences bugs had, respectively what is influenced by a bugfix.
The following list is not complete and likely never will. It is more to give you an idea, what could be tested:
The tests are automatically run every night. When you log in on matsim.org, you'll find a link in the left navigation area ("developer info") where you can look at the nightly status of the tests. If errors or failures occur, an email is sent to Marcel Rieser who will then inform people as necessary.
To run all tests, create a new Run-Configuration. Select to run all Tests in src/test/java with a JUnit 4 runner.

In the Arguments tab, do not forget to increase the available memory for the JVM (-Xmx600m), then click "Run".
export MAVEN_OPTS=-Xmx600m mvn test
Maven should output a summary, listing the number of all tests as well as the number of failed tests (if any).
(The following list has been updated for JUnit 4.7. Many existing tests written for JUnit 3.8 still follow different guidelines.)
MyModuleTest.@Test and name your methods that contain your tests with a starting "test", e.g.: @Test public void testGetParameter();assert keyword from the Java language to check conditions, but use the methods provided by JUnit: Assert.assertEquals(x, y); Assert.assertTrue(x); Assert.assertNull(x); Assert.assertNotNull(y);Assert.assertEquals("different events files.", checksum1, checksum2);
Assert.assertNotNull("did not find person 1.", population.getPersons().get(1));double d1, d2;
Assert.assertEquals(d1, d2); // this matches to assertEquals(Object, Object); likely not what you wanted...
Assert.assertEquals(d1, d2, MatsimTestUtils.EPSILON); // this is the right way to test for double values@Rule MatsimTestRule, see Mini-Introduction to JUnit 4.7.Config loadConfig(String filename);getOutputDirectory(); getInputDirectory(); getClassInputDirectory(); getPackageInputDirectory();EPSILON for comparing double values (see above).MatsimTestUtils.loadConfig().MatsimTestUtils.getOutputDirectory().src/test/resources/test/input/<package>/<class>/<test>/. Example:src/test/resources/test/input/org/matsim/mymodule/MyModuleUtils/testUtilMethod/config.xmlorg.matsim.mymodule.MyModuleUtils.testUtilMethod().JUnit is a framework for writing tests in Java. We currently use JUnit 4.7 for our tests, but many older tests are still written as JUnit 3.8. Thus, the following information is retained only for better understanding of existing tests.
JUnit 3.8 uses three main concepts:
A small example of a test and testcase:
public class MyTests extends TestCase {
protected void setUp() throws Exception {
super.setUp();
// your code here...
}
protected void tearDown() throws Exception {
super.tearDown();
// your code here...
}
public final void testOne() {
// your code here...
assertEquals(expected, actual);
}
public final void testTwo() {
// your code here...
assertNotNull(someObject);
}
}This code defines two tests (testOne, testTwo). Additionally, there are two methods setUp() and tearDown(), which are automatically called by JUnit when executing the TestCase. Make sure to call Gbl.reset() in tearDown() when you use the class Gbl or Config within your tests, so that the following TestCases are not influenced by your TestCase.
JUnit offers many different assert-statements which should be used to verify the results of your tests. Do not use the standardassert() offered by Java, as this must especially be enabled to be executed!
When writing Tests for MATSim, do not extend the class TestCase, but extend MatsimTestCase, as that one offers some convenient methods related to MATSim (see Guidelines for more details).
JUnit is a framework for writing tests in Java. We currently use JUnit 4.7 for our tests, which still supports the older JUnit 3.8 syntax.
A simple example of a testcase:
import org.junit.Assert;
import org.junit.Test;
public class MyTests {
@Test
public final void testOne() {
// your code here...
Assert.assertEquals(expectedValue, actualValue);
}
@Test
public final void testTwo() {
// your code here...
Assert.assertNotNull(someObject);
}
@Test @Ignore("not yet fully implemented")
public final void testThree() {
// your code here...
// TODO complete test
}
} This code defines three tests (testOne, testTwo, testThree). JUnit offers many different assert-statements which should be used to verify the results of your tests. Do not use the standard assert() offered by Java, as this must especially be enabled to be evaluated! If a test is not yet fully implemented but you still want to commit the code, add the annotation @Ignore to the test. In that case, the test will not be executed. Note that your code must still compile when committing ignored tests.
If you need to read in or write out files to disk, use MatsimTestUtils as a rule:
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
public class MyTests {
@Rule public MatsimTestUtils utils = new MatsimTestUtils();
@Test
public final void testOne() {
String inputFile = utils.getInputDirectory() + "myFile.txt";
// your code here...
String outputFile = utils.getOutputDirectory() + "myFile.txt";
Assert.assertEquals(expectedValue, actualValue);
}
} Please note that many methods of MatsimTestUtils can only be used in the actual test (marked with @Test), but not in a constructor or other initialization methods (e.g. in @Before).
Maven maintains an explicit dependency graph, which code uses which other code in order to compile. If your code requires code from other developers, either from a different playground or in form of an external java library, this dependency must be manually registered in order to keep the code compiling.
Imagine you want to write code that relies on classes in someone else's playground. To do this, you have to specify this dependency on the playground of the other person:


First, make sure the library has a license that is compatible with the GPL that MATSim uses. Gnu.org has an extensive list of compatible and non-compatible licenses. If the license is not compatible, do not use it. Also, do not use SNAPSHOT-versions of libraries as a dependeny. Only use stable versions.
Note: The following text will always mention "playground", but the same steps can also be used to create a new contrib-project inside "contribs".
In the playgrounds-project, there exists a directory _template which can be used as a starting point. This template already contains the directory structure and svn meta data for a typical playground. Best is, to copy the template using svn commands. That is:
cd /path/to/workspace/playgrounds/svn copy _template nameOfNewPlaygroundnameOfNewPlayground/pom.xml, change the Artifact Id and the project name from "_template" to the name of the new playground.playgrounds/pom.xml_template directory in Eclipse or in the Explorer! In every case except "svn copy", the metadata will not be correctly updated, resulting in a corrupt svn checkout!
For non-programmers, MATSim is configured via the config file. (For extensions, we have not yet found a good solution.) If you make your code configurable, please observe the following hints.
Examples for automagic are:
The problem with such automagic is that it is nearly impossible to write code that is robust against typoes. As a result, one gets warnings such as
If a user is not able to switch off warnings, she or he will eventually start to ignore them. Which is not good. In that sense:
If a user is not able to switch off warnings, she or he will eventually start to ignore them. Two aspects:
Contributions to the core of MATSim (packages org.matsim.*) require a high quality and stability. Thus, it is usually not desired to develop now concepts directly in a org.matsim-package, even if the code should later be located there. Instead, contributions to the core should go the following way:
org.matsim.core.api.experimental or another appropriate package.org.matsim.api (or other package) on the request of the MATSim Committee.
If you're writing code in MATSim and have a playground or contrib-project, make sure to sign up to the matsim-developers mailing list. On the mailing list, we'll inform you about major refactorings of the code or other important changes related to the development of the MATSim project.
Every public class should have the following items:
All these items should be written in a Javadoc block atop of the class.
MATSim is developed by several persons on different platforms. So we need a basic set of settings to work successfully together.
In the Eclipse Preferences, please set the Text File Encoding to "UTF-8", and the New Text File Line Delimiter to "Unix" (in General > Workspace).

Exceptions are an important concept of Java, as they allow to signal special conditions that need special handling. Java differentiates between two types of Exceptions, checked and unchecked exceptions. Checked exceptions need to be declared in a method and code calling it needs to handle the possible exceptions, for example with a try-catch block:
public void readFile(final String filename) throws IOException {
// IOException is a checked exception, it needs to be declared as "throws"
if (!(new File(filename).exists()) {
throw new IOException("File not found!");
}
// continue with normal code if file exists
}
public void doCalculation(final int a, final int b) {
if (b == 0) {
// a RuntimeException is an unchecked exception, it does not have to be declared
throw new RuntimeException("b cannot be zero!");
}
}
public void someMethod() {
try {
readFile("foo.bar");
// a checked exception must be handled, either with try-catch or by declaring a "throws" on this method
} catch (IOException e) {
// handle exception
}
doCalculation(3, 0);
}Java itself makes use of checked exceptions in many places, most notably in many I/O related methods (IOException). As many programmers dislike to handle checked exceptions correctly (to either handle them or declare them and move the handling further up the caller chain), one can often observe code like the following:
try {
readFile("foo.bar");
} catch (IOException e) {
e.printStackTrace(); // DO NOT DO IT LIKE THIS!
}
Do not do it like this, as then your code will continue to run as if there was no problem, but you may be missing data in your code, or data was not written out, etc. So you'll spend a lot of time wondering why your application did not do what it should have been.
Better wrap the checked exception in an unchecked exception and re-throw it:
try {
readFile("foo.bar");
} catch (IOException e) {
throw new RuntimeException("Could not read the file foo.bar.", e); // This is better
}
In addition, you can still declare the RuntimeException, such that other people using your method know that there could be an exception and optionally handle it:
/** * Does some calculation with a and b. * * @throws RuntimeException if b is zero */ public void doCalculation(final int a, final int b) throws RuntimeException { if (b == 0) {
throw new RuntimeException("b cannot be zero!");
}
// continue calculation
}
Optionally, you could even create your own (unchecked) Exception:
public class MyCustomException extends RuntimeException {
public MyCustomException(final String message) {
super(message);
}
}
Most of MATSim-T is written in Java and requires Java 1.5 to run. While Java is widely known, we stumble from time to time over certain features or specialities we'd like to highlight. So this is the place to collect interesting and informative stuff about Java which might (or might not) have some relation to our code.
Memory usage is a critical point in multi agent simulations, just because there usually are so many of them. Thus, every single byte that is used to describe a single agent enlarges the memory consumption of the whole system massively.
Our agents have several attributes (like sex, car-availability, employment status), their plans contain activities with a type and legs with a mode. Each of these attributes are stored as Strings. Considering that even an empty String takes up to 40 bytes in Java and characters in Java are always 16bit, even a small string like "f' (for Person.sex) or "car" (for Leg.mode) takes a lot of memory—and that's for every single agent, leg and activity!
It is quite obvious that it does not make sense to have more than one string with the same content multiple times, especially when every instance uses so much memory. This is where object pools are often used: a so called pool stores commonly used objects exactly once, and other objects can refer to these objects instead of holding their own, identical, instances. In our case this means that instead of having separate instances of String for every "f", "car" or other attribute, each occurring value exists only once as a String-object, and all the agents, legs and activities only reference the corresponding pool object instead of storing their own instance. Having a population of 200k agents with 5 attributes would contain 1mio strings—that would be more than 40MB of RAM alone, not yet counting the memory used by plans, leg-modes, activity-types. But when using our "object pool" we only need about 10 or 15 different Strings (depending on the number of different values in the attributes), instead of 1mio!
The class String offers already such an internal object pool, so that this optimization can be used without much additional code:
String.intern();
The documentation to String.intern() reads as follows:
Returns a canonical representation for the string object.
A pool of strings, initially empty, is maintained privately by the class String.
When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.
So, the setters for such string-attributes can now be written like the following one:
class Act {
String type = null;
...
public void setType(String type) {
this.type = type.intern();
}
}
Using this simple trick, the memory consumption was reduced by over 25% when reading in 160k agents, while the time used for reading the agents did not change significantly (50secs vs 49secs). Reading larger populations should result in even larger memory savings, as most likely no additional strings have to be added to the pool, and all attributes can just reference to them.
Using Java 1.6.0 can evoke OutOfMemoryErrors while parsing huge xml files. For details see: bugs.sun.com/bugdatabase/view_bug.do?bug_id=6536111
HashSet/HashMap do not specify in which order elements are iterated. Testing such structures are very difficult (sorting is always necessary for comparison). Even more tricky it gets, if tests randomly fail. Debugging will be very hard. Use LinkedHashSet/LinkedHashMap instead. It can be iterated over insertion order.
Our simulations depend heavily on random numbers. But despite using random numbers, we still want the simulations to be deterministic, so that results can be reproduced by running the same scenario a second time.
Usually, random numbers in Java are generated by calling Math.random():
double d = Math.random();
While this method returns a random number, the number is indeed random such as that in a second run of the same scenario, other random numbers would result and the simulation would no longer be deterministic. To overcome this problem, an instance of java.util.Random can be generated and initialized with a custom random seed:
Random random = new Random();
random.setSeed(1234);
...
double d = random.nextDouble();
In this case, everytime the code is run, we get the same random numbers. As drawing random numbers is widely used in the code, MATSim-T offers a global instance of Random, which is automatically initialized with the seed specified in the configuration file:
import org.matsim.core.gbl.MatsimRandom;
...
double d = MatsimRandom.random.nextDouble();
What value should be used as random seed? Is a value of 1 better than the value 86294? As both numbers have the same probability to be chosen in the range from 0 to Integer.MAX_VALUE, any value is equally good for a random seed.
But this is only half of the story. We all know, that these random numbers are only pseudo-random—and they depend on the chosen seed!
PlanAlgorithms could be executed in parallel in multiple threads, e.g. during replanning. As the exact order of execution with multiple threads is not deterministic, the usage of MatsimRandom.random would lead to non-deterministic results. Instead, every instance of a PlanAlgorithm should have its own random number generator. Best way to realize that is that PlanAlgorithms that use Random numbers have a constructor where an object of type java.util.Random can be passed. When instantiating PlanAlgorithms, one can use MatsimRandom.getLocalInstance() to obtain a Random-object that can be passed to the PlanAlgorithm. A Random object received by getLocalInstance() is already correctly initialized to return useful random numbers (see below, Problems when setting the random seed).
In our code, we set the random seed at the start of every iteration, so that we can restart a simulation at any iteration. The code was similar to the example code below:
int baseSeed; // the random seed specified in the configuration file
...
for (int iteration = 0; iteration < 1000; iteration++) {
MatsimRandom.random.setSeed(baseSeed + iteration);
...
}
After running several iterations we realized that the first agent was never chosen for re-planning (remember, they get "randomly" chosen for re-planning). A little bit of research revealed, that the first random number drawn after setting the random seed depends heavily on the random seed! Only a slight change in the random seed (in our case always +1 for each iteration) resulted in only a slight change in the value of the random number. The following figure shows the distribution of the first and second drawn random number after setting different random seeds. As can be clearly seen, the first drawn number only moves in a very small range. The second drawn numbers have a better distribution when the seed is only changed a little.
To overcome this problem, we decided that after setting a random seed, we draw one random number and immediately throw it away, as it seems not enough random.
Note: I consider the following as a rather advanced topic / optimization. I stumbled upon it while testing a new Java-profiler and thought I document it, 'cause others may be interested in it. – Cheers, MarcelWhile the Collections in Java are really nice and useful, they are not always the best solution performance-wise. In a recent case, a
TreeMap<Integer, Integer> was used for travel time lookups. Each link in the network had such a map, storing a (departure) time and the corresponding travel time at that departure time. When searching for routes in the network, this map was accessed really a lot of times. As the queried time was not necessarily a key in the map, often the first entry of a tailmap (a map containing all objects whose key is equal or larger than a certain value) was requested to get the travel time at the next possible departure time.Integer.getValue() was called a crazy number of times, using a lot of time in total, even if I had this function-call nowhere explicitly in my method. Well, to find the correct entry in the map, the Integer-keys had to be compared, which was done by accessing their basic type values. That explained the many calls to this function, which made me think of how to implement the travel time lookup without using Integer-objects, but using the basic type int.int[]), one containing the keys, the other the corresponding values, allowed to use a binary search on the key-array (Arrays.binarySearch()) to find the correct array-index and thus to easily access the corresponding travel time in the value-array. With this change, no Integers were used, thus no (un-)boxing had to be done, and the accessed memory in the array should not be so scattered around then the single map-entry objects, leading to faster access. Finally the code ran in 25% less time!As a lot of functionality in MATSim is created by PhD students, there is often a problem maintaining this functionality after the respective students finished their work and leave university. In order to better communicate which features are "standard MATSim" which will (and have to) be maintained by the MATSim core developers, and which features are just "single-developer functionality", MATSim introduces the concept of "MATSim core" and "MATSim extensions".
The core will be maintained by the core developers, and should contain central functionality which is likely to stay in MATSim forever. Extensions can provide new, but stable, functionality developed to solve specific problems which can be of interest to others in the MATSim community.
Extensions will—as long as they compile and pass all tests—also be packaged for releases and be thus optional parts of MATSim releases. This requires that extensions follow certain guidelines, also in order to keep code maintenance and user support in reasonable bounds.
There are numerous hints that inheritance is not very stable under refactoring; see, for example, Bloch, "Effective Java".
The problem has something to do with the sequence of program execution. Assume
class Base {
run() {
partA() ;
partB() ;
}
partA() {
do1() ;
do2() ;
}
partB() {
do3() ;
do4() ;
}
...
and some derived code
class Derived extends Base {
partA() {
do1() ;
doMyOwnStuff() ;
do2() ;
}
...
Now assume that the maintainer of the base class decides that do3() should be done before do2(). Thus (for example):
class Base {
...
partA() {
do1() ;
do3() ;
do2() ;
}
partB() {
do4() ;
}
...
Now the derived code will not execute do3() at all.
One may argue that this is a consequence of bad design of the base class, e.g. that run() should call the doX() methods directly, or the designer should know beforehand in which sequence something needs to be done. In practice, these arguments do not work: Levels of abstraction are difficult to get right from the start; and there may be situations where sequences of execution originally do not matter, and when it later turns out that they matter, they may be in the wrong sequence.
One may also argue that this is a consequence of bad design of the derived class, i.e. the programmer who overrides methods that have content should always call the super-method. That is
class Derived extends Base {
partA() {
super.partA() ;
doMyOwnStuff() ;
}
...(Note that this is not the same thing as above.)
However, the base class maintainers cannot enforce that class users (those who extend the base class) do this. One may argue that this is the problem of the class users, but in our setup test failures resulting from such issues are, as a tendency, the responsibility of the base class maintainer (since her or his code change broke the tests).
We therefore suggest to prefer composition (=delegation) over inheritance where this is possible. It is only possible when the class that one wants to inherit from implements an interface. In that case, the following is possible (with eclipse):
1. Write a class skeleton as follows:
class MyClass implements XXXInterface {
private XXXInterface delegate = new XXXImplementation(...) ;
}
2. In eclipse, go to "source"/"generate delegate methods" and follow the instructions.
[[Somebody please add a screenshot here. thanks. kai]]
This will delegate all method calls to MyClass to the delegate. Now you can modify some of the delegate methods as you like.
(This sometimes seems to provide less access than inheritance, but I don't think this is true as long as you assume that internal variables/fields are always private.)
It is called "composition" since you can do this with more than one interface/delegate. The classical example is something like
class MyCar implements HasSteering, HasBrakes, HasGears {
private HasSteering steeringDelegate = new PowerSteering(...) ;
private HasBrakes brakesDelegate = new SimpleBrakes(...) ;
private HasGears gearsDelegate = new ElectronicGears(...) ;
}
where the eclipse generate delegate methods will produce methods such as
public void steerToRight( double value ) {
steeringDelegate.steerToRight( value ) ;
}
...
public void brake( double value ) {
brakesDelegate.brake( value ) ;
}
As one can see, this now allows operations such as
MyCar car ... ... car.brake( 3. ) ; car.steerToRight( 0.3 ) ;
that is, the car is now composed of its internals.
In MATSim, we often expose the delegation, that is, the syntax is
car.getBrakes().brake( 3. ) ; car.getSteering().steerToRight( 0.3 ) ;
This has the advantage that, if you extend the interfaces, you do not need to adapt every implementation. It is, clearly, not an option if you want to write a class (such as a PlanStrategy) that is later inserted into the code – that has to fulfill the contract defined by the interface.
Generics can be quite powerful, but also very cumbersome if used wrongly. Thus, respect the following rules:
Documentation about the following MATSim Modules / Features / Projects is available:

The figure shows the main structure of the MATSim Controler. Easily recognizable is the iteration loop consisting of plans-execution, scoring and replanning. At each one of the eight marked points, modules can easily add additional functionality to MATSim.
'package org.matsim.counts:'
<counts xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="[SOME URL]/counts_v1.xsd"
name="[SOME NAME]" desc="[SOME DESC]" year="[SOME YEAR]" layer="[SOME LAYER]">
Contact:
In case of questions or comments, please contact: horni(at)ivt.baug.ethz.ch
Monetarizing car or HDV emissions can be done quite straightforward using the MATSim simulation results. This includes the following steps:
Making this operational is planned within the context of the "detailed evaluation" project (DFG).
One of the main goals of the project is to model the electric demand of Plug-in Hybrid Electric Vehicles (PHEVs) and Electric Vehicles (EVs) and to find out, if the underlying electricity network can support such demand.
For doing this, MATSim has been coupled with a simulation model of the electricity network, which is called PHEV Management and Power System Simulation (PMPSS) [1]. Furthermore a charging module was added to MATSim, which decides the policy, when and how charging is performed by the vehicles. After relaxation of the MATSim Iterations, the charging information is given to PMPSS which finds out, if certain grid constraints have been violated (e.g. transformer capacities). This information is given back to MATSim and the charging module. As such, MATSim and PMPSS form an outer loop around the original MATSim loop.

Three type of charging schemes have been implemented in [1]: Dumb Charging, Dual Tariff Charging and Smart Charging. They are shortly described in the PDF poster, here.
[1] Waraich, R.A., M.D. Galus, C. Dobler, M. Balmer, G. Andersson and K.W. Axhausen (2009) Plug-in Hybrid Electric Vehicles and Smart Grid: Investigations Based on a Micro-Simulation, paper presented at the 12th International Conference on Travel Behaviour Research (IATBR), Jaipur, December 2009.
(http://www.ivt.ethz.ch/vpl/publications/reports/ab592.pdf)
| Attachment | Size |
|---|---|
| 112.43 KB | |
| 3.28 MB |
Marcel Rieser and Michael Balmer, senozon AG ({rieser, balmer}_at_senozon.com)
http://www.matsim.org/javadoc/org/matsim/matrices/package-summary.html
This was used to store things like OD matrices inside matsim. Since we prefer to disaggregate such things right away into individual trips, this module was not maintained. It is not clear if maybe it should be re-surrected.
[mrieser] I recently cleaned the package up a bit, in that it no longer requires Locations (from the deprecated World concept) but just Ids, and that they work more stand-alone. Matrices are used mostly in demand modelling. As such, they are useful, but would probably need more cleanup to come up to standards.
- think about interface Matrix to have different implementations, also backed by matrix-package (e.g. Jama, ...).
- mostly used in initial demand modeling. MATSim needs *some* kind of matrix support for idm.
- probably rename matrices/Matrix to odmatrices/ODMatrix to make clear it's not a general matrix impl?
Documentations for the following micro-simulations currently available:
JDQSim: I moved this to the user part of the documentation since I think it can be used from the config file only. kai, apr'11
Large Scale
The service is available 24h per day, 7 days a week.
The vehicles are ranging from minivans to minibuses (approximately 6 to 12 passengers)
The service works without fixed stations
Taxis can be taken on the fly (smart phones)
Price and utility parameters based on those of other modes in MATSim-T
Available to all agents at every point in time and space
No capacity restrictions (unlimited capacity)
Michal Maciejewski is looking into using MATSim to generate realistic instances of the dynamic vehicle routing problem (DVRP). If one wants to avoid that the DVRP program can "cheat", requests for service should not come out of MATSim before their time. There seem to be the following types of requests:
Let me first look at taxis (i.e. persons make requests for themselves).
The first seems to be relatively easy to model: The leg mode would be "taxi"; the person would end its activity, go into the corresponding departure handler, which would request a taxi and then put the person into the departure queue (presumably, the same as there is for pt, although I am not sure if there is one per link or just one per pt stop).
The second is more difficult. Sending out the request when the activity starts is too early, and the DVRP may use that to its advantage. Possibilities that come to my (kn's) mind:
Option 1 seems plausible at first glance. Yet, it looks like it will cause additional headaches if this is ever combined with within-day replanning (because matsim would need to check which pre-scheduled events an agent has left around when it changes its plan). Given our past experiences with such "quick fixes", this does not sound like a great idea.
Option 2 seems plausible (to me). Within-day agents might be contacted, say once a minute, and asked if they want to call taxi for a pre-scheduled time in the future. A disadvantage, however, is that these requests would all come at the same time, and the DVRP optimizer might take (unwarranted) advantage of that fact.
Option 3 seems a plausible fix for the meantime (to me). It will produce wrong results with respect to agent scoring, but at least it will generate correct taxi requests.
Option 4 looks attractive (to me). A remaining question is how this should look in the plans file. My current (apr'12) intuition would be that there could be additional stuff during the activity, i.e.
<act type="leisure" end_time="20:00:03">
<subact type="taxirequest" time="19:23:33/>
</act>
A clear disadvantage would be the necessary modification of the plans file. One could, however, initially keep the necessary data structure until the problem is sorted out.
Option 5:
<act type="leisure" end_time="19:23:33/> <act type="taxirequest" duration="00:00:00"/> <act type="leisure" end_time="20:00:03" />
This would be more consistent with the approach that we took with the legs ... i.e. leave the hierarchy of the xml file intact and sort it out somewhere else. With the legs, it seemed a bit easier since for legs the utilities are just linear in the durations, but in the end the "removePtInteractionActivities" is also an instance of "sorting it out somewhere else".
Now courier service.
Seems to me that I don't know enough about this. Freight, at this point, is planned to be plugged into matsim by using "truck drivers". I.e. from the point of view of matsim, the transportation of goods will just be a side effect of a driver moving a vehicle from A to B, and that vehicle being loaded with certain goods.
Clearly, we can still make up courier requests without following the goods. For this, once more the within-day agents seems like the most consistent option.
Once there are requests, there need to be taxis. Personally, I would start with a single taxicab. In terms of implementation, this would probably inherit from what is currently (may'11) called ExperimentalBasicWithindayAgent.
(Using delegation/composition instead of inheritance is difficult with matsim agents, since "this" inside some delegated logic points to the delegate, not to the composing object. Yet, the "this" is used to remove the agent from data structures, and insert it into others (e.g. at-activity data structure, wait data structure, in-vehicle data structure).)
As a first step, I would make the taxi agent, every time it arrives somewhere, generate a next activity location and then drive there.
As a second step, I would try to make that taxi agent pick up a waiting passenger and deliver it.
After some thinking, my intuition is that I would stay away from the pt code. Picking up passengers can as well be done with regular arrival, I would think, and that would be much less intrusive.
Update (jul'11): There is an "AdapterAgent" in Michael Z.'s playground, and Michal M. has started using that for his taxicab prototype.
There are now 3 least-cost path algorithms in package org.matsim.router:
- Dijkstra
- AStarEuclidean
- AStarLandmarks
For every router, there exists a class which computes some preprocessing data and is passed to the router class constructor in order to accelerate the routing procedure. The preprocessing classes are located in org.matsim.demandmodeling.router.util:
- PreProcessDijkstra
- PreProcessEuclidean
- PreProcessLandmarks
Dijkstra:
Condition: The link cost must be non-negative, otherwise Dijkstra does not work.
The new version is much faster on short routes than the former version (50 times as fast, if the start and end node of the route are ~1km away from each other) and diminutively faster on long routes (~1.5 times faster with preprocessing). Dijkstra can be used with or without preprocessing data (the preprocessing just marks all nodes that are in dead ends). Preprocessing does not take long (2 seconds on a network with 400'000 nodes on our computer leibnitz) and does not require much additional memory (~ 1 pointer per node) either, therefore it should be used where possible. Invoking Dijkstra may then look like this:
PreProcessDijkstra preProcessData = new PreProcessDijkstra();
preProcessData.run(network);
TravelCostI costFunction = ...
LeastCostPathCalculator routingAlgo = new Dijkstra(network, costFunction, preProcessData);
routingAlgo.calcLeastCostPath(fromNode, toNode, startTime);
If you don't want to preprocess the network, you can invoke Dijkstra as follows:
LeastCostPathCalculator routingAlgo = new Dijkstra(network, costFunction);
AStarEuclidean:
Is about 3 times faster than the above Dijkstra.
Conditions:
- The same as for Dijkstra: The link cost must be non-negative, otherwise Dijkstra does not work.
- The length stored in the links must be greater or equal to the euclidean distance of the link's start and end node, otherwise the algorithm is not guaranteed to deliver least-cost paths. In this case PreProcessEuclidean gives out a warning message.
- The CostCalculator which calculates the cost for each link must implement the TravelMinCostI interface, i.e. it must implement the function getLinkMinimumTravelCost(Link link). The TravelTimeCalculator class does implement it.
PreProcessEuclidean.run() is very fast and needs (almost) no additional memory. Example invocation:
TravelMinCostI costFunction = ...
PreProcessEuclidean preProcessData = new PreProcessEuclidean(costFunction);
preProcessData.run(network);
...
LeastCostPathCalculator routingAlgo = new AStarEuclidean(network, preProcessData);
...
A note about the so-called overdo factor: You can drastically accelerate the routing of AStarEuclidean by providing an overdo factor > 1 (e.g. 1.5, 2 or 3). In this case, AStarEuclidean does not calculate least-cost paths anymore but tends to deliver distance-minimal paths. The greater the overdo factor, the faster the algorithm but the more the calculated routes diverge from the least-cost ones.
A typical invocation then looks like this: LeastCostPathCalculator routingAlgo = new AStarEuclidean(network, preProcessData, 2);
AStarLandmarks:
About double as fast as AStarEuclidean. PreProcessLandmarks.run() takes about 1 minute on 400'000 nodes on leibnitz and requires 2*X double values per node, where X is the number of landmarks. Currently, it is set to 16 (but can be set to another value, as 12 or 8 for example), so with 400'000 nodes we would need 2*8*16*400'000 bytes = about 100MB of additional memory.
Conditions: The same as for AStarEuclidean.
Example invocation:
TravelMinCostI costFunction = ...
PreProcessLandmarks preProcessData = new PreProcessLandmarks(costFunction);
preProcessData.run(network);
...
LeastCostPathCalculator routingAlgo = new AStarLandmarks(network, preProcessData);
...
Currently the following documentation for scoring is available:
This article describes how originally scoring functions were implemented and how it works now.
Originally, each scoring function needed to implement the ScoringFunction interface. The interface contains the following method signatures: startActivity,endActivity, startLeg, endLeg, agentStuck, addMoney, finish, getScore and reset. The documentation of these methods can be found in the source code of the ScoringFunction interface.
This implementation functions fine, but has a few shortcomings. The most important is, that the scoring functions based on this interface are not resuable and often not extendable.
Inorder not to change the current interface, the following approach was taken to make modular scoring functions possible: Five Interfaces have been introduced, which just subdivide the original ScoringFunction interface. These interface together with the methods are listed:
The basic idea is, that a scoring function can consist of an arbitrary number of summand terms. For example you can have scoring terms just depending on a static properties of agents or depnding on Activities. Furthermore a leg part could consist of several summand terms itself.
Every scoring term must implement the BasicScoring interface. A class called ScoringFunctionAccumulator is at the heart of this approach: The scores of all scoring terms registered with this accumulator, are summed up at the end of the iteration, making both reusable and extensible scoring functions easy to implement.
Please look at the package org.matsim.scoring.charyparNagel for an example, which contains the following elements:
Although it would be possible to just put all scoring terms into one class by implementing all scoring term interfaces, this approach is not advisable, as it runs counter to the modularity principle (which was the reason for providing this new approach).
For a description of the algorithms see the respective child pages.
The subtour analysis functionality can use either link or facility as the definition of a "location". The default is to use links. When using TripStructureUtils in code, this can be changed by passing true as the "useFacilitiesInsteadOfLinks" parameter. When using subtour mode choice, this can only be changed programmatically by using the setAnchorSubtoursAtFacilitiesInsteadOfLinks( boolean ) method of ChooseRandomLegModeForSubtour.
The different variants of TripStructureUtils.getSubtours( ... ) provide a convenient way to access the subtour structure of a Plan.
Subtour is defined like the following:
getSubtours(...) methods, those sequences are identified as "open" subtours (Subtour.isClosed() returns false).For up-to-date information about the way to use those methods, the reader is refered to the javadocs.
The ChooseRandomLegModeForSubtour algorithm, used in the SubtourModeChoice module, provides a mode choice procedure inspired by Miller et al.'s (2005) individual trip maker mode choice. It computes a choice set of feasible trip mode combinations given
This section provides a basic description of the idea behind subtour analysis and subtour-level mode choice.




Consider the following scenario:
The plan consists of two subtours, each of which might be performed with one of the car. Alternatively, each trip might be performed woth a trip-based mode (walk, pt). The resulting choice set is:
car-car-car-car
car-car-pt-pt
car-car-walk-walk
car-car-walk-pt
car-car-pt-walk
pt-pt-car-car
walk-walk-car-car
walk-pt-car-car
pt-walk-car-car
pt-pt-pt-pt
pt-pt-pt-walk
pt-pt-walk-pt
pt-pt-walk-walk
pt-walk-pt-pt
pt-walk-pt-walk
pt-walk-walk-pt
pt-walk-walk-walk
walk-pt-pt-pt
walk-pt-pt-walk
walk-pt-walk-pt
walk-pt-walk-walk
walk-walk-pt-pt
walk-walk-pt-walk
walk-walk-walk-pt
walk-walk-walk-walk
See also attached Figure 1 from Miller et al. (2005).
The subtour-level mode choice algorithm is used in the SubtourModeChoice replanning strategy. The behavior of this strategy can be configured by the subtourModeChoice config group, which allows to define the different parameters of the algorithm as defined above:
<module name="subtourModeChoice" >
<!-- Defines whether car availability must be considered or not. A agent has no car only if it has no license, or never access to a car -->
<param name="considerCarAvailability" value="false" />
<!-- Defines all the modes available, including chain-based modes, seperated by commas -->
<param name="modes" value="car,pt,bike,walk" />
</module>
Miller, E. J., M. J. Roorda und J. A. Carrasco (2005) A tour-based model of travel mode choice, Transportation, 32 (4) 399–422.
There are (at least) two versions:
In the end, each approach will be able to emulate the other one, so it may come down to a matter of taste.
For general conceptual material see
If any of these links are not working, check for packages with "withinDay" in their name in the tutorial section of the matsim javadoc or the matsim code.
Reference for the first variant:
Some links to related material:
Possible policy measures, and how they might be implemented in MATSim. A classification with respect to the "four E" (Economy, Engineering, Education, Enforcement) will follow.
For example:
HDVs (heavy duty vehicles) / cars in general are not allowed to enter the city center.
Modelling options in MATSim:
For example
Modelling options in MATSim:
For example changes in transportation costs due to...
Modelling options in MATSim:
Remark: make sure that (i) the router and (ii) the scoring function do perform the distance cost / utility calculations appropriately!
This is not a policy evaluation, but a rule-of-thumb estimate how long it would take to evacuate a large city, in this case Tokyo. It is not meant as any kind of policy advice but it is a very simple combination of numbers that seem plausible in the situation.
Assumptions (to get started):
Evacuation by car. Assumptions (to get started):
==> 16'000 persons / hr
Evacuation by bus. Assumptions (to get started):
==> 120'000 persons / hr
Evacuation by train. Assumptions (to get started):
==> 24'000 persons / hr
Taking the bus and train numbers together, one obtains 150'000 persons / hr. Dividing the 35 million inhabitants by that number results in 233 hours or approximately 10 days of evacuation times.
Sensitivities:
Overall: the 10 days look rather optimistic
Things that we cannot judge:
This text came out of a telephone and email exchange between H. Klüpfel (www.traffgo-ht.com) and K. Nagel (www.vsp.tu-berlin.de), with input from K. Axhausen (www.ivt.ethz.ch).
For example:
Modelling options in MATSim:
With teleportation:
Changes to the public transit mode, e.g.:
Modelling options in MATSim:
For example:
People need to pay for public parking lots.
Modelling options in MATSim:
A policy often discussed in practice:
Trying to convince people to change their mobility behaviour towards environmentally friendly modes. Therefore people have to try out this alternative.
Modelling options in MATSim:
Forcing people to use a bike / public transit / ride sharing / walk plan and fix it in the choice set.
For example:
Due to technical changes and (monetary) incentives set up by the state, environmentally friendly and low emission cars (and busses) become more attractive. Thus, the vehicle fleet and its distribution of emission levels changes.
Modelling options in MATSim:
In order to model this, "vehicle types" have to be distributed to persons or households, e.g. based on survey data. One could now set a certain percentage of electric / low emission cars and that substitute either randomly chosen cars or older cars.
Therefore we need: