proc connect_cells() {local i, j localobj cvec
for j=0, ngranule-1 {
// g2m_connections require previously specified distribution
// parameters
cvec = g2m_connections(j)
for i=0, cvec.size-1 {
mgconnect(cvec.x[i], j, 0)
}
}
}
// connect mitral $1 to granule $2 based on mitral position and granule
// position. Only connect if secden long enough to reach granule
proc mgconnect() {local mp, gp, delta, x, gpdarc localobj mgrs
mp = mitral_x.x[$1]
gp = granule_x.x[$2]
delta = gp - mp
if (ring) {
if (delta > Lsec) {
delta -= len
}else if (delta < -Lsec) {
delta += len
}
}
if (abs(delta) > Lsec) { return }
x = delta/Lsec
gpdarc = g2m_priden_position($1, $2, x)
if (delta >= 0) { // use secden[0]
mgrs = mk_mgrs($1, "secden[0]", x, $2, "priden2[0]", gpdarc, $3)
}else{ // use secden[1]
mgrs = mk_mgrs($1, "secden[1]", -x, $2, "priden2[0]", gpdarc, $3)
}
// store position and relation info in synapse to aid in
// selection and movie making
if (object_id(mgrs)) {
if (object_id(mgrs.fi)) {
mgrs.fi.x = gp
}
if (object_id(mgrs.ampanmda)) {
mgrs.ampanmda.x = gp
}
}
}
// given a granule cell index, return a vector of mitral cell indices which
// specify the existence of a mgrs.
// The primary distribution parameter is the fractional connectivity, g2m_mean
// Other aspects of the distribution are coded in the implementation.
// In particular, in the distribution below, a specified number of mitral
// indices are chosen randomly from the set of possible mitral indices. The
// number chosen is specified from a uniform random distribution
// ranging from (g2m_mean +- g2m_var)*nmitral but of course bounded by
// 1 and the possible number (nmitral-1 if the secondary dendrites span
// the domain).
// Note that with this algorithm, the distribution of number of granules
// per mitral cell is unknown. Possibly gaussian with some variance.
// It is possible some mitrals may have a lot of granule connections and
// some mitrals may have only a few. I would think that since there are
// many more granules than mitrals, the number of granules per mitral would
// be narrowly distributed about the mean of g2m_mean*ngranule
// Note that g2m_connections may be called several times with the same
// granule index and it will return the same "random" mitral index vector.
// This allows computation of load balance prior to construction of the
// network as well as simulation independence with respect to cpu location
// of cells. For a statistically independent connectivity matrix, choose
// a different value for g2m_ranseed.
/* see param.hoc
default_var("g2m_mean", 0.2)
default_var("g2m_var" , 0.1)
default_var("g2m_ranseed", 1)
*/
obfunc g2m_connections() {local i, j, xm, xg, saveseed, n, nmin, nmax \
localobj r, set, c
saveseed = mcell_ran4_init(g2m_ranseed)
nmin = (g2m_mean - g2m_var)*nmitral
nmax = (g2m_mean + g2m_var)*nmitral
if (nmin < 1) nmin = 1
if (nmax > nmitral) nmax = nmitral
r = new Random()
r.MCellRan4($1*1000 + 1)
if (nmin == nmax) {
n = nmin
}else{
n = r.discunif(nmin, nmax)
}
// what is the set of mitrals with a secden domain that overlaps
// the granule? Usually it is all of them but check to make sure
set = new Vector(nmitral) set.resize(0)
xg = granule_x.x[$1]
for i=0, nmitral-1 {
xm = mitral_x.x[i]
if (abs(xm - xg) < Lsec) {
set.append(i)
}
if (ring) {
// mitral on far right looping to beginning
if ((len - xm + xg) < Lsec) {
set.append(i)
}
// mitral at beginning looking left
if ((len - xg + xm) < Lsec) {
set.append(i)
}
}
}
// now pick n integers from at set without replacement
// there are several ways which are better or worse depending on
// n relative to nmitral
c = new Vector(n)
for i=0, n-1 {
j = r.discunif(i, set.size-1)
c.x[i] = set.x[j]
set.x[j] = set.x[i]
set.x[i] = c.x[i]
}
mcell_ran4_init(saveseed)
return c
}
// return a sparse matrix specifying the mitral,granule connections
// space expensive but need for load balance of mitral pieces
objref sparse_connection_matrix_
proc sparse_connections() {local g, i localobj c, sm
sm = new Matrix(nmitral, ngranule, 2)
for g = 0, ngranule-1 {
c = g2m_connections(g)
for i=0, c.size-1 {
sm.x[c.x[i]][g] = 1
}
}
sparse_connection_matrix_ = sm
}
// return arc position on priden2[0] of granule cell for m=$1 and g=$2
// and secondary dendrite arc position $3
// following implementation is all at 0.5 or random 0-1 independent of distance
// see param.hoc
//default_var("g2m_priden_seed_offset", 0) // 0 means all at 0.5
func g2m_priden_position() {local saveseed, x localobj r
if (g2m_priden_seed_offset == 0) {
return 0.5
}
saveseed = mcell_ran4_init(g2m_priden_seed_offset + g2m_ranseed)
r = new Random()
r.MCellRan4(1 + $1 + $2*1000)
x = r.uniform(0,1)
mcell_ran4_init(saveseed)
return x
}