ezmsg.sigproc.window#
Sliding and tumbling window segmentation of streaming data.
Functions
- windowing(axis=None, newaxis=None, window_dur=None, window_shift=None, zero_pad_until='full', anchor=Anchor.BEGINNING, batch_windows=False, buffer_update_strategy='immediate')[source]#
Classes
- class Window(*args, settings=None, **kwargs)[source]#
Bases:
BaseTransformerUnit[WindowSettings,AxisArray,AxisArray,WindowTransformer]- Parameters:
settings (Settings | None)
- SETTINGS#
alias of
WindowSettings
- INPUT_SIGNAL = InputStream:unlocated[AxisArray]()#
- OUTPUT_SIGNAL = OutputStream:unlocated[AxisArray](self.num_buffers=32, self.force_tcp=None, self.allow_local=None)#
- class WindowSettings(axis: str | None = None, newaxis: str | None = None, window_dur: float | None = None, window_shift: float | None = None, zero_pad_until: str = 'full', anchor: str | Anchor = <Anchor.BEGINNING: 'beginning'>, batch_windows: bool = False, buffer_update_strategy: Literal['immediate', 'threshold', 'on_demand']='immediate')[source]#
Bases:
Settings- Parameters:
- newaxis: str | None = None#
Name of the axis windows are delimited on, inserted before
axis.None(default) means the published messages carry no window axis: theWindowunit yields one message per window, each exactlywindow_durlong with its own absolute offset. The transformer still emits awinaxis in that case, because a transformer is 1-in/1-out and several windows may complete at once; the unit is what unbundles them.Set
batch_windowsto trade that per-window guarantee for fewer, larger messages.
- batch_windows: bool = False#
Emit all complete windows as one contiguous message (“batcher mode”).
Only meaningful with
newaxis=Noneandwindow_shift == window_dur, where consecutive windows tile the target axis exactly; requiring both is validated at construction.Off by default, because a message of exactly
window_duris what asking for awindow_durmost obviously means – and consumers with a fixed input size (an FFT, a binned aggregation) depend on it. Turn it on to re-chunk a stream purely for throughput, accepting that an emitted message is then a whole-number multiple ofwindow_dur, since one oversized input can complete several windows at once.
- buffer_update_strategy: Literal['immediate', 'threshold', 'on_demand'] = 'immediate'#
When the backlog copies incoming samples into its own memory. See
ezmsg.sigproc.util.buffer.UpdateStrategy."immediate"(default, matchingSamplerandResample) copies on every write. That is what makes the buffer safe behind a cross-process link: ezmsg marshals with pickle protocol 5 out-of-band buffers, somessage.datais a view into a shared-memory slot that the publisher recycles everynum_buffersmessages. Holding the array keeps the Python object alive but not its contents."on_demand"defers the copy, saving ~3 us per message at 256 channels. Only safe when nothing recycles the incoming buffer – i.e. a graph you know is single-process, where messages are passed by reference (put_local) rather than serialized.
- __init__(axis=None, newaxis=None, window_dur=None, window_shift=None, zero_pad_until='full', anchor=Anchor.BEGINNING, batch_windows=False, buffer_update_strategy='immediate')#
- class WindowState[source]#
Bases:
object- buffer: HybridBuffer | None = None#
Backlog of samples awaiting a complete window.
A
HybridBufferwriting into preallocated memory, rather than re-growing one array per message. With 30-sample chunks feeding a 600-sample window, 19 of every 20 calls produce no output, andconcatenate((buffer, new))made each of those copy the whole backlog – ~25 us at 256 channels, 85% of the call. Copying the new chunk into a fixed allocation instead is ~2 us and independent of how much is already buffered.Whether writes copy immediately is
WindowSettings.buffer_update_strategy; the default copies, because incoming message data may be a view into memory the publisher recycles.
- concat_buffer: ndarray[tuple[Any, ...], dtype[_ScalarT]] | SparseArray | None = None#
Fallback backlog for namespaces
HybridBuffercan’t back.pydata/sparse arrays have no item assignment, so they cannot be written into a preallocated buffer; those streams keep the original grow-by-concatenate behaviour. Sparse windowing is not a throughput path.
- out_newaxis: LinearAxis | None = None#
- out_axis: LinearAxis | None = None#
Target axis re-anchored per
anchor; constant for the life of the state.
- class WindowTransformer(*args, **kwargs)[source]#
Bases:
BaseStatefulTransformer[WindowSettings,AxisArray,AxisArray,WindowState]Apply a sliding window along the specified axis to input streaming data. The windowing method is perhaps the most useful and versatile method in ezmsg.sigproc, but its parameterization can be difficult. Please read the argument descriptions carefully.
Several windows can complete on one input, so the transformer – being 1-in/1-out – represents them along a
winaxis. What reaches subscribers depends on the settings:settings
published messages
newaxis="win"one message,
winaxis, N windowsnewaxis=NoneN messages, no
winaxis, each exactlywindow_durnewaxis=None+one message, no
winaxis,batch_windows=TrueN * window_durcontiguous samplesThe last row is “batcher mode”, available only when
window_shift == window_durso that windows tile the target axis exactly. It is the only mode the transformer can produce without awinaxis, because tiling is what makes concatenation lossless.- __init__(*args, **kwargs)[source]#
- Parameters:
axis – The axis along which to segment windows. If None, defaults to the first dimension of the first seen AxisArray. Note: The windowed axis must be an AxisArray.LinearAxis, not an AxisArray.CoordinateAxis.
newaxis – New axis on which windows are delimited, immediately preceding the target windowed axis. The data length along newaxis may be 0 if this most recent push did not provide enough data for a new window. If window_shift is None then the newaxis length will always be 1.
window_dur – The duration of the window in seconds. If None, the function acts as a passthrough and all other parameters are ignored.
window_shift – The shift of the window in seconds. If None (default), windowing operates in “1:1 mode”, where each input yields exactly one most-recent window.
zero_pad_until –
Determines how the function initializes the buffer. Can be one of “input” (default), “full”, “shift”, or “none”. If window_shift is None then this field is ignored and “input” is always used.
”input” (default) initializes the buffer with the input then prepends with zeros to the window size. The first input will always yield at least one output.
”shift” fills the buffer until window_shift. No outputs will be yielded until at least window_shift data has been seen.
”none” does not pad the buffer. No outputs will be yielded until at least window_dur data has been seen.
anchor – Determines the entry in axis that gets assigned 0, which references the value in newaxis. Can be of class
Anchoror a string representation of anAnchor.
- Return type:
None