diff --git a/Scripts/assignment/emme_assignment.py b/Scripts/assignment/emme_assignment.py index da002288..a9a4fe41 100644 --- a/Scripts/assignment/emme_assignment.py +++ b/Scripts/assignment/emme_assignment.py @@ -172,6 +172,8 @@ def aggregate_results(self, resultdata): linktypes.add(param.roadtypes[linktype]) linklengths = pandas.Series(0.0, linktypes) soft_modes = param.transit_classes + ("bike",) + attr_names = self.day_scenario.attributes("LINK") + resultdata.print_line("Link\t" + "\t".join(attr_names), "links") network = self.day_scenario.get_network() for link in network.links(): linktype = link.type % 100 @@ -197,6 +199,10 @@ def aggregate_results(self, resultdata): linklengths[param.railtypes[linktype]] += link.length else: linklengths[param.roadtypes[vdf]] += link.length / 2 + wkt = "LINESTRING ({} {}, {} {})".format( + link.i_node.x, link.i_node.y, link.j_node.x, link.j_node.y) + attrs = "\t".join([str(link[attr]) for attr in attr_names]) + resultdata.print_line(wkt + "\t" + attrs, "links") if faulty_kela_code_nodes: s = "Municipality KELA code not found for nodes: " + ", ".join( faulty_kela_code_nodes) diff --git a/Scripts/assignment/emme_bindings/mock_project.py b/Scripts/assignment/emme_bindings/mock_project.py index a2f5d614..b6dbe3f8 100644 --- a/Scripts/assignment/emme_bindings/mock_project.py +++ b/Scripts/assignment/emme_bindings/mock_project.py @@ -420,6 +420,11 @@ def __init__(self, idx): def zone_numbers(self): return sorted(self._network._centroids) + def attributes(self, attr_type): + network = self.get_network() + # TODO Return other attributes except extra attributes + return list(network._extra_attr[attr_type]) + def extra_attribute(self, idx): network = self.get_network() for attr_type in network._extra_attr: diff --git a/Scripts/helmet.py b/Scripts/helmet.py index 32c0223a..2d1e5134 100644 --- a/Scripts/helmet.py +++ b/Scripts/helmet.py @@ -85,6 +85,9 @@ def main(args): results_path, ass_model, args.scenario_name) log_extra["status"]["results"] = model.mode_share + model.cdm.set_car_growth(constant=args.car_growth_constant, + factor=args.car_growth_factor) + # Run traffic assignment simulation for N iterations, # on last iteration model-system will save the results log_extra["status"]["state"] = "preparing" @@ -247,6 +250,17 @@ def main(args): action="store_true", default=config.USE_FIXED_TRANSIT_COST, help="Using this flag activates use of pre-calculated (fixed) transit costs."), + # MAL 2023 input data + parser.add_argument( + "--car-growth-constant", + type=float, + default=0.0, + help="Car ownership growth constant. To increase, try 0.1."), + parser.add_argument( + "--car-growth-factor", + type=float, + default=1.0, + help="Car ownership growth factor. To decrease, try 0.8."), args = parser.parse_args() log.initialize(args) diff --git a/Scripts/models/linear.py b/Scripts/models/linear.py index cc3115f4..9a7dfcd3 100644 --- a/Scripts/models/linear.py +++ b/Scripts/models/linear.py @@ -80,10 +80,24 @@ def __init__(self, zone_data_base, zone_data_forecast, bounds, resultdata): out=numpy.array(forecast_sh_detached), where=pop_growth!=0) self.zone_data._values["share_detached_houses_new"] = pandas.Series( share_detached_new, self.zone_data.zone_numbers[self.bounds]) - + self.set_car_growth() + + def set_car_growth(self, constant=0.0, factor=1.0): + """Set extra car ownership growth for sensitivity analyses. + + Parameters + ---------- + constant : float (optional) + Constant to add to prediction + factor : float (optional) + Factor to multiply prediction by + """ + self._growth_constant = constant + self._growth_factor = factor + def predict(self): """Get car ownership prediction for zones. - + Return ------ pandas.Series @@ -108,6 +122,8 @@ def predict(self): .clip(upper=1.0)) prediction = (self.pop_growth_share * prediction + (1-self.pop_growth_share) * base_car_density) + prediction += self._growth_constant + prediction *= self._growth_factor self.print_results(prediction) return prediction