-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
529 additions
and
195 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import typing | ||
from abc import ABC | ||
from datetime import datetime | ||
|
||
from conflowgen.data_summaries.data_summaries_cache import DataSummariesCache | ||
from conflowgen.domain_models.distribution_repositories.container_length_distribution_repository import \ | ||
ContainerLengthDistributionRepository | ||
from conflowgen.previews.container_flow_by_vehicle_type_preview import ContainerFlowByVehicleTypePreview | ||
from conflowgen.domain_models.data_types.mode_of_transport import ModeOfTransport | ||
from conflowgen.domain_models.distribution_validators import validate_distribution_with_one_dependent_variable | ||
from conflowgen.previews.abstract_preview import AbstractPreview | ||
from conflowgen.descriptive_datatypes import InboundAndOutboundContainerVolume, ContainerVolume | ||
|
||
|
||
class QuaySideThroughputPreview(AbstractPreview, ABC): | ||
""" | ||
This preview calculates the quayside throughput based on the schedules. | ||
The preview returns a data structure that can be used for generating reports (e.g., in text or as a figure). The | ||
preview is intended to provide an estimate of the quayside throughput for the given inputs. | ||
""" | ||
|
||
QUAY_SIDE_VEHICLES = { | ||
ModeOfTransport.deep_sea_vessel, | ||
ModeOfTransport.feeder, | ||
# barges are counted as hinterland here | ||
} | ||
|
||
def __init__(self, start_date: datetime.date, end_date: datetime.date, transportation_buffer: float): | ||
super().__init__(start_date, end_date, transportation_buffer) | ||
self.container_flow_by_vehicle_type = ( | ||
ContainerFlowByVehicleTypePreview( | ||
self.start_date, | ||
self.end_date, | ||
self.transportation_buffer, | ||
) | ||
) | ||
|
||
@DataSummariesCache.cache_result | ||
def hypothesize_with_mode_of_transport_distribution( | ||
self, | ||
mode_of_transport_distribution: typing.Dict[ModeOfTransport, typing.Dict[ModeOfTransport, float]] | ||
): | ||
validate_distribution_with_one_dependent_variable( | ||
mode_of_transport_distribution, ModeOfTransport, ModeOfTransport, values_are_frequencies=True | ||
) | ||
self.container_flow_by_vehicle_type.hypothesize_with_mode_of_transport_distribution( | ||
mode_of_transport_distribution | ||
) | ||
|
||
|
||
@DataSummariesCache.cache_result | ||
def get_quay_side_throughput(self) -> InboundAndOutboundContainerVolume: | ||
inbound_to_outbound_flow = self.container_flow_by_vehicle_type.get_inbound_to_outbound_flow() | ||
|
||
quayside_inbound_container_volume_in_teu: int = 0 | ||
quayside_outbound_container_volume_in_teu: int = 0 | ||
|
||
inbound_vehicle_type: ModeOfTransport | ||
outbound_vehicle_type: ModeOfTransport | ||
for inbound_vehicle_type, to_outbound_flow in inbound_to_outbound_flow.items(): | ||
for outbound_vehicle_type, container_volume in to_outbound_flow.items(): | ||
if inbound_vehicle_type in self.QUAY_SIDE_VEHICLES: | ||
quayside_inbound_container_volume_in_teu += container_volume | ||
if outbound_vehicle_type in self.QUAY_SIDE_VEHICLES: | ||
quayside_outbound_container_volume_in_teu += container_volume | ||
|
||
teu_factor = ContainerLengthDistributionRepository().get_teu_factor() | ||
|
||
result = InboundAndOutboundContainerVolume( | ||
inbound=ContainerVolume( | ||
teu=quayside_inbound_container_volume_in_teu, | ||
containers=quayside_inbound_container_volume_in_teu / teu_factor | ||
), | ||
outbound=ContainerVolume( | ||
teu=quayside_outbound_container_volume_in_teu, | ||
containers=quayside_outbound_container_volume_in_teu / teu_factor | ||
) | ||
) | ||
|
||
return result |
86 changes: 86 additions & 0 deletions
86
conflowgen/previews/quay_side_throughput_preview_report.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
from __future__ import annotations | ||
|
||
from typing import Dict | ||
|
||
import pandas as pd | ||
|
||
from conflowgen.descriptive_datatypes import InboundAndOutboundContainerVolume | ||
from conflowgen.domain_models.data_types.mode_of_transport import ModeOfTransport | ||
from conflowgen.previews.quay_side_throughput_preview import QuaySideThroughputPreview | ||
from conflowgen.reporting import AbstractReportWithMatplotlib | ||
|
||
|
||
class QuaySideThroughputPreviewReport(AbstractReportWithMatplotlib): | ||
""" | ||
This preview report takes the data structure as generated by | ||
:class:`.QuaySideThroughputPreview` | ||
and creates a comprehensible representation for the user, either as text or as a graph. | ||
""" | ||
|
||
report_description = """ | ||
This report previews the inbound and outbound traffic at the quay side. | ||
This is only an estimate, additional restrictions (such as the dwell time restrictions) might further | ||
reduce the number of containers one vehicle can in fact pick up for its outbound journey. | ||
""" | ||
|
||
def __init__(self): | ||
super().__init__() | ||
self._df = None | ||
self.preview = QuaySideThroughputPreview( | ||
start_date=self.start_date, | ||
end_date=self.end_date, | ||
transportation_buffer=self.transportation_buffer | ||
) | ||
|
||
def hypothesize_with_mode_of_transport_distribution( | ||
self, | ||
mode_of_transport_distribution: Dict[ModeOfTransport, Dict[ModeOfTransport, float]] | ||
): | ||
self.preview.hypothesize_with_mode_of_transport_distribution(mode_of_transport_distribution) | ||
|
||
def get_report_as_text( | ||
self, **kwargs | ||
) -> str: | ||
assert len(kwargs) == 0, f"No keyword arguments supported for {self.__class__.__name__}" | ||
|
||
quay_side_throughput = self._get_quay_side_throughput() | ||
|
||
# create string representation | ||
report = "\n" | ||
report += "discharged (in containers) " | ||
report += "loaded (in containers)" | ||
report += "\n" | ||
|
||
report += f"{int(round(quay_side_throughput.inbound.containers)):>26} " | ||
report += f"{int(round(quay_side_throughput.outbound.containers)):>22}" | ||
report += "\n" | ||
|
||
report += "(rounding errors might exist)\n" | ||
return report | ||
|
||
def get_report_as_graph(self, **kwargs) -> object: | ||
assert len(kwargs) == 0, f"No keyword arguments supported for {self.__class__.__name__}" | ||
|
||
quay_side_throughput = self._get_quay_side_throughput() | ||
|
||
series = pd.Series({ | ||
"Number discharged containers": quay_side_throughput.inbound.containers, | ||
"Number loaded containers": quay_side_throughput.outbound.containers | ||
}, name="Quayside Throughput") | ||
|
||
ax = series.plot() | ||
|
||
return ax | ||
|
||
def _get_quay_side_throughput(self) -> InboundAndOutboundContainerVolume: | ||
assert self.start_date is not None | ||
assert self.end_date is not None | ||
assert self.transportation_buffer is not None | ||
self.preview.update( | ||
start_date=self.start_date, | ||
end_date=self.end_date, | ||
transportation_buffer=self.transportation_buffer | ||
) | ||
# gather data | ||
quay_side_throughput = self.preview.get_quay_side_throughput() | ||
return quay_side_throughput |
Oops, something went wrong.