Skip to content

Commit f6d16e2

Browse files
author
Daniel Incicau
committed
Add documentation through project
1 parent 48e85e0 commit f6d16e2

File tree

6 files changed

+117
-6
lines changed

6 files changed

+117
-6
lines changed

README.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,20 @@
1-
# Spiking Neural Network for the Visual Cortex (V1) Layer 5
1+
Spiking Neural Network for the Visual Cortex (V1) Layer 5
2+
============================
3+
4+
### Project content
5+
6+
.
7+
├── data # Contains hypertuning results from amplitude simulation run
8+
├── output # Contains output results & plots from complete simulation run (.gitignored)
9+
├── notebooks # Jupyter notebooks used for testing different scenarios
10+
│ ├── layer5_CC_CS_connection.ipynb # Scalar plot simulation for weighted CC->CS connection probability
11+
│ ├── layer5_SST_Soma_selectivity.ipynb # Scalar plot simulation for weighted SST->CC/CS Soma connection probability
12+
│ ├── layer5_sandbox.ipynb # Sandbox notebook used when creating initial network topology
13+
│ └── ...
14+
├── layer5_CC_CS.py # Main network file that defines the topology of the simulation
15+
├── equations.py # Equations for different neuron types
16+
├── parameters.py # Default parameters for simulation
17+
├── helpers.py # Helper methods for analysis
18+
├── plotting.py # Helper methods for plotting
19+
├── run_amplitude_hypertuing.py # Script for running multiple simulations for amplitude hypertuning for different neurons
20+
└── run_complete_simulation.py # Complete simulation run entrypoint

helpers.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ def bin(spiketime, dt):
3030

3131

3232
def count_spikes_for_neuron_type(spike_mon, from_t=None, to_t=None):
33+
"""
34+
Computes spike count by neuron for all neurons monitored by a spike monitor between given interval of time
35+
"""
36+
3337
spike_counts = {}
3438

3539
for index in spike_mon.spike_trains():
@@ -45,13 +49,21 @@ def count_spikes_for_neuron_type(spike_mon, from_t=None, to_t=None):
4549

4650
@check_units(sim_duration=ms)
4751
def compute_firing_rate_for_neuron_type(spike_mon, from_t, to_t):
52+
"""
53+
Computes firing rate by neuron for all neurons monitored by a spike monitor between given interval of time
54+
"""
55+
4856
spikes_for_i = count_spikes_for_neuron_type(spike_mon, from_t, to_t)
4957
duration = to_t - from_t
5058

5159
return spikes_for_i / duration
5260

5361

5462
def compute_interspike_intervals(spike_mon, from_t, to_t):
63+
"""
64+
Computes inter-spike intervals by neuron for all neurons monitored by a spike monitor between given interval of time
65+
"""
66+
5567
by_neuron = []
5668

5769
for neuron_index in spike_mon.spike_trains():
@@ -65,6 +77,10 @@ def compute_interspike_intervals(spike_mon, from_t, to_t):
6577

6678

6779
def compute_autocorr(spike_intervals):
80+
"""
81+
Computes auto-correlation function on the inter-spike intervals
82+
"""
83+
6884
if len(spike_intervals) == 0:
6985
return None, None
7086

@@ -75,6 +91,10 @@ def compute_autocorr(spike_intervals):
7591

7692

7793
def find_minimum_autocorr(acorr):
94+
"""
95+
Finds the minimum of the auto-correlation function given by acorr
96+
"""
97+
7898
if acorr is None:
7999
return None
80100

@@ -93,6 +113,10 @@ def find_minimum_autocorr(acorr):
93113

94114

95115
def compute_autocorr_struct(interspike_intervals, no_bins):
116+
"""
117+
Helper method for computing all relevant auto-correlation metrics for inter-spike intervals given
118+
"""
119+
96120
autocorr_sst = None
97121

98122
sorted_isi = np.sort(interspike_intervals)
@@ -110,6 +134,12 @@ def compute_autocorr_struct(interspike_intervals, no_bins):
110134

111135

112136
def compute_equilibrium_for_neuron_type(spike_mon, time_frame=0.05, tol=0.001):
137+
"""
138+
Computes equilibrium time for a group of neurons monitored by a spike monitor.
139+
It does that by using a sliding window algorithm of `time_frame` and
140+
checking if firing rate of neurons has changed between 2 consecutive time windows
141+
"""
142+
113143
t = 0
114144
last_spike_t = spike_mon.t[-1] / second if len(spike_mon.t) > 0 else t
115145

