ezmsg-sigproc 2.8.0__py3-none-any.whl → 2.9.0__py3-none-any.whl
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/__version__.py +2 -2
- ezmsg/sigproc/aggregate.py +9 -0
- ezmsg/sigproc/coordinatespaces.py +22 -5
- ezmsg/sigproc/diff.py +15 -4
- ezmsg/sigproc/linear.py +7 -5
- ezmsg/sigproc/math/abs.py +11 -6
- ezmsg/sigproc/math/add.py +1 -2
- ezmsg/sigproc/math/clip.py +22 -17
- ezmsg/sigproc/math/difference.py +9 -3
- ezmsg/sigproc/math/invert.py +8 -3
- ezmsg/sigproc/math/log.py +19 -8
- ezmsg/sigproc/math/scale.py +8 -3
- ezmsg/sigproc/transpose.py +22 -7
- {ezmsg_sigproc-2.8.0.dist-info → ezmsg_sigproc-2.9.0.dist-info}/METADATA +1 -1
- {ezmsg_sigproc-2.8.0.dist-info → ezmsg_sigproc-2.9.0.dist-info}/RECORD +17 -17
- {ezmsg_sigproc-2.8.0.dist-info → ezmsg_sigproc-2.9.0.dist-info}/WHEEL +0 -0
- {ezmsg_sigproc-2.8.0.dist-info → ezmsg_sigproc-2.9.0.dist-info}/licenses/LICENSE +0 -0
ezmsg/sigproc/__version__.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '2.
|
|
32
|
-
__version_tuple__ = version_tuple = (2,
|
|
31
|
+
__version__ = version = '2.9.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (2, 9, 0)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
ezmsg/sigproc/aggregate.py
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Aggregation operations over arrays.
|
|
3
|
+
|
|
4
|
+
.. note::
|
|
5
|
+
:obj:`AggregateTransformer` supports the :doc:`Array API standard </guides/explanations/array_api>`,
|
|
6
|
+
enabling use with NumPy, CuPy, PyTorch, and other compatible array libraries.
|
|
7
|
+
:obj:`RangedAggregateTransformer` currently requires NumPy arrays.
|
|
8
|
+
"""
|
|
9
|
+
|
|
1
10
|
import typing
|
|
2
11
|
|
|
3
12
|
import ezmsg.core as ez
|
|
@@ -3,6 +3,10 @@ Coordinate space transformations for streaming data.
|
|
|
3
3
|
|
|
4
4
|
This module provides utilities and ezmsg nodes for transforming between
|
|
5
5
|
Cartesian (x, y) and polar (r, theta) coordinate systems.
|
|
6
|
+
|
|
7
|
+
.. note::
|
|
8
|
+
This module supports the :doc:`Array API standard </guides/explanations/array_api>`,
|
|
9
|
+
enabling use with NumPy, CuPy, PyTorch, and other compatible array libraries.
|
|
6
10
|
"""
|
|
7
11
|
|
|
8
12
|
from enum import Enum
|
|
@@ -11,6 +15,7 @@ from typing import Tuple
|
|
|
11
15
|
import ezmsg.core as ez
|
|
12
16
|
import numpy as np
|
|
13
17
|
import numpy.typing as npt
|
|
18
|
+
from array_api_compat import get_namespace, is_array_api_obj
|
|
14
19
|
from ezmsg.baseproc import (
|
|
15
20
|
BaseTransformer,
|
|
16
21
|
BaseTransformerUnit,
|
|
@@ -20,14 +25,24 @@ from ezmsg.util.messages.axisarray import AxisArray, replace
|
|
|
20
25
|
# -- Utility functions for coordinate transformations --
|
|
21
26
|
|
|
22
27
|
|
|
28
|
+
def _get_namespace_or_numpy(*args: npt.ArrayLike):
|
|
29
|
+
"""Get array namespace if any arg is an array, otherwise return numpy."""
|
|
30
|
+
for arg in args:
|
|
31
|
+
if is_array_api_obj(arg):
|
|
32
|
+
return get_namespace(arg)
|
|
33
|
+
return np
|
|
34
|
+
|
|
35
|
+
|
|
23
36
|
def polar2z(r: npt.ArrayLike, theta: npt.ArrayLike) -> npt.ArrayLike:
|
|
24
37
|
"""Convert polar coordinates to complex number representation."""
|
|
25
|
-
|
|
38
|
+
xp = _get_namespace_or_numpy(r, theta)
|
|
39
|
+
return r * xp.exp(1j * theta)
|
|
26
40
|
|
|
27
41
|
|
|
28
42
|
def z2polar(z: npt.ArrayLike) -> Tuple[npt.ArrayLike, npt.ArrayLike]:
|
|
29
43
|
"""Convert complex number to polar coordinates (r, theta)."""
|
|
30
|
-
|
|
44
|
+
xp = _get_namespace_or_numpy(z)
|
|
45
|
+
return xp.abs(z), xp.atan2(xp.imag(z), xp.real(z))
|
|
31
46
|
|
|
32
47
|
|
|
33
48
|
def cart2z(x: npt.ArrayLike, y: npt.ArrayLike) -> npt.ArrayLike:
|
|
@@ -37,7 +52,8 @@ def cart2z(x: npt.ArrayLike, y: npt.ArrayLike) -> npt.ArrayLike:
|
|
|
37
52
|
|
|
38
53
|
def z2cart(z: npt.ArrayLike) -> Tuple[npt.ArrayLike, npt.ArrayLike]:
|
|
39
54
|
"""Convert complex number to Cartesian coordinates (x, y)."""
|
|
40
|
-
|
|
55
|
+
xp = _get_namespace_or_numpy(z)
|
|
56
|
+
return xp.real(z), xp.imag(z)
|
|
41
57
|
|
|
42
58
|
|
|
43
59
|
def cart2pol(x: npt.ArrayLike, y: npt.ArrayLike) -> Tuple[npt.ArrayLike, npt.ArrayLike]:
|
|
@@ -90,6 +106,7 @@ class CoordinateSpacesTransformer(BaseTransformer[CoordinateSpacesSettings, Axis
|
|
|
90
106
|
"""
|
|
91
107
|
|
|
92
108
|
def _process(self, message: AxisArray) -> AxisArray:
|
|
109
|
+
xp = get_namespace(message.data)
|
|
93
110
|
axis = self.settings.axis or message.dims[-1]
|
|
94
111
|
axis_idx = message.get_axis_idx(axis)
|
|
95
112
|
|
|
@@ -116,9 +133,9 @@ class CoordinateSpacesTransformer(BaseTransformer[CoordinateSpacesSettings, Axis
|
|
|
116
133
|
out_a, out_b = pol2cart(component_a, component_b)
|
|
117
134
|
|
|
118
135
|
# Stack results back along the same axis
|
|
119
|
-
result =
|
|
136
|
+
result = xp.stack([out_a, out_b], axis=axis_idx)
|
|
120
137
|
|
|
121
|
-
# Update axis labels if present
|
|
138
|
+
# Update axis labels if present (use numpy for string labels)
|
|
122
139
|
axes = message.axes
|
|
123
140
|
if axis in axes and hasattr(axes[axis], "data"):
|
|
124
141
|
if self.settings.mode == CoordinateMode.CART2POL:
|
ezmsg/sigproc/diff.py
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Compute differences along an axis.
|
|
3
|
+
|
|
4
|
+
.. note::
|
|
5
|
+
This module supports the :doc:`Array API standard </guides/explanations/array_api>`,
|
|
6
|
+
enabling use with NumPy, CuPy, PyTorch, and other compatible array libraries.
|
|
7
|
+
"""
|
|
8
|
+
|
|
1
9
|
import ezmsg.core as ez
|
|
2
10
|
import numpy as np
|
|
3
11
|
import numpy.typing as npt
|
|
12
|
+
from array_api_compat import get_namespace
|
|
4
13
|
from ezmsg.baseproc import (
|
|
5
14
|
BaseStatefulTransformer,
|
|
6
15
|
BaseTransformerUnit,
|
|
@@ -39,23 +48,25 @@ class DiffTransformer(BaseStatefulTransformer[DiffSettings, AxisArray, AxisArray
|
|
|
39
48
|
self.state.last_time = ax_info.data[0] - 0.001
|
|
40
49
|
|
|
41
50
|
def _process(self, message: AxisArray) -> AxisArray:
|
|
51
|
+
xp = get_namespace(message.data)
|
|
42
52
|
axis = self.settings.axis or message.dims[0]
|
|
43
53
|
ax_idx = message.get_axis_idx(axis)
|
|
44
54
|
|
|
45
|
-
diffs =
|
|
46
|
-
|
|
55
|
+
diffs = xp.diff(
|
|
56
|
+
xp.concat((self.state.last_dat, message.data), axis=ax_idx),
|
|
47
57
|
axis=ax_idx,
|
|
48
58
|
)
|
|
49
59
|
# Prepare last_dat for next iteration
|
|
50
60
|
self.state.last_dat = slice_along_axis(message.data, slice(-1, None), axis=ax_idx)
|
|
51
|
-
# Scale by fs if requested. This
|
|
61
|
+
# Scale by fs if requested. This converts the diff to a derivative. e.g., diff of position becomes velocity.
|
|
52
62
|
if self.settings.scale_by_fs:
|
|
53
63
|
ax_info = message.get_axis(axis)
|
|
54
64
|
if hasattr(ax_info, "data"):
|
|
65
|
+
# ax_info.data is typically numpy for metadata, so use np.diff here
|
|
55
66
|
dt = np.diff(np.concatenate(([self.state.last_time], ax_info.data)))
|
|
56
67
|
# Expand dt dims to match diffs
|
|
57
68
|
exp_sl = (None,) * ax_idx + (Ellipsis,) + (None,) * (message.data.ndim - ax_idx - 1)
|
|
58
|
-
diffs /= dt[exp_sl]
|
|
69
|
+
diffs /= xp.asarray(dt[exp_sl])
|
|
59
70
|
self.state.last_time = ax_info.data[-1] # For next iteration
|
|
60
71
|
else:
|
|
61
72
|
diffs /= ax_info.gain
|
ezmsg/sigproc/linear.py
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""
|
|
2
|
+
Apply a linear transformation: output = scale * input + offset.
|
|
2
3
|
|
|
3
4
|
Supports per-element scale and offset along a specified axis.
|
|
4
|
-
Uses Array API for compatibility with numpy, cupy, torch, etc.
|
|
5
|
-
|
|
6
5
|
For full matrix transformations, use :obj:`AffineTransformTransformer` instead.
|
|
6
|
+
|
|
7
|
+
.. note::
|
|
8
|
+
This module supports the :doc:`Array API standard </guides/explanations/array_api>`,
|
|
9
|
+
enabling use with NumPy, CuPy, PyTorch, and other compatible array libraries.
|
|
7
10
|
"""
|
|
8
11
|
|
|
9
12
|
import ezmsg.core as ez
|
|
10
13
|
import numpy as np
|
|
11
14
|
import numpy.typing as npt
|
|
12
15
|
from array_api_compat import get_namespace
|
|
16
|
+
from ezmsg.baseproc import BaseStatefulTransformer, BaseTransformerUnit, processor_state
|
|
13
17
|
from ezmsg.util.messages.axisarray import AxisArray
|
|
14
18
|
from ezmsg.util.messages.util import replace
|
|
15
19
|
|
|
16
|
-
from .base import BaseStatefulTransformer, BaseTransformerUnit, processor_state
|
|
17
|
-
|
|
18
20
|
|
|
19
21
|
class LinearTransformSettings(ez.Settings):
|
|
20
22
|
scale: float | list[float] | npt.ArrayLike = 1.0
|
ezmsg/sigproc/math/abs.py
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
"""
|
|
2
|
-
|
|
1
|
+
"""
|
|
2
|
+
Take the absolute value of the data.
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
.. note::
|
|
5
|
+
This module supports the :doc:`Array API standard </guides/explanations/array_api>`,
|
|
6
|
+
enabling use with NumPy, CuPy, PyTorch, and other compatible array libraries.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from array_api_compat import get_namespace
|
|
10
|
+
from ezmsg.baseproc import BaseTransformer, BaseTransformerUnit
|
|
5
11
|
from ezmsg.util.messages.axisarray import AxisArray
|
|
6
12
|
from ezmsg.util.messages.util import replace
|
|
7
13
|
|
|
8
|
-
from ..base import BaseTransformer, BaseTransformerUnit
|
|
9
|
-
|
|
10
14
|
|
|
11
15
|
class AbsSettings:
|
|
12
16
|
pass
|
|
@@ -14,7 +18,8 @@ class AbsSettings:
|
|
|
14
18
|
|
|
15
19
|
class AbsTransformer(BaseTransformer[None, AxisArray, AxisArray]):
|
|
16
20
|
def _process(self, message: AxisArray) -> AxisArray:
|
|
17
|
-
|
|
21
|
+
xp = get_namespace(message.data)
|
|
22
|
+
return replace(message, data=xp.abs(message.data))
|
|
18
23
|
|
|
19
24
|
|
|
20
25
|
class Abs(BaseTransformerUnit[None, AxisArray, AxisArray, AbsTransformer]): ... # SETTINGS = None
|
ezmsg/sigproc/math/add.py
CHANGED
|
@@ -5,12 +5,11 @@ import typing
|
|
|
5
5
|
from dataclasses import dataclass, field
|
|
6
6
|
|
|
7
7
|
import ezmsg.core as ez
|
|
8
|
+
from ezmsg.baseproc import BaseTransformer, BaseTransformerUnit
|
|
8
9
|
from ezmsg.baseproc.util.asio import run_coroutine_sync
|
|
9
10
|
from ezmsg.util.messages.axisarray import AxisArray
|
|
10
11
|
from ezmsg.util.messages.util import replace
|
|
11
12
|
|
|
12
|
-
from ..base import BaseTransformer, BaseTransformerUnit
|
|
13
|
-
|
|
14
13
|
# --- Constant Addition (single input) ---
|
|
15
14
|
|
|
16
15
|
|
ezmsg/sigproc/math/clip.py
CHANGED
|
@@ -1,27 +1,32 @@
|
|
|
1
|
-
"""
|
|
2
|
-
|
|
1
|
+
"""
|
|
2
|
+
Clips the data to be within the specified range.
|
|
3
|
+
|
|
4
|
+
.. note::
|
|
5
|
+
This module supports the :doc:`Array API standard </guides/explanations/array_api>`,
|
|
6
|
+
enabling use with NumPy, CuPy, PyTorch, and other compatible array libraries.
|
|
7
|
+
"""
|
|
3
8
|
|
|
4
9
|
import ezmsg.core as ez
|
|
5
|
-
|
|
10
|
+
from array_api_compat import get_namespace
|
|
11
|
+
from ezmsg.baseproc import BaseTransformer, BaseTransformerUnit
|
|
6
12
|
from ezmsg.util.messages.axisarray import AxisArray
|
|
7
13
|
from ezmsg.util.messages.util import replace
|
|
8
14
|
|
|
9
|
-
from ..base import BaseTransformer, BaseTransformerUnit
|
|
10
|
-
|
|
11
15
|
|
|
12
16
|
class ClipSettings(ez.Settings):
|
|
13
|
-
|
|
14
|
-
"""Lower clip bound."""
|
|
17
|
+
min: float | None = None
|
|
18
|
+
"""Lower clip bound. If None, no lower clipping is applied."""
|
|
15
19
|
|
|
16
|
-
|
|
17
|
-
"""Upper clip bound."""
|
|
20
|
+
max: float | None = None
|
|
21
|
+
"""Upper clip bound. If None, no upper clipping is applied."""
|
|
18
22
|
|
|
19
23
|
|
|
20
24
|
class ClipTransformer(BaseTransformer[ClipSettings, AxisArray, AxisArray]):
|
|
21
25
|
def _process(self, message: AxisArray) -> AxisArray:
|
|
26
|
+
xp = get_namespace(message.data)
|
|
22
27
|
return replace(
|
|
23
28
|
message,
|
|
24
|
-
data=
|
|
29
|
+
data=xp.clip(message.data, self.settings.min, self.settings.max),
|
|
25
30
|
)
|
|
26
31
|
|
|
27
32
|
|
|
@@ -29,15 +34,15 @@ class Clip(BaseTransformerUnit[ClipSettings, AxisArray, AxisArray, ClipTransform
|
|
|
29
34
|
SETTINGS = ClipSettings
|
|
30
35
|
|
|
31
36
|
|
|
32
|
-
def clip(
|
|
37
|
+
def clip(min: float | None = None, max: float | None = None) -> ClipTransformer:
|
|
33
38
|
"""
|
|
34
|
-
Clips the data to be within the specified range.
|
|
39
|
+
Clips the data to be within the specified range.
|
|
35
40
|
|
|
36
41
|
Args:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
Returns: :obj:`ClipTransformer`.
|
|
42
|
+
min: Lower clip bound. If None, no lower clipping is applied.
|
|
43
|
+
max: Upper clip bound. If None, no upper clipping is applied.
|
|
41
44
|
|
|
45
|
+
Returns:
|
|
46
|
+
:obj:`ClipTransformer`.
|
|
42
47
|
"""
|
|
43
|
-
return ClipTransformer(ClipSettings(
|
|
48
|
+
return ClipTransformer(ClipSettings(min=min, max=max))
|
ezmsg/sigproc/math/difference.py
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""
|
|
2
|
+
Take the difference between 2 signals or between a signal and a constant value.
|
|
3
|
+
|
|
4
|
+
.. note::
|
|
5
|
+
:obj:`ConstDifferenceTransformer` supports the :doc:`Array API standard </guides/explanations/array_api>`,
|
|
6
|
+
enabling use with NumPy, CuPy, PyTorch, and other compatible array libraries.
|
|
7
|
+
:obj:`DifferenceProcessor` (two-input difference) currently requires NumPy arrays.
|
|
8
|
+
"""
|
|
2
9
|
|
|
3
10
|
import asyncio
|
|
4
11
|
import typing
|
|
5
12
|
from dataclasses import dataclass, field
|
|
6
13
|
|
|
7
14
|
import ezmsg.core as ez
|
|
15
|
+
from ezmsg.baseproc import BaseTransformer, BaseTransformerUnit
|
|
8
16
|
from ezmsg.baseproc.util.asio import run_coroutine_sync
|
|
9
17
|
from ezmsg.util.messages.axisarray import AxisArray
|
|
10
18
|
from ezmsg.util.messages.util import replace
|
|
11
19
|
|
|
12
|
-
from ..base import BaseTransformer, BaseTransformerUnit
|
|
13
|
-
|
|
14
20
|
|
|
15
21
|
class ConstDifferenceSettings(ez.Settings):
|
|
16
22
|
value: float = 0.0
|
ezmsg/sigproc/math/invert.py
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""
|
|
2
|
+
Compute the multiplicative inverse (1/x) of the data.
|
|
2
3
|
|
|
4
|
+
.. note::
|
|
5
|
+
This module supports the :doc:`Array API standard </guides/explanations/array_api>`,
|
|
6
|
+
enabling use with NumPy, CuPy, PyTorch, and other compatible array libraries.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from ezmsg.baseproc import BaseTransformer, BaseTransformerUnit
|
|
3
10
|
from ezmsg.util.messages.axisarray import AxisArray
|
|
4
11
|
from ezmsg.util.messages.util import replace
|
|
5
12
|
|
|
6
|
-
from ..base import BaseTransformer, BaseTransformerUnit
|
|
7
|
-
|
|
8
13
|
|
|
9
14
|
class InvertTransformer(BaseTransformer[None, AxisArray, AxisArray]):
|
|
10
15
|
def _process(self, message: AxisArray) -> AxisArray:
|
ezmsg/sigproc/math/log.py
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""
|
|
2
|
+
Take the logarithm of the data.
|
|
3
|
+
|
|
4
|
+
.. note::
|
|
5
|
+
This module supports the :doc:`Array API standard </guides/explanations/array_api>`,
|
|
6
|
+
enabling use with NumPy, CuPy, PyTorch, and other compatible array libraries.
|
|
7
|
+
"""
|
|
2
8
|
|
|
3
|
-
# TODO: Array API
|
|
4
9
|
import ezmsg.core as ez
|
|
5
|
-
|
|
10
|
+
from array_api_compat import get_namespace
|
|
11
|
+
from ezmsg.baseproc import BaseTransformer, BaseTransformerUnit
|
|
6
12
|
from ezmsg.util.messages.axisarray import AxisArray
|
|
7
13
|
from ezmsg.util.messages.util import replace
|
|
8
14
|
|
|
9
|
-
from ..base import BaseTransformer, BaseTransformerUnit
|
|
10
|
-
|
|
11
15
|
|
|
12
16
|
class LogSettings(ez.Settings):
|
|
13
17
|
base: float = 10.0
|
|
@@ -19,10 +23,17 @@ class LogSettings(ez.Settings):
|
|
|
19
23
|
|
|
20
24
|
class LogTransformer(BaseTransformer[LogSettings, AxisArray, AxisArray]):
|
|
21
25
|
def _process(self, message: AxisArray) -> AxisArray:
|
|
26
|
+
xp = get_namespace(message.data)
|
|
22
27
|
data = message.data
|
|
23
|
-
if self.settings.clip_zero
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
if self.settings.clip_zero:
|
|
29
|
+
# Check if any values are <= 0 and dtype is floating point
|
|
30
|
+
has_non_positive = bool(xp.any(data <= 0))
|
|
31
|
+
is_floating = xp.isdtype(data.dtype, "real floating")
|
|
32
|
+
if has_non_positive and is_floating:
|
|
33
|
+
# Use smallest_normal (Array API equivalent of numpy's finfo.tiny)
|
|
34
|
+
min_val = xp.finfo(data.dtype).smallest_normal
|
|
35
|
+
data = xp.clip(data, min_val, None)
|
|
36
|
+
return replace(message, data=xp.log(data) / xp.log(self.settings.base))
|
|
26
37
|
|
|
27
38
|
|
|
28
39
|
class Log(BaseTransformerUnit[LogSettings, AxisArray, AxisArray, LogTransformer]):
|
ezmsg/sigproc/math/scale.py
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""
|
|
2
|
+
Scale the data by a constant factor.
|
|
3
|
+
|
|
4
|
+
.. note::
|
|
5
|
+
This module supports the :doc:`Array API standard </guides/explanations/array_api>`,
|
|
6
|
+
enabling use with NumPy, CuPy, PyTorch, and other compatible array libraries.
|
|
7
|
+
"""
|
|
2
8
|
|
|
3
9
|
import ezmsg.core as ez
|
|
10
|
+
from ezmsg.baseproc import BaseTransformer, BaseTransformerUnit
|
|
4
11
|
from ezmsg.util.messages.axisarray import AxisArray
|
|
5
12
|
from ezmsg.util.messages.util import replace
|
|
6
13
|
|
|
7
|
-
from ..base import BaseTransformer, BaseTransformerUnit
|
|
8
|
-
|
|
9
14
|
|
|
10
15
|
class ScaleSettings(ez.Settings):
|
|
11
16
|
scale: float = 1.0
|
ezmsg/sigproc/transpose.py
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Transpose or permute array dimensions.
|
|
3
|
+
|
|
4
|
+
.. note::
|
|
5
|
+
This module supports the :doc:`Array API standard </guides/explanations/array_api>`,
|
|
6
|
+
enabling use with NumPy, CuPy, PyTorch, and other compatible array libraries.
|
|
7
|
+
Memory layout optimization (C/F order) only applies to NumPy arrays.
|
|
8
|
+
"""
|
|
9
|
+
|
|
1
10
|
from types import EllipsisType
|
|
2
11
|
|
|
3
12
|
import ezmsg.core as ez
|
|
4
13
|
import numpy as np
|
|
14
|
+
from array_api_compat import get_namespace, is_numpy_array
|
|
5
15
|
from ezmsg.baseproc import (
|
|
6
16
|
BaseStatefulTransformer,
|
|
7
17
|
BaseTransformerUnit,
|
|
@@ -84,6 +94,7 @@ class TransposeTransformer(BaseStatefulTransformer[TransposeSettings, AxisArray,
|
|
|
84
94
|
return super().__call__(message)
|
|
85
95
|
|
|
86
96
|
def _process(self, message: AxisArray) -> AxisArray:
|
|
97
|
+
xp = get_namespace(message.data)
|
|
87
98
|
if self.state.axes_ints is None:
|
|
88
99
|
# No transpose required
|
|
89
100
|
if self.settings.order is None:
|
|
@@ -91,15 +102,19 @@ class TransposeTransformer(BaseStatefulTransformer[TransposeSettings, AxisArray,
|
|
|
91
102
|
# Note: We should not be able to reach here because it should be shortcutted at passthrough.
|
|
92
103
|
msg_out = message
|
|
93
104
|
else:
|
|
94
|
-
#
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
105
|
+
# Memory layout optimization only applies to numpy arrays
|
|
106
|
+
if is_numpy_array(message.data):
|
|
107
|
+
msg_out = replace(
|
|
108
|
+
message,
|
|
109
|
+
data=np.require(message.data, requirements=self.settings.order.upper()[0]),
|
|
110
|
+
)
|
|
111
|
+
else:
|
|
112
|
+
msg_out = message
|
|
99
113
|
else:
|
|
100
114
|
dims_out = [message.dims[ix] for ix in self.state.axes_ints]
|
|
101
|
-
data_out =
|
|
102
|
-
if self.settings.order is not None:
|
|
115
|
+
data_out = xp.permute_dims(message.data, axes=self.state.axes_ints)
|
|
116
|
+
if self.settings.order is not None and is_numpy_array(data_out):
|
|
117
|
+
# Memory layout optimization only applies to numpy arrays
|
|
103
118
|
data_out = np.require(data_out, requirements=self.settings.order.upper()[0])
|
|
104
119
|
msg_out = replace(
|
|
105
120
|
message,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ezmsg-sigproc
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.9.0
|
|
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>, Kyle McGraw <kmcgraw@blackrockneuro.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
ezmsg/sigproc/__init__.py,sha256=8K4IcOA3-pfzadoM6s2Sfg5460KlJUocGgyTJTJl96U,52
|
|
2
|
-
ezmsg/sigproc/__version__.py,sha256=
|
|
2
|
+
ezmsg/sigproc/__version__.py,sha256=24D27WSWcO2HaMUGCrVCG6Zbd76BrLDh2qQ1KbGX6Hc,704
|
|
3
3
|
ezmsg/sigproc/activation.py,sha256=83vnTa3ZcC4Q3VSWcGfaqhCEqYRNySUOyVpMHZXfz-c,2755
|
|
4
4
|
ezmsg/sigproc/adaptive_lattice_notch.py,sha256=ThUR48mbSHuThkimtD0j4IXNMrOVcpZgGhE7PCYfXhU,8818
|
|
5
5
|
ezmsg/sigproc/affinetransform.py,sha256=jl7DiSa5Yb0qsmFJbfSiSeGmvK1SGoBgycFC5JU5DVY,9434
|
|
6
|
-
ezmsg/sigproc/aggregate.py,sha256=
|
|
6
|
+
ezmsg/sigproc/aggregate.py,sha256=7Hdz1m-S6Cl9h0oRQHeS_UTGBemhOB4XdFyX6cGcdHo,9362
|
|
7
7
|
ezmsg/sigproc/bandpower.py,sha256=dAhH56sUrXNhcRFymTTwjdM_KcU5OxFzrR_sxIPAxyw,2264
|
|
8
8
|
ezmsg/sigproc/base.py,sha256=SJvKEb8gw6mUMwlV5sH0iPG0bXrgS8tvkPwhI-j89MQ,3672
|
|
9
9
|
ezmsg/sigproc/butterworthfilter.py,sha256=NKTGkgjvlmC1Dc9gD2Z6UBzUq12KicfnczrzM5ZTosk,5255
|
|
10
10
|
ezmsg/sigproc/butterworthzerophase.py,sha256=Df3F1QBBE39FBjNi67wvTsb1bSdTRTSTZXbZiKFlxC4,4105
|
|
11
11
|
ezmsg/sigproc/cheby.py,sha256=B8pGt5_pOBpNZCmaibNl_NKkyuasd8ZEJXeTDCTaino,3711
|
|
12
12
|
ezmsg/sigproc/combfilter.py,sha256=MSxr1I-jBePW_9AuCiv3RQ1HUNxIsNhLk0q1Iu8ikAw,4766
|
|
13
|
-
ezmsg/sigproc/coordinatespaces.py,sha256=
|
|
13
|
+
ezmsg/sigproc/coordinatespaces.py,sha256=bp_0fTS9b27OQqLoFzgE3f9rb287P8y0S1dWWGrS08o,5298
|
|
14
14
|
ezmsg/sigproc/decimate.py,sha256=DCX9p4ZrcGoQ9di-jmPKqiKERTkvTAtSqLg8chQLp84,2336
|
|
15
15
|
ezmsg/sigproc/denormalize.py,sha256=OACzoINCISNUmZcR2pqWfxi3p8uuBLCz1PMw4XNwOCs,3035
|
|
16
16
|
ezmsg/sigproc/detrend.py,sha256=2C-dhVy-ty4b22aE07kIF3VjqCoFitoZqyrX6hAjXYQ,894
|
|
17
|
-
ezmsg/sigproc/diff.py,sha256=
|
|
17
|
+
ezmsg/sigproc/diff.py,sha256=nDf9-XywZKlfeainIeubl_NccmkuAdLjYMcWSPMquss,3179
|
|
18
18
|
ezmsg/sigproc/downsample.py,sha256=Jqxt1Va1FrQLH1wUQpP0U79iQARTTHEKklKHy7yGL2o,3679
|
|
19
19
|
ezmsg/sigproc/ewma.py,sha256=ecLq1ZlON85NWdW_5cz9chWirxjf4y9zCPMOt3IqQuk,7723
|
|
20
20
|
ezmsg/sigproc/ewmfilter.py,sha256=9AuvVn3TDdf5R4bVolYNM46AtDVHFJa8MLGltY6mYPE,4795
|
|
@@ -28,7 +28,7 @@ ezmsg/sigproc/fir_pmc.py,sha256=Ze2pd9K8XrdDhgJZG2E7x-5C2hfd6kIns4bYjTJsBvc,6997
|
|
|
28
28
|
ezmsg/sigproc/firfilter.py,sha256=7r_I476nYuixJsuwc_hQ0Fbq8WB0gnYBZUKs3zultOQ,3790
|
|
29
29
|
ezmsg/sigproc/gaussiansmoothing.py,sha256=BfXm9YQoOtieM4ABK2KRgxeQz055rd7mqtTVqmjT3Rk,2672
|
|
30
30
|
ezmsg/sigproc/kaiser.py,sha256=dIwgHbLXUHPtdotsGNLE9VG_clhcMgvVnSoFkMVgF9M,3483
|
|
31
|
-
ezmsg/sigproc/linear.py,sha256=
|
|
31
|
+
ezmsg/sigproc/linear.py,sha256=b3NRzQNBvdU2jqenZT9XXFHax9Mavbj2xFiVxOwl1Ms,4662
|
|
32
32
|
ezmsg/sigproc/messages.py,sha256=KQczHTeifn4BZycChN8ZcpfZoQW3lC_xuFmN72QT97s,925
|
|
33
33
|
ezmsg/sigproc/quantize.py,sha256=uSM2z2xXwL0dgSltyzLEmlKjaJZ2meA3PDWX8_bM0Hs,2195
|
|
34
34
|
ezmsg/sigproc/resample.py,sha256=3mm9pvxryNVhQuTCIMW3ToUkUfbVOCsIgvXUiurit1Y,11389
|
|
@@ -40,17 +40,17 @@ ezmsg/sigproc/slicer.py,sha256=xLXxWf722V08ytVwvPimYjDKKj0pkC2HjdgCVaoaOvs,5195
|
|
|
40
40
|
ezmsg/sigproc/spectral.py,sha256=wFzuihS7qJZMQcp0ds_qCG-zCbvh5DyhFRjn2wA9TWQ,322
|
|
41
41
|
ezmsg/sigproc/spectrogram.py,sha256=g8xYWENzle6O5uEF-vfjsF5gOSDnJTwiu3ZudicO470,2893
|
|
42
42
|
ezmsg/sigproc/spectrum.py,sha256=AAxrywIYpAPENRWvaaM2VjcKEaqMt6ra1E3Ao26jdZs,9523
|
|
43
|
-
ezmsg/sigproc/transpose.py,sha256=
|
|
43
|
+
ezmsg/sigproc/transpose.py,sha256=uRGieeYRFTO9gAhWzkq49f-Qo49rpDQhn9r3nLuwx4I,4983
|
|
44
44
|
ezmsg/sigproc/wavelets.py,sha256=mN9TrZencyvKBfnuMiGZ_lzrE1O7DhVo05EYgCjXncg,7428
|
|
45
45
|
ezmsg/sigproc/window.py,sha256=ZlawY4TPbLc46qIgcKhP4X7dpMDo4zNlnfzgV1eFaGU,15335
|
|
46
46
|
ezmsg/sigproc/math/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
47
|
-
ezmsg/sigproc/math/abs.py,sha256=
|
|
48
|
-
ezmsg/sigproc/math/add.py,sha256=
|
|
49
|
-
ezmsg/sigproc/math/clip.py,sha256=
|
|
50
|
-
ezmsg/sigproc/math/difference.py,sha256=
|
|
51
|
-
ezmsg/sigproc/math/invert.py,sha256=
|
|
52
|
-
ezmsg/sigproc/math/log.py,sha256=
|
|
53
|
-
ezmsg/sigproc/math/scale.py,sha256=
|
|
47
|
+
ezmsg/sigproc/math/abs.py,sha256=Zrt0xhGnhf90Vk00S1PYkbeCOQshqkvh1HLj26N4AL0,979
|
|
48
|
+
ezmsg/sigproc/math/add.py,sha256=UikpS_vhaY58ssf46C1r4_tnRUFMl86xCmd5Y8GFZ1Q,3666
|
|
49
|
+
ezmsg/sigproc/math/clip.py,sha256=1D6mUlOzBB7L35G_KKYZmfg7nYlbuDdITV4EH0R-yUo,1529
|
|
50
|
+
ezmsg/sigproc/math/difference.py,sha256=uUYZgbLe-GrFSN6EOFjs9fQZllp827IluxL6m8TJuH8,4791
|
|
51
|
+
ezmsg/sigproc/math/invert.py,sha256=nz8jbfvDoez6s9NmAprBtTAI5oSDj0wNUPk8j13XiVk,855
|
|
52
|
+
ezmsg/sigproc/math/log.py,sha256=JhjSqLnQnvx_3F4txRYHuUPSJ12Yj2HvRTsCMNvlxpo,2022
|
|
53
|
+
ezmsg/sigproc/math/scale.py,sha256=4_xHcHNuf13E1fxIF5vbkPfkN4En6zkfPIKID7lCERk,1133
|
|
54
54
|
ezmsg/sigproc/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
55
55
|
ezmsg/sigproc/util/asio.py,sha256=aAj0e7OoBvkRy28k05HL2s9YPCTxOddc05xMN-qd4lQ,577
|
|
56
56
|
ezmsg/sigproc/util/axisarray_buffer.py,sha256=TGDeC6CXmmp7OUuiGd6xYQijRGYDE4QGdWxjK5Vs3nE,14057
|
|
@@ -59,7 +59,7 @@ ezmsg/sigproc/util/message.py,sha256=ppN3IYtIAwrxWG9JOvgWFn1wDdIumkEzYFfqpH9VQkY
|
|
|
59
59
|
ezmsg/sigproc/util/profile.py,sha256=eVOo9pXgusrnH1yfRdd2RsM7Dbe2UpyC0LJ9MfGpB08,416
|
|
60
60
|
ezmsg/sigproc/util/sparse.py,sha256=NjbJitCtO0B6CENTlyd9c-lHEJwoCan-T3DIgPyeShw,4834
|
|
61
61
|
ezmsg/sigproc/util/typeresolution.py,sha256=fMFzLi63dqCIclGFLcMdM870OYxJnkeWw6aWKNMk718,362
|
|
62
|
-
ezmsg_sigproc-2.
|
|
63
|
-
ezmsg_sigproc-2.
|
|
64
|
-
ezmsg_sigproc-2.
|
|
65
|
-
ezmsg_sigproc-2.
|
|
62
|
+
ezmsg_sigproc-2.9.0.dist-info/METADATA,sha256=H7aJdYvhCekfdihzdsPbvT1a942faGRIlcoeDd_23HI,1908
|
|
63
|
+
ezmsg_sigproc-2.9.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
64
|
+
ezmsg_sigproc-2.9.0.dist-info/licenses/LICENSE,sha256=seu0tKhhAMPCUgc1XpXGGaCxY1YaYvFJwqFuQZAl2go,1100
|
|
65
|
+
ezmsg_sigproc-2.9.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|