/*
Makes a panel (2D array) of graphs that display the effects of
varying two parameters on simulation results.
*/
load_file("nrngui.hoc")
/*
This program loads a file that sets up the model that is to be simulated.
The model setup code is assumed to provide a proc shift() that can be
called with two numerical arguments, e.g.
shift(a,b)
shifts the voltage-dependence of the gating variables m and h
by a and b, respectively.
It is also expected to have a proc spinh() that ensures that model parameters
are correct for this particular series of simulations.
For example, proc shift() in initcav31y.hoc is
proc shift() {
forall {
mshift_cav31= $1
hshift_cav31= $2
}
}
and the NMODL source code for the density mechanism cav31 contains
these statements:
NEURON {
. . .
GLOBAL mshift, hshift
}
PARAMETER {
. . .
mshift = 0 (mV)
hshift = 0 (mV)
}
PROCEDURE rates() {
. . .
minf = 1 /(1+exp(-((v-mshift)+42.9)/5.16))
. . .
if((v-mshift) < -5.95){
: mtau = -0.856 + 1.494*exp(-v/27.4)
mtau = -0.856 + 1.494*exp(-(v-mshift)/27.4)
} else {
mtau = 1.0
}
. . . etc. for hshift's effect on hinf and htau . . .
}
Finally, initcav31y.hoc proc spinh() is
proc spinh() {
tstop = 150
tstop_changed()
ns.number = 1
ns.start = 10
nc.weight = 4e-4
stim.del = 30 // ms
stim.dur = 0.1 // ms
stim.amp = 1.8 // nA
}
*/
strdef MODEL // name of file that sets up the model
// MODEL = "initcav31y.hoc"
// MODEL = "initcav33y.hoc"
//MODEL = "mosinit.hoc" // instead have mosinit.hoc call this file
// if desired
objref gpanel // will be a "panel" of graphs
// implemented as an HBox that contains a bunch of VBoxes
objref pglist // a List that will hold the panel's Graphs
pglist = new List()
NUMV = 5 // # of vBoxes in the panel (# of graphs along the panel's x axis)
NUMG = 5 // # of Graphs in each vBox (# of graphs along the panel's y axis)
XGSIZE = 160 // 120 // width . . .
YGSIZE = 140 // 100 // . . . and height of each Graph
///// set up a gpanel
/*
makes a graph at specified location with specified size
$1 xloc
$2 yloc
$3 width
$4 height
returns objref that points to the graph
*/
obfunc makeg() { localobj tobj
tobj = new Graph(0)
tobj.size(0,5,-80,40)
tobj.view(0, -80, 5, 120, $1, $2, $3, $4)
return tobj
}
proc makeone() { local ii localobj str
str = new String()
ii = pglist.append(makeg(0,0,XGSIZE,YGSIZE))
sprint(str.s,"fig %d",ii-1)
pglist.o(ii-1).label(0.2, 0.3, str.s)
// doesn't need to return anything
}
proc makevbox() { local ii localobj vbox
vbox = new VBox()
vbox.intercept(1)
for ii=0,$1-1 makeone()
vbox.intercept(0)
vbox.map()
// doesn't need to return anything
}
obfunc makegpanel() { local ii,jj localobj gp
gp = new HBox()
gp.intercept(1)
for ii=0,$1-1 {
makevbox($2)
}
gp.intercept(0)
gp.map()
return gp
}
gpanel = makegpanel(NUMV, NUMG)
///// at last, the model cell
// load_file(MODEL) // instead this file is called by mosinit.hoc
//spinh() // so params are appropriate
//load_file("vhd.ses") // show v in spine and adjacent dendrite
// this really belongs in the other file
///// simulation control
///// run simulations and fill the graphs with results
/*
index = 0
for each x value
for each y value
run simulation
plot results in pglist.o(index)
index+=1
*/
objref tvec, cadvec, cahvec, mvec, hvec, m_inhibvec, h_inhibvec
tvec = new Vector()
cadvec = new Vector() // to capture time course of cai in dendrite
cahvec = new Vector() // and spine head
mvec = new Vector()
hvec = new Vector()
m_inhibvec = new Vector()
h_inhibvec = new Vector()
objref cadveclist,cahveclist,tveclist,mveclist,hveclist,m_inhibveclist,h_inhibveclist
cadveclist = new List() // to hold the time courses from all simulations
cahveclist = new List()
tveclist = new List()
mveclist = new List()
hveclist = new List()
m_inhibveclist = new List()
h_inhibveclist = new List()
proc shift() {
// note that a minus sign is included in the vshift_ca setting below
// because the vshift_ca is added to the membrane voltage which has
// the opposite effect of shifting the activation curve. For example
// if the membrane voltage was -50 and we added vshift = -20 to it
// we would get v=-70 so that where the activation is read out at
// at -70 is as though we shifted the activation 20 mV to the right
// if we considered keeping the v=-50.
mshift_ca = 0 // if shifting vshift make sure mshift is 0
vshift_ca = -$1 // global variable (changes for all instances)
Exp2Syn[2].e = $2 // middle spines gabaa synapse reversal potential
}
proc shift_m() {
// note that a minus sign is included in the vshift_ca setting below
// because the vshift_ca is added to the membrane voltage which has
// the opposite effect of shifting the activation curve. For example
// if the membrane voltage was -50 and we added vshift = -20 to it
// we would get v=-70 so that where the activation is read out at
// at -70 is as though we shifted the activation 20 mV to the right
// if we considered keeping the v=-50.
vshift_ca = 0 // if shifting mshift make sure vshift is 0
mshift_ca = -$1 // global variable (changes for all instances)
Exp2Syn[2].e = $2 // middle spines gabaa synapse reversal potential
}
load_file("hoc/int2mstr.hoc") // converts neg ints into m-prefix strdef mstr
strdef mstr1, mstr2 // temporary string to handle negative sign in file name
proc batrun() { local index, mshift, hshift
// debugging time step (big steps)
steps_per_ms = 10
dt=0.1
// first switch to high neck resistance state:
forsec "neck" {diam=0.05}
forsec "neck" {Ra=200}
// see fig1.hoc for key for spine_choice:
// turn on inhibition in Spine[1].head, Spine[spine_choice].head
NC[spine_choice].weight = 0.0004 // 4e-4 uS = 0.4 nS
cadveclist = new List()
cahveclist = new List()
tveclist = new List()
mveclist = new List()
hveclist = new List()
m_inhibveclist = new List()
h_inhibveclist = new List()
tvec = new Vector()
tvec.record(&t)
cadvec = new Vector()
cahvec = new Vector()
mvec = new Vector()
hvec = new Vector()
m_inhibvec = new Vector()
h_inhibvec = new Vector()
// teds dend[0] cadvec.record(&cai(0.1))
// teds head[0] cahvec.record(&cai(0.5))
// dendrite cadvec.record(&cai(181/L)) // 181/L =x adjacent to Spine[1] neck
// let cadvec record the other spine head, an aprox. uninhibited equivalent
if (mh_Ca_or_V==2) { // if true graph m,h
Spine[0].head mvec.record(&m_ca(0.5))
Spine[0].head hvec.record(&h_ca(0.5))
Spine[1].head m_inhibvec.record(&m_ca(0.5))
Spine[1].head h_inhibvec.record(&h_ca(0.5))
}
if (mh_Ca_or_V==1) { // if true graph Ca
Spine[0].head cadvec.record(&cai(0.5))
Spine[1].head cahvec.record(&cai(0.5))
}
if (mh_Ca_or_V==0) { // if true graph V
Spine[0].head cadvec.record(&v(0.5))
Spine[1].head cahvec.record(&v(0.5))
}
index = 0
for (mshift=-20; mshift<=-20+10*(NUMV-1); mshift+=10) {
// for (hshift=-20; hshift<=-20+10*(NUMG-1); hshift+=10) {
for (hshift=-80; hshift<=-80+10*(NUMG-1); hshift+=10) {// role of E_Cl
if (m_or_all) {
shift_m(mshift, hshift) // shift only the activation curve, m
} else {
shift(mshift, hshift) // shift all the curves in ca
}
run()
/*
cadvec.plot(pglist.o(index), tvec)
cahvec.plot(pglist.o(index), tvec)
*/
tveclist.append(tvec.c())
if (mh_Ca_or_V<2) { // graphs either Ca or V with these
cadveclist.append(cadvec.c())
cahveclist.append(cahvec.c())
// plot the copies of the Vectors
cadveclist.o(index).plot(pglist.o(index), tveclist.o(index))
cahveclist.o(index).plot(pglist.o(index), tveclist.o(index),2,1)
} else { // if ==2 then graph m,h)
mveclist.append(mvec.c())
hveclist.append(hvec.c())
m_inhibveclist.append(m_inhibvec.c())
h_inhibveclist.append(h_inhibvec.c())
// plot the copies of the Vectors
mveclist.o(index).plot(pglist.o(index), tveclist.o(index),1,1)
hveclist.o(index).plot(pglist.o(index), tveclist.o(index),3,1)
m_inhibveclist.o(index).plot(pglist.o(index), tveclist.o(index),2,1)
h_inhibveclist.o(index).plot(pglist.o(index), tveclist.o(index),7,1)
}
// store vectors (here is a simple example of write_vec(filename, vec, vec)
// write_vec("fig1/head0.dat",t_vec, head0_cai_vec)
// first take care of converting -20 to "m20" for file names etc.
int2mstr(mshift)
mstr1=mstr
int2mstr(hshift)
mstr2=mstr
if (mh_Ca_or_V==2) { // if true graph m,h
sprint(tmpstr,"figSuppl/mSpineLeft_%s_mshift_%s_E_Cl.dat",mstr1, mstr2)
write_vec(tmpstr,tveclist.o(index), mveclist.o(index))
sprint(tmpstr,"figSuppl/hSpineLeft_%s_mshift_%s_E_Cl.dat",mstr1, mstr2)
write_vec(tmpstr,tveclist.o(index), hveclist.o(index))
sprint(tmpstr,"figSuppl/mSpineMiddle_%s_mshift_%s_E_Cl.dat",mstr1, mstr2)
write_vec(tmpstr,tveclist.o(index), m_inhibveclist.o(index))
sprint(tmpstr,"figSuppl/hSpineMiddle_%s_mshift_%s_E_Cl.dat",mstr1, mstr2)
write_vec(tmpstr,tveclist.o(index), h_inhibveclist.o(index))
}
if (mh_Ca_or_V==1) { // if true graph Ca
sprint(tmpstr,"figSuppl/CaSpineLeft_%s_mshift_%s_E_Cl.dat",mstr1, mstr2)
write_vec(tmpstr,tveclist.o(index), cadveclist.o(index))
sprint(tmpstr,"figSuppl/CaSpineMiddle_%s_mshift_%s_E_Cl.dat",mstr1, mstr2)
write_vec(tmpstr,tveclist.o(index), cahveclist.o(index))
}
if (mh_Ca_or_V==0) { // if true graph V
sprint(tmpstr,"figSuppl/vSpineLeft_%s_mshift_%s_E_Cl.dat",mstr1, mstr2)
write_vec(tmpstr,tveclist.o(index), cadveclist.o(index))
sprint(tmpstr,"figSuppl/vSpineMiddle_%s_mshift_%s_E_Cl.dat",mstr1, mstr2)
write_vec(tmpstr,tveclist.o(index), cahveclist.o(index))
}
sprint(tmpstr,"mshift=%3.0f, E_Cl=%3.0f",mshift, hshift)
pglist.o(index).label(.15,.91,tmpstr)
// specify viewport
// for now the simplest
if (mh_Ca_or_V) { // if true graph Ca, and if false graph V's
pglist.o(index).exec_menu("View = plot")
} else {
pglist.o(index).size(100,130,-80, 20)
}
index+=1
}
}
}
///// convenience stuff for scaling graph axes
// $1 is max y axis value
proc setsize() { local i
for i=0,pglist.count()-1 pglist.o(i).size(0,150,0,$1)
}
proc veqp() { local i
for i=0,pglist.count()-1 pglist.o(i).exec_menu("View = plot")
}
yscale = -1
proc setscale() {
if ($1<=0) {
veqp()
} else {
setsize($1)
}
}
mh_Ca_or_V=0
m_or_all = 0
{
xpanel("Controls", 0)
xbutton("Batch run","batrun()")
xvalue("mh_Ca_or_V")
xlabel("mh_Ca_or_V=2 graphs m,h; mh_Ca_or_V=1 graphs Ca; mh_Ca_or_V=0 graphs V")
xvalue("m_or_all")
xlabel("m_or_all=1 shifts only m, m_or_all=0 shifts all Ca curves")
xvalue("Set y axis", "yscale", 1,"setscale(yscale)", 0, 1)
xlabel("(autoscales if <= 0)")
xpanel(227,704)
}
// this command will zoom in on the APs for the m,h panels:
// for i=0,pglist.count()-1 pglist.o(i).size(100,150,0,1)