Skip to content

Commit

Permalink
congested assignment stop criteria by iteration
Browse files Browse the repository at this point in the history
  • Loading branch information
i-am-sijia committed Aug 19, 2024
1 parent ec9ba4e commit 404b6d6
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 20 deletions.
12 changes: 5 additions & 7 deletions tm2py/components/demand/prepare_demand.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,9 @@ def _prepare_demand(
demand = demand + self._read_demand(file_config, time_period, num_zones)
demand_name = f"{time_period}_{name}"
description = f"{time_period} {description} demand"
self._save_demand(demand_name, demand, description, apply_msa=True)
self._save_demand(
demand_name, demand, description, apply_msa=self.config.apply_msa_demand
)

def _read_demand(self, file_config, time_period, num_zones):
# Load demand from cross-referenced source file,
Expand Down Expand Up @@ -428,7 +430,7 @@ def create_zero_passenger_trips(
self.controller.config.household.transit_demand_file
)
.__str__()
.format(period=time_period),
.format(period=time_period, iter=self.controller.iteration),
"w",
)
# active_out_file = OMXManager(
Expand Down Expand Up @@ -691,11 +693,7 @@ def _read_demand(self, file_config, time_period, skim_set, num_zones):
).__str__()
name = file_config["name"]
return self._read(
path.format(
period=time_period,
# set=skim_set,
# iter=self.controller.iteration
),
path.format(period=time_period, iter=self.controller.iteration),
name,
num_zones,
)
25 changes: 18 additions & 7 deletions tm2py/components/network/transit/transit_assign.py
Original file line number Diff line number Diff line change
Expand Up @@ -711,13 +711,24 @@ def _run_congested_assign(self, time_period: str) -> None:
"assignment_period": _duration,
}

_stop_criteria = {
"max_iterations": self.congested_transit_assn_max_iteration[
time_period.lower()
],
"normalized_gap": self.config.congested.normalized_gap,
"relative_gap": self.config.congested.relative_gap,
}
stop_criteria_settings = self.config.congested.stop_criteria
# get the corresponding stop criteria for the global iteration
_stop_criteria = None
for item in stop_criteria_settings:
if item["global_iteration"] == self.controller.iteration:
_stop_criteria = {
"max_iterations": [
time.max_iteration
for time in item.max_iterations
if time.time_period.lower() == time_period.lower()
][0],
"normalized_gap": item.normalized_gap,
"relative_gap": item.relative_gap,
}
if _stop_criteria is None:
raise ValueError(
f"transit.congested.stop_criteria: Must specifify stop criteria for global iteration {self.controller.iteration}"
)
add_volumes = False
assign_transit(
_tclass_specs,
Expand Down
51 changes: 45 additions & 6 deletions tm2py/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class WarmStartConfig(ConfigItem):
Note that the components will be executed in the order listed.
Properties:
warmstart: Boolean indicating whether warmstart demand matrices are used.
warmstart: Boolean indicating whether warmstart demand matrices are used.
If set to True, the global iteration 0 will either assign warmstart demand for highway and transit, or skip the assignment and just use warmstart skims.
If set to False, the global iteration 0 will assign zero demand for highway and transit.
warmstart_skim: Boolean indicating whether to use warmstart skims. If set to True, then skips warmstart assignment in iteraton 0.
Expand Down Expand Up @@ -242,16 +242,13 @@ class TimePeriodConfig(ConfigItem):
capacites in the highway network
emme_scenario_id: scenario ID to use for Emme per-period
assignment (highway and transit) scenarios
congested_transit_assn_max_iteration: max iterations in congested
transit assignment stopping criteria
"""

name: str = Field(max_length=4)
start_period: float = Field(gt=0)
length_hours: float = Field(gt=0)
highway_capacity_factor: float = Field(gt=0)
emme_scenario_id: int = Field(ge=1)
congested_transit_assn_max_iteration: int = Field(ge=1)
description: Optional[str] = Field(default="")


Expand Down Expand Up @@ -952,6 +949,7 @@ class HighwayConfig(ConfigItem):
to the free-flow speed, capacity, and critical speed values
interchange_nodes_file: relative path to the interchange nodes file, this is
used for calculating highway reliability
apply_msa_demand: average highway demand with previous iterations'. Default to True.
"""

generic_highway_mode_code: str = Field(min_length=1, max_length=1)
Expand All @@ -967,6 +965,7 @@ class HighwayConfig(ConfigItem):
classes: Tuple[HighwayClassConfig, ...] = Field()
capclass_lookup: Tuple[HighwayCapClassConfig, ...] = Field()
interchange_nodes_file: str = Field()
apply_msa_demand: bool = True

@validator("output_skim_filename_tmpl")
def valid_skim_template(value):
Expand Down Expand Up @@ -1284,13 +1283,42 @@ class EawtWeightsConfig(ConfigItem):
default_eawt_factor: float = Field(default=1)


@dataclass(frozen=True)
class CongestedTransitMaxIteration(ConfigItem):
"""Congested transit assignment time period specific max iteration parameters.
Properties:
time_period: time period string
max_iteration: max iteration integer
"""

time_period: str = Field(max_length=4)
max_iteration: int = Field(ge=1)


@dataclass(frozen=True)
class CongestedTransitStopCriteria(ConfigItem):
"""Congested transit assignment stopping criteria parameters.
Properties:
global_iteration: global iteration number
normalized_gap: normalized_gap
relative_gaps: relative gap
max_iterations: max iterations config, one for each time period
"""

global_iteration: int = Field(ge=0)
normalized_gap: float = Field(gt=0)
relative_gap: float = Field(gt=0)
max_iterations: Tuple[CongestedTransitMaxIteration, ...] = Field()


@dataclass(frozen=True)
class CongestedAssnConfig(ConfigItem):
"Congested transit assignment Configuration."
trim_demand_before_congested_transit_assignment: bool = False
output_trimmed_demand_report_path: str = Field(default=None)
normalized_gap: float = Field(default=0.25)
relative_gap: float = Field(default=0.25)
stop_criteria: Tuple[CongestedTransitStopCriteria, ...] = Field()
use_peaking_factor: bool = False
am_peaking_factor: float = Field(default=1.219)
pm_peaking_factor: float = Field(default=1.262)
Expand Down Expand Up @@ -1354,6 +1382,7 @@ def deprecate_capacitated_assignment(cls, value, values):
), "capacitated transit assignment is deprecated, please set use_ccr to false"
return value


@dataclass(frozen=True)
class EmmeConfig(ConfigItem):
"""Emme-specific parameters.
Expand Down Expand Up @@ -1445,6 +1474,16 @@ def relative_gap_length(cls, value, values):
that includes global iteration 0 to {values['run']['end_iteration']}'"
return value

@validator("transit", always=True)
def transit_stop_criteria_length(cls, value, values):
"""Validate transit.congested.stop_criteria is a list of the same length as global iterations."""
if ("run" in values) & (value.congested_transit_assignment):
assert len(value.congested.stop_criteria) == (
values["run"]["end_iteration"]
), f"'transit.relative_gaps must be the same length as end_iteration,\
that includes global iteration 1 to {values['run']['end_iteration']}'"
return value


def _load_toml(path: str) -> dict:
"""Load config from toml file at path."""
Expand Down

0 comments on commit 404b6d6

Please sign in to comment.