from neuron import *
# MPI
pc = h.ParallelContext() # MPI: Initialize the ParallelContext class
nhosts = int(pc.nhost()) # Find number of hosts
if pc.id()==0: print('\nSetting up network...')
import sys
import os
import string
h("strdef simname, allfiles, simfiles, output_file, datestr, uname, osname, comment")
h.simname=simname = "dystdemo"
h.allfiles=allfiles = "pyinit.py geom.py mpisim.py"
h.simfiles=simfiles = "pyinit.py geom.py mpisim.py"
h("runnum=1")
runnum = 1.0
h.datestr=datestr = "16jun21"
h.output_file=output_file = "data/16jun21.14"
h.uname=uname = "x86_64"
h.osname=osname="linux"
h("templates_loaded=0")
templates_loaded=0
h("xwindows=1.0")
xwindows = 1.0
h.xopen("nrnoc.hoc")
h.xopen("init.hoc")
h("proc setMemb () { }") # so e_pas will not get modified
CTYPi = 60.0
STYPi = 20.0
from pyinit import *
from labels import *
delm = numpy.zeros( (CTYPi, CTYPi) )
deld = numpy.zeros( (CTYPi, CTYPi) )
pmat = numpy.zeros( (CTYPi, CTYPi) )
synloc = numpy.zeros( (CTYPi, CTYPi) )
from geom import *
from vector import *
from nqs import *
import random
from pylab import *
from datetime import datetime
#########################################################################
# global params
verbose = dconf['verbose']
ISEED = dconf['iseed']
WSEED = dconf['wseed']
PSEED = dconf['pseed']
scale = dconf['scale']
gGID = 0 # global ID for cells
pmatscale = 1.0 # 1.0 / scale
spiketh = -15 # spike threshold, 10 mV is NetCon default, lower it for all cells
simstr = dconf['simstr']
saveout = dconf['saveout']
recdt = dconf['recdt']
recvdt = dconf['recvdt']
saveconns = dconf['saveconns']
indir = dconf['indir']
outdir = dconf['outdir']
# make dir, catch exceptions
def safemkdir (dn):
try:
os.mkdir(dn)
return True
except OSError:
if not os.path.exists(dn):
print 'could not create', dn
return False
else:
return True
# backup the config file
def backupcfg (simstr):
safemkdir('backupcfg')
fout = 'backupcfg/' + simstr + '.cfg'
if os.path.exists(fout):
print 'removing prior cfg file' , fout
os.system('rm ' + fout)
os.system('cp ' + fcfg + ' ' + fout) # fcfg created in geom.py via conf.py
if pc.id()==0:
backupcfg(simstr) # backup the config file
print "config file is " , fcfg
h.tstop = tstop = dconf['tstop']
tstart = 0.0
h.dt = dconf['dt']
h.steps_per_ms = 1/h.dt
h.v_init = -65
h.celsius = 37
h.fracca_MyExp2SynNMDABB = dconf['nmfracca'] # fraction of NMDA current that is from calcium
rdmsec = dconf['rdmsec']
EEGain = dconf['EEGain']
EIGainFS = dconf['EIGainFS']
EIGainLTS = dconf['EIGainLTS']
IEGain = dconf['IEGain']
IIGain = dconf['IIGain']
IIGainLTSFS = IIGain
IIGainFSLTS = IIGain
IIGainLTSLTS = IIGain
IIGainFSFS = IIGain
GB2R = dconf['GB2R'];
NMAMREE = dconf['NMAMREE']
NMAMREI = dconf['NMAMREI']
mGLURR = dconf['mGLURR'] # ratio of mGLUR weights to AM2 weights
cpernet = [] # cells of a given type for network
wmat = numpy.zeros( (CTYPi, CTYPi, STYPi) ) # internal weights
wmatex = numpy.zeros( (CTYPi, STYPi) ) # external weights
ratex = numpy.zeros( (CTYPi, STYPi) ) # external rates
EXGain = dconf['EXGain']
sgrhzEE = dconf['sgrhzEE'] # external E inputs to E cells; 1000 is default
sgrhzEI = dconf['sgrhzEI'] # external E inputs to I cells
sgrhzIE = dconf['sgrhzIE'] # external I inputs to E cells
sgrhzII = dconf['sgrhzII'] # external I inputs to I cells
sgrhzNME = dconf['sgrhzNME'] # external NM inputs to E cells; 10 is default
sgrhzNMI = dconf['sgrhzNMI'] # external NM inputs to I cells
sgrhzMGLURE = dconf['sgrhzMGLURE'] # external mGLUR inputs to E cells
sgrhzGB2 = dconf['sgrhzGB2'] # external inputs onto E cell GB2 synapses
# params for swire
colside = 120 # 120 microns squared
slambda = 100 # space constant for wiring falloff (used for I -> X)
axonalvelocity = 10000 # axonal velocity in um/ms -- this is 10 mm/s
#########################################################################
# setwmatex - set weights of external inputs to cells
def setwmatex ():
for ct in xrange(CTYPi):
for sy in xrange(STYPi):
ratex[ct][sy]=0
wmatex[ct][sy]=0
for ct in xrange(CTYPi):
if cpernet[ct] <= 0: continue
if IsLTS(ct): # dendrite-targeting interneurons (LTS cells)
ratex[ct][AM2]=sgrhzEI
ratex[ct][NM2] = sgrhzNMI
ratex[ct][GA]=sgrhzII
ratex[ct][GA2]=sgrhzII
wmatex[ct][AM2] = 0.02e-3
wmatex[ct][NM2] = 0.02e-3
wmatex[ct][GA]= 0
wmatex[ct][GA2]= 0.2e-3 # * 0
elif ice(ct): # soma-targeting interneurons (basket/FS cells)
ratex[ct][AM2]=sgrhzEI
ratex[ct][NM2] = sgrhzNMI
ratex[ct][GA]=sgrhzII
ratex[ct][GA2]=sgrhzII
wmatex[ct][AM2] = 0.02e-3 * 5.0
wmatex[ct][NM2] = 0.02e-3 * 5.0
wmatex[ct][GA]= 0
wmatex[ct][GA2]= 0.2e-3
else: # E cells
ratex[ct][MG]=sgrhzMGLURE
ratex[ct][AM2]=sgrhzEE
ratex[ct][NM2]=sgrhzNME
ratex[ct][GA]=sgrhzIE
ratex[ct][GA2]=sgrhzIE
ratex[ct][GB2]=sgrhzGB2
wmatex[ct][MG] = 1.5
wmatex[ct][AM2] = 0.02e-3
wmatex[ct][NM2] = 0.02e-3
wmatex[ct][GA] = 0.2e-3
wmatex[ct][GA2] = 0.2e-3
wmatex[ct][GB2] = 5e-3
for sy in xrange(STYPi): wmatex[ct][sy] *= EXGain # apply gain control
# set number of cells of a type in the network at scale==1
def setcpernet ():
global cpernet
cpernet = []
for i in xrange(CTYPi): cpernet.append(0)
cpernet[E2] = 300
cpernet[I2] = 37
cpernet[I2L] = 37
cpernet[E4] = 173
cpernet[E5R] = 150
cpernet[E5B] = 196
cpernet[E5P] = 196
cpernet[I5] = 89
cpernet[I5L] = 89
cpernet[E6] = 179
cpernet[E6C] = 179
cpernet[I6] = 45
cpernet[I6L] = 45
# synapse locations DEND SOMA AXON
def setsynloc ():
for ty1 in xrange(CTYPi):
for ty2 in xrange(CTYPi):
if ice(ty1):
if IsLTS(ty1):
synloc[ty1][ty2]=DEND # distal [GA2] - from LTS
else:
synloc[ty1][ty2]=SOMA # proximal [GA] - from FS
else:
synloc[ty1][ty2]=DEND # E always distal. use AM2,NM2
# setdelmats -- setup delm,deld
def setdelmats ():
for ty1 in xrange(CTYPi):
for ty2 in xrange(CTYPi):
if synloc[ty1][ty2]==DEND and ice(ty2):
# longer delays at dendrites of interneurons since they are currently single compartment
delm[ty1][ty2]=2.0
deld[ty1][ty2]=0.2
else:
delm[ty1][ty2]=2.0
deld[ty1][ty2]=0.2
# weight params
def setwmat ():
for ty1 in xrange(CTYPi):
for ty2 in xrange(CTYPi):
for sy in xrange(STYPi): wmat[ty1][ty2][sy]=0
# E2 -> I weight
wmat[E2][I2][AM2] = wmat[E2][I2L][AM2] = 0.78
wmat[E2][I5][AM2] = 0.11
wmat[E2][I5L][AM2] = 1.01
# E4 -> I weight
wmat[E4][I2][AM2] = wmat[E4][I2L][AM2] = 0.3625
wmat[E4][I5][AM2] = 1.0775
wmat[E4][I5L][AM2] = 0.1225
wmat[E4][I6][AM2] = wmat[E4][I6L][AM2] = 0.4375
# E5R (IT E5a) -> I weight
wmat[E5R][I2][AM2] = wmat[E5R][I2L][AM2] = 0.3625
wmat[E5R][I5][AM2] = 1.0775
wmat[E5R][I5L][AM2] = 0.1225
wmat[E5R][I6][AM2] = wmat[E5R][I6L][AM2] = 0.4375
# E5B (IT E5b) -> I weight
wmat[E5B][I2][AM2] = wmat[E5B][I2L][AM2] = 0.3625
wmat[E5B][I5][AM2] = 1.0775
wmat[E5B][I5L][AM2] = 0.1225
wmat[E5B][I6][AM2] = wmat[E5B][I6L][AM2] = 0.4375
# E5P (PT E5b) -> I weight
wmat[E5P][I2][AM2] = wmat[E5P][I2L][AM2] = 0.3625
wmat[E5P][I5][AM2] = 1.0775
wmat[E5P][I5L][AM2] = 0.1225
wmat[E5P][I6][AM2] = wmat[E5P][I6L][AM2] = 0.4375
# E6 (IT) -> I weight
wmat[E6][I5][AM2] = wmat[E6][I5L][AM2] = 0.24786
wmat[E6][I6][AM2] = wmat[E6][I6L][AM2] = 0.53
# E6C (CT) -> I weight
wmat[E6C][I5][AM2] = wmat[E6C][I5L][AM2] = 0.24786
wmat[E6C][I6][AM2] = wmat[E6C][I6L][AM2] = 0.53
epops = [E2, E4, E5R, E5B, E5P, E6, E6C]
prty = E2; # E2 -> E weight
for poty,wght in zip(epops,[0.6416, 0.3700, 0.5049, 0.4446, 0.4446, 0.0000, 0.0000]): wmat[prty][poty][AM2] = wght
prty = E4 # E4 -> E weight
for poty,wght in zip(epops,[0.7368, 0.6416, 0.6383, 0.8981, 0.8981, 1.9082, 1.9082]): wmat[prty][poty][AM2] = wght
prty = E5R # E5R -> E weight
for poty,wght in zip(epops,[0.5243, 0.4180, 0.5716, 0.8320, 0.8320, 0.3220, 0.3220]): wmat[prty][poty][AM2] = wght
prty = E5B # E5B -> E weight
for poty,wght in zip(epops,[0.2342, 0.1700, 0.3194, 0.6855, 0.6855, 0.4900, 0.4900]): wmat[prty][poty][AM2] = wght
# E5P -> E weight
wmat[E5P][E5P][AM2] = 0.6855
prty = E6 # E6 -> E weight
for poty,wght in zip(epops,[0.0000, 0.0000, 0.1365, 0.3092, 0.3092, 0.5300, 0.5300]): wmat[prty][poty][AM2] = wght
prty = E6C # E6C -> E weight
for poty,wght in zip(epops,[0.0000, 0.0000, 0.1365, 0.3092, 0.3092, 0.5300, 0.5300]): wmat[prty][poty][AM2] = wght
# I -> X
for prty,sy in zip([I2,I2L],[GA,GA2]):
for poty in [E2,I2,I2L]:
wmat[prty][poty][sy] = 1.5
if IsLTS(prty) and not ice(poty): wmat[prty][poty][GB2] = 1.5 * GB2R
for prty,sy in zip([I5,I5L],[GA,GA2]):
for poty in [E4,E5R,E5B,E5P,I5,I5L]:
wmat[prty][poty][sy] = 1.5
if IsLTS(prty) and not ice(poty): wmat[prty][poty][GB2] = 1.5 * GB2R
for prty,sy in zip([I6,I6L],[GA,GA2]):
for poty in [E6,E6C,I6,I6L]:
wmat[prty][poty][sy] = 1.5
if IsLTS(prty) and not ice(poty): wmat[prty][poty][GB2] = 1.5 * GB2R
# gain control
for ty1 in xrange(CTYPi):
for ty2 in xrange(CTYPi):
for sy in xrange(STYPi):
if wmat[ty1][ty2][sy] > 0:
if ice(ty1): # I -> X
if ice(ty2):
if IsLTS(ty1): # LTS -> I
if IsLTS(ty2): # LTS -> LTS
gn = IIGainLTSLTS
else: # LTS -> FS
gn = IIGainLTSFS
else: # FS -> I
if IsLTS(ty2): # FS -> LTS
gn = IIGainFSLTS
else: # FS -> FS
gn = IIGainFSFS
else: # I -> E
gn = IEGain
else: # E -> X
if ice(ty2): # E -> I
if IsLTS(ty2): # E -> LTS
gn = EIGainLTS
else: # E -> FS
gn = EIGainFS
else: # E -> E
gn = EEGain
if sy==AM2:
wmat[ty1][ty2][MG] = wmat[ty1][ty2][AM2] * mGLURR
if verbose: print 'AM2:',wmat[ty1][ty2][AM2],'mGLURR:',wmat[ty1][ty2][MG]
if sy==AM2:
if ice(ty2): # E -> I
wmat[ty1][ty2][NM2] = wmat[ty1][ty2][AM2] * NMAMREI
else: # E -> E
wmat[ty1][ty2][NM2] = wmat[ty1][ty2][AM2] * NMAMREE
wmat[ty1][ty2][sy] *= gn
def setpmat ():
for ii in xrange(CTYPi):
for jj in xrange(CTYPi): pmat[ii][jj]=0
# E2 -> I wiring
pmat[E2][I2] = pmat[E2][I2L] = 0.1871
pmat[E2][I5] = 0.02
pmat[E2][I5L] = 0.217
# E4 -> I wiring
pmat[E4][I2] = pmat[E4][I2L] = 0.0222
pmat[E4][I5] = 0.1906
pmat[E4][I5L] = 0.0349
pmat[E4][I6] = pmat[E4][I6L] = 0.0155
# E5R (IT E5a) -> I wiring
pmat[E5R][I2] = pmat[E5R][I2L] = 0.0222
pmat[E5R][I5] = 0.1906
pmat[E5R][I5L] = 0.0349
pmat[E5R][I6] = pmat[E5R][I6L] = 0.0155
# E5B (IT E5b) -> I wiring
pmat[E5B][I2] = pmat[E5B][I2L] = 0.0222
pmat[E5B][I5] = 0.1906
pmat[E5B][I5L] = 0.0349
pmat[E5B][I6] = pmat[E5B][I6L] = 0.0155
# E5P (PT E5b) -> I wiring
pmat[E5P][I2] = pmat[E5P][I2L] = 0.0222
pmat[E5P][I5] = 0.1906
pmat[E5P][I5L] = 0.0349
pmat[E5P][I6] = pmat[E5P][I6L] = 0.0155
# E6 (IT) -> I wiring
pmat[E6][I5] = pmat[E6][I5L] = 0.0249
pmat[E6][I6] = pmat[E6][I6L] = 0.0234
# E6C (CT) -> I wiring
pmat[E6C][I5] = pmat[E6C][I5L] = 0.0249
pmat[E6C][I6] = pmat[E6C][I6L] = 0.0234
epops = [E2, E4, E5R, E5B, E5P, E6, E6C]
prty = E2; # E2 -> E wiring
for poty,prob in zip(epops,[0.1503, 0.1100, 0.0509, 0.0124, 0.0690, 0,0]): pmat[prty][poty] = prob
prty = E4 # E4 -> E wiring
for poty,prob in zip(epops,[0.0523, 0.1503, 0.0413, 0.0143, 0.0120, 0.0030, 0.0030]): pmat[prty][poty] = prob
prty = E5R # E5R -> E wiring
for poty,prob in zip(epops,[0.0355, 0.0275, 0.1810, 0.0142, 0.0205, 0.0136, 0.0136]): pmat[prty][poty] = prob
prty = E5B # E5B -> E wiring
for poty,prob in zip(epops,[0.0167, 0.0293, 0.0536, 0.1810, 0.0448, 0.0160, 0.0160]): pmat[prty][poty] = prob
pmat[E5P][E5P] = 0.1810 # E5P -> E5P
prty = E6 # E6 -> E wiring
for poty,prob in zip(epops,[0, 0, 0.0334, 0.0271, 0.0277, 0.0282, 0.0234]): pmat[prty][poty] = prob
prty = E6C # E6C -> E wiring
for poty,prob in zip(epops,[0, 0, 0.0334, 0.0271, 0.0277, 0.0234, 0.0282]): pmat[prty][poty] = prob
# I -> X
for prty in [I2,I2L]:
for poty in [E2,I2,I2L]: pmat[prty][poty] = 1.0
for prty in [I5,I5L]:
for poty in [E4,E5R,E5B,E5P,I5,I5L]: pmat[prty][poty] = 1.0
for prty in [I6,I6L]:
for poty in [E6,E6C,I6,I6L]: pmat[prty][poty] = 1.0
for ii in xrange(CTYPi):
for jj in xrange(CTYPi): pmat[ii][jj]*=pmatscale
numc = [0 for i in xrange(CTYPi)]; # number of cells of a type
ix = [0 for i in xrange(CTYPi)]; #starting index of a cell type (into self.ce list)
ixe = [0 for i in xrange(CTYPi)]; #ending index of a cell type
allcells,ecells,icells = 0,0,0
div = zeros( (CTYPi, CTYPi) )
conv = zeros( (CTYPi, CTYPi) )
syty1 = zeros( (CTYPi, CTYPi) ) # stores synapse codes (from labels.py)
syty2 = zeros( (CTYPi, CTYPi) ) # stores synapse code (from labels.py)
syty3 = zeros( (CTYPi, CTYPi) ) # stores synapse code (from labels.py)
sytys1 = {} # dictionary of synapse names
sytys2 = {} # dictionary of synapse names
sytys3 = {} # dictionary of synapse names
SOMA = 0; BDEND = 1; ADEND1 = 2; ADEND2 = 3; ADEND3 = 4;
dsecnames = ['soma','Bdend','Adend1','Adend2','Adend3']
def setdivmat ():
import math
for ty1 in xrange(CTYPi):
for ty2 in xrange(CTYPi):
if pmat[ty1][ty2] > 0.0:
div[ty1][ty2] = math.ceil(pmat[ty1][ty2]*numc[ty2])
conv[ty1][ty2] = int(0.5 + pmat[ty1][ty2]*numc[ty1])
# setup cell-type-to-cell-type synapse-type information
def setsyty ():
for ty1 in xrange(CTYPi): # go thru presynaptic types
for ty2 in xrange(CTYPi): # go thru postsynaptic types
syty1[ty1][ty2] = syty2[ty1][ty2] = syty3[ty1][ty2] = -1 # initialize to invalid
if numc[ty1] <= 0 or numc[ty2] <= 0: continue
if ice(ty1): # is presynaptic type inhibitory?
if IsLTS(ty1): # LTS -> X
syty1[ty1][ty2] = GA2 # code for dendritic gabaa synapse
if ice(ty2): # LTS -> Io
sytys1[(ty1,ty2)] = "GABAss"
else: # LTS -> E
syty2[ty1][ty2] = GB2 # code for denritic gabab synapse
sytys1[(ty1,ty2)] = "GABAs"
sytys2[(ty1,ty2)] = "GABAB"
else: # BAS -> X
syty1[ty1][ty2] = GA # code for somatic gabaa synapse
sytys1[(ty1,ty2)] = "GABAf"
else: # E -> X
syty1[ty1][ty2] = AM2 # code for dendritic ampa synapse
syty2[ty1][ty2] = NM2 # code for dendritic nmda synapse
if ice(ty2): # E -> I
sytys1[(ty1,ty2)] = "AMPA"
sytys2[(ty1,ty2)] = "NMDA"
else: # E -> E
sytys1[(ty1,ty2)] = "AMPA"
sytys2[(ty1,ty2)] = "NMDA"
sytys3[(ty1,ty2)] = "mGLUR"
syty3[ty1][ty2] = MG # use MG -- for mGluR
lctyID,lctyClass = [],[]
# setup some convenient data structures
def setix (scale):
import math
global allcells,ecells,icells
for i in xrange(CTYPi):
numc[i] = int(math.ceil(cpernet[i]*scale))
if numc[i] > 0:
ty = PyrAdr
if ice(i):
if IsLTS(i): ty = LTS
else: ty = FS
for j in xrange(numc[i]):
lctyClass.append(ty)
lctyID.append(i)
allcells += numc[i]
if ice(i): icells += numc[i]
else: ecells += numc[i]
sidx = 0
for i in xrange(CTYPi):
if numc[i] > 0:
ix[i] = sidx
ixe[i] = ix[i] + numc[i] - 1
sidx = ixe[i] + 1
setdivmat()
setsyty()
# setcellpos([pseed,network diameter in microns])
def setcellpos (pseed=4321,cside=colside):
rdm=Random(); rdm.ACG(pseed)
cellsnq = NQS("id","ty","ice","xloc","yloc","zloc")
cellsnq.clear(allcells) # alloc space
lX,lY,lZ=[],[],[]
ldy = {}
ldy[E2] = (160, 420)
ldy[E4] = (420, 570)
ldy[E5R] = (570, 700)
ldy[E5B] = (700, 1040)
ldy[E5P] = (700, 1040)
ldy[E6] = (1040, 1350)
ldy[E6C] = (1040, 1350)
ldy[I2] = (160, 420)
ldy[I2L] = (160, 420)
ldy[I5] = (420, 1040)
ldy[I5L] = (420, 1040)
ldy[I6] = (1040, 1350)
ldy[I6L] = (1040, 1350)
for i in xrange(allcells):
ctyp = lctyID[i]
[x,y,z] = [rdm.uniform(0,cside), rdm.uniform(ldy[ctyp][0],ldy[ctyp][1]), rdm.uniform(0,cside)]
cellsnq.append(i,ctyp,ice(ctyp),x,y,z); lX.append(x); lY.append(y); lZ.append(z);
return cellsnq,lX,lY,lZ
setcpernet() # setup number of cells per network
setwmatex() # setup matrices of external inputs
setsynloc() # setup synapse location matrices
setdelmats() # setup delay matrices
setwmat() # setup weight matrix
setpmat() # setup connectivity matrix
setix(scale)
cellsnq,lX,lY,lZ=setcellpos()
ce = [] # cells on the host
gidvec = [] # gids of cells on the host
lncrec,ltimevec,lidvec=[],[],[] # spike recorders
dlids = {} # map from gid back to ce index
# create the cells
pcID = int(pc.id());
maxcells=0
cperhost = int(allcells/nhosts)
maxcells = cperhost
extra = allcells - cperhost*nhosts
if extra > 0: # check if any remainder cells
if pcID < extra: # first hosts get extra cell
maxcells += 1 # assign an extra cell if any remainders
gid = pcID * (cperhost + 1)
else: # rest of hosts do not
gid = extra*(cperhost+1) + (pcID-extra) * cperhost
else: # even division? all hosts get equal cells
gid = pcID * cperhost
for i in xrange(maxcells):
ct = lctyID[gid]
cell = lctyClass[gid](0+i*50,0,0,gid,ct)
cell.x,cell.y,cell.z = lX[gid],lY[gid],lZ[gid]
dlids[gid] = len(ce) # map from gid back to ce index
ce.append(cell)
gidvec.append(gid)
pc.set_gid2node(gid,pcID)
timevec,idvec = h.Vector(),h.Vector()
ncrec = h.NetCon(ce[-1].soma(0.5)._ref_v, None, sec=ce[-1].soma)
ncrec.record(timevec,idvec,gid)
ncrec.threshold = spiketh # 10 mV is default, lower it for FS cells
ltimevec.append(timevec); lidvec.append(idvec); lncrec.append(ncrec)
pc.cell(gid,lncrec[-1],1) # 1 as 3rd arg means this cell can be source for events
gid += 1
print(' Number of cells on node %i: %i' % (pcID,len(ce)))
pc.barrier()
# wire the network using a NQS table
nccl = []
def wirenq (cnq):
global nccl
nccl = [] # NetCon list for connections between cells
cnq.tog("DB")
vid1,vid2,vwt1,vwt2,vdel,vsec=cnq.getcol("id1"),cnq.getcol("id2"),cnq.getcol("wt1"),cnq.getcol("wt2"),cnq.getcol("del"),cnq.getcol("sec")
vwt3 = cnq.getcol("wt3")
for i in xrange(int(cnq.v[0].size())):
prid = int(vid1[i])
poid = int(vid2[i])
if not pc.gid_exists(poid): continue # only make the connection on a node that has the target
ty1 = lctyID[prid]
ty2 = lctyID[poid]
sname = dsecnames[int(vsec[i])] # which section is the synapse on?
syn = sname + sytys1[(ty1,ty2)]
wt1 = vwt1[i]
delay = vdel[i]
targ = ce[dlids[poid]]
nc1 = pc.gid_connect(prid, targ.__dict__[syn].syn)
nc1.delay = delay; nc1.weight[0] = wt1; nc1.threshold = spiketh; nccl.append(nc1)
wt2 = vwt2[i]
if wt2 > 0: # two synapses? (i.e., AMPA and NMDA)
syn = sname + sytys2[(ty1,ty2)]
if syn in targ.__dict__: # since GABAB not in Bdend
nc2 = pc.gid_connect(prid, targ.__dict__[syn].syn)
nc2.delay = delay; nc2.weight[0] = wt2; nc2.threshold = spiketh; nccl.append(nc2)
wt3 = vwt3[i]
if wt3 > 0: # three synapses? (i.e., AMPA and NMDA and mGLUR)
if verbose: print 'mGLUR synapse wt3 > 0:',wt3
syn = sname + sytys3[(ty1,ty2)]
if syn in targ.__dict__: # make sure target has this synapse (needed since Bdend does not have mGLUR)
nc3 = pc.gid_connect(prid, targ.__dict__[syn].syn)
nc3.delay = delay; nc3.weight[0] = wt3; nc3.threshold = spiketh; nccl.append(nc3)
#
def picksec (prty, poty, rdm):
if ice(poty): return SOMA
if ice(prty): # I -> E
if IsLTS(prty): # LTS -> E
if rdmsec: return rdm.discunif(ADEND1,ADEND3)
else: return ADEND3
else:
return SOMA
else: # E -> E
if rdmsec: return rdm.discunif(BDEND,ADEND3)
else: return ADEND3
# swire - spatial wiring: wires the network using pmat and cell positions
# (wiring probability affected by distance btwn cells)
# slambda (global) specifies length-constant for spatially-dependent fall-off in wiring probability
# slambda is only used for I->X wiring; for E->X wiring uses fixed probability
def swire (wseed):
global slambda
from math import sqrt,exp
[vidx,vdel,vtmp,vwt1,vwt2,vwt3,vprob] = [Vector() for x in xrange(7)]
z = 0
if slambda <= 0:
print "swire WARN: invalid slambda=", slambda, "setting slambda to ", colside/3
slambda=colside/3
slambdasq = slambda**2 # using squared distance
h.vrsz(1e4,vidx,vdel,vtmp)
rdm=Random(); rdm.ACG(wseed) #initialize random # generator
rdm.uniform(0,1)
vprob.resize(allcells**2); vprob.setrand(rdm)
pdx=0 # index into vprob
connsnq=NQS("id1","id2","del","wt1","wt2","wt3","sec")
connsnq.clear(1e3*allcells)
for prid in xrange(allcells):
vrsz(0,vidx,vdel,vwt1,vwt2,vwt3)
prty=lctyID[prid]
ic1=ice(prty)
for poty in xrange(0,CTYPi):
if numc[poty] > 0 and pmat[prty][poty]>0:
pbase = pmat[prty][poty]
for poid in xrange(ix[poty],ixe[poty]+1): # go thru postsynaptic cells
if prid==poid: continue # no self-connects
ic2=ice(lctyID[poid])
dx = lX[prid] - lX[poid]
dy = lY[prid] - lY[poid]
dz = lZ[prid] - lZ[poid]
ds = sqrt(dx**2 + dy**2 + dz**2) # Connectivity fall-off depends on 3D distance
if ic1: prob = exp(-ds/slambda) # probability of connect falls off only for I->X
else: prob = pbase
if prob >= vprob[pdx]: # rdm.uniform(0,1)
mindelay = delm[prty][poty]-deld[prty][poty]
maxdelay = delm[prty][poty]+deld[prty][poty]
delay=rdm.uniform(mindelay,maxdelay) # synaptic delay
delay += ds/axonalvelocity # add axonal delay
vidx.append(poid); vdel.append(delay)
if syty1[prty][poty]>=0: vwt1.append(wmat[prty][poty][int(syty1[prty][poty])])
else: vwt1.append(0)
if syty2[prty][poty]>=0: vwt2.append(wmat[prty][poty][int(syty2[prty][poty])])
else: vwt2.append(0)
if syty3[prty][poty]>=0: vwt3.append(wmat[prty][poty][int(syty3[prty][poty])])
else: vwt3.append(0)
pdx += 1
for ii in xrange(int(vidx.size())): connsnq.append(prid,vidx[ii],vdel[ii],vwt1[ii],vwt2[ii],vwt3[ii],picksec(prty , lctyID[int(vidx[ii])], rdm))
wirenq(connsnq) # do the actual wiring based on self.connsnq
return connsnq
connsnq=swire(WSEED)
pc.barrier() # wait for wiring to get completed
# setup rxd for E cells
# get list of all Sections associated with an excitatory cell
def getesec ():
esec = []
for cell in ce:
if ice(cell.ty): continue
for s in cell.all_sec: esec.append(s)
return esec
def pcidpr (s):
global pcID
print 'host',pcID,':',s
### RXD ###
[cyt,er,cyt_er_membrane,ca,caextrude,serca,leak,CB,caCB,buffering]=[None for i in xrange(10)]
rxdsec=getesec() # Section list for use with rxd
pc.barrier()
if len(rxdsec) > 0: # only use rxd if there are viable Sections
from neuron import rxd
rxd.options.use_reaction_contribution_to_jacobian = False # faster (checked a few days before 10/16/13)
fc, fe = 0.83, 0.17 # cytoplasmic, er volume fractions
cyt = rxd.Region(rxdsec, nrn_region='i', geometry=rxd.FractionalVolume(fc, surface_fraction=1))
er = rxd.Region(rxdsec, geometry=rxd.FractionalVolume(fe))
cyt_er_membrane = rxd.Region(rxdsec, geometry=rxd.ScalableBorder(1))
caDiff = 0.233
ca = rxd.Species([cyt, er], d=caDiff, name='ca', charge=2, initial=dconf['cacytinit'])
caexinit = dconf['caexinit']
caextrude = rxd.Rate(ca, (caexinit-ca[cyt])/taurcada, regions=cyt, membrane_flux=False)
ip3 = rxd.Species(cyt, d=0.283, name='ip3', initial=0.0)
# action of IP3 receptor
Kip3=0.13; Kact=0.4
minf = ip3[cyt] * 1000. * ca[cyt] / (ip3[cyt] + Kip3) / (1000. * ca[cyt] + Kact)
ip3r_gate_state = rxd.State(cyt_er_membrane, initial=0.8)
h_gate = ip3r_gate_state[cyt_er_membrane]
k = dconf['gip3'] * (minf * h_gate) ** 3
ip3r = rxd.MultiCompartmentReaction(ca[er]<>ca[cyt], k, k, membrane=cyt_er_membrane)
# IP3 receptor gating
ip3rg = rxd.Rate(h_gate, (1. / (1 + 1000. * ca[cyt] / (0.4)) - h_gate) / 400.0)
# IP3 degradation - moves towards baseline level (ip3_init)
ip3degTau = 1000 # 1000 ms
ip3deg = rxd.Rate(ip3, (0.0-ip3[cyt])/ip3degTau, regions=cyt, membrane_flux=False)
### RYR - based on Sneyd et al, 2003
# constants
k_a_pos = 1500000000000.0 # mM^-4/ms
k_a_neg = 0.0288 # /ms
k_b_pos = 1500000000.0 # mM^-3/ms
k_b_neg = 0.3859 # /ms
k_c_pos = 0.00175 # /ms
k_c_neg = 0.0001 # /ms
v1ryr = dconf['v1ryr'] # /ms
Ka_4 = k_a_neg / k_a_pos # Ka**4
Kb_3 = k_b_neg / k_b_pos # Kb**3
Kc = k_c_neg / k_c_pos
# w_state is fraction of RYR not in C2 state (closed state), ie fraction of RYR that is open
# w_infinity - equ: 29
c3ryr = (ca[cyt]**3)/Kb_3;
c4ryr = Ka_4/(ca[cyt]**4);
w_inf = (1.0 + c4ryr + c3ryr) / (1.0+(1.0/Kc)+ c4ryr + c3ryr)
w_state = rxd.State(cyt_er_membrane, initial=0.9999) # 0)#0.9999) # check if initial == 0???? or can put it as w_inf
# equ: 8 (which is the same as equ 22)
w_rate = rxd.Rate(w_state, 1.0 - w_state[cyt_er_membrane] / w_inf)
# P_ryr - gating variable - equ: 7 (which is the same as 27)
# (open probability)
ryr_gate = w_state[cyt_er_membrane] * (1.0 + c3ryr) / (1.0 + c4ryr + c3ryr)
# the following is extracted from equ 9 and 15
k_ryr = v1ryr*ryr_gate
ryr = rxd.MultiCompartmentReaction(ca[er]<>ca[cyt], k_ryr, k_ryr, membrane=cyt_er_membrane)
def setmGLURflux (): # mGLUR synapses generate ip3 that is fed into rxd ip3
for c in ce:
if ice(c.ty): continue
for syn,seg in zip([c.Adend3mGLUR.syn,c.Adend2mGLUR.syn,c.Adend1mGLUR.syn],[c.Adend3(0.5), c.Adend2(0.5), c.Adend1(0.5)]):
for node in ip3.nodes(seg):
node.include_flux(syn._ref_rip3)
def setrecip3 ():
for c in ce:
if ice(c.ty): continue
c.soma_ip3cyt = Vector(tstop/h.dt)
c.soma_ip3cyt.record( ip3[cyt].nodes(c.soma)(0.5)[0]._ref_concentration, recdt )
c.Adend3_ip3cyt = Vector(tstop/h.dt)
c.Adend3_ip3cyt.record( ip3[cyt].nodes(c.Adend3)(0.5)[0]._ref_concentration, recdt )
# SERCA pump: pumps ca from cyt -> ER
Kserca = 0.1 # Michaelis constant for SERCA pump
gserca = dconf['gserca']
serca = rxd.MultiCompartmentReaction(ca[cyt]>ca[er],gserca*(1e3*ca[cyt])**2/(Kserca**2+(1e3*ca[cyt])**2),membrane=cyt_er_membrane,custom_dynamics=True)
gleak = dconf['gleak'] # leak channel: bidirectional ca flow btwn cyt <> ER
leak = rxd.MultiCompartmentReaction(ca[er]<>ca[cyt], gleak, gleak, membrane=cyt_er_membrane)
def setreccaer (): # setup recording of ca[er] for each pyramidal cell in Adend3,soma center
for c in ce:
if ice(c.ty): continue
c.soma_caer = Vector(tstop/h.dt)
c.soma_caer.record( ca[er].nodes(c.soma)(0.5)[0]._ref_concentration, recdt )
c.Adend3_caer = Vector(tstop/h.dt)
c.Adend3_caer.record( ca[er].nodes(c.Adend3)(0.5)[0]._ref_concentration, recdt )
CB_init = dconf["CB_init"]
CB_frate = dconf["CB_frate"]
CB_brate = dconf["CB_brate"]
CBDiff = 0.043 # um^2 / msec
CB = rxd.Species(cyt,d=CBDiff,name='CB',charge=0,initial=CB_init) # CalBindin (Anwar)
caCB = rxd.Species(cyt,d=CBDiff,name='caCB',charge=0,initial=0.0) # Calcium-CB complex
kCB = [CB_frate, CB_brate] # forward,backward buffering rates
buffering = rxd.Reaction(ca+CB <> caCB, kCB[0], kCB[1], regions=cyt)
def setreccacb (): # setup recording of caCB for each pyramidal cell in Adend3,soma center
for c in ce:
if ice(c.ty): continue
c.soma_caCB = Vector(tstop/h.dt)
c.soma_caCB.record( caCB.nodes(c.soma)(0.5)[0]._ref_concentration, recdt )
c.Adend3_caCB = Vector(tstop/h.dt)
c.Adend3_caCB.record( caCB.nodes(c.Adend3)(0.5)[0]._ref_concentration, recdt )
setreccaer() # NB: only record from RXD variables after ALL species setup!
setreccacb() # otherwise, the pointers get messed up.
setrecip3()
setmGLURflux()
# setup inputs - first noise inputs
def getsyns ():
syns = {} # mapping of synapse names, first index is ice, second is synapse code
syns[ (0,MG) ] = ["Adend3mGLUR","Adend2mGLUR","Adend1mGLUR"]
syns[ (0,AM2) ] = ["Adend3AMPA","Adend2AMPA","Adend1AMPA","BdendAMPA"]
syns[ (1,AM2) ] = "somaAMPA"
syns[ (0,NM2) ] = ["Adend3NMDA","Adend2NMDA","Adend1NMDA","BdendNMDA"]
syns[ (1,NM2) ] = "somaNMDA"
syns[ (0,GB2) ] = ["Adend3GABAB","Adend2GABAB","Adend1GABAB"]
syns[ (0,GA2) ] = ["Adend3GABAs","Adend2GABAs","Adend1GABAs"]
syns[ (1,GA2) ] = "somaGABAss"
syns[ (0,GA) ] = "somaGABAf"
syns[ (1,GA) ] = "somaGABAf"
return syns
dsstr = ['AMPA', 'NMDA', 'GABAS', 'mGLUR', 'GABAB']
# adds synapses across dendritic fields for the E cells
def addsyns ():
for cell in ce:
cell.dsy = {}; cell.vsy = {}
if ice(cell.ty): continue
ds = {}; ds[cell.Adend3]='Adend3'; ds[cell.Adend2]='Adend2'; ds[cell.Adend1]='Adend1'; ds[cell.Bdend]='Bdend'
for sec in [cell.Adend3, cell.Adend2, cell.Adend1, cell.Bdend]:
llsy = [];
nloc = sec.nseg
llvsy = []; # for recording currents
for i,seg in enumerate(sec):
if seg.x == 0.0 or seg.x == 1.0: continue # skip endpoints
lsy = []; loc = seg.x; lvsy = [] #AMPA, NMDA, GABAA_slow, GABAB
#print 'loc:',loc
lsy.append(Synapse(sect=sec,loc=loc,tau1=0.05,tau2=5.3,e=0)); lvsy.append(h.Vector())#AMPA
lsy.append(SynapseNMDA(sect=sec,loc=loc,tau1NMDA=15,tau2NMDA=150,r=1,e=0)) # NMDA
lvsy.append(h.Vector())
lsy.append(Synapse(sect=sec,loc=loc,tau1=0.2,tau2=20,e=-80)) # GABAA_slow
lvsy.append(h.Vector())
lsy.append(SynapsemGLUR(sect=sec,loc=loc)) # mGLUR
for node in ip3.nodes(seg): node.include_flux(lsy[-1].syn._ref_rip3 ) # all the sub-segments get flux
lsy.append(SynapseGABAB(sect=sec,loc=loc)) # GABAB
lvsy.append(h.Vector())
llsy.append(lsy); llvsy.append(lvsy)
cell.dsy[sec] = llsy; cell.vsy[sec] = llvsy
sec = cell.soma; llsy = []; nloc = sec.nseg; llvsy = []
for i,seg in enumerate(sec):
if seg.x == 0.0 or seg.x == 1.0: continue # skip endpoints
lsy = []; loc = seg.x; lvsy = []
lsy.append(Synapse(sect=sec,loc=loc,tau1=0.07,tau2=9.1,e=-80)) # GABAA_fast
lvsy.append(h.Vector())
lsy.append(Synapse(sect=sec,loc=loc,tau1=0.05,tau2=5.3,e=0) ) # AMPA
lvsy.append(h.Vector())
lsy.append(SynapseNMDA(sect=sec,loc=loc,tau1NMDA=15,tau2NMDA=150,r=1,e=0)) # NMDA
lvsy.append(h.Vector())
llsy.append(lsy); llvsy.append(lvsy);
cell.dsy[sec] = llsy; cell.vsy[sec] = llvsy;
addsyns()
#creates NetStims (and associated NetCon,Random) - provide 'noise' inputs
#returns next useable value of sead
def makeNoiseNetStim (cel,nsl,ncl,nrl,nrlsead,syn,w,ISI,time_limit,sead):
#rd2 = h.Random(); rd2.ACG(sead); rd2.uniform(0,100)
ns = h.NetStim()
ns.interval = ISI
ns.noise = 1
ns.number = 2 * time_limit / ISI # create enough spikes for extra time, in case goes over limit
if type(syn) == str: nc = h.NetCon(ns,cel.__dict__[syn].syn)
else: nc = h.NetCon(ns,syn)
nc.delay = h.dt * 2 # 0
nc.weight[0] = w
rds = h.Random()
rds.negexp(1) # set random # generator using negexp(1) - avg interval in NetStim
rds.MCellRan4(sead,sead) # seeds are in order, shouldn't matter
ns.noiseFromRandom(rds) # use random # generator for this NetStim
ns.start = tstart # rd2.repick() # start inputs random time btwn 0-1e3 ms to avoid artificial sync
nsl.append(ns)
ncl.append(nc)
nrl.append(rds)
nrlsead.append(sead)
def makeNoiseNetStims (simdur,rdmseed):
nsl = [] #NetStim List
ncl = [] #NetCon List
nrl = [] #Random List for NetStims
nrlsead = [] #List of seeds for NetStim randoms
syns = getsyns() ;
for cell in ce: # go through cell types, check weights,rates of inputs
ct = cell.ty # get cell type code
if ice(ct): # only has 1 compartment
for sy in xrange(STYPi):
if wmatex[ct][sy] <= 0.0 or ratex[ct][sy] <= 0: continue
syn = syns[(ice(ct),sy)]
if type(syn) == list:
for idx,SYN in enumerate(syn):
makeNoiseNetStim(cell,nsl,ncl,nrl,nrlsead,SYN,wmatex[ct][sy],1e3/ratex[ct][sy],simdur,rdmseed*(cell.ID+1)*(idx+1))
else:
makeNoiseNetStim(cell,nsl,ncl,nrl,nrlsead,syn,wmatex[ct][sy],1e3/ratex[ct][sy],simdur,rdmseed*(cell.ID+1))
else: # E cells - need to distribute noise over all sections
for sec in [cell.Adend3, cell.Adend2, cell.Adend1]:
llsy = cell.dsy[sec]
for lsy in llsy:
for i,sy in enumerate([AM2,NM2,GA2,MG,GB2]):
if ratex[ct][sy] > 0. and wmatex[ct][sy] > 0.:
makeNoiseNetStim(cell,nsl,ncl,nrl,nrlsead,lsy[i].syn,wmatex[ct][sy],(1e3/ratex[ct][sy]),simdur,rdmseed*(cell.ID+1)*(i+1));
sec = cell.Bdend; llsy = cell.dsy[sec];
for lsy in llsy:
for i,sy in enumerate([AM2,NM2,GA2]):
if ratex[ct][sy] > 0. and wmatex[ct][sy] > 0.:
makeNoiseNetStim(cell,nsl,ncl,nrl,nrlsead,lsy[i].syn,wmatex[ct][sy],(1e3/ratex[ct][sy]),simdur,rdmseed*(cell.ID+1)*(i+4));
sec = cell.soma; llsy = cell.dsy[sec];
for i,sy in enumerate([GA,AM,NM]):
if ratex[ct][sy] > 0. and wmatex[ct][sy] > 0.:
for lsy in llsy:
makeNoiseNetStim(cell,nsl,ncl,nrl,nrlsead,lsy[i].syn,wmatex[ct][sy],(1e3/ratex[ct][sy]),simdur,rdmseed*(cell.ID+1)*(i+7)); rdmseed+=1
return nsl,ncl,nrl,nrlsead
nsl,ncl,nrl,nrlsead = makeNoiseNetStims(tstart+tstop,ISEED)
pc.barrier() # wait for completion of NetStim creation
#this should be called @ beginning of each sim - done in an FInitializeHandler
def init_NetStims ():
for i in xrange(len(nrl)):
rds = nrl[i]
sead = nrlsead[i]
rds.MCellRan4(sead,sead)
rds.negexp(1)
fihns = h.FInitializeHandler(0, init_NetStims)
# handler for printing out time during simulation run
def fi():
for i in xrange(int(tstart),int(tstart+tstop),100): h.cvode.event(i, "print " + str(i))
if pc.id() == 0: fih = h.FInitializeHandler(1, fi)
vt=Vector(); vt.record(h._ref_t); # record time
pc.barrier() # wait for NetStims to get setup
####################################################################################
### simulation run here
def myrun ():
pc.set_maxstep(10)
dastart,daend=None,None
if pc.id()==0:
dastart = datetime.now()
print 'started at:',dastart
h.stdinit()
if len(rxdsec)>0: # any sections with rxd?
ca[er].concentration = dconf['caerinit'] # 100e-6
ca[cyt].concentration = dconf['cacytinit'] # 100e-6
pc.psolve(h.t+tstop) # run for tstop
pc.barrier() # Wait for all hosts to get to this point
if pc.id()==0:
daend = datetime.now()
print 'finished ',tstop,' ms sim at:',daend
dadiff = daend - dastart;
print 'runtime:',dadiff, '(',tstop/1e3,' s)'
if dconf['dorun']: myrun()
# concatenate the results so can view/save all at once
lspks,lids=array([]),array([])
for host in xrange(nhosts): # is this loop required? can't just post messages from given host?
if host == pc.id():
for i in xrange(len(ltimevec)):
lspks=concatenate((lspks,ltimevec[i]))
lids=concatenate((lids,lidvec[i]))
# save data - output path based on simstr and pcid
def savedata (simstr,pcid):
safemkdir(outdir)
fn = outdir + '/' + simstr + '_pc_' + str(pcid) + '.npz'
print 'host ' , pcid, ' saving to ' , fn
ne,ni,szfast = 0,0,0
lE,lI=[],[]
for c in ce:
if ice(c.ty):
lI.append(c.ID)
ni += 1
else:
lE.append(c.ID)
ne += 1
szfast = int(c.soma_volt.size())
lE=array(lE) # lE is list of E cell IDs from this host
lI=array(lI) # Li is list of I cell IDs from this host
soma_volt = zeros((ne,szfast)); Adend3_volt = zeros((ne,szfast)); Bdend_volt=zeros((ne,szfast));
soma_voltI = zeros((ni,szfast));
cdx = 0; idx = 0;
for c in ce:
if ice(c.ty):
soma_voltI[idx,:] = c.soma_volt.to_python()
idx += 1
continue
soma_volt[cdx,:] = c.soma_volt.to_python()
Adend3_volt[cdx,:] = c.Adend3_volt.to_python()
Bdend_volt[cdx,:] = c.Bdend_volt.to_python()
cdx += 1
numpy.savez(fn,lctyID=array(lctyID),lX=array(lX),lY=array(lY),lZ=array(lZ),vt=vt.as_numpy(),lspks=lspks,lids=lids,lE=lE,lI=lI,Adend3_volt=Adend3_volt,Bdend_volt=Bdend_volt)
pc.barrier()
####################################################################################
if saveout: # save the sim data
if pcID == 0: print 'saving data'
savedata(simstr,pcID)
if saveconns and pcID == 0: # save connectivity data
print 'saving connections'
h.batch_flag = 1 # in case file already exists
connsnq.tog("DB")
connsnq.sv(outdir + '/' + simstr + 'connsnq.nqs')
pc.runworker()
pc.done()
if nhosts > 1: h.quit() # this means was likely running in batch mode