API

Domain datatypes

namedtuple ContainerFlowAdjustedToVehicleType(unchanged: float, train: float, barge: float, truck: float, deep_sea_vessel: float, feeder: float)

This is a mapping of all existing vehicle types and the additional entry ‘unchanged’ to the capacity that has been redirected to the respective type.

Fields
  1.  unchanged (float) – Alias for field number 0

  2.  train (float) – Alias for field number 1

  3.  barge (float) – Alias for field number 2

  4.  truck (float) – Alias for field number 3

  5.  deep_sea_vessel (float) – Alias for field number 4

  6.  feeder (float) – Alias for field number 5

enum ContainerLength(value)

The container length is one of the most important factors of how much space a container occupies. Here, the most common container sizes (neglecting height) are represented.

Valid values are as follows:

twenty_feet = <ContainerLength.twenty_feet: 20>

A twenty-foot container

forty_feet = <ContainerLength.forty_feet: 40>

A forty-foot container

forty_five_feet = <ContainerLength.forty_five_feet: 45>

A forty-five-foot container

other = <ContainerLength.other: -1>

Any other length usually does not fit into the standardized slots and handling processes.

The Enum and its members also have the following methods:

classmethod get_factor(container_length: ContainerLength) float
Each container occupies a certain amount of space when stored.

This required space is measured in TEU.

Note

CONTAINER_LENGTH_TO_OCCUPIED_TEU = {<ContainerLength.twenty_feet: 20>: 1, <ContainerLength.forty_feet: 40>: 2, <ContainerLength.forty_five_feet: 45>: 2.25, <ContainerLength.other: -1>: 2.5}

This is the translation table to specify the occupied storage space in TEU. For 20’, 40’, and 45’, the typical values are picked. The TEU factor for the value ‘other’ is chosen to be rather large because it is assumed to be difficult to find a proper storage position.

Parameters

container_length – The length of the container

Returns

The TEU factor of the container

classmethod cast_element_type(text: str) ContainerLength | None
Parameters

text – The text to parse

Returns

The container length enum name if the cast was successful, None otherwise.

namedtuple ContainersAndTEUContainerFlowPair(containers: Dict[ModeOfTransport, Dict[ModeOfTransport, float]], TEU: Dict[ModeOfTransport, Dict[ModeOfTransport, float]])

This is a pair of two container flows, i.e. the number of containers moving from A to B within a given time window. First, it is reported in containers which is important for reporting the efficiency at the interfaces, e.g. moves per hour for the ship-to-shore gantry cranes. Second, it is reported in TEU which is important for the yard capacity.

Fields
  1.  containers (Dict[ModeOfTransport, Dict[ModeOfTransport, float]]) – Alias for field number 0

  2.  TEU (Dict[ModeOfTransport, Dict[ModeOfTransport, float]]) – Alias for field number 1

namedtuple HinterlandModalSplit(train_capacity: float, barge_capacity: float, truck_capacity: float)

This tuple keeps track of how much of the capacity that is either coming from or is destined to the hinterland is transported and by which vehicle type.

Fields
  1.  train_capacity (float) – Alias for field number 0

  2.  barge_capacity (float) – Alias for field number 1

  3.  truck_capacity (float) – Alias for field number 2

enum ModeOfTransport(value)

The mode of transport describes the vehicle type of the vehicle which either drops off or picks up a container.

Valid values are as follows:

truck = <ModeOfTransport.truck: 'truck'>

An external truck is sent by a freight forwarder

train = <ModeOfTransport.train: 'train'>

A freight train is sent by a train operating company

feeder = <ModeOfTransport.feeder: 'feeder'>

A feeder vessel is a rather small vessel sent by a ship operator and moves in the region

deep_sea_vessel = <ModeOfTransport.deep_sea_vessel: 'deep_sea_vessel'>

A deep sea vessel is a rather large vessel sent by a ship operator and moves between distant regions, e.g. continents.

barge = <ModeOfTransport.barge: 'barge'>

A barge is sent by an inland shipping operator

The Enum and its members also have the following methods:

classmethod get_scheduled_vehicles() List[ModeOfTransport]
Returns

A list of vehicles that follow a schedule

classmethod get_unscheduled_vehicles() List[ModeOfTransport]
Returns

A list of vehicles that are created as they are needed to transport a container

namedtuple OutboundUsedAndMaximumCapacity(used: Dict[ModeOfTransport, float], maximum: Dict[ModeOfTransport, float])

This tuple keeps track of how much each vehicle type transports on the outbound journey and what the maximum capacity is.

Fields
  1.  used (Dict[ModeOfTransport, float]) – Alias for field number 0

  2.  maximum (Dict[ModeOfTransport, float]) – Alias for field number 1

namedtuple RequiredAndMaximumCapacityComparison(currently_planned: float, maximum: float, exceeded: bool)

This is a tuple that maintains three separate values for a given vehicle type. First, the currently planned capacity is recorded. Second, the maximum capacity is noted. If more capacity is requested than available, the exceeded flag is true, otherwise false.

Fields
  1.  currently_planned (float) – Alias for field number 0

  2.  maximum (float) – Alias for field number 1

  3.  exceeded (bool) – Alias for field number 2

enum StorageRequirement(value)

A container is stored in different areas of the yard depending on its requirements.

Valid values are as follows:

empty = <StorageRequirement.empty: 'empty'>

An empty container is stored in an empty container yard.

standard = <StorageRequirement.standard: 'standard'>

A standard container is stored in the full container yard and makes up most of the containers passing through a container terminal.

reefer = <StorageRequirement.reefer: 'reefer'>

A reefer container requires electricity (i.e., a reefer plug) to keep the inner temperature on a low level.

dangerous_goods = <StorageRequirement.dangerous_goods: 'dangerous_goods'>

A dangerous goods container needs a specially prepared storage area so they do not constitute a major hazard to health and environment. These are also sometimes referred to as IMO containers.

namedtuple TransshipmentAndHinterlandComparison(transshipment_capacity: float, hinterland_capacity: float)