@@ -128,6 +158,12 @@ def compute_equilibrium_for_neuron_type(spike_mon, time_frame=0.05, tol=0.001):
128158

129159

130160
def compute_burst_mask(spikes, maxISI):
161+
"""
162+
Computes a burst mask for the spikes of a given neuron.
163+
A spike is said to be in a burst if the inter-spike interval time is less than maxISI
164+
Returns a binary vector. 1 means spike is in a burst. 0 means is not
165+
"""
166+
131167
isi = np.diff(spikes)
132168
mask = np.zeros(len(spikes))
133169

@@ -140,6 +176,10 @@ def compute_burst_mask(spikes, maxISI):
140176

141177

142178
def compute_burst_trains(spike_mon, maxISI):
179+
"""
180+
Computes a burst mask for each neuron monitored by the spike_mon
181+
"""
182+
143183
burst_trains = {}
144184
for neuron_index in spike_mon.spike_trains():
145185
burst_mask = compute_burst_mask(spike_mon.spike_trains()[neuron_index], maxISI)
@@ -149,7 +189,11 @@ def compute_burst_trains(spike_mon, maxISI):
149189

150190

151191
def compute_burst_lengths(burst_mask):
152-
"count how many series of consecutive occurances of 1 appear"
192+
"""
193+
Given a burst mask which is iterated, a burst is defined as series of consecutive occurrences of 1.
194+
Each of these series is considered a burst and has an associated burst length.
195+
Returns a vector of bursts lengths.
196+
"""
153197

154198
burst_lengths = []
155199
idx = 0
@@ -180,6 +224,10 @@ def compute_burst_lengths_by_neuron_group(burst_trains):
180224

181225

