def _ParseFilterString(self, filterString): filterList = [] components = _regex_split('\n|,', filterString) #Supports newline and/or commas for component in components: if component.isspace(): continue #Skip if totally empty parts = component.split(':') if len(parts) != 2: msg = "Error parsing penalty and filter string: Separate label and filter with colons label:filter" msg += ". [%s]" %component raise SyntaxError(msg) strippedParts = [item.strip() for item in parts] filterList.append(strippedParts) return filterList
def _ParseCustomScenarioSet(self): scenarioDataList = [] components = _regex_split('\n|,', self.CustomScenarioSetString) #Supports newline and/or commas for component in components: if component.isspace(): continue #Skip if totally empty parts = component.split(':') if len(parts) not in [6,7]: msg = "Error parsing scenario set: Separate components with colons \ Uncleaned scenario number:Cleaned scenario number:Uncleaned scenario description:Cleaned scenario description:Scenario start:Scenario End:.nup file" msg += ". [%s]" %component raise SyntaxError(msg) partsList = [int(parts[0]), int(parts[1]), parts[2], parts[3], int(parts[4]), int(parts[5])] if len(parts) == 7: if parts[6].lower() == 'none': partsList.append(None) scenarioDataList.append(partsList) continue if not parts[6].strip()[-4:] == ".nup": msg = "Network update file must be in the .nup format" msg += ". [%s]" %component raise SyntaxError(msg) partsList.append(parts[6]) else: partsList.append(None) scenarioDataList.append(partsList) return scenarioDataList
def _ParseFilterString(self, filterString): penaltyFilterList = [] components = _regex_split('\n|,', filterString) #Supports newline and/or commas for component in components: if component.isspace(): continue #Skip if totally empty parts = component.split(':') if len(parts) != 4: msg = "Error parsing penalty and filter string: Separate label, filter and penalty with colons label:filter:penalty:ivttPerception" msg += ". [%s]" %component raise SyntaxError(msg) strippedParts = [item.strip() for item in parts] penaltyFilterList.append(strippedParts) return penaltyFilterList
def _ParseLinkString(self, linkSetString): linkLists = [] components = _regex_split('\n|;', linkSetString) #Supports newline and/or semi-colons for component in components: if component.isspace(): continue #Skip if totally empty parts = component.split(':') if len(parts) != 3: print component; msg = "Error parsing label and link string: Separate label and links with colons label:link1:link2" msg += ". [%s]" %component raise SyntaxError(msg) strippedParts = [item.strip() for item in parts] linkLists.append(strippedParts) return linkLists
def _ParseCustomScenarioSet(self): scenarioDataList = [] components = _regex_split( '\n|,', self.CustomScenarioSetString) #Supports newline and/or commas for component in components: if component.isspace(): continue #Skip if totally empty parts = component.split(':') if len(parts) not in [6, 7]: if len(parts) == 8: checkPath = parts[6] + ":" + parts[7] if os.path.exists(os.path.dirname(checkPath)): parts[6] = checkPath del parts[7] else: msg = "Please verify that your scenario set is separated correctly and/or that the .nup file has a valid path" msg += ". [%s]" % component raise SyntaxError(msg) else: msg = "Error parsing scenario set: Separate components with colons \ Uncleaned scenario number:Cleaned scenario number:Uncleaned scenario description:Cleaned scenario description:Scenario start:Scenario End:.nup file" msg += ". [%s]" % component raise SyntaxError(msg) partsList = [ int(parts[0]), int(parts[1]), parts[2], parts[3], int(parts[4]), int(parts[5]) ] if len(parts) == 7: if parts[6].lower() == 'none': partsList.append(None) scenarioDataList.append(partsList) continue if not parts[6].strip()[-4:] == ".nup": msg = "Network update file must be in the .nup format" msg += ". [%s]" % component raise SyntaxError(msg) partsList.append(parts[6]) else: partsList.append(None) scenarioDataList.append(partsList) return scenarioDataList
def _ParseFilterString(self, filterString): filterList = [] components = _regex_split( '\n|;', filterString) #Supports newline and/or semi-colons for component in components: if component.isspace(): continue #Skip if totally empty parts = component.split(':') if len(parts) != 2: print component msg = "Error parsing label and filter string: Separate label and filter with colons label:filter" msg += ". [%s]" % component raise SyntaxError(msg) strippedParts = [item.strip() for item in parts] filterList.append(strippedParts) return filterList
def _ParseLinkString(self, linkSetString): linkLists = [] components = _regex_split( '\n|;', linkSetString) #Supports newline and/or semi-colons for component in components: if component.isspace(): continue #Skip if totally empty parts = component.split(':') if len(parts) > 5 or len(parts) < 3 or len(parts) == 4: print(component) msg = "Error parsing label, link and line string: Separate label and links/lines with colons label:link1:link2[:line1:line2]" msg += ". [%s]" % component raise SyntaxError(msg) strippedParts = [item.strip() for item in parts] linkLists.append(strippedParts) return linkLists
def _ParseExponentString(self): exponentList = [] components = _regex_split('\n|,', self.CongestionExponentString) for component in components: if component.isspace(): continue parts = component.split(':') if len(parts) != 3: msg = 'Error parsing penalty and filter string: Separate ttf, perception and exponent with colons ttf:perception:exponent' msg += '. [%s]' % component raise SyntaxError(msg) strippedParts = [item.strip() for item in parts] try: ttf = int(strippedParts[0]) except: msg = 'ttf value must be an integer' msg += '. [%s]' % component raise SyntaxError(msg) try: perception = float(strippedParts[1]) except: msg = 'Perception value must be a number' msg += '. [%s]' % component raise SyntaxError(msg) try: exponent = float(strippedParts[2]) except: msg = 'Exponent value must be a number' msg += '. [%s]' % component raise SyntaxError(msg) exponentList.append(strippedParts[0:3]) return exponentList
def _ParseSegmentAggregators(self): #Setup the translation dictionary to get from Emme Desktop attribute names #to Modeller Python attribute names. Extra attributes are named the same. translator = {'length': 'length', 'type': 'type', 'lanes': 'num_lanes', 'vdf': 'volume_delay_func', 'ul1': 'data1_l', 'ul2': 'data2_l', 'ul3': 'data3_l', 'dwt': 'dwell_time', 'dwfac': 'factor_dwell_time_by_length', 'ttf': 'transit_time_func', 'us1': 'data1_s', 'us2': 'data2_s', 'us3': 'data3_s', 'data1_l': 'data1_l', 'data2_l': 'data2_l', 'data3_l': 'data3_l', 'ui1': 'data1_n', 'ui2': 'data2_n', 'ui3': 'data3_n', 'dwell_time': 'dwell_time', 'factor_dwell_time_by_length': 'factor_dwell_time_by_length', 'transit_time_func': 'transit_time_func', 'data1_s': 'data1_s', 'data2_s': 'data2_s', 'data3_s': 'data3_s', 'data1': 'data1', 'data2': 'data2', 'data3': 'data3', 'noali': 'allow_alightings', 'noboa': 'allow_boardings'} multipleDomainAttributes = ['data1', 'data2', 'data3'] validFuncNames = ['sum','avg','or','and','min','max','first','last','zero','avg_by_length','force'] #Setup default aggregator function names linkExtraAttributes = [] segmentExtraAttributes = [] nodeExtraAttributes = [] for exatt in self.BaseScenario.extra_attributes(): id = exatt.name t = exatt.type if t == 'NODE': nodeExtraAttributes.append(id) elif t == 'TRANSIT_SEGMENT': segmentExtraAttributes.append(id) elif t == 'LINK': linkExtraAttributes.append(id) self._linkAggregators = {'length': 'sum', 'data1_l': 'zero', 'data2_l': 'avg_by_length', 'data3_l': 'avg'} for att in linkExtraAttributes: self._linkAggregators[att] = 'avg' translator[att] = att self._segmentAggregators = {'dwell_time': 'sum', 'factor_dwell_time_by_length': 'and', 'transit_time_func': 'force', 'data1_s': 'avg_by_length', 'data2_s': 'zero', 'data3_s': 'zero'} for att in segmentExtraAttributes: self._segmentAggregators[att] = 'avg' translator[att] = att #Save extra attribute names into the translator for recognition self._nodeAggregators = {} for att in nodeExtraAttributes: self._nodeAggregators[att] = 'avg' translator[att] = att #Parse the argument string trimmedString = self.AttributeAggregatorString.replace(" ", '') #Clear spaces components = _regex_split('\n|,', trimmedString) #Supports newline and/or commas for component in components: if component.isspace(): continue #Skip if totally empty parts = component.split(':') if len(parts) != 2: msg = "Error parsing attribute aggregators: Separate attribute name from function with exactly one colon ':'" msg += ". [%s]" %component raise SyntaxError(msg) attName, funcName = parts if attName not in translator: raise IOError("Error parsing attribute aggregators: attribute '%s' not recognized." %attName) attName = translator[attName] if not funcName in validFuncNames: raise IOError("Error parsing attribute aggregators: function '%s' not recognized for attribute '%s'" %(funcName, attName)) if attName in self._linkAggregators: self._linkAggregators[attName] = funcName elif attName in self._segmentAggregators: self._segmentAggregators[attName] = funcName elif attName in self._nodeAggregators: self._nodeAggregators[attName] = funcName elif attName in multipleDomainAttributes: self._linkAggregators[attName] = funcName self._segmentAggregators[attName] = funcName self._nodeAggregators[attName] = funcName for key in self._linkAggregators.iterkeys(): if key.endswith("_l"): newKey = key.replace("_l", "") val = self._linkAggregators.pop(key) self._linkAggregators[newKey] = val for key in self._segmentAggregators.iterkeys(): if key.endswith("_s"): newKey = key.replace("_s", "") val = self._segmentAggregators.pop(key) self._segmentAggregators[newKey] = val for key in self._nodeAggregators.iterkeys(): if key.endswith("_n"): newKey = key.replace("_n", "") val = self._nodeAggregators.pop(key) self._nodeAggregators[newKey] = val for att, funcName in self._linkAggregators.iteritems(): if funcName == 'avg_by_length': self._linkAggregators[att] = self.AVERAGE_BY_LENGTH_LINKS else: self._linkAggregators[att] = _editing.NAMED_AGGREGATORS[funcName] for att, funcName in self._segmentAggregators.iteritems(): if funcName == 'avg_by_length': self._segmentAggregators[att] = self.AVERAGE_BY_LENGTH_SEGMENTS else: self._segmentAggregators[att] = _editing.NAMED_AGGREGATORS[funcName] for att, funcName in self._nodeAggregators.iteritems(): self._nodeAggregators[att] = _editing.NAMED_AGGREGATORS[funcName]