-
Notifications
You must be signed in to change notification settings - Fork 1
/
demo_LFP-kernel.hoc
198 lines (145 loc) · 4.89 KB
/
demo_LFP-kernel.hoc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
//
// Read spike data from spiking neuron network simulations
// - draw rasterplot for selected cells
// - distribute cells randomly on a 4mm x 4mm plane
// - calculate LFP with the kernel method
//
// Written by Alain Destexhe, CNRS, 2020
//
load_file("nrngui.hoc")
// 1. read data in vectors
N = 5000 // nb of cells to consider
Ne = 4000 // nb of excitatory cells
Ni = 1000 // nb of inhibitory cells
NSe = 10133 // nb of excitatory spikes
NSi = 9728 // nb of inhibitory spikes
totspikes = NSe+NSi // total nb of spikes
tmin = 9000 // min time (to skip)
tmax = 1000 // max time
objref Spikes[N] // vectors to store spikes
for i=0,N-1 {
Spikes[i] = new Vector(2500)
}
double nspikes[N] // vector to store the nb of spike of each neuron
ropen("brunel_exc.txt") // open file for excitatory cells
for i=0,NSe-1 {
ncell = fscan() // read next cell spiking
time = 1000 * fscan()-tmin // read next spike time
if(ncell<N) {
j = nspikes[ncell]
Spikes[ncell].set(j,time) // store spike time
nspikes[ncell] = j+1
}
}
ropen("brunel_inh.txt") // open file for inhibitory cells
for i=0,NSi-1 {
ncell = Ne + fscan() // read next cell spiking
time = 1000 * fscan()-tmin // read next spike time
if(ncell<N) {
j = nspikes[ncell]
Spikes[ncell].set(j,time) // store spike time
nspikes[ncell] = j+1
}
}
// 2. draw raster
Nmin = 0 // first cell to draw in rasterplot
Nmax = N-1 // last cell to draw in rasterplot
Nstp = 10 // step cell to draw
objectvar g1 // create graph
g1 = new Graph()
g1.size(0,tmax,0,N+1)
for (i=Nmin;i<=Nmax;i=i+Nstp) { // loop on cells
for j=0,nspikes[i]-1 { // loop on spikes
time = Spikes[i].get(j) // get spike time
if(i<Ne) {
g1.mark(time,i+1,"O",3,3,1) // draw exc spike
} else {
g1.mark(time,i+1,"O",3,2,1) // draw inh spike
}
}
}
g1.flush()
// 3. distribute cells in a 2D grid
xmax = 0.2 // size of the array (in mm)
ymax = 0.2
double x[N],y[N] // create vectors for coordinates
objref rnd // create random generator
rnd = new Random()
for i=0,N-1 { // calculate coordinates to distribute neurons
x[i] = rnd.uniform(0,xmax)
y[i] = rnd.uniform(0,ymax)
// if(i<10) print "cell ",i," , x,y=",x[i],y[i]
}
// 4. calculate LFP
//
// Table of respective amplitudes:
// Layer amp_i amp_e
// deep -2 -1.6
// soma 30 4.8
// sup -12 2.4
// surf 3 -0.8
//
dt = 0.1 // time resolution
npts = tmax/dt // nb points in LFP vector
objref LFP
LFP = new Vector(npts) // create vector for LFP
xe = xmax/2
ye = ymax/2 // coordinates of electrode
va = 200 // axonal velocity (mm/sec)
lambda = 0.2 // space constant (mm)
dur = 100 // total duration of LFP waveform
nlfp = dur/dt // nb of LFP pts
amp_e = 0.7 // uLFP amplitude for exc cells
amp_i = -3.4 // uLFP amplitude for inh cells
sig_i = 2.1 // std-dev of ihibition (in ms)
sig_e = 1.5 * sig_i // std-dev for excitation
//amp_e = -0.16 // exc uLFP amplitude (deep layer)
//amp_i = -0.2 // inh uLFP amplitude (deep layer)
amp_e = 0.48 // exc uLFP amplitude (soma layer)
amp_i = 3 // inh uLFP amplitude (soma layer)
//amp_e = 0.24 // exc uLFP amplitude (superficial layer)
//amp_i = -1.2 // inh uLFP amplitude (superficial layer)
//amp_e = -0.08 // exc uLFP amplitude (surface)
//amp_i = 0.3 // inh uLFP amplitude (surface)
// calculate the contribution of excitatory cells
s_e = 2*sig_e*sig_e
s_i = 2*sig_i*sig_i
i=0
for i=0,Ne-1 { // loop on excitatory cells
dist = sqrt( (x[i]-xe)^2 + (y[i]-ye)^2 ) // calc distance to electrode (in mm)
delay = 10.4 + dist/va // delay to peak (in seconds)
amp = amp_e * exp(-dist/lambda) // calc LFP amplitude at electrode position
print "cell ",i," , amplitude = ",amp
for j=0,nspikes[i]-1 { // loop on spikes
time = Spikes[i].get(j) // get spike time
tp = time + delay // peak time of the uLFP
for k=0,nlfp-1 { // scan uLFP time
t = time + k*dt // time in ms
kernel = amp * exp(-(t-tp)*(t-tp)/s_e) // calc kernel
index = int(t/dt)
if(index<npts) LFP.set(index, LFP.get(index) + kernel) // add to vector
}
}
}
// calculate the contribution of inhibitory cells
for u=0,Ni-1 { // loop on excitatory cells
i=Ne+u // index of the cell
dist = sqrt( (x[i]-xe)^2 + (y[i]-ye)^2 ) // calc distance to electrode (in mm)
delay = 10.4 + dist/va // delay to peak (in seconds)
amp = amp_i * exp(-dist/lambda) // calc LFP amplitude at electrode position
print "cell ",i," , amplitude = ",amp
for j=0,nspikes[i]-1 { // loop on spikes
time = Spikes[i].get(j) // get spike time
tp = time + delay // peak time of the uLFP
for k=0,nlfp-1 { // scan uLFP time
t = time + k*dt // time in ms
kernel = amp * exp(-(t-tp)*(t-tp)/s_i) // calc kernel
index = int(t/dt)
if(index<npts) LFP.set(index, LFP.get(index) + kernel) // add to vector
}
}
}
objectvar g2 // create graph
g2 = new Graph()
g2.size(0,tmax,LFP.min(),LFP.max())
LFP.plot(g2,dt) // plot the LFP