Open source Transport Network Simulation

OpenTNSim is a python package for the investigation of traffic behaviour on networks to compare the consequences of different traffic scenarios and network configurations.

Welcome to OpenTNSim documentation! Please check the contents below for information on installation, getting started and actual example code. If you want to dive straight into the code you can check out our GitHub page or the working examples presented in Jupyter Notebooks. The examples in the notebooks directory are also available as an online book.

_images/book.png

Installation

Stable release

To install OpenTNSim, run this command in your terminal:

# Use pip to install OpenTNSim
pip install opentnsim

This is the preferred method to install OpenTNSim, as it will always install the most recent stable release.

If you do not pip installed, this Python installation guide can guide you through the process.

From sources

The sources for OpenTNSim can be downloaded from the Github repo.

You can either clone the public repository:

# Use git to clone OpenTNSim
git clone git://github.com/TUDelft-CITG/OpenTNSim

Or download the tarball:

# Use curl to obtain the tarball
curl  -OL https://github.com/TUDelft-CITG/OpenTNSim/tarball/master

Once you have a copy of the source, you can install it with:

# Use python to install
python setup.py install

OpenTNSim

This page lists all functions and classes available in the OpenTNSim.model and OpenTNSim.core modules. For examples on how to use these submodules please check out the Examples page, information on installing OpenCLSim can be found on the Installation page.

Submodules

The main components are the Model module and the Core module. All of their components are listed below.

opentnsim.model module

Vessel generator.

class opentnsim.model.Simulation(simulation_start, graph, scenario=None)[source]

Bases: opentnsim.core.Identifiable

A class to generate vessels from a database

add_vessels(origin, destination, vessel=None, vessel_generator=None, arrival_distribution=1, arrival_process='Markovian')[source]

Make arrival process

environment: simpy environment arrival_distribution: specify the distribution from which vessels are generated, int or list arrival_process: process of arrivals

run(duration=86400)[source]

Run the simulation

duration: specify the duration of the simulation in seconds

class opentnsim.model.VesselGenerator(vessel_type, vessel_database, loaded=None, random_seed=3)[source]

Bases: object

A class to generate vessels from a database

arrival_process(environment, origin, destination, arrival_distribution, scenario, arrival_process)[source]

Make arrival process

environment: simpy environment arrival_distribution: specify the distribution from which vessels are generated, int or list arrival_process: process of arrivals

generate(environment, vessel_name, scenario=None)[source]

Generate a vessel

opentnsim.core module

Main module.

class opentnsim.core.ContainerDependentMovable(compute_v, *args, **kwargs)[source]

Bases: opentnsim.core.Movable, opentnsim.core.HasContainer

ContainerDependentMovable class Used for objects that move with a speed dependent on the container level compute_v: a function, given the fraction the container is filled (in [0,1]), returns the current speed

property current_speed
class opentnsim.core.ExtraMetadata(*args, **kwargs)[source]

Bases: object

store all leftover keyword arguments as metadata property (use as last mixin)

class opentnsim.core.HasContainer(capacity, level=0, total_requested=0, *args, **kwargs)[source]

Bases: opentnsim.core.SimpyObject

Mixin class: Something with a storage capacity capacity: amount the container can hold level: amount the container holds initially container: a simpy object that can hold stuff total_requested: a counter that helps to prevent over requesting

property filling_degree
property is_loaded
class opentnsim.core.HasLength(length, remaining_length=0, total_requested=0, *args, **kwargs)[source]

Bases: opentnsim.core.SimpyObject

Mixin class: Something with a storage capacity

capacity: amount the container can hold level: amount the container holds initially total_requested: a counter that helps to prevent over requesting

class opentnsim.core.HasLockDoors(node_1, node_3, *args, **kwargs)[source]

Bases: opentnsim.core.SimpyObject

class opentnsim.core.HasResource(nr_resources=1, priority=False, *args, **kwargs)[source]

Bases: opentnsim.core.SimpyObject

