From a8631b9c3836d857586abc9f5271fd48744979ed Mon Sep 17 00:00:00 2001 From: James Vaughan Date: Wed, 18 Sep 2024 11:18:40 -0400 Subject: [PATCH] Addded selected_link_volumes option for SOLA Path Analysis (#241) --- .../XTMF_internal/multi_class_road_assignment.py | 14 ++++++++++++++ TMGToolbox/src/common/utilities.py | 6 +++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/TMGToolbox/src/XTMF_internal/multi_class_road_assignment.py b/TMGToolbox/src/XTMF_internal/multi_class_road_assignment.py index 2b53530..0d9a0fa 100644 --- a/TMGToolbox/src/XTMF_internal/multi_class_road_assignment.py +++ b/TMGToolbox/src/XTMF_internal/multi_class_road_assignment.py @@ -105,6 +105,7 @@ class MultiClassRoadAssignment(_m.Tool()): ResultAttributes = _m.Attribute(str) xtmf_AnalysisAttributes = _m.Attribute(str) xtmf_AnalysisAttributesMatrixId = _m.Attribute(str) + xtmf_AnalysisSelectedLinkVolumes = _m.Attribute(str) xtmf_AggregationOperator = _m.Attribute(str) xtmf_LowerBound = _m.Attribute(str) xtmf_UpperBound = _m.Attribute(str) @@ -168,6 +169,7 @@ def __call__( ResultAttributes, xtmf_AnalysisAttributes, xtmf_AnalysisAttributesMatrixId, + xtmf_AnalysisSelectedLinkVolumes, xtmf_AggregationOperator, xtmf_LowerBound, xtmf_UpperBound, @@ -197,6 +199,7 @@ def __call__( self.LinkTollAttributeId = [x for x in LinkTollAttributeId.split(",")] AnalysisAttributes = [x for x in xtmf_AnalysisAttributes.split("|")] AnalysisAttributesMatrixId = [x for x in xtmf_AnalysisAttributesMatrixId.split("|")] + AnalysisSelectedLinkVolumes = [x for x in xtmf_AnalysisSelectedLinkVolumes.split("|")] operators = [x for x in xtmf_AggregationOperator.split("|")] lowerBounds = [x for x in xtmf_LowerBound.split("|")] upperBounds = [x for x in xtmf_UpperBound.split("|")] @@ -205,6 +208,7 @@ def __call__( mulitplyPathValue = [x for x in xtmf_MultiplyPathPropByValue.split("|")] self.ClassAnalysisAttributes = [] self.ClassAnalysisAttributesMatrix = [] + self.ClassAnalysisSelectedLinkVolumes = [] self.ClassAnalysisOperators = [] self.ClassAnalysisLowerBounds = [] self.ClassAnalysisUpperBounds = [] @@ -215,6 +219,7 @@ def __call__( for i in range(len(self.Demand_List)): self.ClassAnalysisAttributes.append([x for x in AnalysisAttributes[i].split(",")]) self.ClassAnalysisAttributesMatrix.append([x for x in AnalysisAttributesMatrixId[i].split(",")]) + self.ClassAnalysisSelectedLinkVolumes.append([x for x in AnalysisSelectedLinkVolumes[i].split(",")]) self.ClassAnalysisOperators.append([x for x in operators[i].split(",")]) self.ClassAnalysisLowerBounds.append([x for x in lowerBounds[i].split(",")]) self.ClassAnalysisUpperBounds.append([x for x in upperBounds[i].split(",")]) @@ -228,6 +233,9 @@ def __call__( if self.ClassAnalysisAttributesMatrix[i][j] == "mf0" or self.ClassAnalysisAttributesMatrix[i][j] == "": # make mf0 matrices None for better use in spec self.ClassAnalysisAttributesMatrix[i][j] = None + if self.ClassAnalysisSelectedLinkVolumes[i][j] == "": + # make mf0 matrices None for better use in spec + self.ClassAnalysisSelectedLinkVolumes[i][j] = None try: self.ClassAnalysisLowerBounds[i][j] = float(self.ClassAnalysisLowerBounds[i][j]) self.ClassAnalysisUpperBounds[i][j] = float(self.ClassAnalysisUpperBounds[i][j]) @@ -391,6 +399,7 @@ def get_attribute_name(at): attributeDefined = False allAttributes = [] allMatrices = [] + selectedLinkVolumes = [] operators = [] lowerBounds = [] upperBounds = [] @@ -401,6 +410,7 @@ def get_attribute_name(at): for i in range(len(self.Demand_List)): allAttributes.append([]) allMatrices.append([]) + selectedLinkVolumes.append([]) operators.append([]) lowerBounds.append([]) upperBounds.append([]) @@ -411,6 +421,7 @@ def get_attribute_name(at): _m.logbook_write("Cost matrix defined for class %s" % self.ClassNames[i]) allAttributes[i].append(costAttribute[i].id) allMatrices[i].append(self.CostMatrixId[i]) + selectedLinkVolumes[i].append(None) operators[i].append("+") lowerBounds[i].append(None) upperBounds[i].append(None) @@ -424,6 +435,7 @@ def get_attribute_name(at): _m.logbook_write("Toll matrix defined for class %s" % self.ClassNames[i]) allAttributes[i].append(self.LinkTollAttributeId[i]) allMatrices[i].append(self.TollsMatrixId[i]) + selectedLinkVolumes[i].append(None) operators[i].append("+") lowerBounds[i].append(None) upperBounds[i].append(None) @@ -438,6 +450,7 @@ def get_attribute_name(at): _m.logbook_write("Additional matrix for attribute %s defined for class %s" % (self.ClassAnalysisAttributes[i][j], self.ClassNames[i])) allAttributes[i].append(self.ClassAnalysisAttributes[i][j]) allMatrices[i].append(self.ClassAnalysisAttributesMatrix[i][j]) + selectedLinkVolumes[i].append(self.ClassAnalysisSelectedLinkVolumes[i][j]) operators[i].append(self.ClassAnalysisOperators[i][j]) lowerBounds[i].append(self.ClassAnalysisLowerBounds[i][j]) upperBounds[i].append(self.ClassAnalysisUpperBounds[i][j]) @@ -470,6 +483,7 @@ def get_attribute_name(at): self.normGap, self.PerformanceFlag, self.TimesMatrixId, + selectedLinkVolumes ) report = self._tracker.runTool(trafficAssignmentTool, spec, scenario=self.Scenario) assignmentComplete = True diff --git a/TMGToolbox/src/common/utilities.py b/TMGToolbox/src/common/utilities.py index 678b481..eff8a61 100644 --- a/TMGToolbox/src/common/utilities.py +++ b/TMGToolbox/src/common/utilities.py @@ -949,6 +949,7 @@ def _getPrimarySOLASpec( normGap, PerformanceFlag, TimesMatrixId, + selectedLinkVolumes = None, ): if PerformanceFlag: @@ -994,7 +995,10 @@ def _getPrimarySOLASpec( "path_value": multiplyPathValue[i][j], }, }, - "results": {"od_values": matrices[i][j]}, + "results": { + "od_values": matrices[i][j], + "selected_link_volumes": (selectedLinkVolumes[i][j] if selectedLinkVolumes is not None else None) + }, "analyzed_demand": None, } SOLA_path_analysis[i].append(path)