====== Tutorial 2: Balanced network ====== Here you will learn to wire up a simple balanced network. This assumes that you already know the basics explained in [[Tutorial 1]]. The code of this example can be found here https://github.com/fzenke/auryn/blob/master/examples/sim_tutorial2.cpp ===== Setting up neural populations ===== A balanced network has an excitatory and an inhibitory population which we model as distinct [[manual:NeuronGroup|NeuronGroups]]. Moreover, we will include some external Poisson input to jump start the network and keep activity alive. Copy the basic Auryn simulation skeleton from [[Tutorial 1]] to a new ''sim_mytute2.cpp'' file. In that bare bones simulation, let's first set up the network neurons: int nb_exc_neurons = 20000; int nb_inh_neurons = nb_exc_neurons/4; IFGroup * neurons_exc = new IFGroup(nb_exc_neurons); neurons_exc->set_name("exc neurons"); neurons_exc->get_state_vector("g_nmda")->set_random(); IFGroup * neurons_inh = new IFGroup(nb_inh_neurons); neurons_inh->set_tau_mem(5e-3); neurons_inh->set_name("inh neurons"); The above code snipped initializes an excitatory population (''neurons_exc'') with 20000 neurons and an inhibitory population which is one quarter in size. Here were are using [[manual:IFGroup]] one of Auryn's standard neuron models. These neurons have conductance based synapses with a fast and slow excitatory conductance. Moreover, the model has a relative refractory mechanism. Here, we initialize the NMDA conductances of the excitatory population randomly to avoid that all neurons spike synchronously initially. That's what ''set_random()'' does. Also note that we give the inhibitory neurons a membrane time constant of 5ms. As before in [[Tutorial 1]] we define Poisson input as a separate population: int nb_input_neurons = 5000; float poisson_rate = 2.0; PoissonGroup * poisson = new PoissonGroup(nb_input_neurons,poisson_rate); ===== Connecting the network ===== Now let's connect these three populations. First the input: float weight = 0.2; // conductance amplitude in units of leak conductance float sparseness = 0.05; // probability of connection SparseConnection * con_ext_exc = new SparseConnection(poisson,neurons_exc,weight,sparseness,GLUT); And now the recurrent connctions: float gamma = 4.0; SparseConnection * con_ee = new SparseConnection(neurons_exc,neurons_exc,weight,sparseness,GLUT); SparseConnection * con_ei = new SparseConnection(neurons_exc,neurons_inh,weight,sparseness,GLUT); SparseConnection * con_ie = new SparseConnection(neurons_inh,neurons_exc,gamma*weight,sparseness,GABA); SparseConnection * con_ii = new SparseConnection(neurons_inh,neurons_inh,gamma*weight,sparseness,GABA); Note that we made inhibitory connections stronger by a factor of ''gamma = 4.0''. ===== Set up monitors ===== Let's record spikes from all neurons and the membrane potential from neuron 0 in the excitatory population. To do that we set up the following monitors SpikeMonitor * exc_spike_mon = new SpikeMonitor( neurons_exc, sys->fn("exc","ras") ); VoltageMonitor * voltage_mon = new VoltageMonitor( neurons_exc, 0, sys->fn("neuron","mem") ); voltage_mon->record_for(2); With the last call we limit the recording time for the VoltageMonitor to 2 seconds. Because VoltageMonitor and [[manual:StateMonitor]] have a default sampling interval of 0.1ms they quickly generate a lot of data. It's therefore advisable to limit the recording time to windows when you actually need it to speed up simulations and limit the use of disk space. ===== Running the simulation ===== To run the simulation for 10 seconds we simply add the run command: sys->run(10); That's it. You should now have a program which you can [[manual:compileandrunaurynsimulations|compile and run]]. Assuming your simulation file was called ''sim_tutorial2.cpp'' and you have set up a Makefile as described [[manual:compileandrunaurynsimulations|here]], you can simply enter this on your command line $ make sim_tutorial2 && ./sim_tutorial ====== Visualizing the spikes ====== Running above code will generate the following files: $ ls -ltrs | tail -n 4 912 -rwxrwxr-x 1 zenke zenke 931424 Sep 1 13:45 sim_tutorial2 4724 -rw-rw-r-- 1 zenke zenke 4835075 Sep 1 13:45 exc.0.ras 4 -rw-rw-r-- 1 zenke zenke 1077 Sep 1 13:45 sim_tutorial2.0.log 372 -rw-rw-r-- 1 zenke zenke 380022 Sep 1 13:45 neuron.0.mem Let's take a look at the spikes (in the [[manual:ras]] file first). In [[gnuplot]] this can be done as follows: set xrange [2:5] set yrange [:5000] plot 'exc.0.ras' with dots lc -1 {{ :tutorials:tutorial2_exc_spikes.png?300 |}} That's a lot of spikes, but the image suggests that there is some synchrony going on at times, but there are also phases of asynchronous firing. Let's zoom in a bit more: {{ :tutorials:tutorial2_exc_spikes_zoom.png?300 |}} We can also analyze this a little more and plot for instance the distribution of firing rates: {{ :tutorials:tutorial2_exc_rates.png?300 |}} Now let's have a look the membrane trace we recorded from one of our cells: {{ :tutorials:tutorial2_exc_mem.png?300 |}} After some initial burn in period of the network dynamics the neuron seems to start firing more irregularly. ===== Writing a cell assembly into the E-to-E connections ===== Now for the fun of it, let's add a simple cell assembly to the network. Auryn support multiple ways of doing that, but the simples is to simply write a block into the weight matrix. Let's add the following code after our run instruction: con_ee->set_block(0,500,0,500,5*weight); sys->run(2); which increases weights in a diagonal block in the E->E connections and then runs the simulation for another 2 seconds. Plotting again reveals the effect of this change in the spiking activity: {{ :tutorials:tutorial2_exc_spikes_assembly.png?300 |}} For more sophisticated ways of writing patterns or synfire chain structures into a connectivity matrix, check out the documentation of [[manual:SparseConnection]] and specifically the functions called ''load_patterns'' (see also http://fzenke.net/auryn/doxygen/current/classauryn_1_1SparseConnection.html). You can also always load a weight matrix from an external file which have generated using MATLAB or Python. Auryn supports a coordinate based [[http://math.nist.gov/MatrixMarket/|matrix market]] format which allows for the seamless exchange of weight matrices with external tools (see [[manual:wmat|matrix format]]). In the next [[Tutorial 3|tutorial]] we will make this model plastic. ====== Exercises ====== * Run the same simulation in parallel * Tune the connectivity parameters to asynchronous irregular firing at lower firing rates * Add three cell assemblies and make them multi stable