Something that has a resource limitation, a resource request must be granted before the object can be used.

  • nr_resources: nr of requests that can be handled simultaneously

class opentnsim.core.Identifiable(name, id=None, *args, **kwargs)[source]

Bases: object

Mixin class: Something that has a name and id

  • name: a name

  • id: a unique id generated with uuid

class opentnsim.core.IsLock(node_1, node_2, node_3, lock_length, lock_width, lock_depth, doors_open, doors_close, wlev_dif, disch_coeff, grav_acc, opening_area, opening_depth, simulation_start, operating_time, *args, **kwargs)[source]

Bases: opentnsim.core.HasResource, opentnsim.core.HasLength, opentnsim.core.HasLockDoors, opentnsim.core.Identifiable, opentnsim.core.Log

Mixin class: Something has lock object properties - properties in meters - operation in seconds

change_water_level(side)[source]

Change water level and priorities in queue

convert_chamber(environment, new_level, number_of_vessels)[source]

Convert the water level

operation_time(environment)[source]
class opentnsim.core.IsLockLineUpArea(node, lineup_length, *args, **kwargs)[source]

Bases: opentnsim.core.HasResource, opentnsim.core.HasLength, opentnsim.core.Identifiable, opentnsim.core.Log

Mixin class: Something has lock object properties - properties in meters - operation in seconds

class opentnsim.core.IsLockWaitingArea(node, *args, **kwargs)[source]

Bases: opentnsim.core.HasResource, opentnsim.core.Identifiable, opentnsim.core.Log

Mixin class: Something has lock object properties

  • properties in meters

  • operation in seconds

class opentnsim.core.Locatable(geometry, *args, **kwargs)[source]

Bases: object

Mixin class: Something with a geometry (geojson format)

  • geometry: can be a point as well as a polygon

class opentnsim.core.Log(*args, **kwargs)[source]

Bases: opentnsim.core.SimpyObject

Mixin class: Something that has logging capability

log: log message [format: ‘start activity’ or ‘stop activity’] t: timestamp value: a value can be logged as well geometry: value from locatable (lat, lon)

get_log_as_json()[source]
log_entry(log, t, value, geometry_log)[source]

Log

class opentnsim.core.Movable(v, *args, **kwargs)[source]

Bases: opentnsim.core.Locatable, opentnsim.core.Routeable, opentnsim.core.Log

Mixin class: Something can move

Used for object that can move with a fixed speed

  • geometry: point used to track its current location

  • v: speed

property current_speed
move()[source]

determine distance between origin and destination, and yield the time it takes to travel it Assumption is that self.path is in the right order - vessel moves from route[0] to route[-1].

pass_edge(origin, destination)[source]
class opentnsim.core.Neighbours[source]

Bases: object

Can be added to a locatable object (list)

  • travel_to: list of locatables to which can be travelled

class opentnsim.core.Routeable(route, complete_path=None, *args, **kwargs)[source]

Bases: object

Mixin class: Something with a route (networkx format)

  • route: a networkx path

class opentnsim.core.SimpyObject(env, *args, **kwargs)[source]

Bases: object

General object which can be extended by any class requiring a simpy environment

  • env: a simpy Environment

class opentnsim.core.VesselProperties(type, B, L, h_min=None, T=None, C_B=None, H_e=None, H_f=None, T_e=None, T_f=None, safety_margin=None, h_squat=None, payload=None, vessel_type=None, *args, **kwargs)[source]

Bases: object