This tuple keeps track of how much of the capacity is transshipment (i.e., dropped off and picked up by a vessel) and how much is hinterland (i.e., either dropped off or picked up by a vehicle that is not a vessel, e.g. a train or a truck).

Fields
  1.  transshipment_capacity (float) – Alias for field number 0

  2.  hinterland_capacity (float) – Alias for field number 1

namedtuple CompleteVehicleIdentifier(mode_of_transport: ModeOfTransport, service_name: str, vehicle_name: str)

A vehicle identifier is a composition of the vehicle type, its service name, and the actual vehicle name

Fields
  1.  mode_of_transport (ModeOfTransport) – Alias for field number 0

  2.  service_name (str) – Alias for field number 1

  3.  vehicle_name (str) – Alias for field number 2

Setting up ConFlowGen

class DatabaseChooser(sqlite_databases_directory: Optional[str] = None)

This is a stateful library. For the purpose of reproducibility, the current input distributions are all stored in the database, likewise the generated vehicles etc. Thus, different scenarios can be stored in different SQLite databases.

Parameters

sqlite_databases_directory – The DatabaseChooser opens one directory. All databases are saved to and load from this directory. It defaults to <project root>/data/databases/.

close_current_connection() None

Close current connection, e.g. as a preparatory step to create a new SQLite database.

create_new_sqlite_database(file_name: str, overwrite: bool = False, **seeder_options) None

All required tables are created and all input distributions are seeded with default values. These can be simply overwritten by the use-case specific distributions with the help of the API, e.g. the ContainerLengthDistributionManager, ContainerStorageRequirementDistributionManager, ModeOfTransportDistributionManager, TruckArrivalDistributionManager, or similar. By default, no schedules and no vehicles exist.

Parameters
  • file_name – The file name of an SQLite database that will reside in <project root>/data/databases/

  • overwrite – Whether to overwrite an existing database

  • **seeder_options – In case the database is seeded with default values, some variations exist that the user can choose from. The following options exist:

Keyword Arguments

assume_tas (bool) – If a truck appointment system (TAS) is assumed, the corresponding truck arrival distribution is picked.

list_all_sqlite_databases() List[str]
Returns

A list of all SQLite databases in the opened directory

load_existing_sqlite_database(file_name: str) None
Parameters

file_name – The file name of an SQLite database in the opened directory

setup_logger(logging_directory: Optional[str] = None, format_string: Optional[str] = None) Logger

This sets up the default logger with the name ‘conflowgen’. Several classes and functions use the same logger to inform the user about the current progress. This is just a convenience function, you can easily set up your own logger that uses the same name. See e.g. https://docs.python.org/3/howto/logging.html#configuring-logging for how to set up your own logger.

Parameters
  • logging_directory – The path of the directory where to store logging files. Defaults to <project root>/data/logs/.

  • format_string – The format string to use. See e.g. https://docs.python.org/3/library/logging.html#logrecord-attributes for how to create your own format string. Defaults to %(asctime)s - %(name)s - %(levelname)s - %(message)s.

Returns

The set-up logger instance.

Setting input data

With the following classes, the schedules, input values and input distributions are set. These are all required for generating the synthetic data.

class ContainerFlowGenerationManager

This manager provides the interface to set the properties (i.e., not the distributions that are handled elsewhere) and trigger the synthetic container flow generation. If not provided, for many of these values default values exist.

container_flow_data_exists() bool

When an existing database is opened, pre-existing container flow data could already be stored inside. Invoking ContainerFlowGenerationManager.generate() again would reset that stored data. You might want to skip that set and just re-use the data already stored in the database.

Returns

Whether container flow data exists in the database.

generate(overwrite: bool = True) None

Generate the synthetic container flow according to all the information stored in the database so far. This triggers a multistep procedure of generating vehicles and the containers which are delivered or picked up by the vehicles. More is described in the Section Data Generation Process. The invocation of this method overwrites any already existent data in the database. Consider checking for ContainerFlowGenerationManager.container_flow_data_exists() and skip invoking this method.

get_properties() Dict[str, Union[str, date, float, int]]
Returns

The properties of the container flow.

set_properties(start_date: date, end_date: date, name: Optional[str] = None, minimum_dwell_time_of_import_containers_in_hours: Optional[int] = None, maximum_dwell_time_of_import_containers_in_hours: Optional[int] = None, minimum_dwell_time_of_export_containers_in_hours: Optional[int] = None, maximum_dwell_time_of_export_containers_in_hours: Optional[int] = None, minimum_dwell_time_of_transshipment_containers_in_hours: Optional[int] = None, maximum_dwell_time_of_transshipment_containers_in_hours: Optional[int] = None, transportation_buffer: Optional[float] = None) None
Parameters
  • start_date – The earliest day any scheduled vehicle arrives. Trucks that drop off containers might arrive earlier though.

  • end_date – The latest day any scheduled vehicle arrives. Trucks that pick up containers might arrive later though.

  • name – The name of the generated synthetic container flow which helps to distinguish different scenarios.

  • minimum_dwell_time_of_import_containers_in_hours – No vehicle arrives earlier than this amount of hours to pick up an import container that has previously been dropped off.

  • maximum_dwell_time_of_import_containers_in_hours – No vehicles arrives later than this amount of hours after the previous vehicle which has dropped off the import container has arrived.

  • minimum_dwell_time_of_export_containers_in_hours – No vehicle arrives earlier than this amount of hours to pick up an export container that has previously been dropped off.

  • maximum_dwell_time_of_export_containers_in_hours – No vehicles arrives later than this amount of hours after the previous vehicle which has dropped off the export container has arrived.

  • minimum_dwell_time_of_transshipment_containers_in_hours – No vehicle arrives earlier than this amount of hours to pick up a transshipment container that has previously been dropped off.

  • maximum_dwell_time_of_transshipment_containers_in_hours – No vehicles arrives later than this amount of hours after the previous vehicle which has dropped off the transshipment container has arrived.

  • transportation_buffer – Determines how many percent more of the inbound journey capacity is used at most to transport containers on the outbound journey.

class ContainerLengthDistributionManager

