ezmsg.simbiophys.system.velocity2spike#

Convert polar velocity coordinates to simulated spike waveforms.

This module provides a system that encodes velocity (in polar coordinates) into spike activity using a cosine tuning model, then generates spike events and inserts realistic waveforms.

Pipeline:

polar coords (magnitude, angle) -> cosine encoder -> clip -> Poisson events -> waveforms

Note

This system expects polar coordinates as input. Use CoordinateSpaces with mode=CART2POL upstream to convert Cartesian velocity (vx, vy) to polar coordinates (magnitude, angle).

See also

ezmsg.simbiophys.system.velocity2lfp: Velocity to LFP encoding. ezmsg.simbiophys.system.velocity2ecephys: Combined spike + LFP encoding.

Classes

class Velocity2Spike(*args, settings=None, **kwargs)[source]#

Bases: Collection

Encode velocity (polar coordinates) into simulated spike waveforms.

This system converts polar velocity coordinates into multi-channel spike activity:

  1. Cosine tuning: Each channel has a preferred direction; firing rate is modulated by the cosine of the angle between velocity and preferred direction, scaled by velocity magnitude.

  2. Poisson spike generation: Converts firing rates to discrete spike events using an inhomogeneous Poisson process.

  3. Waveform insertion: Inserts realistic spike waveforms at event times.

Input:

AxisArray with shape (N, 2) containing polar velocity coordinates. Dimension 0 is time, dimension 1 is [magnitude, angle]. Use CoordinateSpaces(mode=CART2POL) upstream if starting from (vx, vy).

Output:

AxisArray with shape (M, output_ch) containing spike waveforms at output_fs sampling rate.

Parameters:

settings (Settings | None)

SETTINGS#

alias of Velocity2SpikeSettings

INPUT_SIGNAL = InputStream:unlocated[<class 'ezmsg.util.messages.axisarray.AxisArray'>]()#
RATE_ENCODER = <ezmsg.simbiophys.cosine_encoder.CosineEncoderUnit object>#
CLIP_RATE = <ezmsg.sigproc.math.clip.Clip object>#
SPIKE_EVENT = <ezmsg.event.poissonevents.PoissonEventUnit object>#
WAVEFORMS = <ezmsg.event.kernel_insert.SparseKernelInserterUnit object>#
OUTPUT_SIGNAL = OutputStream:unlocated[<class 'ezmsg.util.messages.axisarray.AxisArray'>](self.num_buffers=32, self.force_tcp=False)#
configure()[source]#

A lifecycle hook that runs when the Collection is instantiated. This is the best place to call Unit.apply_settings() on each member Unit of the Collection.

Return type:

None

network()[source]#

Override this method and have the definition return a NetworkDefinition which defines how InputStream and OutputStream from member Unit s will be connected.

Return type:

Iterable[Tuple[Union[Stream, str], Union[Stream, str]]]

class Velocity2SpikeSettings(output_fs=30000.0, output_ch=256, baseline_rate=10.0, modulation_depth=0.06369426751592357, min_rate=0.0, seed=6767)[source]#

Bases: Settings

Settings for Velocity2Spike.

Parameters:
output_fs: float = 30000.0#

Output sampling rate in Hz.

output_ch: int = 256#

Number of output channels (simulated electrodes).

baseline_rate: float = 10.0#

Baseline firing rate in Hz.

modulation_depth: float = 0.06369426751592357#

Directional modulation depth in Hz per (pixel/second). At max velocity (~314 px/s), this gives ~20 Hz modulation.

min_rate: float = 0.0#

Minimum firing rate (Hz). Rates are clipped to this value.

seed: int = 6767#

Random seed for reproducible preferred directions and waveform selection.

__init__(output_fs=30000.0, output_ch=256, baseline_rate=10.0, modulation_depth=0.06369426751592357, min_rate=0.0, seed=6767)#
Parameters:
Return type:

None

class Velocity2SpikeSettings(output_fs=30000.0, output_ch=256, baseline_rate=10.0, modulation_depth=0.06369426751592357, min_rate=0.0, seed=6767)[source]#

Bases: Settings

Settings for Velocity2Spike.

Parameters:
output_fs: float = 30000.0#

Output sampling rate in Hz.

output_ch: int = 256#

Number of output channels (simulated electrodes).

baseline_rate: float = 10.0#

Baseline firing rate in Hz.

modulation_depth: float = 0.06369426751592357#

Directional modulation depth in Hz per (pixel/second). At max velocity (~314 px/s), this gives ~20 Hz modulation.

min_rate: float = 0.0#

Minimum firing rate (Hz). Rates are clipped to this value.

seed: int = 6767#

Random seed for reproducible preferred directions and waveform selection.

__init__(output_fs=30000.0, output_ch=256, baseline_rate=10.0, modulation_depth=0.06369426751592357, min_rate=0.0, seed=6767)#
Parameters:
Return type:

None

class Velocity2Spike(*args, settings=None, **kwargs)[source]#

Bases: Collection

Encode velocity (polar coordinates) into simulated spike waveforms.

This system converts polar velocity coordinates into multi-channel spike activity:

  1. Cosine tuning: Each channel has a preferred direction; firing rate is modulated by the cosine of the angle between velocity and preferred direction, scaled by velocity magnitude.

  2. Poisson spike generation: Converts firing rates to discrete spike events using an inhomogeneous Poisson process.

  3. Waveform insertion: Inserts realistic spike waveforms at event times.

Input:

AxisArray with shape (N, 2) containing polar velocity coordinates. Dimension 0 is time, dimension 1 is [magnitude, angle]. Use CoordinateSpaces(mode=CART2POL) upstream if starting from (vx, vy).

Output:

AxisArray with shape (M, output_ch) containing spike waveforms at output_fs sampling rate.

Parameters:

settings (Settings | None)

SETTINGS#

alias of Velocity2SpikeSettings

INPUT_SIGNAL = InputStream:unlocated[<class 'ezmsg.util.messages.axisarray.AxisArray'>]()#
RATE_ENCODER = <ezmsg.simbiophys.cosine_encoder.CosineEncoderUnit object>#
CLIP_RATE = <ezmsg.sigproc.math.clip.Clip object>#
SPIKE_EVENT = <ezmsg.event.poissonevents.PoissonEventUnit object>#
WAVEFORMS = <ezmsg.event.kernel_insert.SparseKernelInserterUnit object>#
OUTPUT_SIGNAL = OutputStream:unlocated[<class 'ezmsg.util.messages.axisarray.AxisArray'>](self.num_buffers=32, self.force_tcp=False)#
configure()[source]#

A lifecycle hook that runs when the Collection is instantiated. This is the best place to call Unit.apply_settings() on each member Unit of the Collection.

Return type:

None

network()[source]#

Override this method and have the definition return a NetworkDefinition which defines how InputStream and OutputStream from member Unit s will be connected.

Return type:

Iterable[Tuple[Union[Stream, str], Union[Stream, str]]]