Skip to content

Commit

Permalink
Merge pull request #133 from SANDAG/ABM3_import_TNED
Browse files Browse the repository at this point in the history
Major update to move from TCOV network to TNED network.
  • Loading branch information
bhargavasana authored May 1, 2024
2 parents 69c9fd7 + a43c107 commit 2c9c92c
Show file tree
Hide file tree
Showing 12 changed files with 831 additions and 1,261 deletions.
42 changes: 31 additions & 11 deletions src/asim/scripts/resident/2zoneSkim.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
nodes['X'] = nodes.geometry.x
nodes['Y'] = nodes.geometry.y

# TEST: nodes
# nodes.to_csv(r"C:/abm_runs/sar/2022_ABM3_tned/src/asim/scripts/resident/nodes.csv")

links = gpd.read_file(sf)
links = links.to_crs(epsg=2230)

Expand All @@ -58,33 +61,48 @@
centroids['Y'] = nodes[nodes[parms['maz_shape_maz_id']]!=0].Y
centroids['MAZ'] = nodes[nodes[parms['maz_shape_maz_id']]!=0].MGRA
centroids['MAZ_centroid_id'] = nodes[nodes[parms['maz_shape_maz_id']]!=0].index

centroids = pd.merge(centroids, maz_closest_network_node_id, left_on='MAZ_centroid_id', right_on=parms['mmms']["mmms_link_ref_id"], how='left')
centroids = centroids.rename(columns={parms['mmms']["mmms_link_nref_id"]:'network_node_id'})

centroids["network_node_x"] = nodes["X"].loc[centroids["network_node_id"]].tolist()
centroids["network_node_y"] = nodes["Y"].loc[centroids["network_node_id"]].tolist()

# TEST: centroids
# centroids.to_csv(r"C:/abm_runs/sar/2022_ABM3_tned/src/asim/scripts/resident/centroids.csv")

# %%
## read transit stop and route file (KK) ============
stops = pd.read_csv(os.path.join(model_inputs, parms['stop_attributes']['file']))
routes = pd.read_csv(os.path.join(model_inputs, parms['route_attributes']['file']))
routes = routes.filter(['Route_ID','Route_Name', 'Mode'])

# TEST: stops 1
# stops.to_csv(r"C:/abm_runs/sar/2022_ABM3_tned/src/asim/scripts/resident/stops_1.csv")

# add mode from route file & convert lat.long to stateplane(KK)=====
stops = stops.merge(routes, left_on='Route_ID', right_on='Route_ID') #
stops = stops.merge(routes, left_on='Route_ID', right_on='Route_ID') #

# TEST: stops 2
# stops.to_csv(r"C:/abm_runs/sar/2022_ABM3_tned/src/asim/scripts/resident/stops_2.csv")

stops.rename(columns={' Latitude': 'Latitude'}, inplace=True)
stops["Longitude1"] = stops["Longitude"]/1000000
stops["Latitude1"] = stops["Latitude"]/1000000
# stops.rename(columns={' Latitude': 'Latitude'}, inplace=True)
# stops["Longitude1"] = stops["Longitude"]/1000000
# stops["Latitude1"] = stops["Latitude"]/1000000

gpd_stops = gpd.GeoDataFrame(stops, geometry = gpd.points_from_xy(stops.Longitude1, stops.Latitude1))
gpd_stops = gpd_stops.set_crs('epsg:4326')
gpd_stops = gpd_stops.to_crs(epsg=2230)
# TEST: stops 3
# stops.to_csv(r"C:/abm_runs/sar/2022_ABM3_tned/src/asim/scripts/resident/stops_3.csv")

gpd_stops = gpd.GeoDataFrame(stops, geometry = gpd.points_from_xy(stops.Longitude, stops.Latitude, crs='epsg:4326'))
gpd_stops = gpd_stops.to_crs('epsg:2230')

# TEST: stops 4
# gpd_stops.to_file(r"C:/abm_runs/sar/2022_ABM3_tned/src/asim/scripts/resident/gpd_stops.shp")

pd.set_option('display.float_format', lambda x: '%.9f' % x)

gpd_stops['Longitude'] = gpd_stops['geometry'].x
gpd_stops['Latitude'] = gpd_stops['geometry'].y
gpd_stops['Longitude'] = gpd_stops['geometry'].x
gpd_stops['Latitude'] = gpd_stops['geometry'].y

stops["network_node_id"] = net.get_node_ids(gpd_stops['Longitude'], gpd_stops['Latitude'])
stops["network_node_x"] = nodes["X"].loc[stops["network_node_id"]].tolist()
Expand All @@ -94,6 +112,9 @@
np.where((stops['Mode']==4) | (stops['Mode']==5) | (stops['Mode']==8) | (stops['Mode']==9) | (stops['Mode']==6) | (stops['Mode']==7), 'E',
'N'))

