# Copyright 2018, National Technology & Engineering Solutions of Sandia, LLC
# (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S.
# Government retains certain rights in this software.
import hashlib
import flask
import scipy.signal
import toyplot.html
import xml.etree
from samlab.dashboard.server import application, require_auth, require_permissions
from samlab.dashboard.service import require_backend
[docs]@application.route("/timeseries-collection/<name>")
@require_auth
def get_timeseries(name):
require_permissions(["read"])
timeseries_collection = require_backend("timeseries-collection", name)
count = len(timeseries_collection)
keys = list(timeseries_collection.keys())
return flask.jsonify(count=count, keys=keys)
[docs]@application.route("/timeseries-collection/<name>/plot", methods=["POST"])
@require_auth
def post_timeseries_plot(name):
require_permissions(["read"])
timeseries_collection = require_backend("timeseries-collection", name)
height = int(float(flask.request.json.get("height", 500)))
keys = flask.request.json.get("keys", [])
legend_corner = flask.request.json.get("legend", "bottom-right")
max_samples = int(float(flask.request.json.get("max_samples", 1000)))
smoothing = float(flask.request.json.get("smoothing", "0"))
width = int(float(flask.request.json.get("width", 500)))
yscale = flask.request.json.get("yscale", "linear")
timeseries = [timeseries_collection.get(key) for key in keys]
canvas = toyplot.Canvas(width=width, height=height)
axes = canvas.cartesian(xlabel="Step", yscale=yscale)
palette = toyplot.color.brewer.palette("Set2")
legend = []
for key in keys:
color_index = int(hashlib.sha256(key.split("/")[0].encode("utf8")).hexdigest(), 16) % len(palette)
color = palette[color_index]
timeseries = timeseries_collection.get(key)
if timeseries is None:
continue
if "values" not in timeseries:
continue
y = timeseries["values"]
if "indices" in timeseries:
indices = timeseries["indices"]
else:
indices = numpy.arange(len(y))
x = indices
if "markers" in timeseries:
marker = timeseries["markers"]
else:
marker = [None] * len(y)
if smoothing:
alpha = 1 - smoothing
b = [alpha]
a = [1, alpha-1]
zi = scipy.signal.lfiltic(b, a, y[0:1], [0])
ys = scipy.signal.lfilter(b, a, y, zi=zi)[0]
axes.plot(x, y, color=color, opacity=0.1)
legend.append((key, axes.plot(x, ys, color=color, marker=marker)))
else:
legend.append((key, axes.plot(x, y, color=color, marker=marker)))
if legend and legend_corner != "none":
height = len(legend) * 16
inset = 50
canvas.legend(legend, corner=(legend_corner, inset, 100, height))
return flask.jsonify({"plot": toyplot.html.tostring(canvas)})