Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tools/output/edgeDataStatistics.py
169674 views
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
4
# Copyright (C) 2012-2025 German Aerospace Center (DLR) and others.
5
# This program and the accompanying materials are made available under the
6
# terms of the Eclipse Public License 2.0 which is available at
7
# https://www.eclipse.org/legal/epl-2.0/
8
# This Source Code may also be made available under the following Secondary
9
# Licenses when the conditions for such availability set forth in the Eclipse
10
# Public License 2.0 are satisfied: GNU General Public License, version 2
11
# or later which is available at
12
# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
13
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
14
15
# @file edgeDataStatistics.py
16
# @author Johannes Rummel
17
# @date 2022-04-05
18
19
"""Reads a list of edge data files and calculates statistic
20
values for related attributes.
21
"""
22
23
from __future__ import absolute_import
24
from __future__ import print_function
25
import os
26
import sys
27
from collections import defaultdict
28
import optparse
29
sys.path.append(os.path.join(os.path.dirname(sys.argv[0]), '..'))
30
from sumolib.output import parse # noqa
31
from sumolib.miscutils import Statistics # noqa
32
33
34
def mylist_callback(option, opt, value, parser):
35
setattr(parser.values, option.dest, value.replace(" ", "").replace('"', '').split(','))
36
37
38
def get_options(args=None):
39
optParser = optparse.OptionParser()
40
optParser.add_option("--attributes-list", type='string', action='callback', callback=mylist_callback,
41
help="if given, calculate statistic values only for the given attributes")
42
# optParser.add_option("--geh", action="store_true",
43
# default=False, help="write geh value instead of absolute differences")
44
# optParser.add_option("--undefined", type="float", default=-1001,
45
# help="value to use if the difference is undefined")
46
# optParser.add_option("--no-statistics", action="store_true", default=False,
47
# help="otherwise: handle attributes starting with 'std_' "
48
# "as standard deviation and calculate propagated error")
49
(options, args) = optParser.parse_args(args=args)
50
51
if len(args) == 2:
52
options.input_list, options.out = args
53
else:
54
optParser.print_help()
55
sys.exit(1)
56
57
return options
58
59
60
def write_stats(options):
61
"""Calculates the statistical values (as mean values and standard deviations) of all (numerical)
62
attributes of the meandata files and writes them as a new meandata file
63
to the output file."""
64
parsed_input_files = []
65
for input_file in options.input_list.replace(" ", "").replace('"', '').split(','):
66
parsed_file = parse(input_file, 'interval', heterogeneous=True)
67
parsed_input_files.append(parsed_file)
68
69
with open(options.out, 'w') as f:
70
f.write("<meandata>\n")
71
for interval_all in zip(*parsed_input_files):
72
# separate calculation for each interval
73
f.write(' <interval begin="%s" end="%s">\n' %
74
(interval_all[0].begin, interval_all[0].end))
75
edges = dict() # set of (edge.id, edge)
76
all_edges = list() # list of dicts, with one dict for each file
77
for interval in interval_all:
78
my_edges = dict([(e.id, e) for e in interval.edge])
79
edges.update(my_edges)
80
all_edges.append(my_edges)
81
# interval_new_edges = dict([(e.id, e) for e in interval_new.edge]) => "edges"
82
for id, edge in edges.items():
83
f.write(' <edge id="%s"' % id)
84
stats = defaultdict(Statistics) # separate stats for each edge
85
for attr in edge._fields:
86
if attr == 'id':
87
continue
88
if options.attributes_list and attr not in options.attributes_list:
89
continue
90
try:
91
for parsed in all_edges:
92
parsed_edge = parsed.get(id, None)
93
if parsed_edge is None:
94
continue
95
try:
96
val = float(getattr(parsed_edge, attr))
97
stats[attr].add(val, id)
98
except Exception:
99
pass
100
mean, std = stats[attr].meanAndStdDev()
101
median = stats[attr].median()
102
q1, median, q3 = stats[attr].quartiles()
103
# todo: add more statistic values here
104
f.write(' %s="%s"' % ("mean_" + attr, mean))
105
f.write(' %s="%s"' % ("std_" + attr, std))
106
f.write(' %s="%s"' % ("median_" + attr, median))
107
f.write(' %s="%s"' % ("q1_" + attr, q1))
108
f.write(' %s="%s"' % ("q3_" + attr, q3))
109
except Exception:
110
pass
111
f.write("/>\n")
112
f.write(" </interval>\n")
113
114
f.write("</meandata>\n")
115
116
117
if __name__ == "__main__":
118
write_stats(get_options())
119
120