Skip to content

Brian2 Library and Drosophila Connectome LIF Model

Brian2 Library Basics

Introduction to Brian2

Brian2 is a Python library for simulating spiking neural networks. It uses differential equations to describe the dynamics of neurons and synapses.

Core Concepts

1. Units System

Brian2 uses a physical unit system to ensure dimensional correctness:

python
from brian2 import *
mV = 1e-3 * volt  # millivolt
ms = 1e-3 * second  # millisecond
Hz = 1/second  # hertz
Mohm = 1e6 * ohm  # megaohm
uF = 1e-6 * farad  # microfarad

2. NeuronGroup

Used to create a group of neurons of the same type:

python
eqs = """
dv/dt = (g - (v - V_resting)) / T_mbr : volt
dg/dt = -g / tau : volt
ref : second
"""
G = NeuronGroup(
    N,  # Number of neurons
    eqs,  # Differential equations
    method="exact",  # Numerical method
    threshold="v>V_threshold",  # Firing threshold condition
    reset=eq_reset,  # Reset condition after firing
    refractory='ref',  # Refractory period
)

Key Parameters:

  • eqs: Differential equations defining neuron dynamics
  • method: Numerical integration method (e.g., "exact", "euler", "rk4")
  • threshold: Condition for triggering action potential
  • reset: Variable reset after firing
  • refractory: Refractory period (time during which neuron doesn't respond to stimuli after firing)

3. Synapses

Define connections between neurons:

python
S = Synapses(
    G, G,  # Source and target neuron groups
    "w: 1",  # Synaptic weight variable
    on_pre="g_post += w*W_syn",  # Operation triggered by presynaptic events
    delay=T_dly  # Synaptic delay
)
S.connect(i=source_indices, j=target_indices)  # Establish connections
S.w = weights  # Set weights

4. Monitors

Used to record data during simulation:

python
# Record spike events
spike_mon = SpikeMonitor(neuron_group)

# Record state variables (e.g., membrane potential)
state_mon = StateMonitor(neuron_group, 'v', record=True)

# Run simulation
run(sim_time)

# Extract data
spike_times = spike_mon.t  # Spike times
spike_indices = spike_mon.i  # Indices of firing neurons

5. PoissonInput

Generate Poisson random input stimuli:

python
P = PoissonInput(
    target_group,  # Target neuron group
    "v",  # Target variable
    1,  # Number of inputs per neuron
    40*Hz,  # Frequency
    (V_threshold - V_resting)*3  # Input amplitude
)

6. Numerical Method Selection

python
# Use numpy backend (slower but better compatibility)
prefs.codegen.target = "numpy"

# Default: use C++ backend (faster)
# No need to set, default automatic selection

Project Architecture Analysis

File Structure

fly-lif-template/
├── main.py              # Main program entry
├── common.py            # Neuron grouping and common functions
├── README.md            # Project documentation
└── fly_lif/            # Core modules
    ├── __init__.py
    ├── structures.py    # Data structure definitions
    ├── process_csv.py   # CSV file processing
    ├── neuron_types.py  # Neuron type prediction
    ├── sort_connectome.py  # Connectome sorting
    └── apis.py         # API interface

Module Responsibilities

1. structures.py - Data Structures

  • Connectome: Connectome graph structure (neurons as vertices, synapses as edges)
  • Neuron: Neuron information (name, transmitters, flags, etc.)
  • Synapse: Synapse information (source neuron, target neuron, weight, transmitter, etc.)
  • NeuronFlag: Neuron flag bits (using IntFlag enumeration)

2. process_csv.py - CSV Processing

  • import_csv_connection_2(): Import connectome data from CSV files
  • Supports importing connections first, then classification information

3. neuron_types.py - Neuron Types

  • predict_neuron_transmitters(): Predict neuron type based on output transmitters
  • modify_synapses_sign(): Modify synapse sign (excitatory/inhibitory) based on neuron type

4. sort_connectome.py - Connectome Sorting

  • sort_connectome(): Sort connectome by neuron flags

5. common.py - Common Functions

  • import_target_neurons(): Import and label target neurons
  • mark_downstream_neurons(): Label downstream neurons
  • get_neuron_groups(): Get indices of different neuron groups

Core Code Analysis

1. LIF Neuron Model Equations

The LIF model defined in the run_simulation() function in main.py:

python
eqs = """
dv/dt = (g - (v - V_resting)) / T_mbr : volt
dg/dt = -g / tau : volt
ref : second
"""

Equation Analysis:

  • dv/dt: Rate of change of membrane potential
    • g: Synaptic input (summed synaptic current)
    • v - V_resting: Deviation from resting potential
    • T_mbr = C_mbr * R_mbr: Membrane time constant (membrane capacitance × membrane resistance)
  • dg/dt: Synaptic current decay (exponential decay)
  • ref: Refractory period time

Parameter Settings:

python
V_resting = -52 * mV      # Resting potential
V_reset = V_resting       # Reset potential (equals resting potential)
V_threshold = -45 * mV    # Firing threshold
R_mbr = 10 * Mohm         # Membrane resistance
T_refractory = 2.2 * ms   # Refractory period
C_mbr = 0.002 * uF        # Membrane capacitance
T_mbr = C_mbr * R_mbr     # Membrane time constant = 20 ms
tau = 5 * ms              # Synaptic time constant
T_dly = 1.8 * ms          # Synaptic delay
W_syn = 0.275 * mV        # Synaptic weight baseline value

2. Neuron Group Creation

python
G = NeuronGroup(
    len(connectome.neurons),  # Total number of neurons
    eqs,
    method="exact",
    threshold="v>V_threshold",
    reset=eq_reset,  # v = V_reset; g = 0*mV
    refractory='ref',
)
G.ref = T_refractory
G.v = V_resting

3. Synapse Connection Establishment

python
# Get connection information from connectome
S_conn = connectome.get_synapses_connection()
# Returns (i, j, w): source indices, target indices, weights

S = Synapses(G, G, "w: 1", on_pre="g_post += w*W_syn", delay=T_dly)
S.connect(i=S_conn[0], j=S_conn[1])  # Establish connections
S.w = S_conn[2]  # Set weights

Key Points:

  • on_pre: When presynaptic neuron fires, execute g_post += w*W_syn
  • w can be positive (excitatory) or negative (inhibitory)
  • delay: Synaptic delay, simulating signal transmission time

4. Input Stimulation

python
# Global background noise
P_all = PoissonInput(G, "v", 1, 5*Hz, (V_threshold - V_resting)*0.5)

# Target neuron stimulation
P0 = PoissonInput(target_neurons_subgroup, "v", 1, 40*Hz, 
                  (V_threshold - V_resting)*3)

# Downstream neuron stimulation
P1 = PoissonInput(downstream1_subgroup, "v", 1, 7.5*Hz, 
                  (V_threshold - V_resting)*1.5)

Parameter Description:

  • Frequency: Average frequency of Poisson process
  • Amplitude: Stimulus strength relative to threshold
    • (V_threshold - V_resting)*3 represents 3 times the threshold-resting potential difference

5. Data Recording

python
target_neurons_mon = SpikeMonitor(target_neurons_subgroup)
downstream_1_mon = SpikeMonitor(downstream1_subgroup)
downstream_2_mon = SpikeMonitor(downstream2_subgroup)

run(sim_time)  # Run simulation

# Extract data
spike_times = np.array(target_neurons_mon.t / ms, dtype=np.float32)
spike_indices = np.array(target_neurons_mon.i, dtype=np.int32)

LIF Neuron Model

Model Principles

The Leaky Integrate-and-Fire (LIF) model is one of the simplest spiking neuron models:

  1. Integration Phase: Membrane potential integrates according to input current
  2. Leak: Membrane potential decays toward resting potential
  3. Firing: When membrane potential exceeds threshold, an action potential is generated
  4. Reset: After firing, membrane potential resets and enters refractory period

Mathematical Model

Standard LIF Equation:

τ_m * dv/dt = -(v - V_rest) + R_m * I_syn(t)

Form Used in This Project:

dv/dt = (g - (v - V_resting)) / T_mbr
dg/dt = -g / tau

Where:

  • g is the sum of synaptic inputs (after decay)
  • tau controls the decay rate of synaptic current
  • T_mbr controls the integration and leak rate of membrane potential

Firing Mechanism

python
threshold="v>V_threshold"  # Trigger when v exceeds threshold
reset="v = V_reset; g = 0*mV"  # Reset after firing
refractory='ref'  # No response during refractory period

Connectome Processing Pipeline

1. Data Import

python
connectome = import_csv_connection_2(
    "connections.csv",      # Connection data
    "classification.csv"    # Neuron classification data
)

connections.csv Format:

Source neuron, Target neuron, Neuropil, Weight, Transmitter

classification.csv Format:

Neuron name, flow, super_cls, cls, sub_cls, cell_type, ...

2. Neuron Labeling

python
# Label target neurons
import_target_neurons(connectome, "target_neurons.csv")

# Label downstream neurons
mark_downstream_neurons(connectome)
# - First-order downstream: neurons directly receiving target neuron outputs
# - Second-order downstream: neurons receiving first-order downstream outputs

# Label functional nuclei (optional)
mark_functional_nuclei(connectome, "functional_nuclei.csv")

3. Neuron Type Prediction

python
predict_neuron_transmitters(connectome)
# Predict neuron type (excitatory/inhibitory) based on output transmitters

modify_synapses_sign(connectome)
# Modify synapse weight signs based on neuron type
# - All output synapses of inhibitory neurons have negative weights
# - Output synapses of excitatory neurons have positive weights

Transmitter Classification:

python
excitatory_transmitters = ["DA", "ACH", "SER", "OCT"]  # Excitatory
inhibitory_transmitters = ["GABA", "GLUT"]            # Inhibitory

4. Connectome Sorting

python
sort_connectome(connectome)
# Sort by neuron flags, grouping neurons of the same type together

5. Get Neuron Groups

python
groups = get_neuron_groups(connectome)
target_neurons_ids = groups['target_neurons']
downstream_1_ids = groups['downstream_1']
downstream_2_ids = groups['downstream_2']

Simulation Workflow

Complete Simulation Flow

python
# 1. Import connectome
connectome = import_connectome()

# 2. Get neuron groups
groups = get_neuron_groups(connectome)

# 3. Run simulation
results = run_simulation(
    connectome, 
    target_neurons_ids, 
    downstream_1_ids, 
    downstream_2_ids,
    with_P0=True,   # Whether to add stimulation to target neurons
    with_P1=True,   # Whether to add stimulation to first-order downstream
    with_P2=False   # Whether to add stimulation to second-order downstream
)

# 4. Data analysis and visualization
# - Calculate firing rates
# - Plot spike raster
# - Save data to CSV

Simulation Parameters

ParameterValueDescription
V_resting-52 mVResting potential
V_threshold-45 mVFiring threshold (+7 mV relative to rest)
R_mbr10 MΩMembrane resistance
C_mbr0.002 μFMembrane capacitance
T_mbr20 msMembrane time constant
tau5 msSynaptic time constant
T_refractory2.2 msRefractory period
T_dly1.8 msSynaptic delay
W_syn0.275 mVSynaptic weight baseline value

Data Output

Spike Data:

  • dfb_spikes.csv: Target neuron spike times
  • downstream_1_spikes.csv: First-order downstream spike times
  • downstream_2_spikes.csv: Second-order downstream spike times

Format:

Neuron ID, Spike Times (ms)
0, 10.5, 25.3, 40.1
1, 15.2, 30.8

Visualization:

  • firing_activity.png: Spike firing activity plot (time vs neuron index)

Key Concepts Summary

1. Neuron Flag System

Use NeuronFlag (IntFlag) to label neuron types:

python
IS_TARGET = NeuronFlag.IS_GROUP_1          # Target neurons
IS_DOWNSTREAM_1 = NeuronFlag.IS_GROUP_2    # First-order downstream
IS_DOWNSTREAM_2 = NeuronFlag.IS_GROUP_3     # Second-order downstream
IS_FUNCTIONALNUCLEI = NeuronFlag.IS_GROUP_4  # Functional nuclei
IS_INHIBITORY = NeuronFlag.IS_INHIBITORY   # Inhibitory neurons

Usage:

python
neuron.flag |= IS_TARGET  # Add flag
if neuron.flag & IS_TARGET:  # Check flag
    # ...

2. Synaptic Weight Signs

  • Excitatory synapses: w > 0, increase target neuron membrane potential
  • Inhibitory synapses: w < 0, decrease target neuron membrane potential
  • Weight sign is determined by the presynaptic neuron type

3. Connection Merging

When multiple connections exist between the same pair of neurons, they are merged into one:

python
# Merging rule:
weight_signed = sum(all connection weight_signed values)
weight = abs(weight_signed)

4. Refractory Period Mechanism

During a period after firing (refractory period), the neuron does not respond to any input, preventing excessive firing:

python
refractory='ref'  # Use ref variable to control refractory period
G.ref = T_refractory  # Set refractory period time

5. Synaptic Delay

Simulates signal transmission delay:

python
delay=T_dly  # 1.8 ms synaptic delay

6. Data Filtering

The code filters out neurons that did not fire:

python
# Only keep firing neurons for subsequent analysis
target_neurons_valid_ids = []
for i, neuron_id in enumerate(target_neurons_ids):
    spike_mask = target_neurons_spike_i == i
    if np.any(spike_mask):  # If fired
        target_neurons_valid_ids.append(neuron_id)

7. Firing Rate Calculation

python
firing_rate = total_spikes / num_neurons / sim_time
# Note: This includes silent neurons (denominator is all neurons)

References

  1. Brian2 Official Documentation: https://brian2.readthedocs.io/
  2. LIF Model: https://en.wikipedia.org/wiki/Biological_neuron_model
  3. Drosophila Connectome: FlyWire Project

Powered by VitePress | Copyright © 2025-present Yongqi Li

Click the lyric to change