Skip to content

Commit 9a33598

Browse files
committed
Merge branch 'assign-bikes-as-F-mode' into helmet5-experimental
2 parents a7941c5 + f2a651c commit 9a33598

File tree

5 files changed

+37
-14
lines changed

5 files changed

+37
-14
lines changed

Scripts/assignment/assignment_period.py

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ def prepare(self, segment_results: Dict[str,Dict[str,str]]):
9999
self._calc_boarding_penalties()
100100
self._calc_background_traffic()
101101
self._specify()
102+
self._fill_h_mode()
102103

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

340341
# Transit function definition
341342
for modeset in param.transit_delay_funcs:
@@ -376,8 +377,7 @@ def _set_car_and_transit_vdfs(self):
376377
segment.transit_time_func = func
377378
if car_mode in link.modes:
378379
link.modes |= {main_mode}
379-
elif main_mode in link.modes:
380-
link.modes -= {main_mode}
380+
if link.num_lanes == 0: link.num_lanes = 1
381381
self.event_handler.on_car_and_transit_vdfs_set(self, network)
382382
self.emme_scenario.publish_network(network)
383383

@@ -405,7 +405,7 @@ def _set_bike_vdfs(self):
405405
roadtype = param.custom_roadtypes[linktype]
406406
else:
407407
roadtype = None
408-
if (roadtype == "motorway" and network.mode('f') in link.modes
408+
if (roadtype == "motorway" and network.mode(param.bike_mode) in link.modes
409409
and link["@pyoratieluokka"] == 0):
410410
# Force bikes on motorways onto separate bikepaths
411411
link["@pyoratieluokka"] = 3
@@ -416,13 +416,9 @@ def _set_bike_vdfs(self):
416416
else:
417417
link.volume_delay_func = pathclass[None]
418418
except KeyError:
419-
link.volume_delay_func = 98
420-
if bike_mode in link.modes:
421-
link.modes |= {main_mode}
422-
elif main_mode in link.modes:
423-
link.modes -= {main_mode}
419+
link.volume_delay_func = 98
424420
self.event_handler.on_bike_vdfs_set(self, network)
425-
self.emme_scenario.publish_network(network)
421+
self.emme_scenario.publish_network(network)
426422

427423
def _set_emmebank_matrices(self,
428424
matrices: Dict[str,numpy.ndarray],
@@ -627,7 +623,7 @@ def _specify(self):
627623
"type": "STANDARD_TRAFFIC_ASSIGNMENT",
628624
"classes": [
629625
{
630-
"mode": param.main_mode,
626+
"mode": param.bike_mode,
631627
"demand": self.emme_matrices["bike"]["demand"],
632628
"results": {
633629
"od_travel_times": {
@@ -702,6 +698,10 @@ def _assign_cars(self,
702698
time_attr = self.extra("car_time")
703699
for link in network.links():
704700
link[time_attr] = link.auto_time
701+
#prevent errors from non-car links
702+
#assignment only uses mode-based subnetworks,
703+
# these should not be used in practice
704+
if link.auto_time > 1e3: link.auto_time = 1e3
705705
self.emme_scenario.publish_network(network)
706706
log.info("Car assignment performed for scenario {}".format(
707707
self.emme_scenario.id))
@@ -748,8 +748,17 @@ def _assign_bikes(self,
748748
specification=spec, scenario=scen)
749749
log.info("Bike assignment performed for scenario " + str(scen.id))
750750

751+
def _fill_h_mode(self):
752+
#Add h mode everywhere just to be sure
753+
network = self.emme_scenario.get_network()
754+
main_mode = network.mode(param.main_mode)
755+
for link in network.links():
756+
link.modes |= {main_mode}
757+
self.emme_scenario.publish_network(network)
758+
751759
def _assign_pedestrians(self):
752760
"""Perform pedestrian assignment for one scenario."""
761+
753762
log.info("Pedestrian assignment started...")
754763
self.emme_project.pedestrian_assignment(
755764
specification=self.walk_spec, scenario=self.emme_scenario)

Scripts/assignment/emme_bindings/mock_project.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,13 @@ def create_mode(self, mode_type: str, idx: str) -> 'Mode':
564564
mode = Mode(idx, mode_type)
565565
self._modes[idx] = mode
566566
return mode
567+
568+
def delete_mode(self, idx: str, cascade: bool = False):
569+
mode = self._modes[idx]
570+
if cascade:
571+
for link in self._links:
572+
self._links[link].modes -= {mode}
573+
self._modes.pop(idx)
567574

568575
def node(self, idx: int) -> 'Node':
569576
idx = int(idx)

Scripts/models/logit.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ def _calc_mode_util(self, impedance):
5959
exps = numpy.exp(utility)
6060
self.mode_exps[mode] = exps
6161
expsum += exps
62+
if expsum.min() == 0:
63+
raise ValueError("Exponentiated utility sum must be greater than zero. The impedance might be too high.")
6264
return expsum
6365

6466
def _calc_dest_util(self, mode, impedance):

Scripts/tests/test_data/Network/modes_test.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ a c 'Auto' 4 1
99
a v 'Pakettiaut' 4 1
1010
a k 'Kuorma-aut' 4 1
1111
a y 'KA peravau' 4 1
12+
a f 'Polkupyora' 4 1
1213
a b 'HSL-bussi' 2 1
1314
a g 'HSL-runkob' 2 1
1415
a d 'Muu bussi' 2 1
@@ -21,4 +22,3 @@ a p 'Pikaratikk' 2 1
2122
a w 'Vesiliiken' 2 1
2223
a a 'Kavely' 3 1 0.00 0.00 0.00 0.00 5.0
2324
a s 'Ulkokavely' 3 1 0.00 0.00 0.00 0.00 5.0
24-
a f 'Polkupyora' 3 1 0.00 0.00 0.00 0.00 17.0

Scripts/utils/validate_network.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ def validate(network, fares=None):
4848
log.error(msg)
4949
raise ValueError(msg)
5050
validate_mode(network, param.main_mode, EMME_AUTO_MODE)
51-
for m in param.assignment_modes.values():
51+
for m in list(param.assignment_modes.values()) + [param.bike_mode]:
5252
validate_mode(network, m, EMME_AUX_AUTO_MODE)
5353
for m in param.transit_modes:
5454
validate_mode(network, m, EMME_TRANSIT_MODE)
55-
for m in param.aux_modes + [param.bike_mode]:
55+
for m in param.aux_modes:
5656
validate_mode(network, m, EMME_AUX_TRANSIT_MODE)
5757
modesets = []
5858
intervals = []
@@ -99,6 +99,11 @@ def validate(network, fares=None):
9999
msg = "Link id {} type must not be 999, please refer to the helmet-docs manual".format(link.id)
100100
log.error(msg)
101101
raise ValueError(msg)
102+
if link.length > 200:
103+
log.warn(
104+
"Link id {} has length {} km. Project settings might be incorrect".format(
105+
link.id, link.length
106+
))
102107

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

0 commit comments

Comments
 (0)