ezmsg-sigproc 2.6.0__tar.gz → 2.8.0__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.
Files changed (168) hide show
  1. ezmsg_sigproc-2.8.0/PKG-INFO +60 -0
  2. ezmsg_sigproc-2.8.0/README.md +42 -0
  3. ezmsg_sigproc-2.8.0/docs/source/api/index.rst +11 -0
  4. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/docs/source/guides/explanations/sigproc.rst +1 -1
  5. ezmsg_sigproc-2.8.0/docs/source/guides/sigproc/architecture.rst +41 -0
  6. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/docs/source/guides/sigproc/content-sigproc.rst +1 -0
  7. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/docs/source/guides/tutorials/signalprocessing.rst +1 -1
  8. ezmsg_sigproc-2.8.0/docs/source/index.md +20 -0
  9. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/pyproject.toml +1 -1
  10. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/__version__.py +2 -2
  11. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/activation.py +1 -1
  12. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/adaptive_lattice_notch.py +1 -2
  13. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/affinetransform.py +26 -5
  14. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/aggregate.py +6 -6
  15. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/bandpower.py +6 -6
  16. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/butterworthzerophase.py +1 -1
  17. ezmsg_sigproc-2.8.0/src/ezmsg/sigproc/coordinatespaces.py +142 -0
  18. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/decimate.py +1 -1
  19. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/denormalize.py +3 -4
  20. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/detrend.py +1 -1
  21. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/diff.py +3 -4
  22. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/downsample.py +5 -6
  23. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/ewma.py +45 -9
  24. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/extract_axis.py +1 -2
  25. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/fbcca.py +4 -4
  26. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/filter.py +3 -4
  27. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/filterbank.py +5 -5
  28. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/filterbankdesign.py +4 -4
  29. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/fir_hilbert.py +1 -1
  30. ezmsg_sigproc-2.8.0/src/ezmsg/sigproc/linear.py +118 -0
  31. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/math/abs.py +3 -0
  32. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/math/add.py +1 -1
  33. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/math/clip.py +3 -0
  34. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/math/difference.py +2 -0
  35. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/math/invert.py +2 -0
  36. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/math/log.py +3 -0
  37. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/math/scale.py +2 -0
  38. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/quantize.py +1 -2
  39. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/resample.py +4 -4
  40. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/rollingscaler.py +4 -4
  41. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/sampler.py +6 -6
  42. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/scaler.py +56 -8
  43. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/signalinjector.py +3 -4
  44. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/slicer.py +5 -6
  45. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/spectrogram.py +4 -4
  46. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/spectrum.py +5 -6
  47. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/transpose.py +5 -6
  48. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/util/axisarray_buffer.py +2 -0
  49. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/util/buffer.py +4 -0
  50. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/util/sparse.py +2 -0
  51. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/wavelets.py +4 -4
  52. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/window.py +5 -5
  53. ezmsg_sigproc-2.8.0/tests/integration/ezmsg/test_coordinatespaces_system.py +226 -0
  54. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_activation.py +8 -3
  55. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_affine_transform.py +33 -26
  56. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_aggregate.py +18 -13
  57. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_bandpower.py +16 -9
  58. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_base.py +3 -3
  59. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_butter.py +29 -28
  60. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_butterworthzerophase.py +2 -2
  61. ezmsg_sigproc-2.8.0/tests/unit/test_coordinatespaces.py +272 -0
  62. ezmsg_sigproc-2.8.0/tests/unit/test_ewma.py +162 -0
  63. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_filterbank.py +3 -3
  64. ezmsg_sigproc-2.8.0/tests/unit/test_linear.py +307 -0
  65. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_math.py +21 -21
  66. ezmsg_sigproc-2.8.0/tests/unit/test_scaler.py +233 -0
  67. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_slicer.py +17 -18
  68. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_spectrogram.py +1 -1
  69. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_spectrum.py +17 -14
  70. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_wavelets.py +10 -8
  71. ezmsg_sigproc-2.6.0/PKG-INFO +0 -73
  72. ezmsg_sigproc-2.6.0/README.md +0 -55
  73. ezmsg_sigproc-2.6.0/docs/source/api/index.rst +0 -157
  74. ezmsg_sigproc-2.6.0/docs/source/guides/ProcessorsBase.md +0 -58
  75. ezmsg_sigproc-2.6.0/docs/source/index.rst +0 -82
  76. ezmsg_sigproc-2.6.0/tests/unit/test_ewma.py +0 -47
  77. ezmsg_sigproc-2.6.0/tests/unit/test_scaler.py +0 -70
  78. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/.github/workflows/docs.yml +0 -0
  79. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/.github/workflows/python-publish.yml +0 -0
  80. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/.github/workflows/python-tests.yml +0 -0
  81. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/.gitignore +0 -0
  82. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/.pre-commit-config.yaml +0 -0
  83. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/LICENSE +0 -0
  84. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/docs/Makefile +0 -0
  85. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/docs/make.bat +0 -0
  86. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/docs/source/_templates/autosummary/module.rst +0 -0
  87. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/docs/source/conf.py +0 -0
  88. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/docs/source/guides/HybridBuffer.md +0 -0
  89. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/docs/source/guides/how-tos/signalprocessing/adaptive.rst +0 -0
  90. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/docs/source/guides/how-tos/signalprocessing/checkpoint.rst +0 -0
  91. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/docs/source/guides/how-tos/signalprocessing/composite.rst +0 -0
  92. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/docs/source/guides/how-tos/signalprocessing/content-signalprocessing.rst +0 -0
  93. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/docs/source/guides/how-tos/signalprocessing/processor.rst +0 -0
  94. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/docs/source/guides/how-tos/signalprocessing/standalone.rst +0 -0
  95. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/docs/source/guides/how-tos/signalprocessing/stateful.rst +0 -0
  96. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/docs/source/guides/how-tos/signalprocessing/unit.rst +0 -0
  97. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/docs/source/guides/img/HybridBufferBasic.svg +0 -0
  98. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/docs/source/guides/img/HybridBufferOverflow.svg +0 -0
  99. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/docs/source/guides/sigproc/base.rst +0 -0
  100. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/docs/source/guides/sigproc/processors.rst +0 -0
  101. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/docs/source/guides/sigproc/units.rst +0 -0
  102. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/__init__.py +0 -0
  103. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/base.py +0 -0
  104. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/butterworthfilter.py +0 -0
  105. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/cheby.py +0 -0
  106. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/combfilter.py +0 -0
  107. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/ewmfilter.py +0 -0
  108. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/fir_pmc.py +0 -0
  109. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/firfilter.py +0 -0
  110. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/gaussiansmoothing.py +0 -0
  111. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/kaiser.py +0 -0
  112. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/math/__init__.py +0 -0
  113. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/messages.py +0 -0
  114. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/spectral.py +0 -0
  115. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/util/__init__.py +0 -0
  116. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/util/asio.py +0 -0
  117. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/util/message.py +0 -0
  118. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/util/profile.py +0 -0
  119. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/src/ezmsg/sigproc/util/typeresolution.py +0 -0
  120. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/__init__.py +0 -0
  121. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/conftest.py +0 -0
  122. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/helpers/__init__.py +0 -0
  123. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/helpers/synth.py +0 -0
  124. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/helpers/util.py +0 -0
  125. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/integration/bytewax/test_spectrum_bytewax.py +0 -0
  126. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/integration/bytewax/test_window_bytewax.py +0 -0
  127. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/integration/ezmsg/test_add_system.py +0 -0
  128. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/integration/ezmsg/test_butterworth_system.py +0 -0
  129. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/integration/ezmsg/test_butterworthzerophase_system.py +0 -0
  130. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/integration/ezmsg/test_decimate_system.py +0 -0
  131. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/integration/ezmsg/test_difference_system.py +0 -0
  132. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/integration/ezmsg/test_downsample_system.py +0 -0
  133. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/integration/ezmsg/test_filter_system.py +0 -0
  134. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/integration/ezmsg/test_fir_hilbert_system.py +0 -0
  135. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/integration/ezmsg/test_fir_pmc_system.py +0 -0
  136. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/integration/ezmsg/test_rollingscaler_system.py +0 -0
  137. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/integration/ezmsg/test_sampler_system.py +0 -0
  138. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/integration/ezmsg/test_scaler_system.py +0 -0
  139. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/integration/ezmsg/test_spectrum_system.py +0 -0
  140. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/integration/ezmsg/test_window_system.py +0 -0
  141. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/resources/xform.csv +0 -0
  142. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/test_profile.py +0 -0
  143. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/buffer/test_axisarray_buffer.py +0 -0
  144. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/buffer/test_buffer.py +0 -0
  145. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/buffer/test_buffer_overflow.py +0 -0
  146. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_adaptive_lattice_notch.py +0 -0
  147. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_combfilter.py +0 -0
  148. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_denormalize.py +0 -0
  149. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_diff.py +0 -0
  150. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_downsample.py +0 -0
  151. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_extract_axis.py +0 -0
  152. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_fbcca.py +0 -0
  153. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_filter.py +0 -0
  154. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_filterbankdesign.py +0 -0
  155. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_fir_hilbert.py +0 -0
  156. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_fir_pmc.py +0 -0
  157. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_firfilter.py +0 -0
  158. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_gaussian_smoothing_filter.py +0 -0
  159. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_kaiser.py +0 -0
  160. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_math_add.py +0 -0
  161. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_math_difference.py +0 -0
  162. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_quantize.py +0 -0
  163. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_resample.py +0 -0
  164. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_rollingscaler.py +0 -0
  165. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_sampler.py +0 -0
  166. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_transpose.py +0 -0
  167. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_util.py +0 -0
  168. {ezmsg_sigproc-2.6.0 → ezmsg_sigproc-2.8.0}/tests/unit/test_window.py +0 -0