# TEST: stops 4
# stops.to_csv(r"C:/abm_runs/sar/2022_ABM3_tned/src/asim/scripts/resident/stops_4.csv")

# %%
# MAZ-to-MAZ Walk
print(f"{datetime.now().strftime('%H:%M:%S')} Build MAZ to MAZ Walk Table...")
Expand Down Expand Up @@ -162,7 +183,6 @@


print(f"{datetime.now().strftime('%H:%M:%S')} Remove Maz Stop Pairs Beyond Max Walk Distance...")

maz_to_stop_walk_cost_out = maz_to_stop_walk_cost[(maz_to_stop_walk_cost["DISTANCE"] <= max_maz_local_bus_stop_walk_dist_feet / 5280.0) & (maz_to_stop_walk_cost['MODE'] == 'L') |
(maz_to_stop_walk_cost["DISTANCE"] <= max_maz_premium_transit_stop_walk_dist_feet / 5280.0) & (maz_to_stop_walk_cost['MODE'] == 'E')].copy()

Expand All @@ -189,7 +209,7 @@
maz_stop_walk['DISTWALK'].fillna(999999, inplace = True)
maz_stop_walk.rename({'MAZ': 'maz', 'DISTWALK': 'walk_dist_' + output}, axis='columns', inplace=True)
maz_stop_walk0 = maz_stop_walk0.merge(maz_stop_walk, left_on='maz', right_on='maz')

maz_stop_walk0.sort_values(by=['maz'], inplace=True)
print(f"{datetime.now().strftime('%H:%M:%S')} Write Results...")
maz_stop_walk0.to_csv(path + '/output/skims/' + "maz_stop_walk.csv", index=False)
Expand Down
40 changes: 13 additions & 27 deletions src/main/emme/toolbox/assignment/build_transit_scenario.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ def __init__(self):
self.attributes = [
"period", "scenario_id", "base_scenario_id",
"data_table_name", "scenario_title", "overwrite"]
self._node_id_tracker = None

