ezmsg-sigproc 1.3.2__tar.gz → 1.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/PKG-INFO +1 -1
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/__version__.py +2 -2
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/affinetransform.py +3 -4
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/tests/test_affine_transform.py +33 -4
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/.github/workflows/python-publish-ezmsg-sigproc.yml +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/.github/workflows/python-tests.yml +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/.gitignore +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/.pre-commit-config.yaml +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/LICENSE.txt +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/README.md +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/pyproject.toml +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/__init__.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/activation.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/aggregate.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/bandpower.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/base.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/butterworthfilter.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/decimate.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/downsample.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/ewmfilter.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/filter.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/filterbank.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/math/__init__.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/math/abs.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/math/clip.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/math/difference.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/math/invert.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/math/log.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/math/scale.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/messages.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/sampler.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/scaler.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/signalinjector.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/slicer.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/spectral.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/spectrogram.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/spectrum.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/synth.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/wavelets.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/src/ezmsg/sigproc/window.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/tests/conftest.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/tests/helpers/__init__.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/tests/helpers/util.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/tests/resources/xform.csv +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/tests/test_activation.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/tests/test_aggregate.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/tests/test_bandpower.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/tests/test_butter.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/tests/test_butterworth.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/tests/test_downsample.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/tests/test_filterbank.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/tests/test_math.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/tests/test_sampler.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/tests/test_scaler.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/tests/test_slicer.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/tests/test_spectrogram.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/tests/test_spectrum.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/tests/test_synth.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/tests/test_wavelets.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/tests/test_window.py +0 -0
- {ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: ezmsg-sigproc
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.3
|
|
4
4
|
Summary: Timeseries signal processing implementations in ezmsg
|
|
5
5
|
Author-email: Griffin Milsap <griffin.milsap@gmail.com>, Preston Peranich <pperanich@gmail.com>, Chadwick Boulay <chadwick.boulay@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -76,16 +76,15 @@ def affine_transform(
|
|
|
76
76
|
):
|
|
77
77
|
in_labels = msg_in.axes[axis].labels
|
|
78
78
|
new_labels = []
|
|
79
|
-
n_in = weights.shape
|
|
80
|
-
n_out = weights.shape[0 if right_multiply else 1]
|
|
79
|
+
n_in, n_out = weights.shape
|
|
81
80
|
if len(in_labels) != n_in:
|
|
82
81
|
# Something upstream did something it wasn't supposed to. We will drop the labels.
|
|
83
82
|
ez.logger.warning(
|
|
84
83
|
f"Received {len(in_labels)} for {n_in} inputs. Check upstream labels."
|
|
85
84
|
)
|
|
86
85
|
else:
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
b_filled_outputs = np.any(weights, axis=0)
|
|
87
|
+
b_used_inputs = np.any(weights, axis=1)
|
|
89
88
|
if np.all(b_used_inputs) and np.all(b_filled_outputs):
|
|
90
89
|
# All inputs are used and all outputs are used, but n_in != n_out.
|
|
91
90
|
# Mapping cannot be determined.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import copy
|
|
2
|
+
from dataclasses import dataclass, field
|
|
2
3
|
from pathlib import Path
|
|
4
|
+
import typing
|
|
3
5
|
|
|
4
6
|
import numpy as np
|
|
5
7
|
from ezmsg.util.messages.axisarray import AxisArray
|
|
@@ -9,11 +11,33 @@ from ezmsg.sigproc.affinetransform import affine_transform, common_rereference
|
|
|
9
11
|
from util import assert_messages_equal
|
|
10
12
|
|
|
11
13
|
|
|
14
|
+
# Define a custom Axis class that has a `labels` attribute
|
|
15
|
+
@dataclass
|
|
16
|
+
class CustomAxis(AxisArray.Axis):
|
|
17
|
+
labels: typing.List[str] = field(default_factory=lambda: [])
|
|
18
|
+
|
|
19
|
+
@classmethod
|
|
20
|
+
def SpaceAxis(
|
|
21
|
+
cls, labels: typing.List[str]
|
|
22
|
+
): # , locs: typing.Optional[npt.NDArray] = None):
|
|
23
|
+
return cls(unit="mm", labels=labels)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# Monkey-patch AxisArray with our customized Axis
|
|
27
|
+
AxisArray.Axis = CustomAxis
|
|
28
|
+
|
|
29
|
+
|
|
12
30
|
def test_affine_generator():
|
|
13
31
|
n_times = 13
|
|
14
32
|
n_chans = 64
|
|
15
33
|
in_dat = np.arange(n_times * n_chans).reshape(n_times, n_chans)
|
|
16
|
-
msg_in = AxisArray(
|
|
34
|
+
msg_in = AxisArray(
|
|
35
|
+
data=in_dat,
|
|
36
|
+
dims=["time", "ch"],
|
|
37
|
+
axes={
|
|
38
|
+
"ch": AxisArray.Axis.SpaceAxis(labels=[f"ch_{i}" for i in range(n_chans)])
|
|
39
|
+
},
|
|
40
|
+
)
|
|
17
41
|
|
|
18
42
|
backup = [copy.deepcopy(msg_in)]
|
|
19
43
|
|
|
@@ -25,33 +49,38 @@ def test_affine_generator():
|
|
|
25
49
|
|
|
26
50
|
assert_messages_equal([msg_in], backup)
|
|
27
51
|
|
|
52
|
+
# Send again just to make sure the generator doesn't crash
|
|
53
|
+
_ = gen.send(msg_in)
|
|
54
|
+
|
|
28
55
|
# Test with weights from a CSV file.
|
|
29
56
|
csv_path = Path(__file__).parent / "resources" / "xform.csv"
|
|
30
57
|
weights = np.loadtxt(csv_path, delimiter=",")
|
|
31
58
|
expected_out = in_dat @ weights.T
|
|
32
59
|
# Same result: expected_out = np.vstack([(step[None, :] * weights).sum(axis=1) for step in in_dat])
|
|
33
60
|
|
|
34
|
-
# Send again just to make sure the generator doesn't crash
|
|
35
|
-
_ = gen.send(msg_in)
|
|
36
|
-
|
|
37
61
|
gen = affine_transform(weights=csv_path, axis="ch", right_multiply=False)
|
|
38
62
|
msg_out = gen.send(msg_in)
|
|
39
63
|
assert np.allclose(msg_out.data, expected_out)
|
|
64
|
+
assert len(msg_out.axes["ch"].labels) == weights.shape[0]
|
|
65
|
+
assert msg_out.axes["ch"].labels[:-1] == msg_in.axes["ch"].labels
|
|
40
66
|
|
|
41
67
|
# Try again as str, not Path
|
|
42
68
|
gen = affine_transform(weights=str(csv_path), axis="ch", right_multiply=False)
|
|
43
69
|
msg_out = gen.send(msg_in)
|
|
44
70
|
assert np.allclose(msg_out.data, expected_out)
|
|
71
|
+
assert len(msg_out.axes["ch"].labels) == weights.shape[0]
|
|
45
72
|
|
|
46
73
|
# Try again as direct ndarray
|
|
47
74
|
gen = affine_transform(weights=weights, axis="ch", right_multiply=False)
|
|
48
75
|
msg_out = gen.send(msg_in)
|
|
49
76
|
assert np.allclose(msg_out.data, expected_out)
|
|
77
|
+
assert len(msg_out.axes["ch"].labels) == weights.shape[0]
|
|
50
78
|
|
|
51
79
|
# One more time, but we pre-transpose the weights and do not override right_multiply
|
|
52
80
|
gen = affine_transform(weights=weights.T, axis="ch", right_multiply=True)
|
|
53
81
|
msg_out = gen.send(msg_in)
|
|
54
82
|
assert np.allclose(msg_out.data, expected_out)
|
|
83
|
+
assert len(msg_out.axes["ch"].labels) == weights.shape[0]
|
|
55
84
|
|
|
56
85
|
|
|
57
86
|
def test_affine_passthrough():
|
{ezmsg_sigproc-1.3.2 → ezmsg_sigproc-1.3.3}/.github/workflows/python-publish-ezmsg-sigproc.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|