Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tools/output/edgeDataDiff.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 edgeDataDiff.py
16
# @author Jakob Erdmann
17
# @author Johannes Rummel
18
# @date 2015-08-14
19
20
from __future__ import absolute_import
21
from __future__ import print_function
22
import os
23
import sys
24
from collections import defaultdict
25
import math
26
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
27
from sumolib.xml import parse # noqa
28
from sumolib.miscutils import Statistics, geh, short_names, parseTime # noqa
29
from sumolib.options import ArgumentParser # noqa
30
from routeSampler import getHourFraction # noqa
31
32
33
def get_options(args=None):
34
optParser = ArgumentParser()
35
optParser.add_argument("orig", help="original data file")
36
optParser.add_argument("new", help="modified data file")
37
optParser.add_argument("out", help="diff output file")
38
optParser.add_option("--relative", action="store_true", default=False,
39
help="write relative instead of absolute differences")
40
optParser.add_option("--geh", action="store_true", default=False,
41
help="write geh value instead of absolute differences")
42
optParser.add_argument("--geh-scale", dest="gehScale", type=float, default=None,
43
help="Should be set to 0.1 when loading traffic for a full day "
44
"(estimating peak hour traffic as 1/10 of daily traffic)")
45
optParser.add_option("--undefined", type=float, default=-1001, help="value to use if the difference is undefined")
46
optParser.add_option("--attributes", help="compare list of custom attributes (A1,A2,B1,B2,C1,C2,...)")
47
optParser.add_option("--no-statistics", action="store_true", default=False,
48
help="otherwise: handle attributes starting with 'std_' as standard"
49
+ "deviation and calculate propagated error")
50
options = optParser.parse_args(args)
51
if options.attributes:
52
options.attributes = options.attributes.split(',')
53
if len(options.attributes) % 2 != 0:
54
print("Option --attributes requires an even-number list of attribute names")
55
sys.exit(1)
56
return options
57
58
59
def write_diff(options):
60
61
diffStats = defaultdict(Statistics)
62
attrList = None
63
if options.attributes:
64
tmp = [[], []]
65
for i, a in enumerate(options.attributes):
66
tmp[i % 2].append(a)
67
attrList = list(zip(*tmp))
68
69
with open(options.out, 'w') as f:
70
f.write("<meandata>\n")
71
for interval_old, interval_new in zip(
72
parse(options.orig, 'interval', heterogeneous=True),
73
parse(options.new, 'interval', heterogeneous=True)):
74
f.write(' <interval begin="%s" end="%s" id="%s@%s - %s@%s">\n' %
75
(interval_old.begin, interval_old.end,
76
interval_new.id, options.new,
77
interval_old.id, options.orig))
78
interval_new_edges = dict([(e.id, e) for e in interval_new.edge])
79
hourFraction = getHourFraction(options, parseTime(interval_old.begin), parseTime(interval_old.end))
80
for edge_old in interval_old.edge:
81
edge_new = interval_new_edges.get(edge_old.id, None)
82
if edge_new is None:
83
continue
84
assert edge_old.id == edge_new.id
85
f.write(' <edge id="%s"' % edge_old.id)
86
if not options.attributes:
87
attrList = zip(edge_old._fields, edge_old._fields)
88
for attr, attr2 in attrList:
89
if attr == 'id':
90
continue
91
try:
92
val_new = float(getattr(edge_new, attr2))
93
val_old = float(getattr(edge_old, attr))
94
delta = val_new - val_old
95
if not options.no_statistics and attr.startswith('std_'):
96
delta = math.sqrt(val_new**2 + val_old**2)
97
else:
98
fmt = ' %s="%s"'
99
if options.relative:
100
if val_old != 0:
101
delta /= abs(val_old)
102
else:
103
delta = options.undefined
104
elif options.geh:
105
delta = geh(val_new / hourFraction, val_old / hourFraction)
106
fmt = ' %s="%.2f"'
107
diffStats[attr].add(delta, edge_old.id)
108
f.write(fmt % (attr, delta))
109
except Exception:
110
pass
111
f.write("/>\n")
112
f.write(" </interval>\n")
113
114
f.write("</meandata>\n")
115
for attr, stats in diffStats.items():
116
stats.label = attr
117
print(stats)
118
119
120
if __name__ == "__main__":
121
write_diff(get_options())
122
123