This manager provides the interface to set and get the container length distribution.

The default distribution is presented in the section Container Length Distribution.

get_container_length_distribution() Dict[ContainerLength, float]
Returns

The distribution of container lengths. Each length is assigned its frequency of showing up.

set_container_length_distribution(container_lengths: Dict[ContainerLength, float]) None

Set the assumed global distribution of container lengths. This is applied to all vehicles that arrive at the terminal.

Parameters

container_lengths – The distribution of container lengths and their corresponding frequency.

class ContainerStorageRequirementDistributionManager

This is the interface to set and get the storage requirement distribution. It determines how many containers are selected to have a certain StorageRequirement.

get_storage_requirement_distribution() Dict[ContainerLength, Dict[StorageRequirement, float]]
Returns

The distribution of storage requirements based on the length of the container.

set_storage_requirement_distribution(storage_requirements: Dict[ContainerLength, Dict[StorageRequirement, float]]) None

Set the assumed global distribution of container storage requirements. This is applied to all containers passing through the terminal.

Parameters

storage_requirements – The distribution of storage requirements depending on the container length.

class ContainerWeightDistributionManager

This is the interface to set and get the container weight distribution. With the help of this distribution, the weight of each container is drawn. The default distribution is presented in the section Container Weight Distribution.

get_container_weight_distribution() Dict[ContainerLength, Dict[int, float]]
Returns

The distribution of container weights. Each length is assigned its frequency of showing up.

set_container_weight_distribution(container_weights: Dict[ContainerLength, Dict[int, float]]) None

Set the assumed global distribution of container weights.

Parameters

container_weights – The distribution of container weights for the respective container lengths.

class ModeOfTransportDistributionManager

This is the interface to set and get the distribution that controls from which vehicle containers are transshipped to which other type of vehicle.

get_mode_of_transport_distribution() Dict[ModeOfTransport, Dict[ModeOfTransport, float]]
Returns

The distribution of mode of transports dependent on the vehicle the container is delivered by. If a container is delivered by a vehicle of type <first-key>, the floating point number describes the fraction that the container is later picked up by vehicle of type <second-key>.

set_mode_of_transport_distribution(distribution: Dict[ModeOfTransport, Dict[ModeOfTransport, float]]) None
Parameters

distribution – If a container is delivered by a vehicle of type <first-key>, the floating point number describes the fraction that the container is later picked up by vehicle of type <second-key>.

class PortCallManager

This manager provides the interface to create schedules for services that periodically call the container terminal, e.g. ships of any size and trains. This explicitly does not cover the trucks which arrive according to a probability distribution set at TruckArrivalDistributionManager.

add_large_scheduled_vehicle(vehicle_type: ModeOfTransport, service_name: str, vehicle_arrives_at: date, vehicle_arrives_at_time: time, average_vehicle_capacity: int, average_moved_capacity: int, next_destinations: Optional[List[Tuple[str, float]]] = None, vehicle_arrives_every_k_days: Optional[int] = None) None

Add the schedule of a ship of any size or a train. The concrete vehicle instances are automatically generated when ContainerFlowGenerationManager.generate() is invoked.

Parameters
  • vehicle_type – One of ModeOfTransport.deep_sea_vessel, ModeOfTransport.feeder, ModeOfTransport.barge, or ModeOfTransport.train

  • service_name – The name of the service, i.e. the shipping line or rail freight line

  • vehicle_arrives_at – A date the service would arrive at the terminal. This can e.g. point at the week day for weekly services. In any case, this is combined with the parameter vehicle_arrives_every_k_days and only arrivals within the time scope between start_date and end_date are considered.

  • vehicle_arrives_at_time – A time of the day (between 00:00 and 23:59).

  • average_vehicle_capacity – Number of TEU that can be transported with the vehicle at most. The number of moved containers can never exceed this number, no matter what the value for the transportation_buffer is set to.

  • average_moved_capacity

    The average moved capacity describes the number of TEU which the vehicle delivers to the terminal on its inbound journey. When summing up the TEU factors of each of the loaded containers on the inbound journey, this value is never exceeded but closely approximated. For the outbound journey, the containers are assigned depending on the distribution kept in ModeOfTransportDistributionManager. The maximum number of containers in TEU on the outbound journey of the vehicle is bound by

    \[min( \text{average_moved_capacity} \cdot \text{transportation_buffer},\text{average_vehicle_capacity} )\]

    If you have calibrated the aforementioned distribution accordingly, the actual number of containers on the outbound journey in TEU should be on average the same as on the inbound journey. In that case, the vehicle moves average_moved_capacity number of containers in TEU on its inbound journey and the same number of containers in TEU again on its outbound journey.

  • next_destinations – Pairs of destination and frequency of the destination being chosen.

  • vehicle_arrives_every_k_days – Defaults to weekly services (arrival every 7 days). Other frequencies are possible as well. In the special case of -1, only a single arrival is scheduled for day vehicle_arrives_at as long as the specified date lies within start_date and end_date. This arrival is only part of the generated container flow if that arrival lies between start_date and end_date.

has_schedule(service_name: str, vehicle_type: ModeOfTransport) bool
Parameters
  • service_name – The name of the service which moves to a schedule that is sought for.

  • vehicle_type – The mode of transport to restrict the search to.

Returns

Whether the requested schedule already exist in the database.

class TruckArrivalDistributionManager

This manager provides the interface to set and get the weekly arrival rates of trucks. When the truck arrival time is drawn from this distribution, first a slice for the minimum and maximum dwell time is created and the arrival time of the truck is drawn from that period. All other vehicles are created based on the schedule they adhere to with the help of the PortCallManager

get_truck_arrival_distribution() Dict[int, float]

Each key represents the hour in the week and each value represents the probability of a truck to arrive between that hour and the start of the next time slot (the successor is the nearest key larger than the current key).

Returns

The truck arrival distribution.

set_truck_arrival_distribution(distribution: Dict[int, float]) None
Parameters

distribution – The truck arrival distribution. Each key represents the hour in the week and each value represents the probability of a truck to arrive between that hour and the start of the next time slot (the successor is the nearest key larger than the current key).

