Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tools/output/tripinfoDiff.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 tripinfoDiff.py
16
# @author Jakob Erdmann
17
# @date 2016-15-04
18
19
"""
20
Compare differences between tripinfo files that contain the same vehicles
21
"""
22
23
from __future__ import absolute_import
24
from __future__ import print_function
25
import os
26
import sys
27
from collections import OrderedDict
28
sys.path.append(os.path.join(os.environ["SUMO_HOME"], 'tools'))
29
from sumolib.output import parse # noqa
30
from sumolib.miscutils import Statistics, parseTime # noqa
31
from sumolib.options import ArgumentParser # noqa
32
33
34
def get_options(args=None):
35
argParser = ArgumentParser()
36
argParser.add_argument("orig", help="the first tripinfo file")
37
argParser.add_argument("new", help="the second tripinfo file")
38
argParser.add_argument("output", help="the output file")
39
argParser.add_argument("--filter-ids", dest="filterIDs",
40
help="only use trip ids with the given substring")
41
argParser.add_argument("--persons", action="store_true",
42
default=False, help="compute personinfo differences")
43
argParser.add_argument("--histogram-scale", type=float, dest="histScale",
44
help="compute data histogram with the FLOAT granularity")
45
options = argParser.parse_args(args=args)
46
options.useHist = options.histScale is not None
47
return options
48
49
50
def write_diff(options):
51
attrs = ["depart", "arrival", "timeLoss", "duration", "routeLength"]
52
# parseTime works just fine for floats
53
attr_conversions = dict([(a, parseTime) for a in attrs])
54
vehicles_orig = OrderedDict([(v.id, v) for v in parse(options.orig, 'tripinfo',
55
attr_conversions=attr_conversions)])
56
descr = ""
57
if options.filterIDs:
58
descr = " (%s)" % options.filterIDs
59
origDurations = Statistics('original durations%s' % descr,
60
histogram=options.useHist, scale=options.histScale)
61
durations = Statistics('new durations%s' % descr,
62
histogram=options.useHist, scale=options.histScale)
63
durationDiffs = Statistics('duration differences%s new-old' % descr,
64
histogram=options.useHist, scale=options.histScale)
65
numNew = 0
66
numMissing = 0
67
with open(options.output, 'w') as f:
68
f.write("<tripDiffs>\n")
69
for v in parse(options.new, 'tripinfo', attr_conversions=attr_conversions):
70
if options.filterIDs and options.filterIDs not in v.id:
71
del vehicles_orig[v.id]
72
continue
73
if v.id in vehicles_orig:
74
vOrig = vehicles_orig[v.id]
75
diffs = [v.getAttribute(a) - vOrig.getAttribute(a) for a in attrs]
76
durations.add(v.duration, v.id)
77
origDurations.add(vOrig.duration, v.id)
78
durationDiffs.add(v.duration - vOrig.duration, v.id)
79
diffAttrs = ''.join([' %sDiff="%s"' % (a, x) for a, x in zip(attrs, diffs)])
80
f.write(' <vehicle id="%s"%s/>\n' % (v.id, diffAttrs))
81
del vehicles_orig[v.id]
82
else:
83
f.write(' <vehicle id="%s" comment="new"/>\n' % v.id)
84
numNew += 1
85
for id in vehicles_orig.keys():
86
f.write(' <vehicle id="%s" comment="missing"/>\n' % id)
87
numMissing += 1
88
f.write("</tripDiffs>\n")
89
90
if numMissing > 0:
91
print("missing: %s" % numMissing)
92
if numNew > 0:
93
print("new: %s" % numNew)
94
print(origDurations)
95
print(durations)
96
print(durationDiffs)
97
98
99
def write_persondiff(options):
100
attrs = ["depart", "arrival", "timeLoss", "duration", "routeLength", "waitingTime"]
101
attr_conversions = dict([(a, parseTime) for a in attrs])
102
persons_orig = OrderedDict([(p.id, p) for p in parse(options.orig, 'personinfo',
103
attr_conversions=attr_conversions)])
104
origDurations = Statistics('original durations')
105
durations = Statistics('new durations')
106
durationDiffs = Statistics('duration differences')
107
statAttrs = ["duration", "walkTimeLoss", "rideWait", "walks", "accesses", "rides", "stops"]
108
with open(options.output, 'w') as f:
109
f.write("<tripDiffs>\n")
110
for p in parse(options.new, 'personinfo', attr_conversions=attr_conversions):
111
if p.id in persons_orig:
112
pOrig = persons_orig[p.id]
113
stats = plan_stats(p)
114
statsOrig = plan_stats(pOrig)
115
diffs = [a - b for a, b in zip(stats, statsOrig)]
116
durations.add(stats[0], p.id)
117
origDurations.add(statsOrig[0], p.id)
118
durationDiffs.add(stats[0] - statsOrig[0], p.id)
119
diffAttrs = ''.join([' %sDiff="%s"' % (a, x) for a, x in zip(statAttrs, diffs)])
120
f.write(' <personinfo id="%s"%s/>\n' % (p.id, diffAttrs))
121
del persons_orig[p.id]
122
else:
123
f.write(' <personinfo id="%s" comment="new"/>\n' % p.id)
124
for id in persons_orig.keys():
125
f.write(' <personinfo id="%s" comment="missing"/>\n' % id)
126
f.write("</tripDiffs>\n")
127
128
print(origDurations)
129
print(durations)
130
print(durationDiffs)
131
132
133
def plan_stats(pInfo):
134
duration = 0
135
timeLoss = 0
136
rideWait = 0
137
walks = 0
138
accesses = 0
139
rides = 0
140
stops = 0
141
if pInfo.walk:
142
walks = len(pInfo.walk)
143
for walk in pInfo.walk:
144
timeLoss += walk.timeLoss
145
duration += walk.duration
146
if pInfo.access:
147
accesses = len(pInfo.access)
148
for access in pInfo.access:
149
duration += access.duration
150
if pInfo.ride:
151
rides = len(pInfo.ride)
152
for ride in pInfo.ride:
153
duration += ride.duration
154
rideWait += ride.waitingTime
155
if pInfo.stop:
156
stops = len(pInfo.stop)
157
for stop in pInfo.stop:
158
duration += stop.duration
159
return (duration, timeLoss, rideWait, walks, accesses, rides, stops)
160
161
162
if __name__ == "__main__":
163
options = get_options()
164
if options.persons:
165
write_persondiff(options)
166
else:
167
write_diff(options)
168
169