Skip to content

Commit

Permalink
Merge pull request #165 from BayAreaMetro/transit-settings
Browse files Browse the repository at this point in the history
Transit settings
  • Loading branch information
i-am-sijia authored Aug 27, 2024
2 parents 50148a1 + 4ca81b5 commit b17cb0e
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 19 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
60 changes: 55 additions & 5 deletions tm2py/config.py
Original file line number Diff line number Diff line change
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.
reliability: bool to skim highway reliability. Default to true. If true, assignment
will be run twice in global iterations 0 (warmstart) and 1, to calculate reliability,
assignment will be run only once in global iterations 2 and 3,
Expand All @@ -973,6 +971,7 @@ class HighwayConfig(ConfigItem):
classes: Tuple[HighwayClassConfig, ...] = Field()
capclass_lookup: Tuple[HighwayCapClassConfig, ...] = Field()
interchange_nodes_file: str = Field()
apply_msa_demand: bool = True
reliability: bool = Field(default=True)

@validator("output_skim_filename_tmpl")
Expand Down Expand Up @@ -1291,13 +1290,46 @@ 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 specific to time period. In the design of tm2py,
congested assignment is run only for AM and PM. For EA, MD, and EV, we run
extended assignment. See code here: tm2py/components/network/transit/transit_assign.py#L465-L466
Therefore, `max_iteration` here does not impact EA, MD, and EV, this setting
is only meaningful for AM and PM.
"""

time_period: str = Field(max_length=4)
max_iteration: int = Field(ge=1, default=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 @@ -1353,6 +1385,14 @@ class TransitConfig(ConfigItem):
default_factory=TransitVehicleConfig
)

@validator("use_ccr")
def deprecate_capacitated_assignment(cls, value, values):
"""Validate use_ccr is false."""
assert (
not value
), "capacitated transit assignment is deprecated, please set use_ccr to false"
return value


@dataclass(frozen=True)
class EmmeConfig(ConfigItem):
Expand Down Expand Up @@ -1445,6 +1485,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 b17cb0e

Please sign in to comment.