ezmsg-sigproc 2.3.0__py3-none-any.whl → 2.4.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.
@@ -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.3.0'
32
- __version_tuple__ = version_tuple = (2, 3, 0)
31
+ __version__ = version = '2.4.0'
32
+ __version_tuple__ = version_tuple = (2, 4, 0)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -1,3 +1,4 @@
1
+ from array_api_compat import get_namespace
1
2
  import typing
2
3
 
3
4
  import numpy as np
@@ -12,6 +13,7 @@ from ezmsg.util.messages.axisarray import (
12
13
 
13
14
  from .spectral import OptionsEnum
14
15
  from .base import (
16
+ BaseTransformer,
15
17
  BaseStatefulTransformer,
16
18
  BaseTransformerUnit,
17
19
  processor_state,
@@ -213,3 +215,70 @@ def ranged_aggregate(
213
215
  return RangedAggregateTransformer(
214
216
  RangedAggregateSettings(axis=axis, bands=bands, operation=operation)
215
217
  )
218
+
219
+
220
+ class AggregateSettings(ez.Settings):
221
+ """Settings for :obj:`Aggregate`."""
222
+
223
+ axis: str
224
+ """The name of the axis to aggregate over. This axis will be removed from the output."""
225
+
226
+ operation: AggregationFunction = AggregationFunction.MEAN
227
+ """:obj:`AggregationFunction` to apply."""
228
+
229
+
230
+ class AggregateTransformer(BaseTransformer[AggregateSettings, AxisArray, AxisArray]):
231
+ """
232
+ Transformer that aggregates an entire axis using a specified operation.
233
+
234
+ Unlike :obj:`RangedAggregateTransformer` which aggregates over specific ranges/bands
235
+ and preserves the axis (with one value per band), this transformer aggregates the
236
+ entire axis and removes it from the output, reducing dimensionality by one.
237
+ """
238
+
239
+ def _process(self, message: AxisArray) -> AxisArray:
240
+ xp = get_namespace(message.data)
241
+ axis_idx = message.get_axis_idx(self.settings.axis)
242
+ op = self.settings.operation
243
+
244
+ if op == AggregationFunction.NONE:
245
+ raise ValueError(
246
+ "AggregationFunction.NONE is not supported for full-axis aggregation"
247
+ )
248
+
249
+ if op == AggregationFunction.TRAPEZOID:
250
+ # Trapezoid integration requires x-coordinates
251
+ target_axis = message.get_axis(self.settings.axis)
252
+ if hasattr(target_axis, "data"):
253
+ x = target_axis.data
254
+ else:
255
+ x = target_axis.value(np.arange(message.data.shape[axis_idx]))
256
+ agg_data = np.trapezoid(np.asarray(message.data), x=x, axis=axis_idx)
257
+ else:
258
+ # Try array-API compatible function first, fall back to numpy
259
+ func_name = op.value
260
+ if hasattr(xp, func_name):
261
+ agg_data = getattr(xp, func_name)(message.data, axis=axis_idx)
262
+ else:
263
+ agg_data = AGGREGATORS[op](message.data, axis=axis_idx)
264
+
265
+ new_dims = list(message.dims)
266
+ new_dims.pop(axis_idx)
267
+
268
+ new_axes = dict(message.axes)
269
+ new_axes.pop(self.settings.axis, None)
270
+
271
+ return replace(
272
+ message,
273
+ data=agg_data,
274
+ dims=new_dims,
275
+ axes=new_axes,
276
+ )
277
+
278
+
279
+ class AggregateUnit(
280
+ BaseTransformerUnit[AggregateSettings, AxisArray, AxisArray, AggregateTransformer]
281
+ ):
282
+ """Unit that aggregates an entire axis using a specified operation."""
283
+
284
+ SETTINGS = AggregateSettings
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ezmsg-sigproc
3
- Version: 2.3.0
3
+ Version: 2.4.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>
6
6
  License-Expression: MIT
@@ -1,9 +1,9 @@
1
1
  ezmsg/sigproc/__init__.py,sha256=8K4IcOA3-pfzadoM6s2Sfg5460KlJUocGgyTJTJl96U,52
2
- ezmsg/sigproc/__version__.py,sha256=KNFYe-Vtdt7Z-oHyl8jmDAQ9qXoCNMAEXigj6BR1QUI,704
2
+ ezmsg/sigproc/__version__.py,sha256=69_lBCO99qjONN2phoPwQ0THjdLm1VftCSvDKqELbGk,704
3
3
  ezmsg/sigproc/activation.py,sha256=qWAhpbFBxSoqbGy4P9JKE5LY-5v8rQI1U81OvNxBG2Y,2820
4
4
  ezmsg/sigproc/adaptive_lattice_notch.py,sha256=3M65PrZpdgBlQtE7Ph4Gu2ISIyWw4j8Xxhm5PpSkLFw,9102
5
5
  ezmsg/sigproc/affinetransform.py,sha256=WU495KoDKZfHPS3Dumh65rgf639koNlfDIx_torIByg,8662
6
- ezmsg/sigproc/aggregate.py,sha256=KR3u9D9jx9KcOQlvI10I6krSxbZCIerG2i4u5Wu5qMI,6754
6
+ ezmsg/sigproc/aggregate.py,sha256=wHUP_aS9NgnOxBCPN1_tSxCqMMb8UPBEoKwGKX7-ASk,9199
7
7
  ezmsg/sigproc/bandpower.py,sha256=j-Y6iWjD2xkggfi-4HAFJVBPJHHBGvAZy1uM4murZkQ,2319
8
8
  ezmsg/sigproc/base.py,sha256=PQr03O2P1v9LzcSR0GJLvPpBCLtnmGaz76gUeXphcH4,48753
9
9
  ezmsg/sigproc/butterworthfilter.py,sha256=7ZP4CRsXBt3-5dzyUjD45vc0J3Fhpm4CLrk-ps28jhc,5305
@@ -53,7 +53,7 @@ ezmsg/sigproc/util/message.py,sha256=l_b1b6bXX8N6VF9RbUELzsHs73cKkDURBdIr0lt3CY0
53
53
  ezmsg/sigproc/util/profile.py,sha256=KNJ_QkKelQHNEp2C8MhqzdhYydMNULc_NQq3ccMfzIk,5775
54
54
  ezmsg/sigproc/util/sparse.py,sha256=mE64p1tYb5A1shaRE1D-VnH-RshbLb8g8kXSXxnA-J4,4842
55
55
  ezmsg/sigproc/util/typeresolution.py,sha256=5R7xmG-F4CkdqQ5aoQnqM-htQb-VwAJl58jJgxtClys,3146
56
- ezmsg_sigproc-2.3.0.dist-info/METADATA,sha256=EDFO5xk2hUAP6WseYifJK4SjYgqpvT903Lf_kQdPQWI,4977
57
- ezmsg_sigproc-2.3.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
58
- ezmsg_sigproc-2.3.0.dist-info/licenses/LICENSE.txt,sha256=seu0tKhhAMPCUgc1XpXGGaCxY1YaYvFJwqFuQZAl2go,1100
59
- ezmsg_sigproc-2.3.0.dist-info/RECORD,,
56
+ ezmsg_sigproc-2.4.0.dist-info/METADATA,sha256=FcsrFuRHBBbdrHsdlVGJjU7hUGkX-ql3xYWGAPdkD1M,4977
57
+ ezmsg_sigproc-2.4.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
58
+ ezmsg_sigproc-2.4.0.dist-info/licenses/LICENSE.txt,sha256=seu0tKhhAMPCUgc1XpXGGaCxY1YaYvFJwqFuQZAl2go,1100
59
+ ezmsg_sigproc-2.4.0.dist-info/RECORD,,