182226
def save_agg_results_to_folder(results, output_folder=None, file_name='results.json'):
227+
"""
228+
Helper method for saving aggregated results for multiple simulations with different degree inputs to folder
229+
"""
230+
183231
if output_folder is not None:
184232
if not os.path.exists(output_folder):
185233
os.makedirs(output_folder)
@@ -190,6 +238,10 @@ def save_agg_results_to_folder(results, output_folder=None, file_name='results.j
190238

191239

192240
def save_results_to_folder(results, output_folder=None, file_name='results.json'):
241+
"""
242+
Helper method for saving individual simulation results to folder
243+
"""
244+
193245
if output_folder is not None:
194246
if not os.path.exists(output_folder):
195247
os.makedirs(output_folder)

layer5_CC_CS.py

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,16 @@ def __init__(self, **entries):
1212

1313

1414
def analyse_network_simulation(spike_monitors, state_monitors, synapses, p, output_folder=None):
15+
"""
16+
Does an analysis of a simulation post-run. Saves plots to `output_folder`
17+
Returns the results of simulation analysis
18+
"""
19+
1520
spike_mon_sst, spike_mon_pv, spike_mon_cs, spike_mon_cc = spike_monitors
1621
state_mon_sst, state_mon_pv, state_mon_cs, state_mon_cc = state_monitors
1722

1823
################################################################################
19-
# Analysis and plotting
24+
# Compute equilibrium time of simulation
2025
################################################################################
2126

2227
if p.recompute_equilibrium:
@@ -41,6 +46,10 @@ def analyse_network_simulation(spike_monitors, state_monitors, synapses, p, outp
4146
from_t = equilibrium_t
4247
to_t = p.duration
4348

49+
################################################################################
50+
# Analysis and plotting
51+
################################################################################
52+
4453
raster_from_t = from_t if p.plot_only_from_equilibrium else 0
4554
raster_to_t = min(raster_from_t + 3 * second, p.duration)
4655
plot_raster(spike_mon_cs, spike_mon_cc, spike_mon_sst, spike_mon_pv, raster_from_t, raster_to_t,
@@ -140,6 +149,11 @@ def analyse_network_simulation(spike_monitors, state_monitors, synapses, p, outp
140149

141150

142151
def run_simulation_without_exh_dendrite(network, neurons, synapses, p, base_output_folder, use_synaptic_probabilities):
152+
"""
153+
Runs simulation for network topology with PYR cells having ONLY somas and NO dendrites.
154+
Also analyses simulation run and returns results.
155+
"""
156+
143157
sst_neurons, pv_neurons, cs_neurons, cc_neurons = neurons
144158

145159
E_l = p.E_l # leak reversal potential
@@ -218,6 +232,13 @@ def run_simulation_without_exh_dendrite(network, neurons, synapses, p, base_outp
218232

219233

220234
def run_simulation_for_weighted_sst_soma_dendrite(network, neurons, synapses, p, p_SST_CS_soma, p_SST_CC_soma, base_output_folder, use_synaptic_probabilities):
235+
"""
236+
Runs simulation for network topology with PYR cells having BOTH somas and dendrites.
237+
Connection probability of SST->CC/CS Soma is weighted through parameters `p_SST_CS_soma` and `p_SST_CC_soma`
238+
Connection probability of SST->CC/CS Dendrite is given by `1 - p_SST_CS_soma` and `1 - p_SST_CC_soma`
239+
Also analyses simulation run and returns results.
240+
"""
241+
221242
sst_neurons, pv_neurons, cs_neurons, cc_neurons = neurons
222243

223244
E_l = p.E_l # leak reversal potential
@@ -315,13 +336,20 @@ def run_simulation_for_weighted_sst_soma_dendrite(network, neurons, synapses, p,
315336

316337

317338
def run_simulation_for_input(params, use_synaptic_probabilities, use_dendrite_model, seed_val, base_output_folder=None):
339+
"""
340+
Given external input and network parameters (through `params`) simulations are run accordingly.
341+
If `use_dendrite_model` multiple simulations are run for each (pSST_CS_soma, pSST_CC_soma) pairs
342+
If NOT `use_dendrite_model` a single simulation is run.
343+
Returns vector of results of simulations
344+
"""
345+
318346
p = Struct(**params)
319347

320348
start_scope()
321349
seed(seed_val)
322350

323351
E_l = p.E_l # leak reversal potential
324-
V_t = p.V_t # spiking threashold
352+
V_t = p.V_t # spiking threshold
325353

326354
assert len(p.pSST_CS_soma) == len(p.pSST_CC_soma) # since they are taken in pairs
327355

@@ -410,7 +438,7 @@ def run_simulation_for_input(params, use_synaptic_probabilities, use_dendrite_mo
410438
neurons = [sst_neurons, pv_neurons, cs_neurons, cc_neurons]
411439

412440
# ##############################################################################
413-
# Define Synapses
441+
# Define Synapses (common synapses for simulation)
414442
# ##############################################################################
415443

416444
synapses = {}
@@ -510,6 +538,10 @@ def run_simulation_for_input(params, use_synaptic_probabilities, use_dendrite_mo
510538

511539
defaultclock.dt = p.sim_dt
512540

541+
# ##############################################################################
542+
# Continue defining specific simulation run
543+
# ##############################################################################
544+
513545
results = []
514546
if use_dendrite_model:
515547
for p_SST_CS_soma, p_SST_CC_soma in zip(p.pSST_CS_soma, p.pSST_CC_soma):
@@ -532,6 +564,12 @@ def run_simulation_for_input(params, use_synaptic_probabilities, use_dendrite_mo
532564

533565

534566
def run_complete_simulation(params, use_dendrite_model=True, use_synaptic_probabilities=True, seed_val=12345):
567+
"""
568+
Runs a complete simulation for given parameters.
569+
Computes both individual simulation results and aggregated simulation results.
570+
Selectivity of network is calculated through varying external input to neurons.
571+
"""
572+
535573
p = Struct(**params)
536574

537575
N = [p.N_cs, p.N_cc, p.N_sst, p.N_pv]

parameters.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
"E_e": 0 * mV, # Excitatory synaptic reversal potential
3333
"E_i": -80 * mV, # Inhibitory synaptic reversal potential
3434

35-
"V_t": -50 * mV, # spiking threashold
35+
"V_t": -50 * mV, # spiking threshold
3636
"V_r": -70 * mV, # reset potential ~ same as E_l ~
3737

3838
"c_d": 2600 * pA, # back-propagates somatic spikes to the dendrites
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ def run_input_amplitude_simulation(params, input_amplitudes, seed_val=12345):
6464

6565

6666
def test_input_amplitudes(params, csv_writer=None, seed_val=12345):
67+
68+
# combinatorically run simulations for the following neuron type amplitudes
6769
input_cs_amplitudes = [100]
6870
input_cc_amplitudes = [100, 200, 300]
6971
input_sst_amplitudes = [10, 25, 50, 75, 100]

0 commit comments

Comments
 (0)