Getting previews

class ContainerFlowByVehicleTypePreview(start_date: date, end_date: date, transportation_buffer: float)

This preview tells the user how many containers are planned to be transshipped between which types of vehicles.

The preview returns a data structure that can be used for generating reports (e.g., in text or as a figure) as it is the case with ContainerFlowByVehicleTypePreviewReport. The preview is intended to provide a first estimate before running the expensive ContainerFlowGenerationManager.generate() method. The preview does not consider all restrictions (such as container dwell times in combination with the schedules) into consideration, thus later deviations might exist.

Parameters
  • start_date – The earliest day to consider when checking the vehicles that move according to schedules

  • end_date – The latest day to consider when checking the vehicles that move according to schedules

  • transportation_buffer – The fraction of how much more a vehicle takes with it on an outbound journey compared to an inbound journey as long as the total vehicle capacity is not exceeded.

get_inbound_to_outbound_flow() Dict[ModeOfTransport, Dict[ModeOfTransport, float]]

The estimated flow of containers from vehicles on their inbound journey to vehicles on their outbound journey based on the mode of transport distribution.

Returns

A flow from vehicle type A to vehicle type B estimated in TEU.

hypothesize_with_mode_of_transport_distribution(mode_of_transport_distribution: Dict[ModeOfTransport, Dict[ModeOfTransport, float]])

This allows to see the effect of different mode of transport distributions on this preview.

Parameters

mode_of_transport_distribution – A mode of transport distribution to try out

class ContainerFlowByVehicleTypePreviewReport

This preview report takes the data structure as generated by ContainerFlowByVehicleTypePreview and creates a comprehensible representation for the user, either as text or as a graph. The visual and table are expected to approximately look like in the example ContainerFlowByVehicleTypePreviewReport.

get_report_as_graph() object

The container flow is represented by a Sankey diagram.

Returns

The plotly figure of the Sankey diagram.

Note

At the time of writing, plotly comes with some shortcomings.

However, it seems to be the best available library for plotting Sankey diagrams that can be visualized e.g. in a Jupyter Notebook.

get_report_as_text() str

The report as a text is represented as a table suitable for logging. It uses a human-readable formatting style.

Returns

The report in text format (possibly spanning over several lines).

class InboundAndOutboundVehicleCapacityPreview(start_date: date, end_date: date, transportation_buffer: float)

This preview examines how much the inbound vehicles deliver to the terminal and how it is redistributed to the outbound journeys of the other vehicles according to the mode of transport distribution. This pre-checks whether the transport capacity of the vehicles will be exceeded. In such case, the input schedules and distributions should be further refined before generating a container flow.

The preview returns a data structure that can be used for generating reports (e.g., in text or as a figure) as it is the case with InboundAndOutboundVehicleCapacityPreviewReport. The preview is intended to provide a first estimate before running the expensive ContainerFlowGenerationManager.generate() method. The preview does not consider all restrictions (such as container dwell times in combination with the schedules) into consideration, thus later deviations might exist.

Parameters
  • start_date – The earliest day to consider when checking the vehicles that move according to schedules

  • end_date – The latest day to consider when checking the vehicles that move according to schedules

  • transportation_buffer – The fraction of how much more a vehicle takes with it on an outbound journey compared to an inbound journey as long as the total vehicle capacity is not exceeded.

get_inbound_capacity_of_vehicles() Dict[ModeOfTransport, float]

For the inbound capacity, first vehicles that adhere to a schedule are considered. Trucks, which are created depending on the outbound distribution, are created based on the assumptions of the further container flow generation process.

get_outbound_capacity_of_vehicles() OutboundUsedAndMaximumCapacity

For the outbound capacity, both the used outbound capacity (estimated) and the maximum outbound capacity is reported. If a vehicle type reaches the maximum outbound capacity, this means that containers need to be redistributed to other vehicle types due to a lack of capacity.

hypothesize_with_mode_of_transport_distribution(mode_of_transport_distribution: Dict[ModeOfTransport, Dict[ModeOfTransport, float]])

This allows to see the effect of different mode of transport distributions on this preview.

Parameters

mode_of_transport_distribution – A mode of transport distribution to try out

class InboundAndOutboundVehicleCapacityPreviewReport

This preview report takes the data structure as generated by InboundAndOutboundVehicleCapacityPreview and creates a comprehensible representation for the user, either as text or as a graph. A similar report can be found at VehicleCapacityExceededPreviewReport. The visual and table are expected to approximately look like in the example InboundAndOutboundVehicleCapacityPreviewReport.

get_report_as_graph() object

The report as a graph is represented as a bar chart using pandas.

Returns

The matplotlib axis of the bar chart.

get_report_as_text() str

The report as a text is represented as a table suitable for logging. It uses a human-readable formatting style.

Returns

The report in text format (possibly spanning over several lines).

class ModalSplitPreview(start_date: date, end_date: date, transportation_buffer: float)

This preview examines the inbound and/or outbound journeys and estimates the modal split. This is separated into two different aspects. First, the transshipment share is indicated. For the hinterland, the modal split is reported.

The preview returns a data structure that can be used for generating reports (e.g., in text or as a figure) as it is the case with ModalSplitPreviewReport. The preview is intended to provide a first estimate before running the expensive ContainerFlowGenerationManager.generate() method. The preview does not consider all restrictions (such as container dwell times in combination with the schedules) into consideration, thus later deviations might exist.

Parameters
  • start_date – The earliest day to consider when checking the vehicles that move according to schedules

  • end_date – The latest day to consider when checking the vehicles that move according to schedules

  • transportation_buffer – The fraction of how much more a vehicle takes with it on an outbound journey compared to an inbound journey as long as the total vehicle capacity is not exceeded.

get_modal_split_for_hinterland(inbound: bool, outbound: bool) HinterlandModalSplit
Parameters
  • inbound – Whether to account for inbound journeys

  • outbound – Whether to account for outbound journeys

Returns

The estimated modal split for the hinterland