def page(self):
if not self.data_table_name:
Expand Down Expand Up @@ -218,6 +219,7 @@ def __call__(self, period, base_scenario, transit_emmebank, scenario_id, scenari
for field in base_scenario.network_fields():
scenario.create_network_field(field.type, field.name, field.atype, field.description)
network = base_scenario.get_network()
self._node_id_tracker = gen_utils.AvailableNodeIDTracker(network)
new_attrs = [
("TRANSIT_LINE", "@xfer_from_day", "Fare for xfer from daypass/trolley"),
("TRANSIT_LINE", "@xfer_from_premium", "Fare for first xfer from premium"),
Expand All @@ -235,7 +237,6 @@ def __call__(self, period, base_scenario, transit_emmebank, scenario_id, scenari
attr.description = desc
network.create_attribute(elem, name)
network.create_attribute("TRANSIT_LINE", "xfer_from_bus")
self._init_node_id(network)

transit_passes = gen_utils.DataTableProc("%s_transit_passes" % data_table_name)
transit_passes = {row["pass_type"]: row["cost"] for row in transit_passes}
Expand Down Expand Up @@ -322,28 +323,23 @@ def __call__(self, period, base_scenario, transit_emmebank, scenario_id, scenari
self.timed_transfers(network, timed_transfers_with_walk, period)
#self.connect_circle_lines(network)
#self.duplicate_tap_adajcent_stops(network)
# The fixed guideway travel times are stored in "@trtime_link_xx"
# The fixed guideway travel times are stored in "@trtime"
# and copied to data2 (ul2) for the ttf
# The congested auto times for mixed traffic are in "@auto_time"
# (output from traffic assignment) which needs to be copied to auto_time (a.k.a. timau)
# (The auto_time attribute is generated from the VDF values which include reliability factor)
## also copying auto_time to ul1, so it does not get wiped when transit connectors are created.

src_attrs = [params["fixed_link_time"]]
dst_attrs = ["data2"]
if scenario.has_traffic_results and "@auto_time" in scenario.attributes("LINK"):
src_attrs.append("@auto_time")
dst_attrs.append("auto_time")
src_attrs.extend(["@auto_time", "@auto_time"])
dst_attrs.extend(["auto_time", "data1"])
values = network.get_attribute_values("LINK", src_attrs)
network.set_attribute_values("LINK", dst_attrs, values)

scenario.publish_network(network)

##copying auto_time to ul1, so it does not get wiped when transit connectors are created.
if scenario.has_traffic_results and "@auto_time" in scenario.attributes("LINK"):
copy_att(from_attribute_name='timau',
to_attribute_name='ul1',
from_scenario=scenario,
to_scenario=scenario)

self._node_id_tracker = None
return scenario

@_m.logbook_trace("Add timed-transfer links", save_arguments=True)
Expand Down Expand Up @@ -449,13 +445,11 @@ def split_link(link, node_id, lines, split_links, stop_attr, waits=None):
if near_side_stop:
in_link.length = length
out_link.length = 0
for p in ["ea", "am", "md", "pm", "ev"]:
out_link["@trtime_link_" + p] = 0
out_link["@trtime"] = 0
else:
out_link.length = length
in_link.length = 0
for p in ["ea", "am", "md", "pm", "ev"]:
in_link["@trtime_link_" + p] = 0
in_link["@trtime"] = 0

for seg in in_link.segments():
if not near_side_stop:
Expand All @@ -476,10 +470,10 @@ def split_link(link, node_id, lines, split_links, stop_attr, waits=None):
split_links = {}
for transfer in network_transfers:
new_alight_node = split_link(
transfer["from_link"], self._get_node_id(), transfer["from_lines"],
transfer["from_link"], self._node_id_tracker.get_id(), transfer["from_lines"],
split_links, "allow_alightings")
new_board_node = split_link(
transfer["to_link"], self._get_node_id(), transfer["to_lines"],
transfer["to_link"], self._node_id_tracker.get_id(), transfer["to_lines"],
split_links, "allow_boardings", waits=transfer["wait"])
walk_link = transfer["walk_link"]
transfer_link = network.create_link(
Expand Down Expand Up @@ -508,7 +502,7 @@ def offset_coords(node):
if first_seg.i_node == last_seg.i_node:
# Add new node, offset from existing node
start_node = line.segment(0).i_node
xfer_node = network.create_node(self._get_node_id(), False)
xfer_node = network.create_node(self._node_id_tracker.get_id(), False)
xfer_node["@network_adj"] = 2
xfer_node.x, xfer_node.y = offset_coords(start_node)
network.create_link(start_node, xfer_node, [line.vehicle.mode])
Expand Down Expand Up @@ -556,11 +550,3 @@ def offset_coords(node):
seg[k] = v

network.delete_attribute("NODE", "circle_lines")

def _init_node_id(self, network):
new_node_id = max(n.number for n in network.nodes())
self._new_node_id = math.ceil(new_node_id / 10000.0) * 10000

def _get_node_id(self):
self._new_node_id += 1
return self._new_node_id
8 changes: 4 additions & 4 deletions src/main/emme/toolbox/assignment/create_transit_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ def create_tr_connectors(self, period, create_connector_flag, main_directory):
delete_existing=True,
selection={
"centroid":"all",
"node": "@ipark=1,9 and %s" % self.line_haul_mode_specs[i],
"node": "@park=1,9 and %s" % self.line_haul_mode_specs[i],
"link":"none",
"exclude_split_links":False,
"only_midblock_nodes": False},
Expand Down Expand Up @@ -289,7 +289,7 @@ def create_tr_connectors(self, period, create_connector_flag, main_directory):
delete_existing=True,
selection={
"centroid":"all",
"node": "@ipark=1,9 and %s" % self.line_haul_mode_specs[i],
"node": "@park=1,9 and %s" % self.line_haul_mode_specs[i],
"link":"none",
"exclude_split_links":False,
"only_midblock_nodes": False},
Expand Down Expand Up @@ -323,7 +323,7 @@ def create_tr_connectors(self, period, create_connector_flag, main_directory):
delete_existing=True,
selection={
"centroid":"all",
"node": "@ipark=1,9 and %s" % self.line_haul_mode_specs[i],
"node": "@park=1,9 and %s" % self.line_haul_mode_specs[i],
"link":"none",
"exclude_split_links":False,
"only_midblock_nodes": False},
Expand All @@ -336,7 +336,7 @@ def create_tr_connectors(self, period, create_connector_flag, main_directory):
delete_existing=True,
selection={
"centroid":"i=1,4",
"node": "@ipark=1,9 and %s" % self.line_haul_mode_specs[i],
"node": "@park=1,9 and %s" % self.line_haul_mode_specs[i],
"link":"none",
"exclude_split_links":False,
"only_midblock_nodes": False},
Expand Down
38 changes: 19 additions & 19 deletions src/main/emme/toolbox/assignment/traffic_assignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -565,15 +565,15 @@ def run_assignment(self, period, relative_gap, max_iterations, num_processors, s
# create_attribute("LINK", "@cost_hov2_%s" % p, "toll (non-mngd) + cost for HOV2",
# 0, overwrite=True, scenario=scenario)
# net_calc("@cost_hov2_%s" % p, "@cost_hov_%s" % p, "modes=d")
# net_calc("@cost_hov2_%s" % p, "@cost_auto_%s" % p, "@lane_restriction=3")
# net_calc("@cost_hov2_%s" % p, "@cost_auto_%s" % p, "@hov=3")

with _m.logbook_trace("Transit line headway and background traffic"):
# set headway for the period
hdw = {"ea": "@headway_op",
hdw = {"ea": "@headway_ea",
"am": "@headway_am",
"md": "@headway_op",
"md": "@headway_md",
"pm": "@headway_pm",
"ev": "@headway_op"}
"ev": "@headway_ev"}
net_calc("hdw", hdw[p], {"transit_line": "all"})

# transit vehicle as background flow with periods
Expand Down Expand Up @@ -734,15 +734,15 @@ def run_stochastic_assignment(
# create_attribute("LINK", "@cost_hov2_%s" % p, "toll (non-mngd) + cost for HOV2",
# 0, overwrite=True, scenario=scenario)
# net_calc("@cost_hov2_%s" % p, "@cost_hov_%s" % p, "modes=d")
# net_calc("@cost_hov2_%s" % p, "@cost_auto_%s" % p, "@lane_restriction=3")
# net_calc("@cost_hov2_%s" % p, "@cost_auto_%s" % p, "@hov=3")

with _m.logbook_trace("Transit line headway and background traffic"):
# set headway for the period: format is (attribute_name, period duration in hours)
hdw = {"ea": ("@headway_op", 3),
hdw = {"ea": ("@headway_ea", 3),
"am": ("@headway_am", 3),
"md": ("@headway_op", 6.5),
"md": ("@headway_md", 6.5),
"pm": ("@headway_pm", 3.5),
"ev": ("@headway_op", 5)}
"ev": ("@headway_ev", 5)}
net_calc('ul2', '0', {'link': 'all'})
net_calc('hdw', '9999.99', {'transit_line': 'all'})
net_calc(
Expand Down Expand Up @@ -789,11 +789,11 @@ def run_stochastic_assignment(

with _m.logbook_trace("Reset transit line headways"):
# set headway for the period
hdw = {"ea": "@headway_op",
hdw = {"ea": "@headway_ea",
"am": "@headway_am",
"md": "@headway_op",
"md": "@headway_md",
"pm": "@headway_pm",
"ev": "@headway_op"}
"ev": "@headway_ev"}
net_calc("hdw", hdw[p], {"transit_line": "all"})
return

Expand Down Expand Up @@ -829,17 +829,17 @@ def calc_network_results(self, period, num_processors, scenario):
create_attribute("TURN", "@auto_time_turn", "traffic turn time (ptimau)",
overwrite=True, scenario=scenario)

net_calc("@hovdist", "length", {"link": "@lane_restriction=2,3"})
net_calc("@hovdist", "length", {"link": "@hov=2,3"})
net_calc("@tollcost", "@cost_auto_%s - @cost_operating" % p)
net_calc("@h2tollcost", "@cost_hov2_%s - @cost_operating" % p, {"link": "@lane_restriction=3,4"})
net_calc("@h3tollcost", "@cost_hov3_%s - @cost_operating" % p, {"link": "@lane_restriction=4"})
net_calc("@h2tollcost", "@cost_hov2_%s - @cost_operating" % p, {"link": "@hov=3,4"})
net_calc("@h3tollcost", "@cost_hov3_%s - @cost_operating" % p, {"link": "@hov=4"})
net_calc("@trk_ltollcost", "@cost_lgt_truck_%s - @cost_operating" % p)
net_calc("@trk_mtollcost", "@cost_med_truck_%s - @cost_operating" % p)
net_calc("@trk_htollcost", "@cost_hvy_truck_%s - @cost_operating" % p)
net_calc("@mlcost", "@toll_%s" % p, {"link": "not @lane_restriction=4"})
net_calc("@tolldist", "length", {"link": "@lane_restriction=2,4"})
net_calc("@h2tolldist", "length", {"link": "@lane_restriction=3,4"})
net_calc("@h3tolldist", "length", {"link": "@lane_restriction=4"})
net_calc("@mlcost", "@toll_%s" % p, {"link": "not @hov=4"})
net_calc("@tolldist", "length", {"link": "@hov=2,4"})
net_calc("@h2tolldist", "length", {"link": "@hov=3,4"})
net_calc("@h3tolldist", "length", {"link": "@hov=4"})
net_calc("@auto_volume", "volau", {"link": "modes=d"})
net_calc("ul2", "volau+volad", {"link": "modes=d"})
vdfs = [f for f in emmebank.functions() if f.type == "VOLUME_DELAY"]
Expand Down Expand Up @@ -1026,7 +1026,7 @@ def change_mode_sovntp(self, scenario):
gen_sov_mode = 's'
sov_mode = scenario.mode(gen_sov_mode)
change_link_modes(modes=[sov_mode], action="ADD",
selection="@lane_restriction=4", scenario=scenario)
selection="@hov=4", scenario=scenario)

def report(self, period, scenario, classes):
emmebank = scenario.emmebank
Expand Down
Loading

0 comments on commit 2c9c92c

Please sign in to comment.