unitary_LFP

Contents

unitary_LFP#

class braintools.metric.unitary_LFP(times, spikes, spike_type, xmax=0.2, ymax=0.2, va=200.0, lambda_=0.2, sig_i=2.1, sig_e=3.1500000000000004, location='soma layer', seed=None)#

Calculate unitary local field potentials (uLFP) from spike train data.

Computes the contribution of spiking neurons to local field potentials using a kernel-based method. This approach models the spatial distribution of neurons, axonal conduction delays, and layer-specific amplitude scaling to estimate the LFP signal recorded at an electrode positioned at the center of the neural population.

The method implements a biophysically-motivated model where each spike contributes to the LFP through a Gaussian kernel with amplitude and delay determined by the neuron’s distance from the recording electrode:

\[\text{uLFP}(t) = \sum_{i,s} A_i \exp\left(-\frac{(t - t_s - \delta_i)^2}{2\sigma^2}\right)\]

where \(A_i\) is the distance-dependent amplitude, \(t_s\) is the spike time, \(\delta_i\) is the conduction delay, and \(\sigma\) is the kernel width (different for excitatory and inhibitory neurons).

Parameters:
  • times (Array | ndarray | bool | number | bool | int | float | complex | Quantity) – Time points of the recording with shape (n_time_steps,). These represent the temporal sampling points for the LFP calculation, typically in milliseconds.

  • spikes (Array | ndarray | bool | number | bool | int | float | complex | Quantity) – Binary spike matrix with shape (n_time_steps, n_neurons) where non-zero values indicate spike occurrences. Each element spikes[t, i] represents whether neuron i fired at time t.

  • spike_type (str) –

    Type of neurons generating the spikes:

    • 'exc': Excitatory neurons (positive contribution)

    • 'inh': Inhibitory neurons (can be positive or negative depending on layer)

  • xmax (Array | ndarray | bool | number | bool | int | float | complex | Quantity) – Spatial extent of the neuron population in the x-dimension (mm). Neurons are randomly distributed within a rectangle of size xmax × ymax centered at the electrode position.

  • ymax (Array | ndarray | bool | number | bool | int | float | complex | Quantity) – Spatial extent of the neuron population in the y-dimension (mm).

  • va (Array | ndarray | bool | number | bool | int | float | complex | Quantity) – Axonal conduction velocity in mm/s. Determines the delay between spike occurrence and its contribution to the LFP. Typical values range from 100-500 mm/s for cortical neurons.

  • lambda (float, default=0.2) – Spatial decay constant in mm. Controls how quickly the LFP amplitude decreases with distance from the electrode. Smaller values result in more localized LFP signals.

  • sig_i (Array | ndarray | bool | number | bool | int | float | complex | Quantity) – Standard deviation of the inhibitory neuron kernel in ms. Determines the temporal width of inhibitory contributions to the LFP.

  • sig_e (Array | ndarray | bool | number | bool | int | float | complex | Quantity) – Standard deviation of the excitatory neuron kernel in ms. Default is 2.1 * 1.5, making excitatory contributions broader than inhibitory ones.

  • location (str) –

    Recording electrode location relative to the cortical layers:

    • 'soma layer': At the soma level (excitatory: +0.48, inhibitory: +3.0)

    • 'deep layer': Below soma layer (excitatory: -0.16, inhibitory: -0.2)

    • 'superficial layer': Above soma layer (excitatory: +0.24, inhibitory: -1.2)

    • 'surface': At cortical surface (excitatory: -0.08, inhibitory: +0.3)

    Values in parentheses indicate the base amplitude scaling factors.

  • seed (int | Array | ndarray) – Random seed for reproducible neuron positioning. If None, positions are generated randomly. Use for consistent results across runs.

Returns:

Unitary LFP signal with shape (n_time_steps,) representing the contribution of the specified neuron population to the local field potential. Units are typically in microvolts (μV).

Return type:

Array

Raises:
  • ValueError – If spike_type is not ‘exc’ or ‘inh’, if spikes is not 2D, or if times and spikes have incompatible shapes.

  • NotImplementedError – If location is not one of the supported options.

Notes

This implementation focuses on spike-triggered LFP contributions and does not account for:

  • Subthreshold synaptic currents

  • Dendritic voltage-dependent ion channels

  • Volume conduction effects from distant sources

  • Frequency-dependent propagation

For realistic LFP modeling, combine contributions from both excitatory and inhibitory populations and consider using multiple electrode locations.

The neuron positions are randomly generated within the specified spatial bounds, and the electrode is positioned at the center (xmax/2, ymax/2). Each neuron’s contribution is weighted by distance and scaled according to the recording location and neuron type.

Examples

Calculate LFP from excitatory and inhibitory populations:

>>> import brainstate as brainstate
>>> import jax.numpy as jnp
>>> import braintools as braintools
>>> # Set up simulation parameters
>>> brainstate.random.seed(42)
>>> n_time, n_exc, n_inh = 1000, 100, 25
>>> dt = 0.1  # ms
>>> times = jnp.arange(n_time) * dt
>>> # Generate sparse random spike trains
>>> exc_spikes = (brainstate.random.random((n_time, n_exc)) < 0.02).astype(float)
>>> inh_spikes = (brainstate.random.random((n_time, n_inh)) < 0.04).astype(float)
>>> # Calculate LFP components
>>> lfp_exc = braintools.metric.unitary_LFP(times, exc_spikes, 'exc', seed=42)
>>> lfp_inh = braintools.metric.unitary_LFP(times, inh_spikes, 'inh', seed=42)
>>> total_lfp = lfp_exc + lfp_inh
>>> print(f"LFP shape: {total_lfp.shape}")
>>> print(f"LFP range: {total_lfp.min():.3f} to {total_lfp.max():.3f}")

Compare different recording locations:

>>> # Same spike data, different recording depths
>>> lfp_soma = braintools.metric.unitary_LFP(times, exc_spikes, 'exc',
...                                  location='soma layer')
>>> lfp_deep = braintools.metric.unitary_LFP(times, exc_spikes, 'exc',
...                                  location='deep layer')
>>> lfp_surface = braintools.metric.unitary_LFP(times, exc_spikes, 'exc',
...                                      location='surface')

Analyze the effect of spatial parameters:

>>> # Larger population area
>>> lfp_large = braintools.metric.unitary_LFP(times, exc_spikes, 'exc',
...                                   xmax=0.5, ymax=0.5)
>>> # Faster conduction velocity
>>> lfp_fast = braintools.metric.unitary_LFP(times, exc_spikes, 'exc', va=500.0)

Visualize the results:

>>> import matplotlib.pyplot as plt
>>> plt.figure(figsize=(10, 6))
>>> plt.plot(times[:500], total_lfp[:500], 'k-', linewidth=1)
>>> plt.xlabel('Time (ms)')
>>> plt.ylabel('LFP Amplitude (μV)')
>>> plt.title('Simulated Local Field Potential')
>>> plt.grid(True, alpha=0.3)
>>> plt.show()

See also

braintools.metric.firing_rate

Calculate population firing rates

braintools.metric.raster_plot

Extract spike timing data

jax.numpy.convolve

Alternative smoothing approach for LFP

References