@@ -0,0 +1,60 @@
1
+ Metadata-Version: 2.4
2
+ Name: ezmsg-sigproc
3
+ Version: 2.8.0
4
+ Summary: Timeseries signal processing implementations in ezmsg
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
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.10.15
9
+ Requires-Dist: array-api-compat>=1.11.1
10
+ Requires-Dist: ezmsg-baseproc>=1.1.0
11
+ Requires-Dist: ezmsg>=3.6.0
12
+ Requires-Dist: numba>=0.61.0
13
+ Requires-Dist: numpy>=1.26.0
14
+ Requires-Dist: pywavelets>=1.6.0
15
+ Requires-Dist: scipy>=1.13.1
16
+ Requires-Dist: sparse>=0.15.4
17
+ Description-Content-Type: text/markdown
18
+
19
+ # ezmsg-sigproc
20
+
21
+ Signal processing primitives for the [ezmsg](https://www.ezmsg.org) message-passing framework.
22
+
23
+ ## Features
24
+
25
+ * **Filtering** - Chebyshev, comb filters, and more
26
+ * **Spectral analysis** - Spectrogram, spectrum, and wavelet transforms
27
+ * **Resampling** - Downsample, decimate, and resample operations
28
+ * **Windowing** - Sliding windows and buffering utilities
29
+ * **Math operations** - Arithmetic, log, abs, difference, and more
30
+ * **Signal generation** - Synthetic signal generators
31
+
32
+ All modules use `AxisArray` as the primary data structure for passing signals between components.
33
+
34
+ ## Installation
35
+
36
+ Install from PyPI:
37
+
38
+ ```bash
39
+ pip install ezmsg-sigproc
40
+ ```
41
+
42
+ Or install from GitHub for the latest development version:
43
+
44
+ ```bash
45
+ pip install git+https://github.com/ezmsg-org/ezmsg-sigproc.git@dev
46
+ ```
47
+
48
+ ## Documentation
49
+
50
+ Full documentation is available at [ezmsg.org](https://www.ezmsg.org).
51
+
52
+ ## Development
53
+
54
+ We use [`uv`](https://docs.astral.sh/uv/) for development.
55
+
56
+ 1. Fork and clone the repository
57
+ 2. `uv sync` to create a virtual environment and install dependencies
58
+ 3. `uv run pre-commit install` to set up linting and formatting hooks
59
+ 4. `uv run pytest tests` to run the test suite
60
+ 5. Submit a PR against the `dev` branch
@@ -0,0 +1,42 @@
1
+ # ezmsg-sigproc
2
+
3
+ Signal processing primitives for the [ezmsg](https://www.ezmsg.org) message-passing framework.
4
+
5
+ ## Features
6
+
7
+ * **Filtering** - Chebyshev, comb filters, and more
8
+ * **Spectral analysis** - Spectrogram, spectrum, and wavelet transforms
9
+ * **Resampling** - Downsample, decimate, and resample operations
10
+ * **Windowing** - Sliding windows and buffering utilities
11
+ * **Math operations** - Arithmetic, log, abs, difference, and more
12
+ * **Signal generation** - Synthetic signal generators
13
+
14
+ All modules use `AxisArray` as the primary data structure for passing signals between components.
15
+
16
+ ## Installation
17
+
18
+ Install from PyPI:
19
+
20
+ ```bash
21
+ pip install ezmsg-sigproc
22
+ ```
23
+
24
+ Or install from GitHub for the latest development version:
25
+
26
+ ```bash
27
+ pip install git+https://github.com/ezmsg-org/ezmsg-sigproc.git@dev
28
+ ```
29
+
30
+ ## Documentation
31
+
32
+ Full documentation is available at [ezmsg.org](https://www.ezmsg.org).
33
+
34
+ ## Development
35
+
36
+ We use [`uv`](https://docs.astral.sh/uv/) for development.
37
+
38
+ 1. Fork and clone the repository
39
+ 2. `uv sync` to create a virtual environment and install dependencies
40
+ 3. `uv run pre-commit install` to set up linting and formatting hooks
41
+ 4. `uv run pytest tests` to run the test suite
42
+ 5. Submit a PR against the `dev` branch
@@ -0,0 +1,11 @@
1
+ API Reference
2
+ =============
3
+
4
+ This page contains auto-generated API reference documentation.
5
+
6
+ .. autosummary::
7
+ :toctree: generated
8
+ :recursive:
9
+ :template: autosummary/module.rst
10
+
11
+ ezmsg.sigproc
@@ -329,7 +329,7 @@ Often, all that is required is the following (e.g., for a custom transformer):
329
329
 
330
330
  import ezmsg.core as ez
331
331
  from ezmsg.util.messages.axisarray import AxisArray
332
- from ezmsg.sigproc.base import BaseTransformer, BaseTransformerUnit
332
+ from ezmsg.baseproc import BaseTransformer, BaseTransformerUnit
333
333
 
334
334
 
335
335
  class CustomTransformerSettings(ez.Settings):
@@ -0,0 +1,41 @@
1
+ Architecture & Usage Patterns
2
+ =============================
3
+
4
+ This page describes the architecture of ezmsg-sigproc and different ways to use its components.
5
+
6
+ Operating Styles: Standalone vs. Pipelines
7
+ ------------------------------------------
8
+
9
+ While each processor is designed to be assembled into an ezmsg pipeline, the components are also well-suited for offline, ad-hoc analysis. You can instantiate processors directly in scripts or notebooks for quick prototyping or to validate results from other code. The companion Unit wrappers, however, are meant for assembling processors into a full ezmsg pipeline.
10
+
11
+ A fully defined ezmsg pipeline shines in online streaming scenarios where message routing, scheduling, and latency handling are crucial. Nevertheless, you can run the same pipeline offline—say, within a Jupyter notebook—if your analysis benefits from ezmsg's structured execution model.
12
+
13
+ Deciding between a standalone processor and a full pipeline comes down to the trade-off between simplicity and the operational overhead of the pipeline:
14
+
15
+ * **Standalone processors**: Low overhead, ideal for one-off or exploratory offline tasks.
16
+ * **Pipeline + Unit wrappers**: Additional setup cost but bring concurrency, standardized interfaces, and automatic message flow—useful when your offline experiment mirrors a live system or when you require fine-grained pipeline behavior.
17
+
18
+ Source Layout
19
+ -------------
20
+
21
+ All source resides under ``src/ezmsg/sigproc``, which contains:
22
+
23
+ * A suite of processors (for example, ``filter.py``, ``spectrogram.py``, ``spectrum.py``, ``sampler.py``)
24
+ * ``math/`` and ``util/`` subpackages for mathematical operations and utilities
25
+
26
+ Key Modules
27
+ ^^^^^^^^^^^
28
+
29
+ * **base.py** (via ``ezmsg.baseproc``): Defines standard protocols—Processor, Producer, Consumer, and Transformer—that enable both stateless and stateful processing chains.
30
+ * **filter.py**: Provides settings dataclasses and a stateful transformer that applies supplied coefficients to incoming data.
31
+ * **spectrogram.py**: Implements spectral analysis using a composite transformer chaining windowing, spectrum computation, and axis adjustments.
32
+
33
+ Where to Learn Next
34
+ -------------------
35
+
36
+ * Study the :doc:`base` page to master the processor architecture.
37
+ * Explore unit tests in the repository for hands-on examples of composing processors and Units.
38
+ * Review the `ezmsg framework <https://www.ezmsg.org>`_ to understand the surrounding ecosystem.
39
+ * Experiment with the code—try running processors standalone and then integrate them into a small pipeline to observe the trade-offs firsthand.
40
+
41
+ This approach equips newcomers to choose the right level of abstraction—raw processor, Unit wrapper, or full pipeline—based on the demands of their analysis or streaming application.
@@ -17,6 +17,7 @@ This may occur when the generator receives inadequate data to produce a valid ou
17
17
  .. toctree::
18
18
  :maxdepth: 1
19
19
 
20
+ architecture
20
21
  base
21
22
  units
22
23
  processors
@@ -132,7 +132,7 @@ Add the following import statements to the top of the `downsample.py` file:
132
132
  )
133
133
  import ezmsg.core as ez
134
134
 
135
- from ezmsg.sigproc.base import (
135
+ from ezmsg.baseproc import (
136
136
  BaseStatefulTransformer,
137
137
  BaseTransformerUnit,
138
138
  processor_state,
@@ -0,0 +1,20 @@
1
+ ```{include} ../../README.md
2
+ ```
3
+
4
+ ## Documentation
5
+
6
+ ```{toctree}
7
+ :maxdepth: 2
8
+ :caption: Contents:
9
+
10
+ guides/sigproc/content-sigproc
11
+ guides/HybridBuffer
12
+ guides/how-tos/signalprocessing/content-signalprocessing
13
+ guides/tutorials/signalprocessing
14
+ api/index
15
+ ```
16
+
17
+ ## Indices and tables
18
+
19
+ - {ref}`genindex`
20
+ - {ref}`modindex`
@@ -13,7 +13,7 @@ requires-python = ">=3.10.15"
13
13
  dynamic = ["version"]
14
14
  dependencies = [
15
15
  "array-api-compat>=1.11.1",
16
- "ezmsg-baseproc>=1.0.3",
16
+ "ezmsg-baseproc>=1.1.0",
17
17
  "ezmsg>=3.6.0",
18
18
  "numba>=0.61.0",
19
19
  "numpy>=1.26.0",
@@ -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.6.0'
32
- __version_tuple__ = version_tuple = (2, 6, 0)
31
+ __version__ = version = '2.8.0'
32
+ __version_tuple__ = version_tuple = (2, 8, 0)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -1,9 +1,9 @@
1
1
  import ezmsg.core as ez
2
2
  import scipy.special
3
+ from ezmsg.baseproc import BaseTransformer, BaseTransformerUnit
3
4
  from ezmsg.util.messages.axisarray import AxisArray
4
5
  from ezmsg.util.messages.util import replace
5
6
 
6
- from .base import BaseTransformer, BaseTransformerUnit
7
7
  from .spectral import OptionsEnum
8
8
 
9
9
 
@@ -2,11 +2,10 @@ import ezmsg.core as ez
2
2
  import numpy as np
3
3
  import numpy.typing as npt
4
4
  import scipy.signal
5
+ from ezmsg.baseproc import BaseStatefulTransformer, processor_state
5
6
  from ezmsg.util.messages.axisarray import AxisArray, CoordinateAxis
6
7
  from ezmsg.util.messages.util import replace
7
8
 
8
- from .base import BaseStatefulTransformer, processor_state
9
-
10
9
 
11
10
  class AdaptiveLatticeNotchFilterSettings(ez.Settings):
12
11
  """Settings for the Adaptive Lattice Notch Filter."""
@@ -1,24 +1,32 @@
1
+ """Affine transformations via matrix multiplication: y = Ax or y = Ax + B.
2
+
3
+ For full matrix transformations where channels are mixed (off-diagonal weights),
4
+ use :obj:`AffineTransformTransformer` or the `AffineTransform` unit.
5
+
6
+ For simple per-channel scaling and offset (diagonal weights only), use
7
+ :obj:`LinearTransformTransformer` from :mod:`ezmsg.sigproc.linear` instead,
8
+ which is more efficient as it avoids matrix multiplication.
9
+ """
10
+
1
11
  import os
2
12
  from pathlib import Path
3
13
 
4
14
  import ezmsg.core as ez
5
15
  import numpy as np
6
16
  import numpy.typing as npt
7
- from ezmsg.util.messages.axisarray import AxisArray, AxisBase
8
- from ezmsg.util.messages.util import replace
9
-
10
- from .base import (
17
+ from ezmsg.baseproc import (
11
18
  BaseStatefulTransformer,
12
19
  BaseTransformer,
13
20
  BaseTransformerUnit,
14
21
  processor_state,
15
22
  )
23
+ from ezmsg.util.messages.axisarray import AxisArray, AxisBase
24
+ from ezmsg.util.messages.util import replace
16
25
 
17
26
 
18
27
  class AffineTransformSettings(ez.Settings):
19
28
  """
20
29
  Settings for :obj:`AffineTransform`.
21
- See :obj:`affine_transform` for argument details.
22
30
  """
23
31
 
24
32
  weights: np.ndarray | str | Path
@@ -40,6 +48,19 @@ class AffineTransformState:
40
48
  class AffineTransformTransformer(
41
49
  BaseStatefulTransformer[AffineTransformSettings, AxisArray, AxisArray, AffineTransformState]
42
50
  ):
51
+ """Apply affine transformation via matrix multiplication: y = Ax or y = Ax + B.
52
+
53
+ Use this transformer when you need full matrix transformations that mix
54
+ channels (off-diagonal weights), such as spatial filters or projections.
55
+
56
+ For simple per-channel scaling and offset where each output channel depends
57
+ only on its corresponding input channel (diagonal weight matrix), use
58
+ :obj:`LinearTransformTransformer` instead, which is more efficient.
59
+
60
+ The weights matrix can include an offset row (stacked as [A|B]) where the
61
+ input is automatically augmented with a column of ones to compute y = Ax + B.
62
+ """
63
+
43
64
  def __call__(self, message: AxisArray) -> AxisArray:
44
65
  # Override __call__ so we can shortcut if weights are None.
45
66
  if self.settings.weights is None or (
@@ -4,6 +4,12 @@ import ezmsg.core as ez
4
4
  import numpy as np
5
5
  import numpy.typing as npt
6
6
  from array_api_compat import get_namespace
7
+ from ezmsg.baseproc import (
8
+ BaseStatefulTransformer,
9
+ BaseTransformer,
10
+ BaseTransformerUnit,
11
+ processor_state,
12
+ )
7
13
  from ezmsg.util.messages.axisarray import (
8
14
  AxisArray,
9
15
  AxisBase,
@@ -11,12 +17,6 @@ from ezmsg.util.messages.axisarray import (
11
17
  slice_along_axis,
12
18
  )
13
19
 
14
- from .base import (
15
- BaseStatefulTransformer,
16
- BaseTransformer,
17
- BaseTransformerUnit,
18
- processor_state,
19
- )
20
20
  from .spectral import OptionsEnum
21
21
 
22
22
 
@@ -1,6 +1,12 @@
1
1
  from dataclasses import field
2
2
 
3
3
  import ezmsg.core as ez
4
+ from ezmsg.baseproc import (
5
+ BaseProcessor,
6
+ BaseStatefulProcessor,
7
+ BaseTransformerUnit,
8
+ CompositeProcessor,
9
+ )
4
10
  from ezmsg.util.messages.axisarray import AxisArray
5
11
 
6
12
  from .aggregate import (
@@ -8,12 +14,6 @@ from .aggregate import (
8
14
  RangedAggregateSettings,
9
15
  RangedAggregateTransformer,
10
16
  )
11
- from .base import (
12
- BaseProcessor,
13
- BaseStatefulProcessor,
14
- BaseTransformerUnit,
15
- CompositeProcessor,
16
- )
17
17
  from .spectrogram import SpectrogramSettings, SpectrogramTransformer
18
18
 
19
19
 
@@ -4,10 +4,10 @@ import typing
4
4
  import ezmsg.core as ez
5
5
  import numpy as np
6
6
  import scipy.signal
7
+ from ezmsg.baseproc import SettingsType
7
8
  from ezmsg.util.messages.axisarray import AxisArray
8
9
  from ezmsg.util.messages.util import replace
9
10
 
10
- from ezmsg.sigproc.base import SettingsType
11
11
  from ezmsg.sigproc.butterworthfilter import ButterworthFilterSettings, butter_design_fun
12
12
  from ezmsg.sigproc.filter import (
13
13
  BACoeffs,
@@ -0,0 +1,142 @@
1
+ """
2
+ Coordinate space transformations for streaming data.
3
+
4
+ This module provides utilities and ezmsg nodes for transforming between
5
+ Cartesian (x, y) and polar (r, theta) coordinate systems.
6
+ """
7
+
8
+ from enum import Enum
9
+ from typing import Tuple
10
+
11
+ import ezmsg.core as ez
12
+ import numpy as np
13
+ import numpy.typing as npt
14
+ from ezmsg.baseproc import (
15
+ BaseTransformer,
16
+ BaseTransformerUnit,
17
+ )
18
+ from ezmsg.util.messages.axisarray import AxisArray, replace
19
+
20
+ # -- Utility functions for coordinate transformations --
21
+
22
+
23
+ def polar2z(r: npt.ArrayLike, theta: npt.ArrayLike) -> npt.ArrayLike:
24
+ """Convert polar coordinates to complex number representation."""
25
+ return r * np.exp(1j * theta)
26
+
27
+
28
+ def z2polar(z: npt.ArrayLike) -> Tuple[npt.ArrayLike, npt.ArrayLike]:
29
+ """Convert complex number to polar coordinates (r, theta)."""
30
+ return np.abs(z), np.angle(z)
31
+
32
+
33
+ def cart2z(x: npt.ArrayLike, y: npt.ArrayLike) -> npt.ArrayLike:
34
+ """Convert Cartesian coordinates to complex number representation."""
35
+ return x + 1j * y
36
+
37
+
38
+ def z2cart(z: npt.ArrayLike) -> Tuple[npt.ArrayLike, npt.ArrayLike]:
39
+ """Convert complex number to Cartesian coordinates (x, y)."""
40
+ return np.real(z), np.imag(z)
41
+
42
+
43
+ def cart2pol(x: npt.ArrayLike, y: npt.ArrayLike) -> Tuple[npt.ArrayLike, npt.ArrayLike]:
44
+ """Convert Cartesian coordinates (x, y) to polar coordinates (r, theta)."""
45
+ return z2polar(cart2z(x, y))
46
+
47
+
48
+ def pol2cart(r: npt.ArrayLike, theta: npt.ArrayLike) -> Tuple[npt.ArrayLike, npt.ArrayLike]:
49
+ """Convert polar coordinates (r, theta) to Cartesian coordinates (x, y)."""
50
+ return z2cart(polar2z(r, theta))
51
+
52
+
53
+ # -- ezmsg transformer classes --
54
+
55
+
56
+ class CoordinateMode(str, Enum):
57
+ """Transformation mode for coordinate conversion."""
58
+
59
+ CART2POL = "cart2pol"
60
+ """Convert Cartesian (x, y) to polar (r, theta)."""
61
+
62
+ POL2CART = "pol2cart"
63
+ """Convert polar (r, theta) to Cartesian (x, y)."""
64
+
65
+
66
+ class CoordinateSpacesSettings(ez.Settings):
67
+ """
68
+ Settings for :obj:`CoordinateSpaces`.
69
+
70
+ See :obj:`coordinate_spaces` for argument details.
71
+ """
72
+
73
+ mode: CoordinateMode = CoordinateMode.CART2POL
74
+ """The transformation mode: 'cart2pol' or 'pol2cart'."""
75
+
76
+ axis: str | None = None
77
+ """
78
+ The name of the axis containing the coordinate components.
79
+ Defaults to the last axis. Must have exactly 2 elements (x,y or r,theta).
80
+ """
81
+
82
+
83
+ class CoordinateSpacesTransformer(BaseTransformer[CoordinateSpacesSettings, AxisArray, AxisArray]):
84
+ """
85
+ Transform between Cartesian and polar coordinate systems.
86
+
87
+ The input must have exactly 2 elements along the specified axis:
88
+ - For cart2pol: expects (x, y), outputs (r, theta)
89
+ - For pol2cart: expects (r, theta), outputs (x, y)
90
+ """
91
+
92
+ def _process(self, message: AxisArray) -> AxisArray:
93
+ axis = self.settings.axis or message.dims[-1]
94
+ axis_idx = message.get_axis_idx(axis)
95
+
96
+ if message.data.shape[axis_idx] != 2:
97
+ raise ValueError(
98
+ f"Coordinate transformation requires exactly 2 elements along axis '{axis}', "
99
+ f"got {message.data.shape[axis_idx]}."
100
+ )
101
+
102
+ # Extract components along the specified axis
103
+ slices_a = [slice(None)] * message.data.ndim
104
+ slices_b = [slice(None)] * message.data.ndim
105
+ slices_a[axis_idx] = 0
106
+ slices_b[axis_idx] = 1
107
+
108
+ component_a = message.data[tuple(slices_a)]
109
+ component_b = message.data[tuple(slices_b)]
110
+
111
+ if self.settings.mode == CoordinateMode.CART2POL:
112
+ # Input: x, y -> Output: r, theta
113
+ out_a, out_b = cart2pol(component_a, component_b)
114
+ else:
115
+ # Input: r, theta -> Output: x, y
116
+ out_a, out_b = pol2cart(component_a, component_b)
117
+
118
+ # Stack results back along the same axis
119
+ result = np.stack([out_a, out_b], axis=axis_idx)
120
+
121
+ # Update axis labels if present
122
+ axes = message.axes
123
+ if axis in axes and hasattr(axes[axis], "data"):
124
+ if self.settings.mode == CoordinateMode.CART2POL:
125
+ new_labels = np.array(["r", "theta"])
126
+ else:
127
+ new_labels = np.array(["x", "y"])
128
+ axes = {**axes, axis: replace(axes[axis], data=new_labels)}
129
+
130
+ return replace(message, data=result, axes=axes)
131
+
132
+
133
+ class CoordinateSpaces(
134
+ BaseTransformerUnit[CoordinateSpacesSettings, AxisArray, AxisArray, CoordinateSpacesTransformer]
135
+ ):
136
+ """
137
+ Unit for transforming between Cartesian and polar coordinate systems.
138
+
139
+ See :obj:`CoordinateSpacesSettings` for configuration options.
140
+ """
141
+
142
+ SETTINGS = CoordinateSpacesSettings
@@ -1,9 +1,9 @@
1
1
  import typing
2
2
 
3
3
  import ezmsg.core as ez
4
+ from ezmsg.baseproc import BaseTransformerUnit
4
5
  from ezmsg.util.messages.axisarray import AxisArray
5
6
 
6
- from .base import BaseTransformerUnit
7
7
  from .cheby import ChebyshevFilterSettings, ChebyshevFilterTransformer
8
8
  from .downsample import Downsample, DownsampleSettings
9
9
  from .filter import BACoeffs, SOSCoeffs
@@ -1,14 +1,13 @@
1
1
  import ezmsg.core as ez
2
2
  import numpy as np
3
3
  import numpy.typing as npt
4
- from ezmsg.util.messages.axisarray import AxisArray
5
- from ezmsg.util.messages.util import replace
6
-
7
- from ezmsg.sigproc.base import (
4
+ from ezmsg.baseproc import (
8
5
  BaseStatefulTransformer,
9
6
  BaseTransformerUnit,
10
7
  processor_state,
11
8
  )
9
+ from ezmsg.util.messages.axisarray import AxisArray
10
+ from ezmsg.util.messages.util import replace
12
11
 
13
12
 
14
13
  class DenormalizeSettings(ez.Settings):
@@ -1,7 +1,7 @@
1
1
  import scipy.signal as sps
2
+ from ezmsg.baseproc import BaseTransformerUnit
2
3
  from ezmsg.util.messages.axisarray import AxisArray, replace
3
4
 
4
- from ezmsg.sigproc.base import BaseTransformerUnit
5
5
  from ezmsg.sigproc.ewma import EWMASettings, EWMATransformer
6
6
 
7
7
 
@@ -1,14 +1,13 @@
1
1
  import ezmsg.core as ez
2
2
  import numpy as np
3
3
  import numpy.typing as npt
4
- from ezmsg.util.messages.axisarray import AxisArray, slice_along_axis
5
- from ezmsg.util.messages.util import replace
6
-
7
- from ezmsg.sigproc.base import (
4
+ from ezmsg.baseproc import (
8
5
  BaseStatefulTransformer,
9
6
  BaseTransformerUnit,
10
7
  processor_state,
11
8
  )
9
+ from ezmsg.util.messages.axisarray import AxisArray, slice_along_axis
10
+ from ezmsg.util.messages.util import replace
12
11
 
13
12
 
14
13
  class DiffSettings(ez.Settings):
@@ -1,17 +1,16 @@
1
1
  import ezmsg.core as ez
2
2
  import numpy as np
3
+ from ezmsg.baseproc import (
4
+ BaseStatefulTransformer,
5
+ BaseTransformerUnit,
6
+ processor_state,
7
+ )
3
8
  from ezmsg.util.messages.axisarray import (
4
9
  AxisArray,
5
10
  replace,
6
11
  slice_along_axis,
7
12
  )
8
13
 
9
- from .base import (
10
- BaseStatefulTransformer,
11
- BaseTransformerUnit,
12
- processor_state,
13
- )
14
-
15
14
 
16
15
  class DownsampleSettings(ez.Settings):
17
16
  """