orchestration.coe.1.0.0.source-code.crosscheck-plot.py Maven / Gradle / Ivy
#!/usr/bin/env python
# packages to install on windows
# http://www.lfd.uci.edu/~gohlke/pythonlibs/#scipy
# http://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy
#
import matplotlib.pyplot as plt
import csv
import argparse
import numpy as np
import scipy.interpolate as sciint
import os
import pandas as pd
rtol = 0.1
parser = argparse.ArgumentParser(description='Result plotter')
parser.add_argument('--name', metavar='NAME',
help='The name to be displayed in the report')
parser.add_argument('--result', metavar='RESULT_PATH', required=True,
help='The path of the COE generated result file (CSV)')
parser.add_argument('--ref', metavar='REF_PATH', required=False,
help='The path of the export tool generated result file (CSV)')
parser.add_argument('--config', metavar='CONFIG_PATH',
help='The path of the COE config file (JSON)')
args = parser.parse_args()
def createWebHeader(title, config):
return """
""" + title + """
""";
def webConfigDiv(title, html):
return '' + title + '
' + """
Configuration
""" + html + """
""";
def webOutputDiv(name):
return """
""" + name + """
""";
PASSED = 1
REJECTED = -1
FAILED = -2
NOT_SET = 0
def webOutputDivHtml(html, status):
statusType = "info"
statusText = "unknown"
if status == PASSED:
statusType = "success"
statusText = "passed"
if status == REJECTED:
statusType = "warning"
statusText = "rejected"
if status == FAILED:
statusType = "danger"
statusText = "failed"
return "" + name + "
" + html + "" + statusText + "";
def readSvgHtml(fname):
html = ""
with open(fname) as f:
next(f)
for line in f:
html += line + "\n"
return html
def csvRead(path, stripInstances=0):
df = pd.read_csv(path, encoding='utf8', engine='python')
column = {}
headers= list()
for h in df:
hstr = str(h)
if stripInstances:
if "." in hstr:
hstr = hstr[hstr.rfind(".") + 1:]
column[hstr] = df[h].values
headers.append(hstr)
return {'headers': headers, 'columns': column}
def createHtml(name, config, body, status):
web = createWebHeader(name, config)
html = "Tolerance: " + str(rtol) + "
"
statusType = "info"
statusText = "unknown"
if status == PASSED:
statusType = "success"
statusText = "passed"
if status == REJECTED:
statusType = "warning"
statusText = "rejected"
if status == FAILED:
statusType = "danger"
statusText = "failed"
html += "" + statusText + ""
web += '' + webConfigDiv(name, html) + body
web += ''
return web
# print column
config = "{}"
name = "unknown"
if args.name:
name = args.name;
if args.config:
with open(args.config, 'r') as myfile:
config = myfile.read().replace('\n', '')
config = "\"" + config.replace('"', '\\"') + "\""
data = csvRead(args.result, 1)
if args.ref:
dataRef = csvRead(args.ref)
else:
dataRef = {'headers': [], 'columns': []}
headers = data['headers']
column = data['columns']
passed = True
passedCurrent = True
htmlBody = ""
for h in headers:
if h == 'time' or h == 'step-size':
continue
fig = plt.figure(h)
fsimTime = np.array(column["time"], dtype=float)
xlim = fsimTime[-1]
ax = fig.add_subplot(2, 1, 1)
ax.set_ylabel(h)
# lgd2 = lgd
if h in dataRef['headers']:
cols = dataRef['columns']
# time column
frefTime = np.array(cols["time"], dtype=float)
# adjust xlim
xlim = min(frefTime[-1], xlim)
# add reference signal to plot
ax.plot(cols['time'], cols[h], 'r-', label=h + '_Ref')
isBoolean = all(x == '0' or x == '1' for x in column[h]) and all(
x == '0' or x == '1' for x in cols[h])
print "Is Boolean: " + str(isBoolean)
if isBoolean:
type = bool
else:
type = float
# generate diff sub plot
# generate diff
a = np.array(cols[h], dtype=type)
v = np.array(column[h], dtype=type)
if not isBoolean:
ax.plot(cols["time"], [x + rtol for x in a], 'y-',
label=h + '_upper', color='#d3f7cd')
ax.plot(cols["time"], [x - rtol for x in a], 'b-',
label=h + '_lower', color='#d3f7cd')
ax.fill_between(frefTime, [x + rtol for x in a],
[x - rtol for x in a], color='#d3f7cd')
# interpolate signals
fref = sciint.interp1d(np.array(cols["time"], dtype=float), a)
fsig = sciint.interp1d(np.array(column["time"], dtype=float), v)
# find last commen index in result which has a time not exceding the _ref signal
compIndexEnd = len(column["time"]) - 1
for x in range(0, compIndexEnd):
for j in range(len(cols["time"]), 0):
if column["time"][x] <= cols["time"][j]:
compIndexEnd = x;
break;
# check result against reference with relative tolorance
if not isBoolean:
g = [
fref(fsimTime[x]) + rtol >= v[x] and fref(fsimTime[x]) - rtol <=
v[x] for x in range(0, len(fsimTime[:compIndexEnd]))]
else:
g = [fref(column["time"][x]) == v[x] for x in
range(0, len(fsimTime[:compIndexEnd]))]
print "End time: " + str(fsimTime[compIndexEnd])
# the overall status for the result signal within the tolorance
passedCurrent = all(x for x in g)
print "Is " + h + " passed: " + str(passedCurrent)
passed = passed and passedCurrent
stepSize = xlim / min(len(frefTime), len(fsimTime))
xnew = np.linspace(0, xlim, num=xlim / stepSize, endpoint=True)
ax2 = fig.add_subplot(2, 1, 2)
ax2.plot(xnew, fref(xnew) - fsig(xnew), 'g-', label=h + '_ref - ' + h)
ax2.set_xlim([0, xlim])
ax2.set_ylabel("interpolated (linear) signal difference")
lgd2 = ax2.legend(loc='center left', bbox_to_anchor=(1, 0.5))
# add simulated signal to plot
ax.plot(column['time'], column[h], 'b-', label=h, color='0.75')
# configure plot
ax.set_xlim([0, xlim])
lgd = ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))
if 'lgd2' not in locals():
lgd2 = lgd
plt.xlabel('time [s]')
DefaultSize = fig.get_size_inches()
fig.set_size_inches((DefaultSize[0] * 1.8, DefaultSize[1] * 2.5))
imgfname = h + ".svg"
fig.savefig(imgfname, bbox_extra_artists=(lgd, lgd2), bbox_inches='tight')
status = FAILED
if passedCurrent:
status = PASSED
htmlBody += webOutputDivHtml(readSvgHtml(imgfname), status)
try:
os.remove(imgfname)
except Exception:
pass
# plt.show()
status = PASSED
if os.path.exists("rejected"):
status = REJECTED
else:
if passed:
status = PASSED
else:
status = FAILED
with open("index.html", "w") as text_file:
text_file.write(createHtml(name, config, htmlBody, status))
print "Is passed: " + str(passed)
if status == PASSED:
if not os.path.exists("passed"):
with open("passed", "w") as text_file:
text_file.write("")
else:
if status == FAILED:
if not os.path.exists("failed"):
with open("failed", "w") as text_file:
text_file.write("result did not match reference signal")
© 2015 - 2024 Weber Informatics LLC | Privacy Policy