get_transshipment_and_hinterland_share() TransshipmentAndHinterlandComparison
Returns

The amount of containers in TEU dedicated for or coming from the hinterland versus the amount of containers in TEU that are transshipped.

hypothesize_with_mode_of_transport_distribution(mode_of_transport_distribution: Dict[ModeOfTransport, Dict[ModeOfTransport, float]])

This allows to see the effect of different mode of transport distributions on this preview.

Parameters

mode_of_transport_distribution – A mode of transport distribution to try out

class ModalSplitPreviewReport

This preview report takes the data structure as generated by ModalSplitPreview and creates a comprehensible representation for the user, either as text or as a graph. The visual and table are expected to approximately look like in the example ModalSplitPreviewReport.

get_report_as_graph() object

The report as a graph is represented as a set of pie charts using pandas.

Returns

The matplotlib axis of the last bar chart.

Todo

All pie charts should be plotted in a single plot using subplots.

get_report_as_text() str

The report as a text is represented as a table suitable for logging. It uses a human-readable formatting style.

Returns

The report in text format (possibly spanning over several lines).

run_all_previews(as_text: bool = True, as_graph: bool = False, display_text_func: Optional[Callable] = None, display_in_markup_language: Optional[Union[DisplayAsMarkupLanguage, str]] = None, static_graphs: bool = False) None

Runs all preview analyses in sequence. This is just a convenience function to ensure that all reports are presented. The text output is logged to the logger with the name ‘conflowgen’ by default. See setup_logger() for more details.

Parameters
  • as_text – Whether to get the reports as text and log them.

  • as_graph – Whether to display the reports as graphs (visualizations will pop up).

  • display_text_func – The function to use to display the text. Defaults to logger.info().

  • display_in_markup_language – The markup language to use. Currently, the options ‘markdown’ and ‘plaintext’ exist. Defaults to DisplayAsPlainText (same as ‘plaintext’), users can provide their own approach with DisplayAsMarkupLanguage.

  • static_graphs – Whether the graphs should be static. Plotly has some nice interactive options that are currently not supported inside some websites such as the HTML version of the documentation. In such cases, the static version of the plots is used.

class VehicleCapacityExceededPreview(start_date: date, end_date: date, transportation_buffer: float)

The preview examines the outbound traffic and checks if the intended transportation demands can be satisfied by the existing transport capacities (per vehicle type).

The preview returns a data structure that can be used for generating reports (e.g., in text or as a figure) as it is the case with VehicleCapacityExceededPreviewReport. The preview is intended to provide a first estimate before running ContainerFlowGenerationManager.generate() which is time-consuming. The preview does not consider all restrictions (such as container dwell times in combination with the schedules) into consideration, thus later deviations might exist.

Parameters
  • start_date – The earliest day to consider when checking the vehicles that move according to schedules

  • end_date – The latest day to consider when checking the vehicles that move according to schedules

  • transportation_buffer – The fraction of how much more a vehicle takes with it on an outbound journey compared to an inbound journey as long as the total vehicle capacity is not exceeded.

compare() Dict[ModeOfTransport, RequiredAndMaximumCapacityComparison]

Compare the required capacity of vehicles on their outbound journey to transport all containers and the maximum capacity of the vehicles on their outbound journey. If the maximum capacity of the vehicles is exceeded, this mismatch is indicated (per vehicle type, in TEU).

hypothesize_with_mode_of_transport_distribution(mode_of_transport_distribution: Dict[ModeOfTransport, Dict[ModeOfTransport, float]])

This allows to see the effect of different mode of transport distributions on this preview.

Parameters

mode_of_transport_distribution – A mode of transport distribution to try out

class VehicleCapacityExceededPreviewReport

This preview report takes the data structure as generated by VehicleCapacityExceededPreview and creates a comprehensible representation for the user, either as text or as a graph. A similar report can be found at InboundAndOutboundVehicleCapacityPreviewReport. The visual and table are expected to approximately look like in the example InboundAndOutboundVehicleCapacityPreviewReport.

get_report_as_graph() object
Returns

The matplotlib axis of the bar chart.

get_report_as_text() str

The report as a text is represented as a table suitable for logging. It uses a human-readable formatting style.

Returns

The report in text format (possibly spanning over several lines).

Getting analyses

class ContainerFlowAdjustmentByVehicleTypeAnalysis(transportation_buffer: Optional[float] = None)

This analysis can be run after the synthetic data has been generated. The analysis returns a data structure that can be used for generating reports (e.g., in text or as a figure) as it is the case with ContainerFlowAdjustmentByVehicleTypeAnalysisReport.

Parameters

transportation_buffer – The buffer, e.g. 0.2 means that 20% more containers (in TEU) can be put on a vessel compared to the amount of containers it had on its inbound journey - as long as the total vehicle capacity would not be exceeded.

static get_initial_to_adjusted_outbound_flow() ContainersAndTEUContainerFlowPair

When containers are generated, in order to obey the maximum dwell time, the vehicle type that is used for onward transportation might change. The initial outbound vehicle type is the vehicle type that is drawn randomly for a container at the time of generation. The adjusted vehicle type is the vehicle type that is drawn in case no vehicle of the initial outbound vehicle type is left within the maximum dwell time.

Returns

The data structure describes how often an initial outbound vehicle type had to be adjusted with which other vehicle type.

class ContainerFlowAdjustmentByVehicleTypeAnalysisReport

This analysis report takes the data structure as generated by ContainerFlowAdjustmentByVehicleTypeAnalysis and creates a comprehensible representation for the user, either as text or as a graph.

get_report_as_graph() object

The container flow is represented by a Sankey diagram.

Note

At the time of writing, plotly comes with some shortcomings.

However, it seems to be the best available library for plotting Sankey diagrams that can be visualized e.g. in a Jupyter Notebook.

Returns

The plotly figure of the Sankey diagram.

get_report_as_text() str

The report as a text is represented as a table suitable for logging. It uses a human-readable formatting style.

Returns

The report in text format (possibly spanning over several lines).