Mixin class: Something that has vessel properties This mixin is updated to better accommodate the ConsumesEnergy mixin

  • type: can contain info on vessel type (avv class, cemt_class or other)

  • B: vessel width

  • L: vessel length

  • h_min: vessel minimum water depth, can also be extracted from the network edges if they have the property [‘Info’][‘GeneralDepth’]

  • T: actual draught

  • C_B: block coefficient (‘fullness’) [-]

  • safety_margin : the water area above the waterway bed reserved to prevent ship grounding due to ship squatting during sailing, the value of safety margin depends on waterway bed material and ship types. For tanker vessel with rocky bed the safety margin is recommended as 0.3 m based on Van Dorsser et al. The value setting for safety margin depends on the risk attitude of the ship captain and shipping companies.

  • h_squat: the water depth considering ship squatting while the ship moving (if set to False, h_squat is disabled)

  • payload: cargo load [ton], the actual draught can be determined by knowing payload based on van Dorsser et al’s method.(https://www.researchgate.net/publication/344340126_The_effect_of_low_water_on_loading_capacity_of_inland_ships)

  • vessel_type: vessel type can be selected from “Container”,”Dry_SH”,”Dry_DH”,”Barge”,”Tanker”. (“Dry_SH” means dry bulk single hull, “Dry_DH” means dry bulk double hull), based on van Dorsser et al’s paper.(https://www.researchgate.net/publication/344340126_The_effect_of_low_water_on_loading_capacity_of_inland_ships)

Alternatively you can specify draught based on filling degree - H_e: vessel height unloaded - H_f: vessel height loaded - T_e: draught unloaded - T_f: draught loaded

property H

Calculate current height based on filling degree

property T

Compute the actual draught

There are 3 ways to get actual draught - by directly providing actual draught values in the notebook - Or by providing ship draughts in fully loaded state and empty state, the actual draught will be computed based on filling degree

calculate_h_squat(v, h_0)[source]
calculate_max_sinkage(v, h_0)[source]

Calculate the maximum sinkage of a moving ship

the calculation equation is described in Barrass, B. & Derrett, R.’s book (2006), Ship Stability for Masters and Mates, chapter 42. https://doi.org/10.1016/B978-0-08-097093-6.00042-6

some explanation for the variables in the equation: - h_0: water depth - v: ship velocity relative to the water - 150: Here we use the standard width 150 m as the waterway width

get_route(origin, destination, graph=None, minWidth=None, minHeight=None, minDepth=None, randomSeed=4)[source]

Calculate a path based on vessel restrictions

property h_min

Module contents

Contributing

Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given.

You can contribute in many ways:

Types of Contributions

Report Bugs

Report bugs at https://github.com/TUDelft-CITG/OpenTNSim/issues.

If you are reporting a bug, please include:

  • Your operating system name and version.

  • Any details about your local setup that might be helpful in troubleshooting.

  • Detailed steps to reproduce the bug.

Fix Bugs

Look through the GitHub issues for bugs. Anything tagged with “bug” and “help wanted” is open to whoever wants to implement it.

Implement Features

Look through the GitHub issues for features. Anything tagged with “enhancement” and “help wanted” is open to whoever wants to implement it.

Write Documentation

OpenTNSim could always use more documentation, whether as part of the official OpenTNSim docs, in docstrings, or even on the web in blog posts, articles, and such.

Submit Feedback

The best way to send feedback is to file an issue at https://github.com/TUDelft-CITG/OpenTNSim/issues.

If you are proposing a feature:

  • Explain in detail how it would work.

  • Keep the scope as narrow as possible, to make it easier to implement.

  • Remember that this is a volunteer-driven project, and that contributions are welcome :)

Get Started!

Ready to contribute? Here’s how to set up OpenTNSim for local development.

  1. Fork the OpenTNSim repository on GitHub.

  2. Clone your fork locally:

    $ git clone git@github.com:your_name_here/OpenTNSim.git
    
  3. Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development:

    $ mkvirtualenv opentnsim
    $ cd opentnsim/
    $ python setup.py develop
    
  4. Create a branch for local development:

    $ git checkout -b name-of-your-bugfix-or-feature
    

    Now you can make your changes locally.

  5. When you’re done making changes, check that your changes pass flake8 and the tests, including testing other Python versions with tox:

    $ flake8 opentnsim tests
    $ python setup.py test or py.test
    $ tox
    

    To get flake8 and tox, just pip install them into your virtualenv.

  6. The style of OpenTNSim is according to Black. Format your code using Black witht the following lines of code:

    $ black opentnsim
    $ black tests
    

    You can install black using pip.

  7. Commit your changes and push your branch to GitHub:

    $ git add .
    $ git commit -m "Your detailed description of your changes."
    $ git push origin name-of-your-bugfix-or-feature
    
  8. Submit a pull request through the GitHub website.

Pull Request Guidelines

Before you submit a pull request, check that it meets these guidelines:

  1. The pull request should include tests.

  2. If the pull request adds functionality, the docs should be updated. Put your new functionality into a function with a docstring, and add the feature to the list in README.rst.

  3. The pull request should work for Python 3.4, 3.5 and 3.6, and for PyPy. Check CircleCI and make sure that the tests pass for all supported Python versions.

Tips

To run a subset of tests:

$ py.test tests.test_opentnsim

To make the documentation pages $ make docs # for linux/osx

For windows $ del docsopentnsim.rst $ del docsmodules.rst $ sphinx-apidoc -o docs/ opentnsim $ cd docs $ make html $ start explorer _buildhtmlindex.html

Deploying

A reminder for the maintainers on how to deploy. Make sure all your changes are committed (including an entry in HISTORY.rst). Then run:

$ bumpversion patch # possible: major / minor / patch
$ git push
$ git push --tags

Travis will then deploy to PyPI if tests pass.

Credits

Contributors

Various MSc projects

  • Jeroen van der Does de Willebois, 2019. Assessing the impact of quay-wall renovations on the nautical traffic in Amsterdam: A simulation study. MSc thesis. Delft University of Technology, Civil Engineering and Geosciences, Hydraulic Engineering - Ports and Waterways. Delft, the Netherlands.

  • Leonore Vehmeijer, 2019. Measures for the reduction of CO2 emissions, by the inland shipping fleet, on the Rotterdam-Antwerp corridor. MSc thesis. Delft University of Technology, Civil Engineering and Geosciences, Hydraulic Engineering - Ports and Waterways. Delft, the Netherlands.

  • Sophie Ensing, 2019. Agent-based modeling and simulation of public transport to identify effects of network changes on passenger flows. MSc thesis. University of Amsterdam, Faculty of Science, Data Science, Information Studies. Amsterdam, the Netherlands.

  • Loes Segers, 2021. Mapping inland shipping emissions in time and space for the benefit of emission policy development: A case study on the Rotterdam-Antwerp corridor. MSc thesis. Delft University of Technology, Civil Engineering and Geosciences, Hydraulic Engineering - Ports and Waterways. Delft, the Netherlands.

History

1.1.2 (2022-04-05)

  • Final edits for Jiang et al (2022)

1.1.1 (2022-03-24)

  • Updated energy module Jiang et al (2022)

1.1 (2022-03-17)

  • Release energy module Jiang et al (2022)

1.1-beta.2 (2021-05-26)

  • Release in preparation of SmartShipping project

1.1-beta.1 (2021-05-26)

  • Release in preparation of SmartShipping project

1.0.0 (2020-05-07)

  • Release in preparation of SmartShipping project

0.1.0 (2019-07-18)

  • First release to PyPI and rename to OpenTNSim

Version conventions

This package is being developed continuously. Branch protection is turned on for the master branch. Useful new features and bugfixes can be developed in a separate branch or fork. Pull requests can be made to integrate updates into the master branch. To keep track of versions, every change to the master branch will receive a version tag. This page outlines the version tags’ naming convention.

Each change to the master branch is stamped with a unique version identifier. We use sequence based version identifiers, that consist of a sequence of three numbers: the first number is a major change identifier, followed by a minor change idenfier and finally a maintenance identifier. This leads to version identifiers of the form:

major.minor.maintenance (example: 1.2.2)

The following guideline gives an idea what types of changes are considered major changes, minor changes and maintenance:

  • Major changes (typically breaking changes) -> major + 1

  • Minor changes (typically adding of new features) -> minor + 1

  • Maintenance (typically bug fixes and updates in documentation -> maintenance + 1

Indices and tables