from __future__ import absolute_import
from __future__ import print_function
from __future__ import division
import os
import sys
import re
from collections import defaultdict
if "SUMO_HOME" in os.environ:
sys.path += [os.path.join(os.environ["SUMO_HOME"], "tools")]
import sumolib
def get_options(args=None):
op = sumolib.options.ArgumentParser()
op.add_argument("logfile", type=op.file, category="input", help="log file")
op.add_option("-a", "--aggregation", type=op.time, default=3600,
help="define the time aggregation in seconds")
op.add_option("-p", "--gnuplot-output", type=op.file, dest="plotfile", category="output",
help="define the gnuplot output file")
op.add_option("-e", "--edgedata-output", type=op.file, dest="edgedata", category="output",
help="define the edgedata output file")
options = op.parse_args()
if options.plotfile is None:
options.plotfile = options.logfile + '.plot'
if options.edgedata is None:
options.edgedata = options.logfile + "data.xml"
return options
def parse_log(logfile, aggregate=3600):
print("Parsing %s" % logfile)
reEdge = re.compile("edge '([^']*)'")
reTime = re.compile(r"time.(\d*)\.")
reHRTime = re.compile(r"time.(\d):(\d\d):(\d\d):(\d*).")
jamCounts = defaultdict(lambda: 0)
jamStepCounts = defaultdict(lambda: 0)
with open(logfile) as log:
for index, line in enumerate(log):
try:
if "is jammed on edge" in line:
match = reEdge.search(line)
edge = match.group(1)
timeMatch = reTime.search(line)
if timeMatch:
time = int(timeMatch.group(1))
else:
timeMatch = reHRTime.search(line)
time = (24 * 3600 * int(timeMatch.group(1))
+ 3600 * int(timeMatch.group(2))
+ 60 * int(timeMatch.group(3))
+ int(timeMatch.group(4)))
jamCounts[edge] += 1
jamStepCounts[time // aggregate] += 1
except Exception:
print(sys.exc_info())
sys.exit("error when parsing line '%s'" % line)
if index % 1000 == 0:
sys.stdout.write(".")
sys.stdout.flush()
print()
print("read %s lines" % index)
return jamCounts, jamStepCounts
def print_counts(countDict, label, num=10):
counts = sorted(countDict.items(), key=lambda k: -k[1])
print(label, "worst %s edges: " % num, counts[:num])
print(label, 'total:', sum(countDict.values()))
def main(options):
jamCounts, jamStepCounts = parse_log(options.logfile, aggregate=int(options.aggregation))
print_counts(jamCounts, 'waiting')
if len(jamStepCounts) > 0:
min_step = min(jamStepCounts.keys())
max_step = max(jamStepCounts.keys())
with open(options.plotfile, 'w') as f:
if options.aggregation >= 3600:
xfactor = options.aggregation / 3600.0
xlabel = "%s hours" % xfactor
else:
xfactor = options.aggregation / 60.0
xlabel = "%s minute" % xfactor
if xfactor != 1:
xlabel += "s"
f.write(("# plot '%s' using 1:2 with lines title 'jammed per %s'\n") % (options.plotfile, xlabel))
for step in range(min_step, max_step + 1):
print(' '.join(
map(str, [xfactor * step, jamStepCounts[step]])), file=f)
with open(options.edgedata, 'w') as f:
print('<meandata>\n <interval begin="0" end="100:00:00:00">', file=f)
for item in jamCounts.items():
print(' <edge id="%s" jammed="%s"/>' % item, file=f)
print(" </interval>\n</meandata>", file=f)
if __name__ == "__main__":
main(get_options())