class ContainerFlowAdjustmentByVehicleTypeAnalysisSummary(transportation_buffer: Optional[float] = None)

This analysis summary can be run after the synthetic data has been generated. The analysis summary returns a data structure that can be used for generating reports (e.g., in text or as a figure) as it is the case with ContainerFlowAdjustmentByVehicleTypeAnalysisSummaryReport.

Parameters

transportation_buffer – The buffer, e.g. 0.2 means that 20% more containers (in TEU) can be put on a vessel compared to the amount of containers it had on its inbound journey - as long as the total vehicle capacity would not be exceeded.

get_summary() ContainerFlowAdjustedToVehicleType

Under certain circumstances (as explained in ContainerFlowAdjustmentByVehicleTypeAnalysis.get_initial_to_adjusted_outbound_flow()), the containers must change the vehicle they leave the yard with. Thus, the question remains how often this has been the case and which vehicles were the primary target for this redirected traffic? The capacity is expressed in TEU.

class ContainerFlowAdjustmentByVehicleTypeAnalysisSummaryReport

This analysis report takes the data structure as generated by ContainerFlowAdjustmentByVehicleTypeAnalysisSummary and creates a comprehensible representation for the user, either as text or as a graph.

get_report_as_graph() object

The report as a graph is represented as a pie chart.

Returns

The matplotlib axis of the pie chart.

get_report_as_text() str

The report as a text is represented as a table suitable for logging. It uses a human-readable formatting style.

Returns

The report in text format (possibly spanning over several lines).

class ContainerFlowByVehicleTypeAnalysis(transportation_buffer: Optional[float] = None)

This analysis can be run after the synthetic data has been generated. The analysis returns a data structure that can be used for generating reports (e.g., in text or as a figure) as it is the case with ContainerFlowByVehicleTypeAnalysisReport.

Parameters

transportation_buffer – The buffer, e.g. 0.2 means that 20% more containers (in TEU) can be put on a vessel compared to the amount of containers it had on its inbound journey - as long as the total vehicle capacity would not be exceeded.

static get_inbound_to_outbound_flow(as_teu: bool = True) Dict[ModeOfTransport, Dict[ModeOfTransport, float]]

This is the overview of the generated inbound to outbound container flow by vehicle type.

class ContainerFlowByVehicleTypeAnalysisReport

This analysis report takes the data structure as generated by ContainerFlowByVehicleTypeAnalysis and creates a comprehensible representation for the user, either as text or as a graph.

get_report_as_graph() object

The container flow is represented by a Sankey diagram.

Returns

The plotly figure of the Sankey diagram.

Note

At the time of writing, plotly comes with some shortcomings.

However, it seems to be the best available library for plotting Sankey diagrams that can be visualized e.g. in a Jupyter Notebook.

get_report_as_text() str

The report as a text is represented as a table suitable for logging. It uses a human-readable formatting style.

Returns

The report in text format (possibly spanning over several lines).

class InboundAndOutboundVehicleCapacityAnalysis(transportation_buffer: float)

This analysis can be run after the synthetic data has been generated. The analysis returns a data structure that can be used for generating reports (e.g., in text or as a figure) as it is the case with InboundAndOutboundVehicleCapacityAnalysisReport.

Parameters

transportation_buffer – The buffer, e.g. 0.2 means that 20% more containers (in TEU) can be put on a vessel compared to the amount of containers it had on its inbound journey - as long as the total vehicle capacity would not be exceeded.

static get_inbound_capacity_of_vehicles() Dict[ModeOfTransport, float]

This is the used capacity of all vehicles separated by vehicle type on their inbound journey in TEU.

get_outbound_capacity_of_vehicles() OutboundUsedAndMaximumCapacity

This is the used and the maximum capacity of all vehicles separated by vehicle type on their outbound journey in TEU. If for a vehicle type, the used capacity is very close to the maximum capacity, you might want to reconsider the mode of transport distribution. See ModeOfTransportDistributionManager for further details.

class InboundAndOutboundVehicleCapacityAnalysisReport

This analysis report takes the data structure as generated by InboundAndOutboundVehicleCapacityAnalysis and creates a comprehensible representation for the user, either as text or as a graph.

get_report_as_graph() object

The report as a graph is represented as a bar chart using pandas.

Returns

The matplotlib axis of the bar chart.

get_report_as_text() str

The report as a text is represented as a table suitable for logging. It uses a human-readable formatting style.

Returns

The report in text format (possibly spanning over several lines).

class InboundToOutboundVehicleCapacityUtilizationAnalysis(transportation_buffer: float)

This analysis can be run after the synthetic data has been generated. The analysis returns a data structure that can be used for generating reports (e.g., in text or as a figure) as it is the case with InboundToOutboundCapacityUtilizationAnalysisReport.

Parameters

transportation_buffer – The buffer, e.g. 0.2 means that 20% more containers (in TEU) can be put on a vessel compared to the amount of containers it had on its inbound journey - as long as the total vehicle capacity would not be exceeded.

static get_inbound_and_outbound_capacity_of_each_vehicle(vehicle_type='all') Dict[CompleteVehicleIdentifier, Tuple[float, float]]
Parameters

vehicle_type – Either "all", a single vehicle of type ModeOfTransport or a whole collection of vehicle types, e.g. passed as a list or set. Only the vehicles that correspond to the provided vehicle type(s) are considered in the analysis.

Returns

The transported containers of each vehicle on their inbound and outbound journey in TEU.

class InboundToOutboundVehicleCapacityUtilizationAnalysisReport

This analysis report takes the data structure as generated by InboundToOutboundCapacityUtilizationAnalysis and creates a comprehensible representation for the user, either as text or as a graph.

get_report_as_graph(**kwargs) object

The report as a graph is represented as a scatter plot using pandas.

Keyword Arguments
Returns

The matplotlib figure

get_report_as_text(**kwargs) str

The report as a text is represented as a table suitable for logging. It uses a human-readable formatting style.

Keyword Arguments

vehicle_type – Either "all", a single vehicle of type ModeOfTransport or a whole collection of vehicle types, e.g. passed as a list or set. For the exact interpretation of the parameter, check InboundToOutboundVehicleCapacityUtilizationAnalysis.

