from __future__ import absolute_import
from __future__ import print_function
import math
import sys
import os
import matplotlib.pyplot as plt
import detector
SUMO_HOME = os.environ.get('SUMO_HOME',
os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..'))
sys.path.append(os.path.join(SUMO_HOME, 'tools'))
import sumolib
def get_options(args=None):
parser = sumolib.options.ArgumentParser()
parser.add_argument("-d", "--detector-file", dest="detfile", category="input", type=parser.additional_file,
help="read detectors from FILE (mandatory)", metavar="FILE")
parser.add_argument("--flow-column", dest="flowcol", default="qPKW", type=str,
help="which column contains flows", metavar="STRING")
parser.add_argument("-z", "--respect-zero", action="store_true", dest="respectzero",
default=False, help="respect detectors without data (or with permanent zero) with zero flow")
parser.add_argument("-i", "--interval", type=parser.time,
default=60, help="aggregation interval in minutes")
parser.add_argument("--long-names", action="store_true", dest="longnames",
default=False, help="do not use abbreviated names for detector groups")
parser.add_argument("--edge-names", action="store_true", dest="edgenames",
default=False, help="include detector group edge name in output")
parser.add_argument("-b", "--begin", type=parser.time, default=0, help="begin time in minutes")
parser.add_argument("-e", "--end", type=parser.time, default=None, help="end time in minutes")
parser.add_argument("-o", "--csv-output", dest="csv_output", type=str,
help="write plot data with prefix", category="output", metavar="FILE")
parser.add_argument("--extension", help="extension for saving plots", default="png", type=str, category="output")
parser.add_argument("-s", "--show", action="store_true", default=False, help="show plot directly")
parser.add_argument("-g", "--group-by", dest="groupby",
help="group detectors (all, none, type) ", default="all", type=str)
parser.add_argument("-t", "--type-filter", dest="typefilter", type=str, help="only show selected types")
parser.add_argument("-r", "--reference-flow", dest="reference", type=parser.file,
help="reference flow file that should not be grouped", metavar="FILE")
parser.add_argument("--id-filter", dest="idfilter", type=str, help="filter detector ids")
parser.add_argument("--single-plot", action="store_true", dest="singleplot",
default=False, help="put averything in a single plot")
parser.add_argument("-m", "--max-files", type=int, dest="maxfiles",
category="input", help="limit number of input files")
parser.add_argument("-n", "--no-legend", dest="nolegend", action="store_true",
default=False, help="dont draw legend")
parser.add_argument("-v", "--verbose", action="store_true", default=False, help="tell me what you are doing")
parser.add_argument("flowfiles", help="read flows from FILE(s) (mandatory)", nargs="+",
category="input", type=parser.file, metavar="FILE+")
options = parser.parse_args()
if options.maxfiles is not None:
options.flowfiles = options.flowfiles[:options.maxfiles]
print(options.flowfiles)
if not options.detfile or not options.flowfiles:
parser.print_help()
sys.exit()
return options
def write_csv(keys, data, fname):
with open(fname, 'w') as f:
f.write("#key;value\n")
for key, v in zip(keys, data):
f.write("%s;%s\n" % (key, v))
def initDataList(begin, end, interval):
return [None] * int(math.ceil((end - begin) / interval))
def addToDataList(data, i, val):
if val is not None:
if data[i] is None:
data[i] = val
else:
data[i] += val
def plot(options, allData, prefix="", linestyle="-"):
if not options.singleplot:
plt.figure()
labelsuffix = ""
if prefix != "":
labelsuffix = "_%s" % prefix
plt.ylabel("Avg. Simulation Flow %s" % prefix)
plt.xlabel("Minutes")
x = range(int(options.begin), int(options.end), int(options.interval))
for f, data in zip(options.flowfiles, allData):
label = f[:-4] + labelsuffix
plt.plot(x, data, label=label, linestyle=linestyle)
label = label.replace(";", "_")
if options.csv_output is not None:
fname = options.csv_output
if len(options.flowfiles) > 1:
lastdir = os.path.basename(os.path.dirname(f))
fname = "%s_%s.%s.csv" % (options.csv_output, label, lastdir)
write_csv(x, data, fname)
if not options.nolegend:
plt.legend(loc='best')
if not options.singleplot:
plt.savefig(label + "." + options.extension)
def main(options):
detReaders = [detector.DetectorReader(options.detfile, detector.LaneMap()) for f in options.flowfiles]
for f in options.flowfiles:
options.begin, options.end = detReaders[0].findTimes(f, options.begin, options.end)
if options.verbose:
print("begin=%s, end=%s" % (options.begin, options.end))
for detReader, f in zip(detReaders, options.flowfiles):
if options.verbose:
print("reading %s" % f)
detReader.clearFlows(options.begin, options.interval)
detReader.readFlowsTimeline(f, options.interval, begin=options.begin, end=options.end, flowCol=options.flowcol)
if options.singleplot:
plt.figure(figsize=(14, 9), dpi=100)
if options.groupby == "all":
allData = []
for detReader, f in zip(detReaders, options.flowfiles):
data = initDataList(options.begin, options.end, options.interval)
for edge, group in detReader.getGroups():
if options.idfilter is not None and options.idfilter not in group.ids[0]:
continue
assert len(group.timeline) <= len(data)
for i, (flow, speed) in enumerate(group.timeline):
addToDataList(data, i, flow)
allData.append(data)
plot(options, allData)
elif options.groupby == "type":
for detType, linestyle in [("source", "-"), ("sink", ":"), ("between", "--")]:
allData = []
for detReader, f in zip(detReaders, options.flowfiles):
data = initDataList(options.begin, options.end, options.interval)
for edge, group in detReader.getGroups():
if options.idfilter is not None and options.idfilter not in group.ids[0]:
continue
assert len(group.timeline) <= len(data)
if group.type == detType:
for i, (flow, speed) in enumerate(group.timeline):
addToDataList(data, i, flow)
allData.append(data)
plot(options, allData, detType, linestyle)
elif options.groupby == "none":
for det, groupName in [(g.ids[0], g.getName(options.longnames, None)) for e, g in detReaders[0].getGroups()]:
allData = []
for detReader, f in zip(detReaders, options.flowfiles):
data = initDataList(options.begin, options.end, options.interval)
group = detReader.getGroup(det)
if options.typefilter is not None and group.type != options.typefilter:
continue
if options.idfilter is not None and options.idfilter not in group.ids[0]:
continue
assert len(group.timeline) <= len(data)
for i, (flow, speed) in enumerate(group.timeline):
addToDataList(data, i, flow)
allData.append(data)
plot(options, allData, "%s_%s" % (groupName, group.type))
else:
raise RuntimeError("group-by '%s' not supported" % options.groupby)
if options.singleplot:
plt.savefig("singlePlot." + options.extension)
if options.show:
plt.show()
if __name__ == "__main__":
main(get_options())