/*
brunel.sli
Copyright (C) 2004 The NEST Initiative
This file is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307, USA.
*/
/*
Brunel Network
The SLI code in this file creates a sparsely coupled network of
excitatory and inhibitory neurons. Connections within and across
both populations are created at random. Both neuron populations
receive Poissonian background input. The spike output of 500
neurons from each population are recorded. Neurons are modeled
as leaky integrate-and-fire neurons with current-injecting synapses
(alpha functions). The model is based on
Nicolas Brunel
Dynamics of sparsely connected networks of excitatory
and inhibitory spiking neurons
Journal of Computational Neuroscience, 2000, vol 8, pp 183-208.
There are two differences to Brunel's model: we use alpha
functions instead of delta for synaptic currents, and our neurons
reset to the resting potential (0 mv) instead of to half-way
between resting potential and threshold.
This example shows how to
- organize subpopulations in subnets
- instrument a network with injection and recording devices
- record data to files
- define own functions
- set parameters in a simple way
- communicate with the user in a simple way
Abigail Morrison, Marc-Oliver Gewaltig, Hans Ekkehard Plesser
*/
%%% PARAMETER SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% define all relevant parameters: changes should be made here
% all data is place in the userdict dictionary
userdict begin % open dictionary, all variables stored here
/order 2500 def % scales size of network (total 5*order neurons)
% case C : slow oscillations
/g 5.0 def % rel strength, inhibitory synapses
/eta 2.0 def % nu_ext / nu_thresh
% case D : slow oscillations
%/g 4.5 def % rel strength, inhibitory synapses
%/eta 0.95 def % nu_ext / nu_thresh
/simtime 1000.0 def % simulation time [ms]
/dt 0.1 def % simulation step length [ms]
/connectseed 12345789 def % seed for random generator for conns.
/kernelseeds [43210987] def % seed(s) for kernel rng(s)
% array with one element per thread
/exfilename (spikes_ex.gdf) def % output file for excit. population
/infilename (spikes_in.gdf) def % output file for excit. population
end % close userdict
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% NO USER-SERVICABLE PARTS BELOW
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% FUNCTION SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Take spike detector, find total number of spikes registered,
% return average rate per neuron in Hz
%
% spike_det ComputeRate -> rate
/ComputeRate
{
userdict begin % ensure we are in userdict
GetStatus % get entire status dictionary
/events get % extract number of spike recorded
Nrec simtime mul % normalization factor
cvd div % convert divisor to double before dividing
1000 mul % convert from mHz to Hz, leave on stack
end
} bind % optional, improves performance
def
%%% PREPARATION SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
userdict begin
/NE 4 order mul cvi def % number of excitatory neurons
/NI 1 order mul cvi def % number of inhibitory neurons
/N NI NE add def % total number of neurons
/epsilon 0.1 def % connectivity
/CE epsilon NE mul cvi def % number of excitatory synapses on neuron
/CI epsilon NI mul cvi def % number of inhibitory synapses on neuron
/C CE CI add def % total number of internal synapses per n.
/Cext CE def % number of external synapses on neuron
/tauMem 20.0 def % neuron membrane time constant [ms]
/tauSyn 0.5 def % synaptic time constant [ms]
/tauRef 2.0 def % refractory time [ms]
/U0 0.0 def % resting potential [mV]
/theta 20.0 def % threshold
% synaptic weights, scaled for our alpha functions, such that
% for constant membrane potential, charge J would be deposited
/delay 1.5 def % synaptic delay, all connections [ms]
/J 0.1 def % synaptic weight [mV]
/fudge 0.41363506632638 def % ensures dV = J at V=0
/JE J tauSyn div fudge mul def
/JI g JE mul neg def % inhibitory
% threshold rate
/nu_thresh theta J CE mul tauMem mul div def
/nu_ext eta nu_thresh mul def % external rate per synapse
/p_rate nu_ext Cext mul 1000. mul def % external input rate per neuron
% must be given in Hz
% number of neurons per population to record from
/Nrec 500 def
% number of synapses---just so we know
/Nsyn
C % internal synapses
1 add % synapse from PoissonGenerator
N mul
Nrec 2 mul % "synapses" to spike detectors
add
def
end
%%% CONSTRUCTION SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ResetKernel % clear all existing network elements
modeldict begin % open model and user dictionaries
userdict begin
% set resolution and limits on delays
% limits must be set BEFORE connecting any elements
[0]
<<
/resolution dt
/min_delay dt
/max_delay delay
>> SetStatus
tic % start timer on construction
(Creating excitatory population.) = % show message
/E_net subnet Create def % create subnet
E_net ChangeSubnet % enter subnet
iaf_neuron NE CreateMany % create neurons in subnet
; % pop port numbers returned by CreateMany
[0] ChangeSubnet % return to full network
(Creating inhibitory population.) = % show message
/I_net subnet Create def % create subnet
I_net ChangeSubnet % enter subnet
iaf_neuron NI CreateMany % create neurons in subnet
; % pop port numbers returned by CreateMany
[0] ChangeSubnet % return to full network
(Creating excitatory Poisson generator.) =
/expoisson poisson_generator Create def
expoisson
<< % set firing rate
/rate p_rate
>> SetStatus
(Creating inhibitory Poisson generator.) =
/inpoisson poisson_generator Create def
inpoisson
<<
/rate p_rate
>> SetStatus
% one detector would in principle be enough,
% but by recording the populations separately,
% we save us a lot of sorting work later
(Creating excitatory spike detector.) =
/exsd spike_detector Create def
exsd
<<
/withtime true % record time of spikes
/withpath true % record which neuron spiked
>> SetStatus
(Creating inhibitory spike detector.) =
/insd spike_detector Create def
insd
<<
/withtime true
/withpath true
>> SetStatus
% some connecting functions need lists (arrays) over all
% neurons they should work on, so we need to extract these
% lists from the subnetworks
% obtain array with GIDs of all excitatory neurons
/E_neurons E_net GetNodes def
% obtain array with GIDs of all inhibitory neurons
/I_neurons I_net GetNodes def
% all neurons
/allNeurons E_neurons I_neurons join def
(Configuring neuron parameters.) =
allNeurons
{
dup % make copy of GID for ReserveConnections call
<<
/Tau tauMem
/TauSyn tauSyn
/TauR tauRef
/U0 U0
/Theta theta
/C 1.0 % capacitance is unity in Brunel model
>> SetStatus
GetAddress % ReserveConnections need address, not GID
% reserving space for all connections originating from
% a neuron before connecting saves a lot of time
% C is the expected number of outgoing connections from
% each neuron
C ReserveConnections
} forall
% Create random generator to use in randomized connection
% functions
/rng
rngdict /knuthlfg get % extract generator type from rngdict
connectseed
CreateRNG
def
(Connecting excitatory population.) =
% space for neuron to neuron connections was reserved above
% reserve space for connections from Poisson generator to neurons
expoisson NE ReserveConnections
E_neurons
{
/target Set
% E -> E connections
% the following is a single call to RandomConvergentConnect
rng % random number generator
E_neurons % source population [we pick from this]
target % target neuron
CE % number of source neurons to pick
SpikeEvent % event==connection type: send spikes!
JE % connection weight
delay % connection delay
RandomConvergentConnect
% I -> E connections
% as above, but on a single line
rng I_neurons target CI SpikeEvent JI delay RandomConvergentConnect
% Connect Poisson generator to neuron
expoisson % source: is in address form
target GetAddress % is GID, conversion necessary
Connect % defaults: SpikeEvent, weight 1, delay 1 step
% returns port number
expoisson exch % stack: expoisson portnumber
JE SetWeight % set weight for port from Poisson gen to node
} bind % bind improves efficiency
forall
(Connecting inhibitory population.) =
% ... as above, just written more compact
inpoisson NI ReserveConnections
I_neurons
{
/target Set
rng E_neurons target CE SpikeEvent JE delay RandomConvergentConnect
rng I_neurons target CI SpikeEvent JI delay RandomConvergentConnect
inpoisson target GetAddress Connect
inpoisson exch JE SetWeight
} bind forall
% Spike detectors are connected to the first Nrec neurons in each
% population. Since neurons are equal and connectivity is homogeneously
% randomized, this is equivalent to picking Nrec neurons at random
% from each population
(Connecting spike detectors.) =
exsd Nrec ReserveConnections
insd Nrec ReserveConnections
E_neurons Nrec Take % pick the first 500 neurons
{
exsd exch % stack: SDaddress neuronGID
GetAddress % stack: SDaddress neuronaddress
Connect % defaults: SpikeEvent, weight 1, delay 1 step
; % pop port number
} bind forall
% same for inhibitory population
I_neurons Nrec Take
{
insd exch GetAddress Connect ;
} bind forall
% read out time used for building
toc /BuildCPUTime Set
end % userdict
end % modeldict
%%% SIMULATION SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
userdict begin
% open output files & register files with detectors
/exspikefile exfilename (w) file def
exsd << /output_stream exspikefile >> SetStatus
/inspikefile infilename (w) file def
insd << /output_stream inspikefile >> SetStatus
% seed kernel RNG(s)
[0] << /rng_seeds kernelseeds >> SetStatus
% run, measure computer time with tic-toc
tic
simtime Simulate
toc /SimCPUTime Set
% close output files
inspikefile close
exspikefile close
% write a little report
(\nBrunel Network Simulation) =
(Number of Neurons : ) =only N =
(Number of Synapses: ) =only Nsyn =
(Excitatory rate : ) =only exsd ComputeRate =only ( Hz) =
(Inhibitory rate : ) =only insd ComputeRate =only ( Hz) =
(Building time : ) =only BuildCPUTime =only ( s) =
(Simulation time : ) =only SimCPUTime =only ( s\n) =
end % userdict
|