Skip to content

Commit 422e67f

Browse files
committed
adding brunel network from paper
1 parent a55dffc commit 422e67f

33 files changed

+1128
-0
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"level_of_detail": "exp2syn",
3+
"tau1": 0.1,
4+
"tau2": 2.0,
5+
"erev": 0.0
6+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"level_of_detail": "exp2syn",
3+
"tau1": 0.1,
4+
"tau2": 2.0,
5+
"erev": -80.0
6+
}
7+
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# The EI-network
2+
3+
Network loosely based on the model described in "Dynamics of sparsely connected networks of excitatory
4+
and inhibitory spiking" (Brunel, 2000). Contains 12,000 cells across two populations, one population of excitatory
5+
neurons and another of inhibitory neurons. This network provides the same network with comparable dynamics using
6+
multi-compartmental models (BioNet), glif point-neuron models (PointNet), and population models (PopNet).
7+
8+
## Running the models
9+
10+
The scripts for building the network and running the simulations can be found in each simulators subdirectory. To
11+
build and run a simulation for BioNet:
12+
13+
```bash
14+
$ cd bionet
15+
$ python build_network.py
16+
$ python run_bionet.py config.json
17+
```
18+
19+
And for PointNet (or PopNet) replace "bionet" with "pointnet" (or "popnet").
20+
21+
22+
## Analyzing the results
23+
24+
Unless changed in the *config.json* file, simulation results will be saved to the *output* directory by default. BioNet
25+
and PointNet will produce spike-trains for each neuron. While PopNet will produce the firing-rate dynamics of the
26+
two populations.
27+
28+
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Excitatory/Inhibitory Network for BioNet
2+
3+
## Requirements
4+
5+
* BMTK
6+
* Neuron 7.4+
7+
8+
## Files
9+
* network/ - Circuit file of E/I cells and external network. If folder doesn't exists use the build_network.py script.
10+
* inputs/ - Spike-train files corresponding to the external network used to drive the simulation.
11+
* config.json - simulation and network parameters.
12+
* build_network.py - Used to build the network/ files.
13+
* build_input.py - Used to build the inputs/ file(s).
14+
* run_bionet.py - Script for running the network simulation.
15+
16+
17+
## Building the Network
18+
19+
The Network model files must be built for running the simulation using the build_network.py script. It may take
20+
anywhere between 5-10 minutes to complete and will save all required files in network/ folder.
21+
22+
```bash
23+
$ python build_network.py
24+
```
25+
26+
## Running the Simulation
27+
28+
You can use config.json to change parameters for simulating the network. By default everything recorded during the
29+
simulation is saved in the output/ directory, including a running log.txt to keep track of progress.
30+
31+
```bash
32+
$ python run_bionet.py config.json
33+
```
34+
35+
The network may have problems running on a single computer core. It is recommended to use a computing cluster, or
36+
if running on a single machnie use MPI to run on multtple cores:
37+
```bash
38+
$ mpirun -n <N> nrniv -mpi -python run_bionet.py config.json
39+
```
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import os
2+
import numpy as np
3+
import h5py
4+
5+
from bmtk.utils.io.spike_trains import PoissonSpikesGenerator
6+
from bmtk.builder.aux.node_params import positions_columinar, xiter_random
7+
8+
#input_ids = [n.node_id for n in inputNetwork.nodes()]
9+
10+
input_h5 = h5py.File('network/external_nodes.h5','r')
11+
node_ids = np.array(input_h5['/nodes/external/node_id'],dtype = np.uint)
12+
input_ids = node_ids.tolist()
13+
14+
from bmtk.utils.io.spike_trains import PoissonSpikesGenerator
15+
16+
# Create a Poisson Spike train for all input nodes that fire at a rate of 0.5Hz.
17+
# The time units below is in milliseconds
18+
19+
psg = PoissonSpikesGenerator(gids=input_ids, firing_rate = 2.2, tstart=0.0, tstop=3000.0)
20+
21+
# Save the spike trains
22+
if not os.path.exists('network/source_input/'):
23+
os.makedirs('network/source_input/')
24+
25+
psg.to_hdf5(file_name='inputs/poission_r1000_10in2p2.h5')
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
import os
2+
import numpy as np
3+
4+
from bmtk.builder import NetworkBuilder
5+
from bmtk.utils.io.spike_trains import PoissonSpikesGenerator
6+
from bmtk.builder.auxi.node_params import positions_columinar, xiter_random
7+
from bmtk.analyzer import nodes_table
8+
9+
# Brunel network parameters -------------------------------------------------------------------------
10+
N_exc = 10000 # number of excitatory LIF neurons 80%
11+
N_inh = 2500 # number of inhibitory LIF neurons 20%
12+
n_cells = N_exc + N_inh # total number of internal neurons
13+
N_ext = 100 # number of neurons in the external network
14+
15+
JE = 0.1 # excitatory synaptic strength (mV)
16+
g = 5. # ratio of inhibitory synpatic strength to excitatory synaptic strength (unitless)*************
17+
JI = g*JE # inhibitory synpatic strength (mv)
18+
eps = 0.1 # percentage of all possible target neurons that are connected to any given source
19+
CE = int(eps*N_exc) # number of internal connections with excitatory source neurons
20+
C_ext = CE # number of connections to each internal cell from the input network
21+
n_syn = int(C_ext/N_ext) # number of synapses per neuron in the input network
22+
CI = int(eps*N_inh) # number of internal connections with inhibitory source neurons
23+
C = CE + CI # number of internal connections
24+
tau_e = 20. # membrane time constant of excitatory neurons (ms)
25+
theta = 20. # neuron firing threshold (mV)
26+
Vr = 10. # neuron rest potential (mV)
27+
tau_rp = 2. # refractory period (ms)
28+
D = 1.5 # transmission delay (ms)
29+
v_ext_v_thr_ratio = 100. # ratio of v_ext to v_thr (unitless)***************
30+
eps_ext = C_ext/float(n_cells) # external connection probability
31+
v_thr = theta/(JE*CE*tau_e) # frequency needed for a neuron to reach threshold in absence of feedback
32+
v_ext = v_ext_v_thr_ratio*v_thr # external firing frequency
33+
34+
#-----------------------------------------------------------------------------------------------
35+
36+
def generate_random_positions(N):
37+
'''
38+
Generate N random positions.
39+
N: number of positions to generate
40+
'''
41+
42+
x = np.random.random(N) # x-axis location
43+
y = np.random.random(N) # y-axis location
44+
z = np.random.random(N) # z-axis location
45+
46+
positions = np.column_stack((x, y, z))
47+
48+
return positions
49+
50+
build_recurrent_edges = True
51+
52+
bio_models = {
53+
"Internal_exc": {
54+
'N': N_exc,
55+
'model_type' :'biophysical',
56+
'model_name': 'Scnn1a', 'ei': 'e',
57+
'morphology': 'Scnn1a_473845048_m.swc',
58+
'model_template': 'nml:Cell_472363762.cell.nml'
59+
},
60+
61+
"Internal_inh": {
62+
'N': N_inh,
63+
'model_type' :'biophysical',
64+
'model_name': 'PV1', 'ei': 'i',
65+
'morphology': 'Pvalb_470522102_m.swc',
66+
'model_template': 'nml:Cell_472912177.cell.nml'
67+
}
68+
}
69+
70+
71+
internal = NetworkBuilder("internal")
72+
73+
for model in bio_models:
74+
params = bio_models[model].copy()
75+
internal.add_nodes(**params)
76+
77+
#internal.save_nodes(nodes_file_name='internal_nodes.h5', node_types_file_name='internal_node_types.csv',output_dir='network')
78+
79+
def random_connections(source,target, p = 0.1 ):
80+
81+
sid = source['node_id'] # Get source id
82+
tid = target['node_id'] # Get target id
83+
84+
# Avoid self-connections.
85+
if (sid == tid):
86+
if sid % 1000 == 0:
87+
print(sid)
88+
return None
89+
return np.random.binomial(1,p) #nsyns
90+
91+
if build_recurrent_edges:
92+
# exc --> exc connections
93+
internal.add_edges(source={'ei': 'e'}, target={'ei': 'e'},
94+
connection_rule=random_connections,
95+
connection_params={'p': eps},
96+
dynamics_params='brunel_excitatory.json',
97+
model_template='Exp2Syn',
98+
syn_weight=7.0e-5,
99+
delay=D,
100+
target_sections=['basal','apical'],
101+
distance_range=[0.0, 1e+20])
102+
103+
# exc --> inh connections
104+
internal.add_edges(source={'ei': 'e'}, target={'ei': 'i'},
105+
connection_rule=random_connections,
106+
connection_params={'p': eps},
107+
dynamics_params='brunel_excitatory.json',
108+
model_template='Exp2Syn',
109+
syn_weight=7.0e-5,
110+
delay=D,
111+
target_sections=['somatic','basal'],
112+
distance_range=[0.0, 1e+20])
113+
# inh --> exc connections
114+
internal.add_edges(source={'ei': 'i'}, target={'ei': 'e', 'model_type': 'biophysical'},
115+
connection_rule=random_connections,
116+
connection_params={'p': eps},
117+
dynamics_params='brunel_inhibitory.json',
118+
model_template='Exp2Syn',
119+
syn_weight=17.5e-5,
120+
delay=D,
121+
target_sections=['somatic','basal','apical'],
122+
distance_range=[0.0, 200])
123+
124+
# inh --> inh connections
125+
internal.add_edges(source={'ei': 'i'}, target={'ei': 'i', 'model_type': 'biophysical'},
126+
connection_rule=random_connections,
127+
connection_params={'p': eps},
128+
dynamics_params='brunel_inhibitory.json',
129+
model_template='Exp2Syn',
130+
syn_weight=17.5e-5,
131+
delay=D,
132+
target_sections=['somatic','basal'],
133+
distance_range=[0.0, 1e+20])
134+
135+
internal.build()
136+
137+
print('Saving internal')
138+
internal.save(output_dir='network')
139+
print('Building external connections')
140+
external = NetworkBuilder("external")
141+
external.add_nodes(N=N_ext, model_type='virtual', ei='e')
142+
143+
cm = external.add_edges(source=external.nodes(),
144+
target=internal.nodes(),
145+
connection_rule=random_connections,
146+
connection_params={'p': 0.1},
147+
dynamics_params='AMPA_ExcToExc.json',
148+
model_template='Exp2Syn',
149+
syn_weight = 7.0e-3,
150+
delay=D,
151+
target_sections = ['somatic','basal'],
152+
distance_range=[0.0, 1e+20])
153+
154+
external.build()
155+
print('Saving external')
156+
external.save(output_dir='network')
157+
158+
159+
160+
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
{
2+
"manifest": {
3+
"$BASE_DIR": "${configdir}",
4+
"$OUTPUT_DIR": "$BASE_DIR/output",
5+
"$INPUT_DIR": "$BASE_DIR/inputs",
6+
"$NETWORK_DIR": "$BASE_DIR/network",
7+
"$COMPONENT_DIR": "$BASE_DIR/../../biophys_components"
8+
},
9+
10+
"run": {
11+
"tstop": 3000.0,
12+
"dt": 0.1,
13+
"dL": 20.0,
14+
"spike_threshold": -15,
15+
"nsteps_block": 5000
16+
},
17+
18+
"target_simulator":"NEURON",
19+
20+
"conditions": {
21+
"celsius": 34.0,
22+
"v_init": -80
23+
},
24+
25+
"inputs": {
26+
"external_spikes": {
27+
"input_type": "spikes",
28+
"module": "h5",
29+
"input_file": "$INPUT_DIR/poission_r1000_10in6.h5",
30+
"node_set": "external"
31+
}
32+
},
33+
34+
"output":{
35+
"log_file": "$OUTPUT_DIR/log.txt",
36+
"output_dir": "$OUTPUT_DIR",
37+
"spikes_file": "$OUTPUT_DIR/spikes.h5",
38+
"spikes_file_csv": "$OUTPUT_DIR/spikes.csv"
39+
},
40+
41+
"node_sets": {
42+
"bio_cells": {
43+
"model_type": "biophysical"
44+
}
45+
},
46+
47+
"reports": {
48+
49+
"membrane_potential": {
50+
"cells": [0,2500,5000,7500,10000,12499],
51+
"variable_name": "v",
52+
"module": "membrane_report",
53+
"file_name": "$OUTPUT_DIR/cell_vars.h5",
54+
"sections": "soma",
55+
"enabled": true
56+
}
57+
},
58+
59+
"components": {
60+
"morphologies_dir": "$COMPONENT_DIR/morphologies",
61+
"synaptic_models_dir": "$COMPONENT_DIR/synaptic_models",
62+
"mechanisms_dir":"$COMPONENT_DIR/mechanisms",
63+
"biophysical_neuron_models_dir": "$COMPONENT_DIR/biophysical_neuron_templates/nml",
64+
"point_neuron_models_dir": "$COMPONENT_DIR/point_neuron_templates"
65+
},
66+
67+
"networks": {
68+
"nodes": [
69+
{
70+
"nodes_file": "$NETWORK_DIR/internal_nodes.h5",
71+
"node_types_file": "$NETWORK_DIR/internal_node_types.csv"
72+
},
73+
{
74+
"nodes_file": "$NETWORK_DIR/external_nodes.h5",
75+
"node_types_file": "$NETWORK_DIR/external_node_types.csv"
76+
}
77+
],
78+
79+
"edges": [
80+
{
81+
"edges_file": "$NETWORK_DIR/internal_internal_edges.h5",
82+
"edge_types_file": "$NETWORK_DIR/internal_edge_types.csv"
83+
},
84+
{
85+
"edges_file": "$NETWORK_DIR/external_internal_edges.h5",
86+
"edge_types_file": "$NETWORK_DIR/external_edge_types.csv"
87+
}
88+
]
89+
}
90+
}
Binary file not shown.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import sys, os
2+
3+
from bmtk.simulator import bionet
4+
5+
6+
def run(config_file):
7+
conf = bionet.Config.from_json(config_file, validate=True)
8+
conf.build_env()
9+
10+
net = bionet.BioNetwork.from_config(conf)
11+
sim = bionet.BioSimulator.from_config(conf, network=net)
12+
sim.run()
13+
bionet.nrn.quit_execution()
14+
15+
from bmtk.analyzer.visualization.spikes import plot_spikes, plot_rates
16+
plot_spikes('network/nodes.h5', 'network/node_types.csv', 'output/spikes.h5', save_as = 'rasters/plot.png',group_key='model_name')
17+
18+
if __name__ == '__main__':
19+
if __file__ != sys.argv[-1]:
20+
run(sys.argv[-1])
21+
else:
22+
run('config_A.json')
23+
# run('config_je1e80g3jext5e-4_10in50.json')
24+

0 commit comments

Comments
 (0)