// General CA1 pyramidal cell model
// - with minimal set of ion channels and their distributions
// Morphology of cell n5038804 as used in Migliore et al J Neurophys 94:4145-4155, 2005.
// Based on Migliore et al 2005 - passive properties, Na, Kdr, Ka, Ih
// and Poirazzi et al Neuron 37:977-987, 2003 - IM, calcium currents (L, T, R), mAHP, sAHP
// Also Holbro et al PNAS 107:15975-15980, 2010 (fast Ca R)
// Geometry files must define the section lists:
// basal_list, apical_list, trunk_list, oblique_list, SR_list, SLM_list
// soma and axon sections must be called "soma" and "axon"
// SLMbr_list is a special list containing the sections in a single SLM branch
// (used for focal stimulation)
// Last update: BPG 2-5-14
begintemplate PyramidalCell
public is_art, totnseg, totarea, Vrest
public gna, NaMULT, arSOMA, arDIST, arMAX, gka, ghd
public init, topol, basic_shape, subsets, geom, biophys, set_dendrite
public pre_list, connect2target
public cell_init, plotvmx, newsyn, showsyn, showlayersyn, plotcamx, plotcamxd, plotcamxt
public soma, soma_list, axon_list, dendrite_list
public basal_list, apical_list, trunk_list, oblique_list
public SR_list, SRbrp_list, SRbrd_list, SRbrt_list, SRbrt2_list, SRbrtc_list
public SRprox_list, SRdist_list
public SLM_list, SLMbr_list, SLMbrt_list
public shead, sneck, spine_list, sneck_list
objref basal_list, apical_list, trunk_list, oblique_list
objref SR_list, SRbrp_list, SRbrd_list, SRbrt_list, SRbrt2_list, SRbrtc_list
objref SRprox_list, SRdist_list
objref SLM_list, SLMbr_list, SLMbrt_list
objref soma_list, axon_list, dendrite_list, pre_list, spine_list, sneck_list
external lambda_f
proc geom_nseg() {
forall { nseg = int((L/(0.1*lambda_f(freq))+.9)/2)*2 + 1 }
}
xopen("Cells/Mig_sec5038804.hoc") // Migliore section file
proc init() {
soma_list = new SectionList()
axon_list = new SectionList()
dendrite_list = new SectionList()
basal_list = new SectionList()
apical_list = new SectionList()
trunk_list = new SectionList()
oblique_list = new SectionList()
SR_list = new SectionList()
SRbrp_list = new SectionList()
SRbrd_list = new SectionList()
SRbrt_list = new SectionList()
SRbrt2_list = new SectionList()
SRbrtc_list = new SectionList()
SRprox_list = new SectionList()
SRdist_list = new SectionList()
SLM_list = new SectionList()
SLMbr_list = new SectionList()
SLMbrt_list = new SectionList()
spine_list = new SectionList()
sneck_list = new SectionList()
xopen("Cells/Mig_geo5038804.hoc") // Migliore geometry file
fix_seg = 0
// Spine dimesions (if spines used)
// approximate Grunditz et al model
//sneck_diam = 0.04 /* um (high resistance) */
sneck_diam = 0.125 /* um (low resistance) */
sneck_len = 1.0 /* um */
shead_diam = 0.5 /* um */
shead_len = 0.5 /* um */
// Passive properties from Migliore 2005
Vrest = -65
celsius = 35.0
Rm = 28000 // Migliore
//Rm = 200000 // Poirazi soma (cf Kali 300000)
RmDend = Rm
RmSoma = Rm
RmAx = Rm
Cm = 1
CmSoma= Cm
CmAx = Cm
CmDend = Cm
//RaAll= 50 // low Ra
//RaSoma=50
//RaAx = 50
//RaSpine = 50
RaAll= 150 // Migliore 2005
RaSoma=150
RaAx = 150
RaSpine = 150
gna = 0.025 // Migliore 2005
AXONM = 5
NaMULT = 0.015/0.025 // scale Na in dendrites (=1 for Migliore)
arSOMA = 1.0 // slow inactivation at soma (1=none; 0=max) (BPG)
arMAX = 0.5 // slow inact at distance (BPG)
arDIST = 350 // distance at which inactivation saturates (BPG)
gkdr = 0.01
gka = 0.03 // standard high KA
//gka = 0.01 // suitably reduced: low KA
KMULT = gka
KMULTP = gka
ghd=0.00005
//ghd=0.0001 // doubled Ih
soma_km = 0.06 // not used (BPG)
soma_caR = 0.03
soma_sAHP = 0.001
soma_mAHP = 0.001
caR_init = 0.03
sAHP_init = 0.001
mAHP_init = 0.001
caR_spine = 0.03
sAHP_spine = 0.001
mAHP_spine = 0.001
caR_vact = -30 // make half-activation point more hyperpolarised
caR_tinact = 20 // make inactivation faster
forsec axon_list {insert pas e_pas=Vrest g_pas = 1/RmAx Ra=RaAx cm=CmAx}
forsec soma_list {insert pas e_pas=Vrest g_pas = 1/RmSoma Ra=RaSoma cm=CmSoma}
forsec dendrite_list {insert pas e_pas=Vrest g_pas = 1/RmDend Ra=RaAll cm=CmDend}
access soma
freq=50
if (!fix_seg) {geom_nseg()} // adjust segment number in each section
totnseg=0
forall {totnseg=totnseg+nseg}
totarea=0
forall {for (x) totarea=totarea+area(x)}
access soma
distance()
forsec axon_list {
insert nax gbar_nax=gna*AXONM
insert kdr gkdrbar_kdr=gkdr
insert kap gkabar_kap = KMULTP
}
forsec soma_list {
insert hd ghdbar_hd=ghd vhalfl_hd=-73
insert na3 gbar_na3=gna ar_na3=arSOMA
insert kdr gkdrbar_kdr=gkdr
insert kap gkabar_kap = KMULTP
//insert km gbar_km=soma_km
insert carF gcabar_carF = soma_caR vha_carF=caR_vact ti_carF=caR_tinact
//insert kca gbar_kca = soma_sAHP // sAHP
insert kmAHP gkbar_kmAHP = soma_mAHP // mAHP
insert cad // calcium pump/buffering mechanism
}
forsec dendrite_list {
insert hd ghdbar_hd=ghd
insert na3 gbar_na3=gna*NaMULT
insert kdr gkdrbar_kdr=gkdr
insert kap gkabar_kap=0
insert kad gkabar_kad=0
//insert km gbar_km=soma_km
insert carF gcabar_carF = caR_init vha_carF=caR_vact ti_carF=caR_tinact
//insert kca gbar_kca = sAHP_init // sAHP
insert kmAHP gkbar_kmAHP = mAHP_init // mAHP
insert cad // calcium pump/buffering mechanism
insert ds
insert dca
for (x) if (x>0 && x<1) { xdist = distance(x)
// Na slow inactivation saturates at 350um (BPG)
if (xdist < arDIST) {
ar_na3(x) = arSOMA-(arSOMA-arMAX)*(xdist/arDIST)
} else {
ar_na3(x) = arMAX
}
// Ih saturates at 350um (BPG)
if (xdist < 350) {
ghdbar_hd(x) = ghd*(1+3*xdist/100)
} else {
ghdbar_hd(x) = ghd*(1+3*350/100)
}
// KA saturates at 350um (BPG)
if (xdist > 100 && xdist < 350) {
vhalfl_hd=-81
gkabar_kad(x) = KMULT*(1+xdist/100)
} else if (xdist >= 350) {
vhalfl_hd=-81
gkabar_kad(x) = KMULT*(1+350/100)
} else {
vhalfl_hd=-73
gkabar_kap(x) = KMULTP*(1+xdist/100)
}
}
}
cell_init()
pre_list = new List()
//synapses()
} // end init
proc set_dendrite() {
KMULT = gka
KMULTP = gka
access soma
distance()
forsec dendrite_list {
gbar_na3=gna*NaMULT
for (x) if (x>0 && x<1) { xdist = distance(x)
// Na slow inactivation saturates at 350um (BPG)
if (xdist < arDIST) {
ar_na3(x) = arSOMA-(arSOMA-arMAX)*(xdist/arDIST)
} else {
ar_na3(x) = arMAX
}
// Ih saturates at 350um (BPG)
if (xdist < 350) {
ghdbar_hd(x) = ghd*(1+3*xdist/100)
} else {
ghdbar_hd(x) = ghd*(1+3*350/100)
}
// KA saturates at 350um (BPG)
if (xdist > 100 && xdist < 350) {
vhalfl_hd=-81
gkabar_kad(x) = KMULT*(1+xdist/100)
} else if (xdist >= 350) {
vhalfl_hd=-81
gkabar_kad(x) = KMULT*(1+350/100)
} else {
vhalfl_hd=-73
gkabar_kap(x) = KMULTP*(1+xdist/100)
}
}
}
cell_init()
}
proc cell_init() {
t=0
forall {
v=Vrest
if (ismembrane("nax") || ismembrane("na3")) {ena=55}
if (ismembrane("kdr") || ismembrane("kap") || ismembrane("kad")) {ek=-90}
if (ismembrane("hd") ) {ehd_hd=-30}
}
finitialize(Vrest)
fcurrent()
forall {
for (x) {
if (ismembrane("na3")||ismembrane("nax")){e_pas(x)=v(x)+(ina(x)+ik(x))/g_pas(x)}
if (ismembrane("hd")) {e_pas(x)=e_pas(x)+i_hd(x)/g_pas(x)}
}
}
}
objref distrx, distry, c
proc plotvmx() { // plot max voltage with distance
c = new Graph()
c.size(0,1000,0,100)
c.xaxis(1)
c.exec_menu("10% Zoom out")
c.color(1)
c.label(0.4,0.8," peak AP")
distrx=new Vector()
distry=new Vector()
forsec $o1 {
for (x) if (x>0 && x<1) {
if (diam>=0.) {
distrx.append(distance(x))
distry.append(vmax_ds(x)-Vrest)
}
}
}
distry.mark(c,distrx,"O",3,3,2)
// distry.mark(c,distrx,"t",5,1,1)
c.flush()
doNotify()
}
objref cax, cay, cca
proc plotcamx() {local i // plot max ca across spine heads
cca = new Graph()
cca.size(0,$2,0,$3)
cca.xaxis(1)
cca.exec_menu("10% Zoom out")
cca.color(1)
cca.label(0.4,0.8," peak Ca")
cax=new Vector()
cay=new Vector()
i = 0
forsec $o1 {
i = i+1
cax.append(i)
cay.append(camax_dca(0.5))
}
cay.mark(cca,cax,"O",3,3,2)
cca.flush()
doNotify()
print cay.mean(), cay.max(), cay.min()
}
objref tcax, tcay, ccat
proc plotcamxt() {local i // plot max ca against time
ccat = new Graph()
ccat.size(0,$2,0,$3)
ccat.xaxis(1)
ccat.exec_menu("10% Zoom out")
ccat.color(1)
ccat.label(0.4,0.8," peak Ca")
tcax=new Vector()
tcay=new Vector()
i = 0
forsec $o1 {
tcax.append(tmax_dca(0.5))
tcay.append(camax_dca(0.5))
}
tcay.mark(ccat,tcax,"O",3,3,2)
ccat.flush()
doNotify()
print tcay.mean(), tcay.max(), tcay.min()
}
objref dcax, dcay, ccad
proc plotcamxd() { // plot max calcium with distance
ccad = new Graph()
ccad.size(0,1000,0,1)
ccad.xaxis(1)
ccad.exec_menu("10% Zoom out")
ccad.color(1)
ccad.label(0.4,0.8," peak Ca")
dcax=new Vector()
dcay=new Vector()
forsec $o1 {
for (x) if (x>0 && x<1) {
if (diam>=0.) {
dcax.append(distance(x))
dcay.append(camax_dca(x))
}
}
}
dcay.mark(ccad,dcax,"O",3,3,2)
// distry.mark(ccad,dcax,"t",5,1,1)
ccad.flush()
doNotify()
print dcay.mean(), dcay.max(), dcay.min()
}
obfunc connect2target() { localobj nc //$o1 target point process, optional $o2 returned NetCon
soma nc = new NetCon(&v(1), $o1)
nc.threshold = -10
if (numarg() == 2) { $o2 = nc } // for backward compatibility
return nc
}
// Code to add individual synapses in random locations (BPG 6-2-10)
create shead[1], sneck[1]
spi = 0 // current spine index
proc newsyn() { local i, j localobj syn, rl, syn_list, snr, shr
// $1 type $2 number $o3 target section list, $o4 uniform random no., $5 flag spines, $6 total spines
access soma
rl = new RandomLocation($o3, $o4)
if ($5 == 1 && spi == 0) {
create sneck[$6], shead[$6]
}
for i=0, $2-1 {
syn_list = new List()
if ($1 == 1) { // AMPA
soma syn = new Exp2Syn(0.5) pre_list.append(syn)
syn.tau1 = 0.5
syn.tau2 = 3
syn.e = 0
syn_list.append(syn)
} else if ($1 == 2) { // AMPA/NMDA
soma syn = new Exp2Syn(0.5) pre_list.append(syn)
syn.tau1 = 0.5 // Spruston JPhysiol 1995
syn.tau2 = 3 // Spruston JPhysiol 1995
syn.e = 0
syn_list.append(syn)
soma syn = new NMDAca(0.5) pre_list.append(syn)
syn.fCa = 0.1 // fraction of Ca current (Bloodgood & Sabatini)
syn.tcon = 3
syn.tcoff = 100
syn.mgconc = 1 // (mM) standard Mg conc
syn.gamma = 0.08 // Larkum Science 2009 (sharpens voltage curve)
syn_list.append(syn)
} else if ($1 == 3) { // GABAA
soma syn = new Exp2Syn(0.5) pre_list.append(syn)
syn.tau1 = 1
syn.tau2 = 8
syn.e = -75
syn_list.append(syn)
} else if ($1 == 4) { // GABAB
soma syn = new Exp2Syn(0.5) pre_list.append(syn)
syn.tau1 = 35
syn.tau2 = 100
syn.e = -75
syn_list.append(syn)
}
if ($5 == 1) { // spines
sneck[spi].L = sneck_len
sneck[spi].diam = sneck_diam
shead[spi].L = shead_len
shead[spi].diam = shead_diam
sneck[spi] {insert pas e_pas=Vrest g_pas=1/RmDend Ra=RaAll cm=CmDend
insert cad taur_cad=14 insert ds insert dca}
shead[spi] {insert pas e_pas=Vrest g_pas=1/RmDend Ra=RaAll cm=CmDend
insert carF gcabar_carF=caR_spine vha_carF=caR_vact ti_carF=caR_tinact
insert kmAHP gkbar_mAHP = mAHP_spine // mAHP
insert cad taur_cad=14 depth_cad=shead_diam/2
insert ds insert dca
}
sneck[spi] snr = new SectionRef()
sneck[spi] sneck_list.append()
shead[spi] shr = new SectionRef()
shead[spi] spine_list.append()
access soma
rl.locsp(syn_list, snr, shr)
spi = spi + 1
} else { // no spines
rl.loc(syn_list)
}
}
}
objref cell_shape
proc showsyn() { local i
cell_shape = new Shape()
for i=0,pre_list.count()-1 {
cell_shape.point_mark(pre_list.o(i), 3)
}
}
proc showlayersyn() { local i
if ($4 == 1) {
cell_shape = new Shape()
}
for i=$1,$2 {
cell_shape.point_mark(pre_list.o(i), $3)
}
}
//**********************************************************************
objref syn_
proc synapses() {
/* E0 */ soma syn_ = new Exp2Syn(0.5) pre_list.append(syn_)
syn_.tau1 = 0.5
syn_.tau2 = 3
}
func is_art() { return 0 }
endtemplate PyramidalCell