Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 20 additions & 11 deletions Scripts/assignment/assignment_period.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ def prepare(self, segment_results: Dict[str,Dict[str,str]]):
self._calc_boarding_penalties()
self._calc_background_traffic()
self._specify()
self._fill_h_mode()

def assign(self, matrices: dict, iteration: Union[int,str]) -> Dict:
"""Assign cars, bikes and transit for one time period.
Expand Down Expand Up @@ -335,7 +336,7 @@ def _set_car_and_transit_vdfs(self):
break
else:
# Link with no car traffic
link.volume_delay_func = 0
link.volume_delay_func = 10 #good enough as default function

# Transit function definition
for modeset in param.transit_delay_funcs:
Expand Down Expand Up @@ -376,8 +377,7 @@ def _set_car_and_transit_vdfs(self):
segment.transit_time_func = func
if car_mode in link.modes:
link.modes |= {main_mode}
Comment on lines 378 to 379
Copy link
Collaborator

Choose a reason for hiding this comment

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

You have already allowed main_mode on all links, so this is unnecessary now, is it not?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This can indeed be dropped.

elif main_mode in link.modes:
link.modes -= {main_mode}
if link.num_lanes == 0: link.num_lanes = 1
self.event_handler.on_car_and_transit_vdfs_set(self, network)
self.emme_scenario.publish_network(network)

Expand Down Expand Up @@ -405,7 +405,7 @@ def _set_bike_vdfs(self):
roadtype = param.custom_roadtypes[linktype]
else:
roadtype = None
if (roadtype == "motorway" and network.mode('f') in link.modes
if (roadtype == "motorway" and network.mode(param.bike_mode) in link.modes
and link["@pyoratieluokka"] == 0):
# Force bikes on motorways onto separate bikepaths
link["@pyoratieluokka"] = 3
Expand All @@ -416,13 +416,9 @@ def _set_bike_vdfs(self):
else:
link.volume_delay_func = pathclass[None]
except KeyError:
link.volume_delay_func = 98
if bike_mode in link.modes:
link.modes |= {main_mode}
elif main_mode in link.modes:
link.modes -= {main_mode}
link.volume_delay_func = 98
self.event_handler.on_bike_vdfs_set(self, network)
self.emme_scenario.publish_network(network)
self.emme_scenario.publish_network(network)

def _set_emmebank_matrices(self,
matrices: Dict[str,numpy.ndarray],
Expand Down Expand Up @@ -627,7 +623,7 @@ def _specify(self):
"type": "STANDARD_TRAFFIC_ASSIGNMENT",
"classes": [
{
"mode": param.main_mode,
"mode": param.bike_mode,
"demand": self.emme_matrices["bike"]["demand"],
"results": {
"od_travel_times": {
Expand Down Expand Up @@ -702,6 +698,10 @@ def _assign_cars(self,
time_attr = self.extra("car_time")
for link in network.links():
link[time_attr] = link.auto_time
#prevent errors from non-car links
#assignment only uses mode-based subnetworks,
# these should not be used in practice
if link.auto_time > 1e3: link.auto_time = 1e3
self.emme_scenario.publish_network(network)
log.info("Car assignment performed for scenario {}".format(
self.emme_scenario.id))
Expand Down Expand Up @@ -748,8 +748,17 @@ def _assign_bikes(self,
specification=spec, scenario=scen)
log.info("Bike assignment performed for scenario " + str(scen.id))

def _fill_h_mode(self):
#Add h mode everywhere just to be sure
network = self.emme_scenario.get_network()
main_mode = network.mode(param.main_mode)
for link in network.links():
link.modes |= {main_mode}
self.emme_scenario.publish_network(network)

Comment on lines +752 to +758
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do you do this here, when it has nothing to do with pedestrian assignment?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is more like a fix for the older networks to bring them to newer standard.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes, so maybe you could move this fix to some more natural place, like prepare()?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea, I moved them to prepare. Prepare does not seem to be used for mock assignment, but that does not seem to be a big issue as of now.

def _assign_pedestrians(self):
"""Perform pedestrian assignment for one scenario."""

log.info("Pedestrian assignment started...")
self.emme_project.pedestrian_assignment(
specification=self.walk_spec, scenario=self.emme_scenario)
Expand Down
7 changes: 7 additions & 0 deletions Scripts/assignment/emme_bindings/mock_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,13 @@ def create_mode(self, mode_type: str, idx: str) -> 'Mode':
mode = Mode(idx, mode_type)
self._modes[idx] = mode
return mode

def delete_mode(self, idx: str, cascade: bool = False):
mode = self._modes[idx]
if cascade:
for link in self._links:
self._links[link].modes -= {mode}
self._modes.pop(idx)

def node(self, idx: int) -> 'Node':
idx = int(idx)
Expand Down
2 changes: 2 additions & 0 deletions Scripts/models/logit.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ def _calc_mode_util(self, impedance):
exps = numpy.exp(utility)
self.mode_exps[mode] = exps
expsum += exps
if expsum.min() == 0:
raise ValueError("Exponentiated utility sum must be greater than zero. The impedance might be too high.")
return expsum

def _calc_dest_util(self, mode, impedance):
Expand Down
2 changes: 1 addition & 1 deletion Scripts/tests/test_data/Network/modes_test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ a c 'Auto' 4 1
a v 'Pakettiaut' 4 1
a k 'Kuorma-aut' 4 1
a y 'KA peravau' 4 1
a f 'Polkupyora' 4 1
a b 'HSL-bussi' 2 1
a g 'HSL-runkob' 2 1
a d 'Muu bussi' 2 1
Expand All @@ -21,4 +22,3 @@ a p 'Pikaratikk' 2 1
a w 'Vesiliiken' 2 1
a a 'Kavely' 3 1 0.00 0.00 0.00 0.00 5.0
a s 'Ulkokavely' 3 1 0.00 0.00 0.00 0.00 5.0
a f 'Polkupyora' 3 1 0.00 0.00 0.00 0.00 17.0
9 changes: 7 additions & 2 deletions Scripts/utils/validate_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ def validate(network, fares=None):
log.error(msg)
raise ValueError(msg)
validate_mode(network, param.main_mode, EMME_AUTO_MODE)
for m in param.assignment_modes.values():
for m in list(param.assignment_modes.values()) + [param.bike_mode]:
validate_mode(network, m, EMME_AUX_AUTO_MODE)
for m in param.transit_modes:
validate_mode(network, m, EMME_TRANSIT_MODE)
for m in param.aux_modes + [param.bike_mode]:
for m in param.aux_modes:
validate_mode(network, m, EMME_AUX_TRANSIT_MODE)
modesets = []
intervals = []
Expand Down Expand Up @@ -99,6 +99,11 @@ def validate(network, fares=None):
msg = "Link id {} type must not be 999, please refer to the helmet-docs manual".format(link.id)
log.error(msg)
raise ValueError(msg)
if link.length > 200:
log.warn(
"Link id {} has length {} km. Project settings might be incorrect".format(
link.id, link.length
))

linktype = link.type % 100
if (linktype != 70 and link.length == 0):
Expand Down