Skip to content

Commit

Permalink
Consider container dwell times (#130)
Browse files Browse the repository at this point in the history
  • Loading branch information
1kastner authored Aug 2, 2022
1 parent 7198812 commit 5713338
Show file tree
Hide file tree
Showing 165 changed files with 4,938 additions and 1,333 deletions.
1 change: 1 addition & 0 deletions .flake8_nb
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ ignore =
F821 # Variables such as 'In' or 'display' are not detected and variables of imported Jupyter Notebook cannot be detected
E501 # Allow long lines
W503 # Long lines need to be broken somewhere and otherwise W504 is violated
E402 # Module level imports are decided on by developers

show_source = True
12 changes: 0 additions & 12 deletions .github/workflows/installation-from-remote.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ jobs:
- name: Skip Duplicate Actions
uses: fkirc/[email protected]

- uses: actions/checkout@v2
with:
lfs: false

- uses: conda-incubator/setup-miniconda@v2
with:
auto-update-conda: true
Expand All @@ -50,10 +46,6 @@ jobs:
- name: Skip Duplicate Actions
uses: fkirc/[email protected]

- uses: actions/checkout@v2
with:
lfs: false

- uses: conda-incubator/setup-miniconda@v2
with:
auto-update-conda: true
Expand Down Expand Up @@ -87,10 +79,6 @@ jobs:
- name: Skip Duplicate Actions
uses: fkirc/[email protected]

- uses: actions/checkout@v2
with:
lfs: false

- uses: actions/setup-python@v4
with:
python-version: '3.10'
Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/linting.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,11 @@ jobs:
- name: Check code quality with pylint
run: |
pylint conflowgen && pylint setup.py
pylint conflowgen
pylint setup.py
pylint conflowgen.tests
- name: Check code quality with flake8 and flake8_nb
run: |
flake8 && flake8_nb
flake8
flake8_nb
9 changes: 7 additions & 2 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
fail-under=8.0

# Files or directories to be skipped. They should be base names, not paths.
ignore=.git
ignore=.git,
tests

# Add files or directories matching the regex patterns to the ignore-list. The
# regex matches against paths.
Expand Down Expand Up @@ -57,6 +58,7 @@ disable=
R1710, # inconsistent-return-statements -- leave it up to the programmers to decide this
W0511, # fixme - allow todos in the code -- this should be eventually changed but it is not top priority
W0122, # exec-used -- as this module only works locally (no networking), executing arbitrary code bears no threats
R0201, # no-self-use -- leave it up to the programmers to decide this

[MESSAGES CONTROL]

Expand Down Expand Up @@ -191,7 +193,10 @@ good-names=i,
Run,
_,
df,
ax
ax,
x,
xs,
mu

# Good variable names regexes, separated by a comma. If names match any regex,
# they will always be accepted
Expand Down
57 changes: 33 additions & 24 deletions conflowgen/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# List of classes
# Distribution managers
from conflowgen.api.container_length_distribution_manager import ContainerLengthDistributionManager
from conflowgen.api.container_weight_distribution_manager import ContainerWeightDistributionManager
from conflowgen.api.container_flow_generation_manager import ContainerFlowGenerationManager
from conflowgen.api.container_dwell_time_distribution_manager import ContainerDwellTimeDistributionManager
from conflowgen.api.database_chooser import DatabaseChooser
from conflowgen.api.export_container_flow_manager import ExportContainerFlowManager
from conflowgen.api.mode_of_transport_distribution_manager import ModeOfTransportDistributionManager
Expand All @@ -10,6 +11,7 @@
from conflowgen.api.container_storage_requirement_distribution_manager import \
ContainerStorageRequirementDistributionManager

# Previews and their reports
from conflowgen.previews.inbound_and_outbound_vehicle_capacity_preview_report import \
InboundAndOutboundVehicleCapacityPreviewReport
from conflowgen.previews.inbound_and_outbound_vehicle_capacity_preview import \
Expand All @@ -24,36 +26,43 @@
from conflowgen.previews.modal_split_preview import ModalSplitPreview
from conflowgen.previews.modal_split_preview_report import ModalSplitPreviewReport

from conflowgen.posthoc_analyses.inbound_and_outbound_vehicle_capacity_analysis import \
# Analyses and their reports
from conflowgen.analyses.inbound_and_outbound_vehicle_capacity_analysis import \
InboundAndOutboundVehicleCapacityAnalysis
from conflowgen.posthoc_analyses.inbound_and_outbound_vehicle_capacity_analysis_report import \
from conflowgen.analyses.inbound_and_outbound_vehicle_capacity_analysis_report import \
InboundAndOutboundVehicleCapacityAnalysisReport
from conflowgen.posthoc_analyses.inbound_to_outbound_vehicle_capacity_utilization_analysis import \
from conflowgen.analyses.inbound_to_outbound_vehicle_capacity_utilization_analysis import \
InboundToOutboundVehicleCapacityUtilizationAnalysis
from conflowgen.posthoc_analyses.inbound_to_outbound_vehicle_capacity_utilization_analysis_report import \
from conflowgen.analyses.inbound_to_outbound_vehicle_capacity_utilization_analysis_report import \
InboundToOutboundVehicleCapacityUtilizationAnalysisReport
from conflowgen.posthoc_analyses.container_flow_by_vehicle_type_analysis import ContainerFlowByVehicleTypeAnalysis
from conflowgen.posthoc_analyses.container_flow_by_vehicle_type_analysis_report import \
from conflowgen.analyses.container_flow_by_vehicle_type_analysis import ContainerFlowByVehicleTypeAnalysis
from conflowgen.analyses.container_flow_by_vehicle_type_analysis_report import \
ContainerFlowByVehicleTypeAnalysisReport
from conflowgen.posthoc_analyses.modal_split_analysis import ModalSplitAnalysis
from conflowgen.posthoc_analyses.modal_split_analysis_report import ModalSplitAnalysisReport
from conflowgen.posthoc_analyses.container_flow_adjustment_by_vehicle_type_analysis import \
from conflowgen.analyses.modal_split_analysis import ModalSplitAnalysis
from conflowgen.analyses.modal_split_analysis_report import ModalSplitAnalysisReport
from conflowgen.analyses.container_flow_adjustment_by_vehicle_type_analysis import \
ContainerFlowAdjustmentByVehicleTypeAnalysis
from conflowgen.posthoc_analyses.container_flow_adjustment_by_vehicle_type_analysis_report import \
from conflowgen.analyses.container_flow_adjustment_by_vehicle_type_analysis_report import \
ContainerFlowAdjustmentByVehicleTypeAnalysisReport
from conflowgen.posthoc_analyses.container_flow_adjustment_by_vehicle_type_analysis_summary import \
from conflowgen.analyses.container_flow_adjustment_by_vehicle_type_analysis_summary import \
ContainerFlowAdjustmentByVehicleTypeAnalysisSummary
from conflowgen.posthoc_analyses.container_flow_adjustment_by_vehicle_type_analysis_summary_report import \
from conflowgen.analyses.container_flow_adjustment_by_vehicle_type_analysis_summary_report import \
ContainerFlowAdjustmentByVehicleTypeAnalysisSummaryReport
from conflowgen.posthoc_analyses.yard_capacity_analysis import YardCapacityAnalysis
from conflowgen.posthoc_analyses.yard_capacity_analysis_report import YardCapacityAnalysisReport
from conflowgen.posthoc_analyses.quay_side_throughput_analysis import QuaySideThroughputAnalysis
from conflowgen.posthoc_analyses.quay_side_throughput_analysis_report import QuaySideThroughputAnalysisReport
from conflowgen.posthoc_analyses.truck_gate_throughput_analysis import TruckGateThroughputAnalysis
from conflowgen.posthoc_analyses.truck_gate_throughput_analysis_report import TruckGateThroughputAnalysisReport
from conflowgen.analyses.yard_capacity_analysis import YardCapacityAnalysis
from conflowgen.analyses.yard_capacity_analysis_report import YardCapacityAnalysisReport
from conflowgen.analyses.quay_side_throughput_analysis import QuaySideThroughputAnalysis
from conflowgen.analyses.quay_side_throughput_analysis_report import QuaySideThroughputAnalysisReport
from conflowgen.analyses.truck_gate_throughput_analysis import TruckGateThroughputAnalysis
from conflowgen.analyses.truck_gate_throughput_analysis_report import TruckGateThroughputAnalysisReport
from conflowgen.analyses.container_dwell_time_analysis import ContainerDwellTimeAnalysis
from conflowgen.analyses.container_dwell_time_analysis_report import ContainerDwellTimeAnalysisReport

# Specific classes for reports
from conflowgen.reporting.output_style import DisplayAsMarkupLanguage, DisplayAsPlainText, DisplayAsMarkdown

# Specific classes for distributions
from conflowgen.tools.continuous_distribution import ContinuousDistribution

# List of enums
from conflowgen.application.data_types.export_file_format import ExportFileFormat
from conflowgen.domain_models.data_types.mode_of_transport import ModeOfTransport
Expand All @@ -62,18 +71,18 @@

# List of functions
from conflowgen.logging.logging import setup_logger
from conflowgen.posthoc_analyses import run_all_analyses
from conflowgen.analyses import run_all_analyses
from conflowgen.previews import run_all_previews

# List of named tuples
from conflowgen.previews.vehicle_capacity_exceeded_preview import RequiredAndMaximumCapacityComparison
from conflowgen.previews.inbound_and_outbound_vehicle_capacity_preview import OutboundUsedAndMaximumCapacity
from conflowgen.posthoc_analyses.abstract_posthoc_analysis import ContainersAndTEUContainerFlowPair
from conflowgen.posthoc_analyses.container_flow_adjustment_by_vehicle_type_analysis_summary import \
from conflowgen.analyses.abstract_analysis import ContainersAndTEUContainerFlowPair
from conflowgen.analyses.container_flow_adjustment_by_vehicle_type_analysis_summary import \
ContainerFlowAdjustedToVehicleType
from conflowgen.descriptive_datatypes import TransshipmentAndHinterlandComparison
from conflowgen.descriptive_datatypes import TransshipmentAndHinterlandSplit
from conflowgen.descriptive_datatypes import HinterlandModalSplit
from conflowgen.posthoc_analyses.inbound_to_outbound_vehicle_capacity_utilization_analysis import \
from conflowgen.analyses.inbound_to_outbound_vehicle_capacity_utilization_analysis import \
CompleteVehicleIdentifier

# Add metadata constants
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging
from typing import Optional, Union, Callable, Iterable, Type

from .container_dwell_time_analysis_report import ContainerDwellTimeAnalysisReport
from .container_flow_adjustment_by_vehicle_type_analysis_report import \
ContainerFlowAdjustmentByVehicleTypeAnalysisReport
from .container_flow_adjustment_by_vehicle_type_analysis_summary_report import \
Expand All @@ -25,6 +26,7 @@
ContainerFlowAdjustmentByVehicleTypeAnalysisReport,
ContainerFlowAdjustmentByVehicleTypeAnalysisSummaryReport,
ModalSplitAnalysisReport,
ContainerDwellTimeAnalysisReport,
QuaySideThroughputAnalysisReport,
TruckGateThroughputAnalysisReport,
YardCapacityAnalysisReport,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def get_week_based_range(start: datetime.date, end: datetime.date) -> List[datet
] + [end]


class AbstractPostHocAnalysis(abc.ABC):
class AbstractAnalysis(abc.ABC):

def __init__(
self,
Expand All @@ -68,7 +68,7 @@ def update(
transportation_buffer: Optional[float]
):
"""
As the transportation buffer is not stored in the database, for some analyses it needs to be provided.
For some analyses, the transportation buffer needs to be provided.
Args:
transportation_buffer: The buffer, e.g. 0.2 means that 20% more containers (in TEU) can be put on a vessel
Expand Down
116 changes: 116 additions & 0 deletions conflowgen/analyses/container_dwell_time_analysis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
from __future__ import annotations

import datetime
from typing import Collection, Union

from conflowgen.domain_models.data_types.mode_of_transport import ModeOfTransport
from conflowgen.domain_models.data_types.storage_requirement import StorageRequirement
from conflowgen.domain_models.arrival_information import TruckArrivalInformationForDelivery, \
TruckArrivalInformationForPickup
from conflowgen.domain_models.container import Container
from conflowgen.domain_models.vehicle import LargeScheduledVehicle, Truck
from conflowgen.analyses.abstract_analysis import AbstractAnalysis
from conflowgen.tools import hashable


class ContainerDwellTimeAnalysis(AbstractAnalysis):
"""
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 :class:`.ContainerDwellTimeAnalysisReport`.
"""

@staticmethod
def get_container_dwell_times(
container_delivered_by_vehicle_type: Union[str, Collection[ModeOfTransport], ModeOfTransport] = "all",
container_picked_up_by_vehicle_type: Union[str, Collection[ModeOfTransport], ModeOfTransport] = "all",
storage_requirement: Union[str, Collection[StorageRequirement], StorageRequirement] = "all"
) -> set[datetime.timedelta]:
"""
The containers are filtered according to the provided vehicle types and storage requirements.
Then, the time between the arrival of the container in the yard and the departure of the container is
calculated.
Args:
container_delivered_by_vehicle_type: One of
``"all"``,
a collection of :class:`ModeOfTransport` enum values (as a list, set, or similar), or
a single :class:`ModeOfTransport` enum value.
container_picked_up_by_vehicle_type: One of
``"all"``,
a collection of :class:`ModeOfTransport` enum values (as a list, set, or similar), or
a single :class:`ModeOfTransport` enum value.
storage_requirement: One of
``"all"``,
a collection of :class:`StorageRequirement` enum values (as a list, set, or similar), or
a single :class:`StorageRequirement` enum value.
Returns:
A set of container dwell times.
"""
container_dwell_times: set[datetime.timedelta] = set()

selected_containers = Container.select()

if storage_requirement != "all":
if hashable(storage_requirement) and storage_requirement in set(StorageRequirement):
selected_containers = selected_containers.where(
Container.storage_requirement == storage_requirement
)
else: # assume it is some kind of collection (list, set, ...)
selected_containers = selected_containers.where(
Container.storage_requirement << storage_requirement
)

if container_delivered_by_vehicle_type != "all":
if hashable(container_delivered_by_vehicle_type) \
and container_delivered_by_vehicle_type in set(ModeOfTransport):
selected_containers = selected_containers.where(
Container.delivered_by == container_delivered_by_vehicle_type
)
else: # assume it is some kind of collection (list, set, ...)
selected_containers = selected_containers.where(
Container.delivered_by << container_delivered_by_vehicle_type
)

if container_picked_up_by_vehicle_type != "all":
if hashable(container_picked_up_by_vehicle_type) \
and container_picked_up_by_vehicle_type in set(ModeOfTransport):
selected_containers = selected_containers.where(
Container.picked_up_by == container_picked_up_by_vehicle_type
)
else: # assume it is some kind of collection (list, set, ...)
selected_containers = selected_containers.where(
Container.picked_up_by << container_picked_up_by_vehicle_type
)

for container in selected_containers:
container_enters_yard: datetime.datetime
container_leaves_yard: datetime.datetime
if container.delivered_by_truck is not None:
truck: Truck = container.delivered_by_truck
arrival_time_information: TruckArrivalInformationForDelivery = \
truck.truck_arrival_information_for_delivery
container_enters_yard = arrival_time_information.realized_container_delivery_time
elif container.delivered_by_large_scheduled_vehicle is not None:
vehicle: LargeScheduledVehicle = container.delivered_by_large_scheduled_vehicle
container_enters_yard = vehicle.scheduled_arrival
else:
raise Exception(f"Faulty data: {container}")

if container.picked_up_by_truck is not None:
truck: Truck = container.picked_up_by_truck
arrival_time_information: TruckArrivalInformationForPickup = \
truck.truck_arrival_information_for_pickup
container_leaves_yard = arrival_time_information.realized_container_pickup_time
elif container.picked_up_by_large_scheduled_vehicle is not None:
vehicle: LargeScheduledVehicle = container.picked_up_by_large_scheduled_vehicle
container_leaves_yard = vehicle.scheduled_arrival
else:
raise Exception(f"Faulty data: {container}")

container_dwell_time = container_leaves_yard - container_enters_yard

container_dwell_times.add(container_dwell_time)

return container_dwell_times
Loading

0 comments on commit 5713338

Please sign in to comment.