//----------------------------------------------------------------------------
// Initialize global variables
//----------------------------------------------------------------------------
/* COMMENTS see DBS_stim.txt */
DBS_STN = 0
DBS_STNGPe = 1
DBS_STNGPi = 2
DBS_GPeSTN = 3
DBS_GPeGPi = 4
DBS_GPeGPe = 5
DBS_GPiTha = 6
numDBS = 7
objref dbsONflags[numDBS],dbs_activationProb[numDBS], dbs_gidOffset
for tmpi=0,numDBS-1 {
dbsONflags[tmpi] = new Vector() //array of vectors containing indices into dbsStim object arrays
}
dbs_activationProb[DBS_STN] = new Vector(numSTN, 0.8)
dbs_activationProb[DBS_STNGPe] = new Vector(numSTN, 0.8)
dbs_activationProb[DBS_STNGPi] = new Vector(numSTN, 0.8)
dbs_activationProb[DBS_GPeSTN] = new Vector(numGPe, 0.8)
dbs_activationProb[DBS_GPeGPi] = new Vector(numGPe, 0.8)
dbs_activationProb[DBS_GPeGPe] = new Vector(numGPe, 0.8)
dbs_activationProb[DBS_GPiTha] = new Vector(numGPi, 0.8)
//gid offset of artificial cell (dbsStim object) gids, must be beyond those assigned to STN,GPe,GPi cells
// need gid to make connection for orthodromic event to be communicated
if (ncell > 1000) {
print "ERROR - gid overlap in dbsStim.hoc"
}
dbs_gidOffset = new Vector(numDBS)
dbs_gidOffset.x(DBS_STN) = 1000
dbs_gidOffset.x(DBS_STNGPe) = 2000
dbs_gidOffset.x(DBS_STNGPi) = 3000
dbs_gidOffset.x(DBS_GPeSTN) = 4000
dbs_gidOffset.x(DBS_GPeGPi) = 5000
dbs_gidOffset.x(DBS_GPeGPe) = 6000
dbs_gidOffset.x(DBS_GPiTha) = 7000
// ad* objects are dbsSTIM objects that apply a current to their somatic parent and send an event to orthodromic targets
// odnc* objects are pointers to NetCon objects connect an ad* to a target synapse, used to set weights and delays
objref directSTN[numSTN], adSTNGPe[numSTN], adSTNGPi[numSTN], adGPeSTN[numGPe], adGPeGPi[numGPe], adGPeGPe[numGPe], adGPiTha[numGPi]
//orthodromic effects through NetCon from antidromic sources of presyn cells that project to target
objref odncSTNGPe[numGPe], odncSTNGPi[numGPi], odncGPeSTN[numSTN], odncGPeGPi[numGPi], odncGPeGPe[numGPe] //vector of nclist indices for each cell
for tmpi=0,numSTN-1 {
if (pnm.gid_exists(cellID(ID_STN, tmpi))) {
directSTN[tmpi] = new dbsStim()
adSTNGPe[tmpi] = new dbsStim()
adSTNGPi[tmpi] = new dbsStim()
odncGPeSTN[tmpi] = new Vector()
}
}
for tmpi=0,numGPe-1 {
if (pnm.gid_exists(cellID(ID_GPe, tmpi))) {
adGPeSTN[tmpi] = new dbsStim()
adGPeGPi[tmpi] = new dbsStim()
adGPeGPe[tmpi] = new dbsStim()
odncSTNGPe[tmpi] = new Vector()
odncGPeGPe[tmpi] = new Vector()
}
}
for tmpi=0,numGPi-1 {
if (pnm.gid_exists(cellID(ID_GPi, tmpi))) {
adGPiTha[tmpi] = new dbsStim()
odncGPeGPi[tmpi] = new Vector()
odncSTNGPi[tmpi] = new Vector()
}
}
//----------------------------------------------------------------------------
// Functions to set up network from current value of global variables
//----------------------------------------------------------------------------
proc newStimOBJ() {local gid localobj dbs,nc,nil //($1:cell type, $2:index, $3:pathway type, $o4:dbsStim obj)
dbs = $o4
pnm.pc.gid2obj(cellID($1, $2)).soma dbs.loc(.5)
gid = cellID($1, $2) + dbs_gidOffset.x($3) //global id
pnm.pc.set_gid2node(gid, pnm.pc.id())
pnm.cells.append(dbs)
nc = new NetCon(dbs, nil)
pnm.pc.cell(gid, nc)
}
proc newStimNc() {local k,ncIndx localobj dbs,nc //($1:srctype,$2:srcIndx,$3:tartype,$4:tarIndx,$5:synIndx,$6:pathtype,$o7:ncIndx array[.])
//Get dbsStim object associated with presyn cell in this NetCon object.
// When it is antidromically active, its net_event will trigger an
// orthodromic event too, through this NetCon
ncIndx = pnm.nc_append(cellID($1, $2)+dbs_gidOffset.x($6), cellID($3, $4), synNum($1, $3, $5), 0, 0)
if (ncIndx >= 0) {
$o7.append(ncIndx)
}
}
proc STIconnectNet() { local i,j,k
//-----------------------------------------
// connections at/from STN
for i=0,numSTN-1 {
if (pnm.gid_exists(cellID(ID_STN, i))) {
newStimOBJ(ID_STN, i, DBS_STN, directSTN[i])
newStimOBJ(ID_STN, i, DBS_STNGPe, adSTNGPe[i])
newStimOBJ(ID_STN, i, DBS_STNGPi, adSTNGPi[i])
}
}
//-----------------------------------------
// connections from GPe
for i=0,numGPe-1 {
if (pnm.gid_exists(cellID(ID_GPe, i))) {
newStimOBJ(ID_GPe, i, DBS_GPeSTN, adGPeSTN[i])
newStimOBJ(ID_GPe, i, DBS_GPeGPi, adGPeGPi[i])
newStimOBJ(ID_GPe, i, DBS_GPeGPe, adGPeGPe[i])
}
}
//-----------------------------------------
// connections from GPi
for i=0,numGPi-1 {
if (pnm.gid_exists(cellID(ID_GPi, i))) {
newStimOBJ(ID_GPi, i, DBS_GPiTha, adGPiTha[i])
}
}
// Go through synapse lists for each cell (A) and find ad dbsStim objects for each presyn cell (Bs),
// then connect them as presyn objects to that cell (A)
//-----------------------------------------
// orthodromic dbs to STN
for i=0,numSTN-1 {
for j=0,numGPeSTN-1 {
newStimNc(ID_GPe, srcGPeSTN[i].x(j), ID_STN, i, j, DBS_GPeSTN, odncGPeSTN[i])
}
}
//-----------------------------------------
// orthodromic dbs to GPe
for i=0,numGPe-1 {
for j=0,numSTNGPe-1 {
newStimNc(ID_STN, srcSTNGPe[i].x(j), ID_GPe, i, j, DBS_STNGPe, odncSTNGPe[i])
}
for j=0,numGPeGPe-1 {
newStimNc(ID_GPe, srcGPeGPe[i].x(j), ID_GPe, i, j, DBS_GPeGPe, odncGPeGPe[i])
}
}
//-----------------------------------------
// orthodromic dbs to GPi
for i=0,numGPi-1 {
for j=0,numSTNGPi-1 {
newStimNc(ID_STN, srcSTNGPi[i].x(j), ID_GPi, i, j, DBS_STNGPi, odncSTNGPi[i])
}
for j=0,numGPeGPi-1 {
newStimNc(ID_GPe, srcGPeGPi[i].x(j), ID_GPi, i, j, DBS_GPeGPi, odncGPeGPi[i])
}
}
}
//----------------------------------------------------------------------------
proc STIupdateWeights() { local i,j
//-----------------------------------------
// connections at/from STN
for i=0,numSTN-1 {
if (pnm.gid_exists(cellID(ID_STN, i))) {
directSTN[i].del = dbs_del
directSTN[i].dur = dbs_dur
directSTN[i].amp = dbs_direct_amp
directSTN[i].pw = dbs_direct_pw
directSTN[i].period = dbs_period
directSTN[i].actPrb = dbs_activationProb[DBS_STN].x(i)
adSTNGPe[i].del = dbs_del
adSTNGPe[i].dur = dbs_dur
adSTNGPe[i].amp = dbs_ad_amp
adSTNGPe[i].pw = dbs_ad_pw
adSTNGPe[i].period = dbs_period
adSTNGPe[i].actPrb = dbs_activationProb[DBS_STNGPe].x(i)
adSTNGPi[i].del = dbs_del
adSTNGPi[i].dur = dbs_dur
adSTNGPi[i].amp = dbs_ad_amp
adSTNGPi[i].pw = dbs_ad_pw
adSTNGPi[i].period = dbs_period
adSTNGPi[i].actPrb = dbs_activationProb[DBS_STNGPi].x(i)
for j=0,numGPeSTN-1 {
pnm.nclist.o(odncGPeSTN[i].x(j)).weight = gmaxGPeSTN/numGPeSTN
pnm.nclist.o(odncGPeSTN[i].x(j)).weight[1] = 1 //dbs NetCon
pnm.nclist.o(odncGPeSTN[i].x(j)).delay = delGPeSTN
}
}
}
//-----------------------------------------
// connections from GPe
for i=0,numGPe-1 {
if (pnm.gid_exists(cellID(ID_GPe, i))) {
adGPeSTN[i].del = dbs_del
adGPeSTN[i].dur = dbs_dur
adGPeSTN[i].amp = dbs_ad_amp
adGPeSTN[i].pw = dbs_ad_pw
adGPeSTN[i].period = dbs_period
adGPeSTN[i].actPrb = dbs_activationProb[DBS_GPeSTN].x(i)
adGPeGPi[i].del = dbs_del
adGPeGPi[i].dur = dbs_dur
adGPeGPi[i].amp = dbs_ad_amp
adGPeGPi[i].pw = dbs_ad_pw
adGPeGPi[i].period = dbs_period
adGPeGPi[i].actPrb = dbs_activationProb[DBS_GPeGPi].x(i)
adGPeGPe[i].del = dbs_del
adGPeGPe[i].dur = dbs_dur
adGPeGPe[i].amp = dbs_ad_amp
adGPeGPe[i].pw = dbs_ad_pw
adGPeGPe[i].period = dbs_period
adGPeGPe[i].actPrb = dbs_activationProb[DBS_GPeGPe].x(i)
for j=0,numSTNGPe-1 {
pnm.nclist.o(odncSTNGPe[i].x(j)).weight = gmaxSTNGPe/numSTNGPe
pnm.nclist.o(odncSTNGPe[i].x(j)).weight[1] = 1 //dbs NetCon
pnm.nclist.o(odncSTNGPe[i].x(j)).delay = delSTNGPe
}
for j=0,numGPeGPe-1 {
pnm.nclist.o(odncGPeGPe[i].x(j)).weight = gmaxGPeGPe/numGPeGPe
pnm.nclist.o(odncGPeGPe[i].x(j)).weight[1] = 1 //dbs NetCon
pnm.nclist.o(odncGPeGPe[i].x(j)).delay = delGPeGPe
}
}
}
//-----------------------------------------
// connections from GPi
for i=0,numGPi-1 {
if (pnm.gid_exists(cellID(ID_GPi, i))) {
adGPiTha[i].del = dbs_del
adGPiTha[i].dur = dbs_dur
adGPiTha[i].amp = dbs_ad_amp
adGPiTha[i].pw = dbs_ad_pw
adGPiTha[i].period = dbs_period
adGPiTha[i].actPrb = dbs_activationProb[DBS_GPiTha].x(i)
for j=0,numSTNGPi-1 {
pnm.nclist.o(odncSTNGPi[i].x(j)).weight = gmaxSTNGPi/numSTNGPi
pnm.nclist.o(odncSTNGPi[i].x(j)).weight[1] = 1 //dbs NetCon
pnm.nclist.o(odncSTNGPi[i].x(j)).delay = delSTNGPi
}
for j=0,numGPeGPi-1 {
pnm.nclist.o(odncGPeGPi[i].x(j)).weight = gmaxGPeGPi/numGPeGPi
pnm.nclist.o(odncGPeGPi[i].x(j)).weight[1] = 1 //dbs NetCon
pnm.nclist.o(odncGPeGPi[i].x(j)).delay = delGPeGPi
}
}
}
}
strdef pstr
//----------------------------------------------------------------------------
proc dbsRESET() { local i
dbsOFF()
if (pnm.pc.id() == 0) {
// master tells all slave nodes to update network with inputs vector
pnm.pc.look_take("dbsRESET")
pnm.pc.post("dbsRESET")
pnm.pc.context("dbsRESET", 0)
for i=1,pnm.pc.nhost-1 {
sprint(pstr, "dbsRESET%d", i)
pnm.pc.take(pstr)
}
} else {
// slave nodes clear message from master and doit
pnm.pc.look("dbsRESET")
sprint(pstr, "dbsRESET%d", pnm.pc.id())
pnm.pc.post(pstr)
}
for i=0,numDBS-1 {
dbsONflags[i].resize(0)
}
}
//----------------------------------------------------------------------------
proc dbsOFF() { local i
if (pnm.pc.id() == 0) {
// master tells all slave nodes to update network with inputs vector
pnm.pc.look_take("dbsOFF")
pnm.pc.post("dbsOFF")
pnm.pc.context("dbsOFF", 0)
for i=1,pnm.pc.nhost-1 {
sprint(pstr, "dbsOFF%d", i)
pnm.pc.take(pstr)
}
} else {
// slave nodes clear message from master and doit
pnm.pc.look("dbsOFF")
sprint(pstr, "dbsOFF%d", pnm.pc.id())
pnm.pc.post(pstr)
}
// turn all OFF
for i=0,numSTN-1 {
if (pnm.gid_exists(cellID(ID_STN, i))) {
directSTN[i].active = 0
adSTNGPe[i].active = 0
adSTNGPi[i].active = 0
}
}
for i=0,numGPe-1 {
if (pnm.gid_exists(cellID(ID_GPe, i))) {
adGPeSTN[i].active = 0
adGPeGPi[i].active = 0
adGPeGPe[i].active = 0
}
}
for i=0,numGPi-1 {
if (pnm.gid_exists(cellID(ID_GPi, i))) {
adGPiTha[i].active = 0
}
}
}
//----------------------------------------------------------------------------
proc dbsON() { local i,j
dbsOFF()
if (pnm.pc.id() == 0) {
// master tells all slave nodes to update network with inputs vector
pnm.pc.look_take("dbsON")
for i=0,numDBS-1 {
pnm.pc.pack(dbsONflags[i])
}
pnm.pc.post("dbsON")
pnm.pc.context("dbsON", 0)
for i=1,pnm.pc.nhost-1 {
sprint(pstr, "dbsON%d", i)
pnm.pc.take(pstr)
}
} else {
// slave nodes clear message from master and doit
pnm.pc.look("dbsON")
for i=0,numDBS-1 {
pnm.pc.unpack(dbsONflags[i])
}
sprint(pstr, "dbsON%d", pnm.pc.id())
pnm.pc.post(pstr)
}
// turn selected components ON
for i=0, numDBS-1 {
for j=0,dbsONflags[i].size-1 {
if (i == DBS_STN) {
if (pnm.gid_exists(cellID(ID_STN, dbsONflags[i].x(j)))) {
directSTN[dbsONflags[i].x(j)].active = 1
}
}
if (i == DBS_STNGPe) {
if (pnm.gid_exists(cellID(ID_STN, dbsONflags[i].x(j)))) {
adSTNGPe[dbsONflags[i].x(j)].active = 1
}
}
if (i == DBS_STNGPi) {
if (pnm.gid_exists(cellID(ID_STN, dbsONflags[i].x(j)))) {
adSTNGPi[dbsONflags[i].x(j)].active = 1
}
}
if (i == DBS_GPeSTN) {
if (pnm.gid_exists(cellID(ID_GPe, dbsONflags[i].x(j)))) {
adGPeSTN[dbsONflags[i].x(j)].active = 1
}
}
if (i == DBS_GPeGPi) {
if (pnm.gid_exists(cellID(ID_GPe, dbsONflags[i].x(j)))) {
adGPeGPi[dbsONflags[i].x(j)].active = 1
}
}
if (i == DBS_GPeGPe) {
if (pnm.gid_exists(cellID(ID_GPe, dbsONflags[i].x(j)))) {
adGPeGPe[dbsONflags[i].x(j)].active = 1
}
}
if (i == DBS_GPiTha) {
if (pnm.gid_exists(cellID(ID_GPi, dbsONflags[i].x(j)))) {
adGPiTha[dbsONflags[i].x(j)].active = 1
}
}
}
}
}
//----------------------------------------------------------------------------
// Call setup functions when .hoc file is loaded
//----------------------------------------------------------------------------
STIconnectNet()
STIupdateWeights()
//----------------------------------------------------------------------------
// Dialog to update parameter values
//----------------------------------------------------------------------------