Skip to content

Commit

Permalink
minimal working version refs #12233
Browse files Browse the repository at this point in the history
  • Loading branch information
namdre committed Dec 8, 2022
1 parent f80104b commit f8c3495
Showing 1 changed file with 135 additions and 0 deletions.
135 changes: 135 additions & 0 deletions tools/output/fcdDiff.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#!/usr/bin/env python
# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
# Copyright (C) 2012-2022 German Aerospace Center (DLR) and others.
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0/
# This Source Code may also be made available under the following Secondary
# Licenses when the conditions for such availability set forth in the Eclipse
# Public License 2.0 are satisfied: GNU General Public License, version 2
# or later which is available at
# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later

# @file scheduleStats.py
# @author Jakob Erdmann
# @date 2022-12-06

"""
Compare two fcd output files with regard to spatial difference
"""

from __future__ import absolute_import
from __future__ import print_function

import os
import sys
from math import sqrt

import pandas as pd

if 'SUMO_HOME' in os.environ:
sys.path.append(os.path.join(os.environ['SUMO_HOME'], 'tools'))
import sumolib # noqa
from sumolib.miscutils import parseTime, humanReadableTime # noqa
from sumolib.statistics import Statistics # noqa
from sumolib.xml import parse_fast_nested # noqa

pd.options.display.width = 0 # auto-detect terminal width

GROUPSTATS = {
'mean': lambda s: s.avg(),
'median': lambda s: s.median(),
'min': lambda s: s.min,
'max': lambda s: s.max,
}


def get_options(args=None):
parser = sumolib.options.ArgumentParser(description="Compare route-file stop timing with stop-output")
parser.add_argument("old", help="the first fcd file")
parser.add_argument("new", help="the second fcd file")
parser.add_argument("-o", "--xml-output", dest="output",
help="xml output file")
parser.add_option("--csv-output", dest="csv_output", help="write plot as csv", metavar="FILE")
parser.add_option("--filter-ids", dest="filterIDs", help="only plot data points from the given list of ids")
parser.add_argument("-H", "--human-readable-time", dest="hrTime", action="store_true", default=False,
help="Write time values as hour:minute:second or day:hour:minute:second rathern than seconds")
parser.add_argument("-t", "--tripid", dest="tripId", action="store_true", default=False,
help="use attr tripId for matching instead of vehicle id")
parser.add_argument("-i", "--histogram", dest="histogram", type=float,
help="histogram bin size")
parser.add_argument("-v", "--verbose", action="store_true",
default=False, help="tell me what you are doing")

options = parser.parse_args(args=args)
if options.old is None or options.new is None:
parser.print_help()
sys.exit()

return options


ATTR_CONVERSIONS = {
'time': parseTime,
}


def key(row):
return "%s_%s" % (row[0], humanReadableTime(row['t']))


def getDataFrame(fname, attrs, columns, tripId):
data = []
if tripId:
orderedAttrs = attrs[2:] + [attrs[0]]
else:
orderedAttrs = [attrs[0]] + attrs[2:]

for ts, v in parse_fast_nested(fname, 'timestep', ['time'], 'vehicle', orderedAttrs):
data.append([getattr(v, attrs[0]), parseTime(ts.time)] + [float(getattr(v, a)) for a in attrs[2:]])
return pd.DataFrame.from_records(data, columns=columns)


def main(options):
nan = float("nan")
idAttr = 'tripId' if options.tripId else 'id'
attrs = [
idAttr,
't', # time
'x',
'y',
]
cols2 = [
idAttr,
't', # time
'x2',
'y2',
]

df1 = getDataFrame(options.old, attrs, attrs, options.tripId)
print("read", options.old)
df2 = getDataFrame(options.new, attrs, cols2, options.tripId)
print("new", options.old)

# merge on common columns id, time
df = pd.merge(df1, df2, on=attrs[:2], how="inner")
# outer merge to count missing entries
dfOuter = pd.merge(df1, df2, on=attrs[:2], how="outer")

if options.verbose:
print("Found %s matches" % len(df))
print("Found %s records" % len(dfOuter))
print("missing in old: %s" % dfOuter['x'].isna().sum())
print("missing in new: %s" % dfOuter['x2'].isna().sum())

useHist = options.histogram is not None
fun = (lambda r, s: s.add(sqrt((r['x'] - r['x2']) ** 2 + (r['y'] - r['y2']) ** 2) , key(r)))
s = Statistics("euclidian_error", histogram=useHist, scale=options.histogram)
df.apply(fun, axis=1, args=(s,))

print(s)
#print(dfOuter)

if __name__ == "__main__":
main(get_options())

0 comments on commit f8c3495

Please sign in to comment.