Returns

The report in text format (possibly spanning over several lines).

class ModalSplitAnalysis

This analysis can be run after the synthetic data has been generated. The analysis returns a data structure that can be used for generating reports (e.g., in text or as a figure) as it is the case with ModalSplitAnalysisReport.

Parameters

transportation_buffer – The buffer, e.g. 0.2 means that 20% more containers (in TEU) can be put on a vessel compared to the amount of containers it had on its inbound journey - as long as the total vehicle capacity would not be exceeded.

get_modal_split_for_hinterland(inbound: bool, outbound: bool) HinterlandModalSplit
Parameters
  • inbound – Whether to account for inbound journeys

  • outbound – Whether to account for outbound journeys

Returns

The modal split for the hinterland as generated.

get_transshipment_and_hinterland_fraction() TransshipmentAndHinterlandComparison
Returns

The amount of containers in TEU dedicated for or coming from the hinterland versus the amount of containers in TEU that are transshipped.

class ModalSplitAnalysisReport

This analysis report takes the data structure as generated by ModalSplitAnalysis and creates a comprehensible representation for the user, either as text or as a graph.

get_report_as_graph() object

The report as a graph is represented as a set of pie charts using pandas.

Returns

The matplotlib axis of the last bar chart.

Todo

All pie charts should be plotted in a single plot using subplots.

get_report_as_text() str

The report as a text is represented as a table suitable for logging. It uses a human-readable formatting style.

class QuaySideThroughputAnalysis(transportation_buffer: Optional[float] = None)

This analysis can be run after the synthetic data has been generated. The analysis returns a data structure that can be used for generating reports (e.g., in text or as a figure) as it is the case with QuaySideThroughputAnalysisReport.

Parameters

transportation_buffer – The buffer, e.g. 0.2 means that 20% more containers (in TEU) can be put on a vessel compared to the amount of containers it had on its inbound journey - as long as the total vehicle capacity would not be exceeded.

classmethod get_throughput_over_time(inbound: bool = True, outbound: bool = True) Dict[date, float]

For each week, the containers crossing the quay are checked. Based on this, the required quay capacity in boxes can be deduced - it is the maximum of these values (based on all the assumptions, in reality an additional buffer might be reasonable to add).

The rather coarse time window is due to the fact that the discharging and loading process are not modelled. At this stage, as a simplification all containers arriving with a vessel are discharged at once and all containers departing with a vessel are loaded at once. This is smoothed by the larger time window.

Parameters
  • inbound – Whether to check for vessels which deliver a container on their inbound journey

  • outbound – Whether to check for vessels which pick up a container on their outbound journey

class QuaySideThroughputAnalysisReport

This analysis report takes the data structure as generated by QuaySideThroughputAnalysis and creates a comprehensible representation for the user, either as text or as a graph.

get_report_as_graph() object

The report as a graph is represented as a line graph using pandas.

Returns

The matplotlib axis of the bar chart.

get_report_as_text() str

The report as a text is represented as a table suitable for logging. It uses a human-readable formatting style.

Returns

The report in text format (possibly spanning over several lines).

run_all_analyses(as_text: bool = True, as_graph: bool = False, display_text_func: Optional[Callable] = None, display_in_markup_language: Optional[Union[DisplayAsMarkupLanguage, str]] = None, static_graphs: bool = False) None

Runs all post-hoc analyses in sequence. This is just a convenience function to ensure that all reports are presented. The text output is logged to the logger with the name ‘conflowgen’ by default.. See setup_logger() for more details.

Parameters
  • as_text – Whether to get the reports as text and log them

  • as_graph – Whether to display the reports as graphs (visualizations will pop up)

  • display_text_func – The function to use to display the text. Defaults to logger.info().

  • display_in_markup_language – The markup language to use. Currently, the options ‘markdown’ and ‘plaintext’ exist. Defaults to DisplayAsPlainText (same as ‘plaintext’), users can provide their own approach with DisplayAsMarkupLanguage.

  • static_graphs – Whether the graphs should be static. Plotly has some nice interactive options that are currently not supported inside some websites such as the HTML version of the documentation. In such cases, the static version of the plots is used.

class TruckGateThroughputAnalysis(transportation_buffer: Optional[float] = None)

This analysis can be run after the synthetic data has been generated. The analysis returns a data structure that can be used for generating reports (e.g., in text or as a figure) as it is the case with TruckGateThroughputAnalysisReport.

Parameters

transportation_buffer – The buffer, e.g. 0.2 means that 20% more containers (in TEU) can be put on a vessel compared to the amount of containers it had on its inbound journey - as long as the total vehicle capacity would not be exceeded.

classmethod get_throughput_over_time(inbound: bool = True, outbound: bool = True) Dict[datetime, float]

For each hour, the trucks entering through the truck gate are checked. Based on this, the required truck gate capacity in boxes can be deduced.

Parameters
  • inbound – Whether to check for trucks which deliver a container on their inbound journey

  • outbound – Whether to check for trucks which pick up a container on their outbound journey

class TruckGateThroughputAnalysisReport

This analysis report takes the data structure as generated by TruckGateThroughputAnalysis and creates a comprehensible representation for the user, either as text or as a graph.

get_report_as_graph() object

The report as a graph is represented as a line graph using pandas.

Returns

The matplotlib axis of the bar chart.

get_report_as_text() str

The report as a text is represented as a table suitable for logging. It uses a human-readable formatting style.

Returns

The report in text format (possibly spanning over several lines).

class YardCapacityAnalysis(transportation_buffer: Optional[float] = None)

This analysis can be run after the synthetic data has been generated. The analysis returns a data structure that can be used for generating reports (e.g., in text or as a figure) as it is the case with YardCapacityAnalysisReport.

Parameters

transportation_buffer – The buffer, e.g. 0.2 means that 20% more containers (in TEU) can be put on a vessel compared to the amount of containers it had on its inbound journey - as long as the total vehicle capacity would not be exceeded.

