Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setup Model #168

Merged
merged 10 commits into from
Nov 19, 2024
34 changes: 34 additions & 0 deletions examples/setup_config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#######################
# Setup Model Configs #
#######################

# this is where user want to create the MTC model
ROOT_DIR = "V:/projects/MTC/US0024934.9168/setup_model"

# user-defined model folder name (naming convention: ModelYear_ModelVersion_Project_Scenario)
MODEL_FOLDER_NAME = "2023_TM22_Demo"

# location of the networks
# this includes file such as tolls, transit fares etc.
INPUT_NETWORK_DIR = "V:/projects/MTC/US0024934.9168/setup_model/model_inputs/2015-tm22-dev-sprint-02"

# this is location/folder for Emme Netorks (built from Lasso)
INPUT_EMME_NETWORK_DIR = "V:/projects/MTC/US0024934.9168/setup_model/emme_network"

# location of the populationsim and land use inputs
INPUT_POPLU_DIR = "V:/projects/MTC/US0024934.9168/setup_model/model_inputs/2015-tm22-dev-sprint-02"

# location of nonres inputs
INPUT_NONRES_DIR = "V:/projects/MTC/US0024934.9168/setup_model/model_inputs/2015-tm22-dev-sprint-02"

# this is location of demand matrices for warm start
WARMSTART_DEMAND_DIR = "V:/projects/MTC/transit_path_builder_calib/TM2.2.1.2/warmstart"

# this is location/folder for Emme Netorks
EMME_TEMPLATE_PROJECT_DIR = "V:/projects/MTC/US0024934.9168/setup_model/emme_23_project_template"

# github raw link for toml config files
CONFIGS_GITHUB_PATH = "https://raw.githubusercontent.com/BayAreaMetro/travel-model-two-config/sprint_02/2015-tm22-dev-sprint-02"

# travel model two release tag to fetch
TRAVEL_MODEL_TWO_RELEASE_TAG = "TM2.2.2"
3 changes: 3 additions & 0 deletions tm2py/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from .controller import RunController
from .examples import get_example
from .logger import Logger, LogStartEnd
from .setup_model.setup import SetupModel

