diff options
| author | J08nY | 2020-03-05 14:40:05 +0100 |
|---|---|---|
| committer | J08nY | 2020-03-05 14:40:05 +0100 |
| commit | 79de2bbc6f099b0bd1d79427aabd6113e87c31d3 (patch) | |
| tree | 8d4cb9f762006eb59fb6e6ca1693f241683cc24f | |
| parent | 0c3c4a8d6725c01d8c4ba7b4a4e5f43922ec1e65 (diff) | |
| download | pyecsca-79de2bbc6f099b0bd1d79427aabd6113e87c31d3.tar.gz pyecsca-79de2bbc6f099b0bd1d79427aabd6113e87c31d3.tar.zst pyecsca-79de2bbc6f099b0bd1d79427aabd6113e87c31d3.zip | |
| -rw-r--r-- | pyecsca/sca/trace/combine.py | 19 | ||||
| -rw-r--r-- | pyecsca/sca/trace/plot.py | 49 | ||||
| -rw-r--r-- | setup.py | 7 | ||||
| -rw-r--r-- | test/sca/test_plot.py | 33 |
4 files changed, 71 insertions, 37 deletions
diff --git a/pyecsca/sca/trace/combine.py b/pyecsca/sca/trace/combine.py index 2ab552a..0e7f325 100644 --- a/pyecsca/sca/trace/combine.py +++ b/pyecsca/sca/trace/combine.py @@ -1,6 +1,7 @@ +from typing import Callable, Optional + import numpy as np from public import public -from typing import Callable, Optional from .trace import Trace, CombinedTrace @@ -23,7 +24,8 @@ def average(*traces: Trace) -> Optional[CombinedTrace]: @public -def conditional_average(*traces: Trace, condition: Callable[[Trace], bool]) -> Optional[CombinedTrace]: +def conditional_average(*traces: Trace, condition: Callable[[Trace], bool]) -> Optional[ + CombinedTrace]: """ Average `traces` for which the `condition` is True, sample-wise. @@ -47,3 +49,16 @@ def standard_deviation(*traces: Trace) -> Optional[CombinedTrace]: dtype = traces[0].samples.dtype result_samples = np.std(np.array([trace.samples for trace in traces]), axis=0).astype(dtype) return CombinedTrace(result_samples, None, None) + + +@public +def subtract(one: Trace, other: Trace) -> CombinedTrace: + """ + Subtract `other` from `one`, sample-wise. + + :param one: + :param other: + :return: + """ + result_samples = one.samples - other.samples + return CombinedTrace(result_samples, None, None) diff --git a/pyecsca/sca/trace/plot.py b/pyecsca/sca/trace/plot.py index 4d5c6db..e784e82 100644 --- a/pyecsca/sca/trace/plot.py +++ b/pyecsca/sca/trace/plot.py @@ -1,42 +1,49 @@ """ This module provides functions for plotting traces. """ -from bokeh.io import show, save, export_png, export_svgs -from bokeh.layouts import column -from bokeh.plotting import Figure -from bokeh.resources import CDN +from functools import reduce + +import holoviews as hv +from holoviews.operation.datashader import datashade from public import public from .trace import Trace @public -def new_figure(): - return Figure() - - -@public -def show_figure(figure: Figure): - show(figure) +def save_figure(figure, fname: str): + hv.save(figure, fname + ".html", fmt="html") @public -def save_figure(figure: Figure, fname: str, title: str): - lay = column(figure, sizing_mode='stretch_both') - save(lay, fname, resources=CDN, title=title) +def save_figure_png(figure, fname: str): + hv.save(figure, fname + ".png", fmt="png") @public -def save_figure_png(figure: Figure, fname: str, width: int, height: int): - export_png(figure, fname, height, width) +def save_figure_svg(figure, fname: str): + hv.save(figure, fname + ".svg", fmt="svg") @public -def save_figure_svg(figure: Figure, fname: str): - lay = column(figure, sizing_mode='stretch_both') - export_svgs(lay, fname) +def plot_trace(trace: Trace, **kwargs): + line = hv.Curve((range(len(trace)), trace.samples), kdims="x", vdims="y", **kwargs) + return datashade(line, normalization="log") @public -def plot_trace(figure: Figure, trace: Trace, **kwargs): - figure.line(range(len(trace)), trace.samples, **kwargs) +def plot_traces(*traces: Trace, **kwargs): + _cmaps = [ + ["lightblue", "darkblue"], + ["lightcoral", "red"], + ["lime", "green"], + ["orange", "darkorange"], + ["plum", "deeppink"], + ["peru", "chocolate"], + ["cyan", "darkcyan"] + ] + dss = [] + for i, trace in enumerate(traces): + line = hv.Curve((range(len(trace)), trace.samples), kdims="x", vdims="y", **kwargs) + dss.append(datashade(line, normalization="log", cmap=_cmaps[i % len(_cmaps)])) + return reduce(lambda x, y: x * y, dss) @@ -29,12 +29,15 @@ setup( "numpy", "scipy", "atpublic", - "matplotlib", "cython", "fastdtw", "asn1crypto", "h5py", - "bokeh" + "holoviews", + "bokeh", + "matplotlib", + "datashader", + "xarray" ], extras_require={ "picoscope_sdk": ["picosdk"], diff --git a/test/sca/test_plot.py b/test/sca/test_plot.py index d004cf5..9158e5c 100644 --- a/test/sca/test_plot.py +++ b/test/sca/test_plot.py @@ -1,29 +1,38 @@ from os import getenv import numpy as np - +import holoviews as hv from pyecsca.sca.trace import Trace -from pyecsca.sca.trace.plot import (new_figure, plot_trace, save_figure, save_figure_png, - save_figure_svg) -from .utils import Plottable, disabled +from pyecsca.sca.trace.plot import (plot_trace, save_figure, save_figure_png, save_figure_svg, + plot_traces) +from .utils import Plottable class PlotTests(Plottable): def setUp(self) -> None: - self.trace = Trace(np.array([6, 7, 3, -2, 5, 1], dtype=np.dtype("i1")), None, None) - self.fig = new_figure() - plot_trace(self.fig, self.trace) + self.trace1 = Trace(np.array([6, 7, 3, -2, 5, 1], dtype=np.dtype("i1")), None, None) + self.trace2 = Trace(np.array([2, 3, 7, 0, -1, 0], dtype=np.dtype("i1")), None, None) def test_html(self): if getenv("PYECSCA_TEST_PLOTS") is None: return - save_figure(self.fig, self.get_fname() + ".html", "Trace plot") + hv.extension("bokeh") + fig = plot_trace(self.trace1) + save_figure(fig, self.get_fname()) + other = plot_traces(self.trace1, self.trace2) + save_figure(other, self.get_fname()) - @disabled def test_png(self): - save_figure_png(self.fig, self.get_fname() + ".png", 1000, 400) + if getenv("PYECSCA_TEST_PLOTS") is None: + return + hv.extension("matplotlib") + fig = plot_trace(self.trace1) + save_figure_png(fig, self.get_fname()) - @disabled def test_svg(self): - save_figure_svg(self.fig, self.get_fname() + ".svg") + if getenv("PYECSCA_TEST_PLOTS") is None: + return + hv.extension("matplotlib") + fig = plot_trace(self.trace1) + save_figure_svg(fig, self.get_fname()) |