static get_used_yard_capacity_over_time(storage_requirement: Union[str, Collection, StorageRequirement] = 'all') Dict[datetime, float]

For each hour, the containers entering and leaving the yard are checked. Based on this, the required yard capacity in TEU can be deduced - it is simply the maximum of these values. In addition, with the parameter storage_requirement the yard capacity can be filtered, e.g. to only include standard containers, empty containers, or any other kind of subset.

Please be aware that this method slightly overestimates the required capacity. If one container leaves the yard at the beginning of the respective time window and another container enters the yard at the end of the same time window, still the TEU equivalence of both containers is recorded as the required yard capacity. Obviously the entering container could use the same slot as the container which entered later. This minor inaccuracy might be of little importance because no yard should be planned that tight. The benefit is that it further allows a faster computation.

Parameters

storage_requirement – One of "all", a collection of StorageRequirement enum values (as a list, set, or similar), or a single StorageRequirement enum value.

Returns

A series of the used yard capacity in TEU over the time.

class YardCapacityAnalysisReport

This analysis report takes the data structure as generated by YardCapacityAnalysis and creates a comprehensible representation for the user, either as text or as a graph.

get_report_as_graph(**kwargs) object

The report as a graph is represented as a line graph using pandas.

Keyword Arguments

storage_requirement – Either a single storage requirement of type StorageRequirement or a whole collection of them e.g. passed as a list or set. For the exact interpretation of the parameter, check YardCapacityAnalysis.get_used_yard_capacity_over_time().

Returns

The matplotlib axis of the bar chart.

get_report_as_text(**kwargs) str

The report as a text is represented as a table suitable for logging. It uses a human-readable formatting style.

Keyword Arguments

storage_requirement – Either a single storage requirement of type StorageRequirement or a whole collection of them e.g. passed as a list or set. For the exact interpretation of the parameter, check YardCapacityAnalysis.get_used_yard_capacity_over_time().

Returns

The report in text format (possibly spanning over several lines).

Working with reports

When working with run_all_previews() or run_all_analyses(), there is some common functionality. If you wish to add another markup language besides plaintext and markdown for these two lists of reports, you can define them here and pass them as parameters to the aforementioned functions.

class DisplayAsMarkdown(display_markdown_func: Callable)

With this style, the output is set in Markdown. This is e.g. helpful when showing the output in Jupyter Notebooks.

display_explanation(text: str)
Parameters

text – The text of an explanatory text (shown in normal font, wrapped if required). Different paragraphs are separated by repeated invocations of this method.

display_headline(text: str, level: int = 3)
Parameters
  • text – The text of the headline

  • level – The level of the headline, 1 being the upmost headline. The number of levels depends on the markup language.

display_verbatim(text: str)
Parameters

text – The text of the verbatim block (shown as-is)

class DisplayAsMarkupLanguage

This is the abstract class new markup language definitions can derive from.

abstract display_explanation(text: str) None
Parameters

text – The text of an explanatory text (shown in normal font, wrapped if required). Different paragraphs are separated by repeated invocations of this method.

abstract display_headline(text: str, level: int) None
Parameters
  • text – The text of the headline

  • level – The level of the headline, 1 being the upmost headline. The number of levels depends on the markup language.

abstract display_verbatim(text: str) None
Parameters

text – The text of the verbatim block (shown as-is)

class DisplayAsPlainText(display_text_func: Callable)

With this style, the output is simply returned in a plain manner. This is e.g. helpful when logging the text.

display_explanation(text: str)
Parameters

text – The text of an explanatory text (shown in normal font, wrapped if required). Different paragraphs are separated by repeated invocations of this method.

display_headline(text: str, level: int = -1)
Parameters
  • text – The text of the headline.

  • level – The level of the headline is not supported for the plaintext mode.

display_verbatim(text: str)
Parameters

text – The text of the verbatim block (shown as-is)

Exporting data

class ExportContainerFlowManager

In the SQLite databases all data is stored. This might not be the right format for further usage though. This manager provides the interface to export the container flow, excluding the input distributions etc., so that they can be read in easily for the next step, e.g. a routine in a simulation model or mathematical optimization script.

export(folder_name: str, path_to_export_folder: Optional[str] = None, file_format: Optional[ExportFileFormat] = None, overwrite: bool = False) str

This extracts the container movement data from the SQL database to a folder of choice in a tabular data format.

Parameters
  • folder_name – Name of folder that bundles the tabular data which belongs together

  • path_to_export_folder – Path to directory where all exports are kept, defaults to <project root>/data/exports/

  • file_format – Desired tabular format, defaults to ExportFileFormat.csv.

  • overwrite – Whether to overwrite previously exported data, defaults to False

Returns

The path to the folder where the tabular data is located

enum ExportFileFormat(value)

The export file format supports tables. The export function enables the user to read in the generated synthetic data into another tool, such as a software for mathematical optimization or discrete event simulation.

Valid values are as follows:

csv = <ExportFileFormat.csv: 'csv'>

Comma-separated values files are very simplistic representation but unrestricted and widely supported.

xlsx = <ExportFileFormat.xlsx: 'xlsx'>

The xlsx file format can be opened by e.g. Microsoft Excel which might help to quickly analyse the output data. However, this file format comes with known limitations listed at https://support.microsoft.com/en-us/office/excel-specifications-and-limits-1672b34d-7043-467e-8e27-269d656771c3. On January 4th, 2022, the known maximum number of rows is 1,048,576. Thus, if e.g. 1.1 million containers are generated, opening this xlsx file in Excel is not supported by the specifications.

xls = <ExportFileFormat.xls: 'xls'>

The xls format is the precursor of the xlsx format. This should only be used if a software demands this file format. Older versions of Excel had more restrictions on the size, e.g. Excel 2003 is known to have only supported 65,536 rows (see e.g. http://web.archive.org/web/20140819001409/http://news.office-watch.com/t/n.aspx?articleid=1408&zoneid=9) which is less than what large terminals nowadays handle within a month. Even with a hypothetical TEU factor of 2, this only reaches 1,572,864 TEU throughput per year.