__all__ = [
# component
Expand All @@ -24,6 +25,8 @@
"TimePeriodConfig",
# controller
"RunController",
# setupmodel
"SetupModel",
# logger
"Logger",
"LogStartEnd",
Expand Down
7 changes: 5 additions & 2 deletions tm2py/acceptance/simulated.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,11 @@ def __init__(
scenario_file: str = None,
model_file: str = None,
on_board_assign_summary: bool = False,
iteration: int = 3,
) -> None:
self.c = canonical
self.scenario_file = scenario_file
self.iter = iteration
self._load_configs(scenario=True, model=False)

if not on_board_assign_summary:
Expand Down Expand Up @@ -605,7 +607,8 @@ def _reduce_simulated_station_to_station(self):

df["boarding"] = df["boarding"].astype(int)
df["alighting"] = df["alighting"].astype(int)
df["simulated"] = df["simulated"].astype(float)
# there are occasional odd simulated values with characters, such as '309u4181'
df["simulated"] = pd.to_numeric(df['simulated'], errors='coerce').fillna(0)

file.close()

Expand Down Expand Up @@ -1022,7 +1025,7 @@ def _read_transit_demand(self):

out_df = pd.DataFrame()
for time_period in self.model_time_periods:
filename = os.path.join(dem_dir, "trn_demand_{}.omx".format(time_period))
filename = os.path.join(dem_dir, "trn_demand_{}_{}.omx".format(time_period, self.iter))
omx_handle = omx.open_file(filename)

running_df = None
Expand Down
48 changes: 27 additions & 21 deletions tm2py/components/demand/household.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def run(self):
self._stop_java()
# consume ctramp person trip list and create trip tables for assignment
self._prepare_demand_for_assignment()
self._copy_auto_maz_demand()

def _prepare_demand_for_assignment(self):
prep_demand = PrepareHighwayDemand(self.controller)
Expand Down Expand Up @@ -77,6 +78,31 @@ def _run_resident_model(self):
def _stop_java():
run_process(['taskkill /im "java.exe" /F'])

def _copy_auto_maz_demand(self):
time_period_names = self.time_period_names

for period in time_period_names:
for maz_group in [1, 2, 3]:
output_path = (
self.controller.get_abs_path(
self.controller.config.highway.maz_to_maz.demand_file
)
.__str__()
.format(
period=period, number=maz_group, iter=self.controller.iteration
)
)

input_path = (
self.controller.get_abs_path(
self.config.highway_maz_ctramp_output_file
)
.__str__()
.format(period=period, number=maz_group)
)

_shutil.copyfile(input_path, output_path)

def _consolidate_demand_for_assign(self):
"""
CTRAMP writes out demands in separate omx files, e.g.
Expand Down Expand Up @@ -123,27 +149,7 @@ def _consolidate_demand_for_assign(self):
output_omx.close()

# auto MAZ
for period in time_period_names:
for maz_group in [1, 2, 3]:
output_path = (
self.controller.get_abs_path(
self.controller.config.highway.maz_to_maz.demand_file
)
.__str__()
.format(
period=period, number=maz_group, iter=self.controller.iteration
)
)

input_path = (
self.controller.get_abs_path(
self.config.highway_maz_ctramp_output_file
)
.__str__()
.format(period=period, number=maz_group)
)

_shutil.copyfile(input_path, output_path)
self._copy_auto_maz_demand()

# transit TAP
# for period in time_period_names:
Expand Down
Empty file.
12 changes: 10 additions & 2 deletions tm2py/components/network/transit/transit_assign.py
Original file line number Diff line number Diff line change
Expand Up @@ -452,14 +452,22 @@ def run(self):
self.transit_network.update_auto_times(time_period)

if self.controller.iteration == 0:
# iteration = 0 : run uncongested transit assignment
use_ccr = False
congested_transit_assignment = False
print("running uncongested transit assignment with warmstart demand")
self.run_transit_assign(
time_period, use_ccr, congested_transit_assignment
)

else: # iteration >=1
elif (self.controller.iteration == 1) & (self.controller.config.warmstart.use_warmstart_skim):
# iteration = 1 and use_warmstart_skim = True : run uncongested transit assignment
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why so? is it to compromise for the fact that no warmstart transit assignment was run in global iteration 0, or is it to save run time?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, because when using the warm start with the skim option, we skip the transit skim and assignment in the global iteration 0. In iteration 1, the generated transit demand for an OD pair could be non-zero, even if the skim for that OD pair is zero in the warm start skim file (making it inconsistent), and thereby crashing in the congested transit assignment.

I ran into this above issue before making the code change.

use_ccr = False
congested_transit_assignment = False
self.run_transit_assign(
time_period, use_ccr, congested_transit_assignment
)
else:
# iteration >= 1 and use_warmstart_skim = False : run congested transit assignment
use_ccr = self.config.use_ccr
if time_period in ["EA", "EV", "MD"]:
congested_transit_assignment = False
Expand Down
15 changes: 8 additions & 7 deletions tm2py/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ class HouseholdConfig(ConfigItem):
highway_demand_file: pathlib.Path
transit_demand_file: pathlib.Path
active_demand_file: pathlib.Path
highway_maz_ctramp_output_file: pathlib.Path
OwnedAV_ZPV_factor: float
TNC_ZPV_factor: float
ctramp_indiv_trip_file: str
Expand Down Expand Up @@ -1418,7 +1419,7 @@ class EmmeConfig(ConfigItem):
active_north_database_path: pathlib.Path
active_south_database_path: pathlib.Path
transit_database_path: pathlib.Path
num_processors: str = Field(regex=r"^MAX$|^MAX-\d+$|^\d+$")
num_processors: str = Field(pattern=r"^MAX$|^MAX-\d+$|^\d+$")


@dataclass(frozen=True)
Expand Down Expand Up @@ -1477,21 +1478,21 @@ def maz_skim_period_exists(cls, value, values):

@validator("highway", always=True)
def relative_gap_length(cls, value, values):
"""Validate highway.relative_gaps is a list of the same length as global iterations."""
"""Validate highway.relative_gaps is a list of length greater or equal to global iterations."""
if "run" in values:
assert len(value.relative_gaps) == (
assert len(value.relative_gaps) >= (
values["run"]["end_iteration"] + 1
), f"'highway.relative_gaps must be the same length as end_iteration+1,\
), f"'highway.relative_gaps must be the same or greater length as end_iteration+1,\
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."""
"""Validate transit.congested.stop_criteria is a list of length greater or equal to global iterations."""
if ("run" in values) & (value.congested_transit_assignment):
assert len(value.congested.stop_criteria) == (
assert len(value.congested.stop_criteria) >= (
values["run"]["end_iteration"]
), f"'transit.relative_gaps must be the same length as end_iteration,\
), f"'transit.stop_criteria must be the same or greater length as end_iteration,\
that includes global iteration 1 to {values['run']['end_iteration']}'"
return value

Expand Down
8 changes: 4 additions & 4 deletions tm2py/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,21 +265,21 @@ def run_next(self):
elif self.config.warmstart.use_warmstart_skim:
highway_skim_file = self.get_abs_path(
self.config["highway"].output_skim_path
+ self.config["highway"].output_skim_filename_tmpl
/ self.config["highway"].output_skim_filename_tmpl
).__str__()
for time in self.config["time_periods"]:
path = highway_skim_file.format(period=time.name)
path = highway_skim_file.format(time_period=time.name)
assert os.path.isfile(
path
), f"{path} required as warmstart skim does not exist"
transit_skim_file = self.get_abs_path(
self.config["transit"].output_skim_path
+ self.config["transit"].output_skim_filename_tmpl
/ self.config["transit"].output_skim_filename_tmpl
).__str__()
for time in self.config["time_periods"]:
for tclass in self.config["transit"]["classes"]:
path = transit_skim_file.format(
period=time.name, iter=tclass.name
time_period=time.name, tclass=tclass.name
)
assert os.path.isfile(
path
Expand Down
Loading
Loading