aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ08nY2020-03-05 00:43:57 +0100
committerJ08nY2020-03-05 00:43:57 +0100
commit0c3c4a8d6725c01d8c4ba7b4a4e5f43922ec1e65 (patch)
treea5531714c910f0a7a42280eb244a21c7787bc4bc
parentf8345c356e37cb8e277d5bf5262c7cc2e57477bd (diff)
downloadpyecsca-0c3c4a8d6725c01d8c4ba7b4a4e5f43922ec1e65.tar.gz
pyecsca-0c3c4a8d6725c01d8c4ba7b4a4e5f43922ec1e65.tar.bz2
pyecsca-0c3c4a8d6725c01d8c4ba7b4a4e5f43922ec1e65.zip
Add plotting of traces.
-rw-r--r--.coveragerc1
-rw-r--r--Makefile6
-rw-r--r--pyecsca/sca/trace/plot.py42
-rw-r--r--test/plots/.gitignore4
-rw-r--r--test/sca/test_align.py8
-rw-r--r--test/sca/test_filter.py12
-rw-r--r--test/sca/test_match.py8
-rw-r--r--test/sca/test_plot.py29
-rw-r--r--test/sca/test_sampling.py6
-rw-r--r--test/sca/utils.py64
10 files changed, 136 insertions, 44 deletions
diff --git a/.coveragerc b/.coveragerc
index fedfb33..92627e6 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -3,6 +3,7 @@ branch = True
omit =
test/*
setup.py
+ fakesource
[report]
exclude_lines =
diff --git a/Makefile b/Makefile
index 0e43a25..cc7409c 100644
--- a/Makefile
+++ b/Makefile
@@ -3,15 +3,15 @@ ec.test_params ec.test_key_agreement ec.test_key_generation ec.test_mod ec.test_
ec.test_mult ec.test_naf ec.test_op ec.test_point ec.test_signature
SCA_TESTS = sca.test_align sca.test_combine sca.test_edit sca.test_filter sca.test_match sca.test_process \
-sca.test_sampling sca.test_target sca.test_test sca.test_trace sca.test_traceset
+sca.test_sampling sca.test_target sca.test_test sca.test_trace sca.test_traceset sca.test_plot
TESTS = ${EC_TESTS} ${SCA_TESTS}
test:
- nose2 -s test -A !slow -C -v ${TESTS}
+ nose2 -s test -E "not slow and not disabled" -C -v ${TESTS}
test-plots:
- env PYECSCA_TEST_PLOTS=1 nose2 -s test -A !slow -C -v ${TESTS}
+ env PYECSCA_TEST_PLOTS=1 nose2 -s test -E "not slow and not disabled" -C -v ${TESTS}
test-all:
nose2 -s test -C -v ${TESTS}
diff --git a/pyecsca/sca/trace/plot.py b/pyecsca/sca/trace/plot.py
index e69de29..4d5c6db 100644
--- a/pyecsca/sca/trace/plot.py
+++ b/pyecsca/sca/trace/plot.py
@@ -0,0 +1,42 @@
+"""
+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 public import public
+
+from .trace import Trace
+
+
+@public
+def new_figure():
+ return Figure()
+
+
+@public
+def show_figure(figure: Figure):
+ show(figure)
+
+
+@public
+def save_figure(figure: Figure, fname: str, title: str):
+ lay = column(figure, sizing_mode='stretch_both')
+ save(lay, fname, resources=CDN, title=title)
+
+
+@public
+def save_figure_png(figure: Figure, fname: str, width: int, height: int):
+ export_png(figure, fname, height, width)
+
+
+@public
+def save_figure_svg(figure: Figure, fname: str):
+ lay = column(figure, sizing_mode='stretch_both')
+ export_svgs(lay, fname)
+
+
+@public
+def plot_trace(figure: Figure, trace: Trace, **kwargs):
+ figure.line(range(len(trace)), trace.samples, **kwargs)
diff --git a/test/plots/.gitignore b/test/plots/.gitignore
index aab52d9..365fb3e 100644
--- a/test/plots/.gitignore
+++ b/test/plots/.gitignore
@@ -1 +1,3 @@
-*.png \ No newline at end of file
+*.png
+*.html
+*.svg \ No newline at end of file
diff --git a/test/sca/test_align.py b/test/sca/test_align.py
index b595058..f446f17 100644
--- a/test/sca/test_align.py
+++ b/test/sca/test_align.py
@@ -3,10 +3,10 @@ from unittest import TestCase
import numpy as np
from pyecsca.sca import align_correlation, align_peaks, align_sad, align_dtw_scale,\
align_dtw, Trace, InspectorTraceSet
-from .utils import plot, slow
+from .utils import Plottable, slow
-class AlignTests(TestCase):
+class AlignTests(Plottable):
def test_align(self):
first_arr = np.array([10, 64, 120, 64, 10, 10, 10, 10, 10], dtype=np.dtype("i1"))
@@ -60,7 +60,7 @@ class AlignTests(TestCase):
self.assertEqual(np.argmax(result[0].samples), np.argmax(result[1].samples))
self.assertEqual(np.argmax(result[1].samples), np.argmax(result[2].samples))
- plot(self, *result)
+ self.plot(*result)
def test_dtw_align(self):
first_arr = np.array([10, 64, 14, 120, 15, 30, 10, 15, 20, 15, 15, 10, 10, 8, 10, 12, 10, 13, 9], dtype=np.dtype("i1"))
@@ -73,4 +73,4 @@ class AlignTests(TestCase):
self.assertEqual(np.argmax(result[0].samples), np.argmax(result[1].samples))
self.assertEqual(np.argmax(result[1].samples), np.argmax(result[2].samples))
- plot(self, *result)
+ self.plot(*result)
diff --git a/test/sca/test_filter.py b/test/sca/test_filter.py
index 73516d8..fda5626 100644
--- a/test/sca/test_filter.py
+++ b/test/sca/test_filter.py
@@ -2,10 +2,10 @@ from unittest import TestCase
import numpy as np
from pyecsca.sca import Trace, filter_lowpass, filter_highpass, filter_bandpass, filter_bandstop
-from .utils import plot
+from .utils import Plottable
-class FilterTests(TestCase):
+class FilterTests(Plottable):
def setUp(self):
self._trace = Trace(
@@ -16,22 +16,22 @@ class FilterTests(TestCase):
result = filter_lowpass(self._trace, 100, 20)
self.assertIsNotNone(result)
self.assertEqual(len(self._trace.samples), len(result.samples))
- plot(self, self._trace, result)
+ self.plot(self._trace, result)
def test_highpass(self):
result = filter_highpass(self._trace, 128, 20)
self.assertIsNotNone(result)
self.assertEqual(len(self._trace.samples), len(result.samples))
- plot(self, self._trace, result)
+ self.plot(self._trace, result)
def test_bandpass(self):
result = filter_bandpass(self._trace, 128, 20, 60)
self.assertIsNotNone(result)
self.assertEqual(len(self._trace.samples), len(result.samples))
- plot(self, self._trace, result)
+ self.plot(self._trace, result)
def test_bandstop(self):
result = filter_bandstop(self._trace, 128, 20, 60)
self.assertIsNotNone(result)
self.assertEqual(len(self._trace.samples), len(result.samples))
- plot(self, self._trace, result)
+ self.plot(self._trace, result)
diff --git a/test/sca/test_match.py b/test/sca/test_match.py
index 549f143..1781d9d 100644
--- a/test/sca/test_match.py
+++ b/test/sca/test_match.py
@@ -3,10 +3,10 @@ from unittest import TestCase
import numpy as np
from pyecsca.sca import Trace, match_pattern, match_part, pad
-from .utils import plot
+from .utils import Plottable
-class MatchingTests(TestCase):
+class MatchingTests(Plottable):
def test_simple_match(self):
pattern = Trace(np.array([1, 15, 12, -10, 0, 13, 17, -1, 0], dtype=np.dtype("i1")), None,
@@ -16,7 +16,7 @@ class MatchingTests(TestCase):
dtype=np.dtype("i1")), None, None, None)
filtered = match_part(base, 7, 9)
self.assertListEqual(filtered, [7])
- plot(self, base=base, pattern=pad(pattern, (filtered[0], 0)))
+ self.plot(base=base, pattern=pad(pattern, (filtered[0], 0)))
def test_multiple_match(self):
pattern = Trace(np.array([1, 15, 12, -10, 0, 13, 17, -1, 0], dtype=np.dtype("i1")), None,
@@ -27,4 +27,4 @@ class MatchingTests(TestCase):
dtype=np.dtype("i1")), None, None, None)
filtered = match_pattern(base, pattern, 0.9)
self.assertListEqual(filtered, [7, 19])
- plot(self, base=base, pattern1=pad(pattern, (filtered[0], 0)), pattern2=pad(pattern, (filtered[1], 0)))
+ self.plot(base=base, pattern1=pad(pattern, (filtered[0], 0)), pattern2=pad(pattern, (filtered[1], 0)))
diff --git a/test/sca/test_plot.py b/test/sca/test_plot.py
new file mode 100644
index 0000000..d004cf5
--- /dev/null
+++ b/test/sca/test_plot.py
@@ -0,0 +1,29 @@
+from os import getenv
+
+import numpy as np
+
+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
+
+
+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)
+
+ def test_html(self):
+ if getenv("PYECSCA_TEST_PLOTS") is None:
+ return
+ save_figure(self.fig, self.get_fname() + ".html", "Trace plot")
+
+ @disabled
+ def test_png(self):
+ save_figure_png(self.fig, self.get_fname() + ".png", 1000, 400)
+
+ @disabled
+ def test_svg(self):
+ save_figure_svg(self.fig, self.get_fname() + ".svg")
diff --git a/test/sca/test_sampling.py b/test/sca/test_sampling.py
index c08128c..1af1579 100644
--- a/test/sca/test_sampling.py
+++ b/test/sca/test_sampling.py
@@ -2,10 +2,10 @@ from unittest import TestCase
import numpy as np
from pyecsca.sca import Trace, downsample_average, downsample_pick, downsample_decimate
-from .utils import plot
+from .utils import Plottable
-class SamplingTests(TestCase):
+class SamplingTests(Plottable):
def setUp(self):
self._trace = Trace(np.array([20, 40, 50, 50, 10], dtype=np.dtype("i1")), None, None)
@@ -34,4 +34,4 @@ class SamplingTests(TestCase):
self.assertIsNotNone(result)
self.assertIsInstance(result, Trace)
self.assertEqual(len(result.samples), 15)
- plot(self, trace, result)
+ self.plot(trace, result)
diff --git a/test/sca/utils.py b/test/sca/utils.py
index 643ab68..7b3ae97 100644
--- a/test/sca/utils.py
+++ b/test/sca/utils.py
@@ -1,34 +1,52 @@
-import matplotlib.pyplot as plt
-from unittest import TestCase
-from pyecsca.sca import Trace
-from os.path import join, exists, split
from os import mkdir, getenv, getcwd
+from os.path import join, exists, split
+from unittest import TestCase
+
+import matplotlib.pyplot as plt
+from pyecsca.sca import Trace
force_plot = True
+
def slow(func):
func.slow = 1
return func
+
+def disabled(func):
+ func.disabled = 1
+ return func
+
+
cases = {}
-def plot(case: TestCase, *traces: Trace, **kwtraces: Trace):
- if not force_plot and getenv("PYECSCA_TEST_PLOTS") is None:
- return
- fig = plt.figure()
- ax = fig.add_subplot(111)
- for i, trace in enumerate(traces):
- ax.plot(trace.samples, label=str(i))
- for name, trace in kwtraces.items():
- ax.plot(trace.samples, label=name)
- ax.legend(loc="best")
- if split(getcwd())[1] == "test":
- directory = "plots"
- else:
- directory = join("test", "plots")
- if not exists(directory):
- mkdir(directory)
- case_id = cases.setdefault(case.id(), 0) + 1
- cases[case.id()] = case_id
- plt.savefig(join(directory, case.id() + str(case_id) + ".png"))
+
+class Plottable(TestCase):
+
+ def get_dir(self):
+ if split(getcwd())[1] == "test":
+ directory = "plots"
+ else:
+ directory = join("test", "plots")
+ if not exists(directory):
+ mkdir(directory)
+ return directory
+
+ def get_fname(self):
+ directory = self.get_dir()
+ case_id = cases.setdefault(self.id(), 0) + 1
+ cases[self.id()] = case_id
+ return join(directory, self.id() + str(case_id))
+
+ def plot(self, *traces: Trace, **kwtraces: Trace):
+ if not force_plot and getenv("PYECSCA_TEST_PLOTS") is None:
+ return
+ fig = plt.figure()
+ ax = fig.add_subplot(111)
+ for i, trace in enumerate(traces):
+ ax.plot(trace.samples, label=str(i))
+ for name, trace in kwtraces.items():
+ ax.plot(trace.samples, label=name)
+ ax.legend(loc="best")
+ plt.savefig(self.get_fname() + ".png")