/* Copyright (c) 2015 EPFL-BBP, All rights reserved.
THIS SOFTWARE IS PROVIDED BY THE BLUE BRAIN PROJECT ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE BLUE BRAIN PROJECT
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This work is licensed under a
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
To view a copy of this license, visit
http://creativecommons.org/licenses/by-nc-sa/4.0/legalcode or send a letter to
Creative Commons,
171 Second Street, Suite 300,
San Francisco, California, 94105, USA.
*/
/*
* @file synapses.hoc
* @brief Template that store the synapses
* @author Werner Van Geit @ BBP
* @date 2015
*/
begintemplate synapses_45f62e2816
public load_synapses, synapse_list, netcon_list, netstim_list, \
pre_mtypes_bitmap, n_of_pre_mtypes, id_mtype_map, pre_mtypes, \
active_pre_mtypes, update_synapses, pre_mtype_netconlists, \
pre_mtype_freqs, pre_mtype_netstimlists, reset_synapses, \
weights, delays, synconf_list
objref synapse_list, netcon_list, netstim_list, pre_mtypes_bitmap, \
id_mtype_map, pre_mtypes, active_pre_mtypes, pre_mtype_netconlists, \
pre_cell_ids, pre_mtype_freqs, pre_mtype_netstimlists, rng_list, \
pre_mtype_weightlists, pre_mtype_synapselists, \
were_active_pre_mtypes, pre_mtypes_excinh, weights, delays, \
synconf_list, stringtools, tmp_synapse, this
/** Constructor */
proc init() { local mtype_id localobj mtype_map_file, mtype_name_string
strdef line, mtype_name
// Number of m-types
n_of_mtypes = 55
synapse_list = new List()
rng_list = new List()
netcon_list = new List()
netstim_list = new List()
weights = new Vector()
delays = new Vector()
pre_mtype_netconlists = new List()
pre_mtype_netstimlists = new List()
pre_mtype_weightlists = new List()
pre_mtype_synapselists = new List()
pre_mtypes_bitmap = new Vector(n_of_mtypes, 0)
pre_mtypes_excinh = new Vector(n_of_mtypes, 1)
active_pre_mtypes = new Vector(n_of_mtypes, 0)
were_active_pre_mtypes = new Vector(n_of_mtypes, 0)
pre_mtype_freqs = new Vector(n_of_mtypes, 10.0)
pre_mtypes = new Vector()
pre_cell_ids = new Vector()
for i=0, n_of_mtypes-1 {
pre_mtype_netconlists.append(new List())
pre_mtype_netstimlists.append(new List())
pre_mtype_synapselists.append(new List())
pre_mtype_weightlists.append(new Vector())
}
id_mtype_map = new List()
// Read the mapping between m-type names and m-type IDs
mtype_map_file = new File("synapses/mtype_map.tsv")
mtype_map_file.ropen()
for i=0, n_of_mtypes-1 {
mtype_map_file.gets(line)
sscanf(line, "%d\t%s", &mtype_id, mtype_name)
mtype_name_string = new String(mtype_name)
id_mtype_map.append(mtype_name_string)
}
mtype_map_file.close()
stringtools = new StringFunctions()
}
/** Update the active synapses in the GUI
Arguments:
synapse_plot: synapse plot object
*/
proc update_synapses() { localobj pre_mtype_netcons, pre_mtype_netstims, \
pre_mtype_weights, pre_mtype_synapses, synapse_plot
synapse_plot = $o1
for i=0, n_of_mtypes-1 {
pre_mtype_netcons = pre_mtype_netconlists.o(i)
pre_mtype_weights = pre_mtype_weightlists.o(i)
pre_mtype_synapses = pre_mtype_synapselists.o(i)
// Use different color for exc / inh synapses
if (pre_mtypes_excinh.x[i] == 0) {
// Red, excitatory
syn_color = 2
} else {
// Yellow, inhibitory
syn_color = 5
}
// Loop over the synapses.
// enable and plot active synapses,
// disable and remove inactive ones
// only do something if status of a synapse changed since last update
for j=0, pre_mtype_netcons.count()-1 {
if (active_pre_mtypes.x[i] == 1 && \
were_active_pre_mtypes.x[i] == 0) {
// Set weight to correct value
pre_mtype_netcons.o(j).weight = pre_mtype_weights.x[j]
// Draw the synapses
synapse_plot.point_mark(pre_mtype_synapses.o(j), \
syn_color, 4, 6)
} else if (active_pre_mtypes.x[i] == 0 && \
were_active_pre_mtypes.x[i] == 1) {
// Disable synapse by setting weight to 0
pre_mtype_netcons.o(j).weight = 0.0
// Remove synapse from plot
synapse_plot.point_mark_remove(pre_mtype_synapses.o(j))
}
}
// Update the list were_active_pre_mtypes, which is the list of
// mtypes that are active after this update
if (active_pre_mtypes.x[i] == 1 && were_active_pre_mtypes.x[i] == 0) {
were_active_pre_mtypes.x[i] = 1
} else if (active_pre_mtypes.x[i] == 0 && \
were_active_pre_mtypes.x[i] == 1) {
were_active_pre_mtypes.x[i] = 0
}
// Update the netstim frequencies
pre_mtype_netstims = pre_mtype_netstimlists.o(i)
for j=0, pre_mtype_netstims.count()-1 {
pre_mtype_netstims.o(j).interval = 1000.0 / pre_mtype_freqs.x[i]
}
}
}
/** Disable all the synapses */
proc reset_synapses() {
for i=0, n_of_mtypes-1 {
were_active_pre_mtypes.x[i] = 0
}
}
/** Load the synconf file
Arguments:
nsynapses: number of synapses in cell
*/
proc load_synconf() { localobj synconf_file, synconf_gids
strdef synconf_string
nsynapses = $1
synconf_list = new List()
for isynapse=0, nsynapses-1 {
synconf_list.append(new List())
}
synconf_file = new File("synapses/synconf.txt")
{synconf_file.ropen()}
synconf_gids = new Vector()
while (synconf_file.gets(synconf_string) > 0) {
stringtools.left(synconf_string, stringtools.len(synconf_string)-1)
synconf_gids.scantil(synconf_file, -1e15)
for i=0, synconf_gids.size()-1 {
synconf_list.o(synconf_gids.x[i]).append(new String(synconf_string))
}
}
}
/** Load all the synapses
Arguments:
cell_ref: reference to the cell object
*/
proc load_synapses() { local isynapse, nsynapses, ncols, synapse_id, \
pre_cell_id, seg_x, synapse_type, \
dep, fac, use, tau_d, delay, weight, \
base_seed, gid, netstim_id \
localobj synapse_data, synapse_file, cell_ref, \
synapse, section, rng, netcon, netstim
printf("Starting to add synapses\n")
strdef sectionlist_name, synapse_type_name, synconf_string, head_string, \
tail_string
cell_ref = $o1
// Load the file that contains all the information about the synapses
synapse_file = new File("synapses/synapses.tsv")
{synapse_file.ropen()}
// Data structure to store the data in synapses.tsv
synapse_data = new Matrix()
synapse_data.scanf(synapse_file)
synapse_file.close()
nsynapses = synapse_data.nrow
ncols = synapse_data.ncol
// There is only one cell in this simulation, so let's give it gid 1
gid = 197963
// Base seed for the rngs
base_seed = 0
// Load list of hoc commands that have to be execute on every synapse
// to set certain parameters that are not specified in synapse.tsv
load_synconf(nsynapses)
for isynapse=0, nsynapses-1 {
// Read the synapse parameters from the matrix
synapse_id = synapse_data.x[isynapse][0]
pre_cell_id = synapse_data.x[isynapse][1]
pre_mtype = synapse_data.x[isynapse][2]
sectionlist_id = synapse_data.x[isynapse][3]
sectionlist_index = synapse_data.x[isynapse][4]
seg_x = synapse_data.x[isynapse][5]
synapse_type = synapse_data.x[isynapse][6]
dep = synapse_data.x[isynapse][7]
fac = synapse_data.x[isynapse][8]
use = synapse_data.x[isynapse][9]
tau_d = synapse_data.x[isynapse][10]
delay = synapse_data.x[isynapse][11]
weight = synapse_data.x[isynapse][12]
// Create sectionref to the section the synapse will be placed on
if ( sectionlist_id == 0 ) {
cell_ref.soma[sectionlist_index] section = new SectionRef()
sectionlist_name = "somatic"
} else if ( sectionlist_id == 1 ) {
cell_ref.dend[sectionlist_index] section = new SectionRef()
sectionlist_name = "basal"
} else if ( sectionlist_id == 2 ) {
cell_ref.apic[sectionlist_index] section = new SectionRef()
sectionlist_name = "apical"
} else if ( sectionlist_id == 3 ) {
cell_ref.axon[sectionlist_index] section = new SectionRef()
sectionlist_name = "axonal"
} else {
printf("Sectionlist_id %d not support\n", sectionlist_id)
exit(1)
}
// If synapse_type < 100 the synapse is inhibitory, otherwise
// excitatory
if ( synapse_type < 100 ) {
synapse_type_name = "inhibitory"
section.sec synapse = new ProbGABAAB_EMS(seg_x)
synapse.tau_d_GABAA = tau_d
rng = new Random()
rng.MCellRan4( isynapse*100000+100, gid+250+base_seed )
rng.lognormal(0.2, 0.1)
synapse.tau_r_GABAA = rng.repick()
pre_mtypes_excinh.x[pre_mtype] = 1
} else {
synapse_type_name = "excitatory"
section.sec synapse = new ProbAMPANMDA_EMS(seg_x)
synapse.tau_d_AMPA = tau_d
pre_mtypes_excinh.x[pre_mtype] = 0
}
synapse.Use = abs( use )
synapse.Dep = abs( dep )
synapse.Fac = abs( fac )
// Execute all the extra synaptic configuration lines from synconf.txt
tmp_synapse = synapse
for isynconf=0,synconf_list.o(isynapse).count()-1 {
synconf_string = synconf_list.o(isynapse).o(isynconf).s
// Replacing all occurrences of %s with the temporary synapse name
while( stringtools.substr( synconf_string, "%s" ) != -1 ) {
stringtools.head(synconf_string, "%s", head_string)
stringtools.tail(synconf_string, "%s", synconf_string)
sprint(synconf_string, "%s%s%s", head_string, "tmp_synapse", synconf_string)
}
// Add {} around the string
sprint(synconf_string, "{%s}", synconf_string)
// Execute the statement
execute1(synconf_string, this)
}
// Create the random number generator for the synapse
rng = new Random()
rng.MCellRan4( isynapse*100000+100, gid+250+base_seed )
rng.uniform(0,1)
synapse.setRNG( rng )
rng_list.append(rng)
synapse_list.append(synapse)
// Check if there is already a netstim (spike generator)
// for the presynaptic cell
// If it exists, use that one
// Otherwise create a new one
if (pre_cell_ids.contains(pre_cell_id)) {
netstim_id = pre_cell_ids.indwhere("==", pre_cell_id)
netstim = netstim_list.o(netstim_id)
} else {
section.sec netstim = new NetStim(seg_x)
netstim.start = 0
netstim.interval = 100
netstim.number = 1e20
netstim.noise = 1
netstim_list.append(netstim)
pre_mtype_netstimlists.o(pre_mtype).append(netstim)
pre_cell_ids.append(pre_cell_id)
}
// Create a connection between the netstim and the synapse
netcon = new NetCon(netstim, synapse)
netcon.delay = delay
netcon.weight = 0.0
netcon_list.append(netcon)
// Save all the objects we made to make them persistent
pre_mtype_netconlists.o(pre_mtype).append(netcon)
pre_mtype_weightlists.o(pre_mtype).append(weight)
weights.append(weight)
delays.append(delay)
pre_mtype_synapselists.o(pre_mtype).append(synapse)
pre_mtypes_bitmap.x[pre_mtype] = 1
printf("Added %s synapse %d originating from cell %d of m-type %s on %s section %d(%f) and dep %f\n", \
synapse_type_name, synapse_id, pre_cell_id, id_mtype_map.o(pre_mtype).s, sectionlist_name, \
sectionlist_index, seg_x, dep)
}
// Make a list of all the m-types presynaptic to this cell, used by the GUI
for i=0, n_of_mtypes-1 {
if (pre_mtypes_bitmap.x[i] == 1) {
pre_mtypes.append(i)
}
}
}
endtemplate synapses_45f62e2816