firing_rate#
- class braintools.metric.firing_rate(spikes, width, dt=None)#
Calculate the smoothed population firing rate from spike data.
Computes the time-varying population firing rate by averaging spike counts across neurons and applying temporal smoothing with a rectangular window. This provides a measure of the overall activity level of the neural population over time.
The instantaneous firing rate at time \(t\) is calculated as:
\[r(t) = \frac{1}{N} \sum_{i=1}^{N} s_i(t)\]where \(N\) is the number of neurons and \(s_i(t)\) is the spike indicator for neuron \(i\) at time \(t\). The rate is then smoothed using a rectangular window:
\[\bar{r}(t) = \frac{1}{T} \int_{t-T/2}^{t+T/2} r(\tau) d\tau\]where \(T\) is the window width.
- Parameters:
spikes (
Array|ndarray|bool|number|bool|int|float|complex|Quantity) – Spike matrix with shape(n_time_steps, n_neurons)where each element indicates spike occurrence (typically 0 or 1). Non-zero values represent spikes at the corresponding time step and neuron.width (
float|Quantity) – Width of the smoothing window. If a float, interpreted as time units consistent withdt(assumed seconds when both are plain floats, so the rate comes out in Hz). If a brainunit.Quantity, should have time dimensions (e.g., milliseconds). Larger values produce more smoothing.dt (
float|Quantity) – Time step between successive samples in the spike matrix. If None, uses the default time step from the brainstate environment (brainstate.environ.get_dt()). A plain float is assumed to be in seconds.
- Returns:
Smoothed population firing rate with shape
(n_time_steps,). Values are in Hz (spikes per second) when using appropriate time units. The smoothing may introduce edge effects at the beginning and end of the time series.- Return type:
numpy.ndarray
Examples
Calculate firing rate from spike data:
>>> import numpy as np >>> import brainunit as u >>> import braintools as braintools >>> # Create sample spike data (100 time steps, 50 neurons) >>> np.random.seed(42) >>> spikes = (np.random.random((100, 50)) < 0.1).astype(float) >>> dt = 0.1 * u.ms # 0.1 ms time steps >>> window_width = 5 * u.ms # 5 ms smoothing window >>> rates = braintools.metric.firing_rate(spikes, window_width, dt) >>> print(f"Rate shape: {rates.shape}") >>> print(f"Mean rate: {np.mean(rates):.2f} Hz")
Compare different smoothing window sizes:
>>> narrow_rates = braintools.metric.firing_rate(spikes, 2*u.ms, dt) >>> wide_rates = braintools.metric.firing_rate(spikes, 10*u.ms, dt) >>> # narrow_rates will be more variable, wide_rates more smooth
Plot the results:
>>> import matplotlib.pyplot as plt >>> time = np.arange(len(rates)) * float(dt.to_decimal(u.ms)) >>> plt.plot(time, rates, label='Population rate') >>> plt.xlabel('Time (ms)') >>> plt.ylabel('Firing rate (Hz)') >>> plt.title('Population Firing Rate') >>> plt.show()
Notes
This method is adapted from the Brian2 simulator and uses convolution with a rectangular window for smoothing. The window size is automatically adjusted to be odd-sized for symmetric smoothing.
Edge effects occur at the beginning and end of the time series due to the convolution operation. For critical applications, consider using alternative boundary conditions or trimming the results.
The result is always expressed in Hz. When
width/dtarebrainunit.Quantityobjects the conversion is exact for any time unit. When they are plain floats they are assumed to be in seconds, so the returned rate ismean_spike_fraction / window_duration_seconds. Passwidthanddtin the same time unit.widthanddtmust be concrete (static) values: the window length is computed with Pythonint, so this function is usable insidejitonly whenwidth/dtare static.See also
braintools.metric.raster_plotExtract spike times for visualization
numpy.convolveUnderlying convolution operation for smoothing
jax.numpy.meanPopulation averaging operation
References