Layer V pyramidal cell model with reduced morphology (Mäki-Marttunen et al 2018)

 Download zip file   Auto-launch 
Help downloading and running models
Accession:187474
" ... In this work, we develop and apply an automated, stepwise method for fitting a neuron model to data with fine spatial resolution, such as that achievable with voltage sensitive dyes (VSDs) and Ca2+ imaging. ... We apply our method to simulated data from layer 5 pyramidal cells (L5PCs) and construct a model with reduced neuronal morphology. We connect the reduced-morphology neurons into a network and validate against simulated data from a high-resolution L5PC network model. ..."
References:
1 . Hay E, Hill S, Schürmann F, Markram H, Segev I (2011) Models of neocortical layer 5b pyramidal cells capturing a wide range of dendritic and perisomatic active properties. PLoS Comput Biol 7:e1002107 [PubMed]
2 . Hay E, Segev I (2015) Dendritic Excitability and Gain Control in Recurrent Cortical Microcircuits. Cereb Cortex 25:3561-71 [PubMed]
3 . Mäki-Marttunen T, Halnes G, Devor A, Metzner C, Dale AM, Andreassen OA, Einevoll GT (2018) A stepwise neuron model fitting procedure designed for recordings with high spatial resolution: Application to layer 5 pyramidal cells. J Neurosci Methods 293:264-283 [PubMed]
Model Information (Click on a link to find other models with that property)
Model Type: Neuron or other electrically excitable cell;
Brain Region(s)/Organism: Neocortex;
Cell Type(s): Neocortex L5/6 pyramidal GLU cell;
Channel(s): I Na,p; I Na,t; I L high threshold; I T low threshold; I A; I M; I h; I K,Ca; I Calcium; I A, slow;
Gap Junctions:
Receptor(s):
Gene(s):
Transmitter(s):
Simulation Environment: NEURON; NEURON (web link to model); Python; NeuroML;
Model Concept(s):
Implementer(s): Maki-Marttunen, Tuomo [tuomo.maki-marttunen at tut.fi]; Metzner, Christoph [c.metzner at herts.ac.uk];
Search NeuronDB for information about:  Neocortex L5/6 pyramidal GLU cell; I Na,p; I Na,t; I L high threshold; I T low threshold; I A; I M; I h; I K,Ca; I Calcium; I A, slow;
/
reducedhaymodel
network
models
TTC.hoc
TTC_det.hoc
                            
// Author: Etay Hay 2014
// Dendritic excitability and gain control in recurrent cortical microcircuits (Hay and Segev, 2014, Cerebral Cortex)
//
// Cell template of L5 thick-tufted pyramidal cell (TTC)
//
// Modified by Tuomo Maki-Marttunen 2015-2016, made the following changes:
//  -use ProbAMPANMDA2groupdet.mod instead of ProbAMPANMDA2.mod and ProbUDFsyn2groupdet.mod instead of ProbUDFsyn2.mod
//  -distributeSyn2 does what distributeSyn does in TTC.hoc: takes as an argument a list of numbers of synapses in each compartment
//  -distributeSyn divides the synapses into synapse groups

begintemplate TTC

public init, biophys, geom_nseg, biophys_inhomo
public synlist, connect2target, APC
public locateSites, getLongestBranch, distributeSyn, distributeSyn2
public initRand,insertMCcons
public preconlist ,synLocList, rList, preTrainList, preTrainIndexList
public setnetworkparameters,initPreSynTrain,queuePreTrains,setpretrains
public pA

public soma, dend, apic, stimThreshold, ASCIIrpt, HDF5rpt, getAbsSecIndex
public all, somatic, apical, basal, nSecSoma, nSecApical, nSecBasal, nSecAll, SecSyn
public nsegs
public NsynsE, NsynsI

objref synlist, SecSyn, ASCIIrpt, HDF5rpt, APC
objref all, somatic, apical, basal
objref preconlist, syngroupIndexList, rList, preTrainList, preTrainIndexList
objref rd1
objref this
objref sref,fih
objref NsynsE, NsynsI
objref synvarVecList, treenameList

strdef tstr

create soma[1], dend[1], apic[2]


proc init() {localobj nl,import
  all = new SectionList()
  somatic = new SectionList()
  basal = new SectionList()
  apical = new SectionList()

  apic[0] apical.append()
  apic[1] apical.append()
  soma[0] somatic.append()
  dend[0] basal.append()

  apic[0] all.append()
  apic[1] all.append()
  soma[0] all.append()
  dend[0] all.append()
  
  connect dend[0](0), soma[0](0)
  connect apic[0](0), soma[0](1)
  connect apic[1](0), apic[0](1)

  access soma

  soma insert pas
  dend insert pas
  apic[0] insert pas
  apic[1] insert pas

  nsegs = 5

  soma {nseg = nsegs Ra = 100 diam = 13.47 L = 23.17 cm = 1 V = -80 e_pas = -90}
  dend {nseg = nsegs Ra = 100 diam = 10.28 L = 282.13 cm = 2 V = -80 e_pas = -90}
  apic[0] {nseg = nsegs Ra = 100 diam = 5.04 L = 700.0 cm = 2 V = -80 e_pas = -90}
  apic[1] {nseg = nsegs Ra = 100 diam = 5.04 L = 600.53 cm = 2 V = -80 e_pas = -90}

  soma {
    insert Ca_LVAst
    insert Ca_HVA
    insert SKv3_1
    insert SK_E2
    insert K_Tst
    insert K_Pst
    insert Nap_Et2
    insert NaTa_t
    insert CaDynamics_E2
    insert Ih
    ek = -85
    ena = 50
    gIhbar_Ih = 0.0002
    g_pas = 0.0000338
    decay_CaDynamics_E2 = 460.0
    gamma_CaDynamics_E2 = 0.000501
    gCa_LVAstbar_Ca_LVAst = 0.00343
    gCa_HVAbar_Ca_HVA = 0.000992
    gSKv3_1bar_SKv3_1 = 0.693
    gSK_E2bar_SK_E2 = 0.0441
    gK_Tstbar_K_Tst = 0.0812
    gK_Pstbar_K_Pst = 0.00223
    gNap_Et2bar_Nap_Et2 = 0.00172
    gNaTa_tbar_NaTa_t = 2.04
  }
  dend {
    insert Ih
    gIhbar_Ih = 0.0002
    g_pas = 0.0000467
  }
  apic[0] {
    insert Ca_LVAst
    insert Ca_HVA
    insert SKv3_1
    insert SK_E2
    insert NaTa_t
    insert Im
    insert CaDynamics_E2
    insert Ih
    ek = -85
    ena = 50
    decay_CaDynamics_E2 = 122
    gamma_CaDynamics_E2 = 0.000509
    gSK_E2bar_SK_E2 = 0.0012
    gSKv3_1bar_SKv3_1 = 0.000261
    gNaTa_tbar_NaTa_t = 0.0213
    gImbar_Im = 0.0000675
    g_pas = 0.0000589
    gIhbar_Ih = 0.0004
    gCa_LVAstbar_Ca_LVAst = 0.0187
    gCa_HVAbar_Ca_HVA = 0.000555
  }
  apic[1] {
    insert Ca_LVAst
    insert Ca_HVA
    insert SKv3_1
    insert SK_E2
    insert NaTa_t
    insert Im
    insert CaDynamics_E2
    insert Ih
    ek = -85
    ena = 50
    decay_CaDynamics_E2 = 122
    gamma_CaDynamics_E2 = 0.000509
    gSK_E2bar_SK_E2 = 0.0012
    gSKv3_1bar_SKv3_1 = 0.000261
    gNaTa_tbar_NaTa_t = 0.0213
    gImbar_Im = 0.0000675
    g_pas = 0.0000589
    gIhbar_Ih = 0.0004
    gCa_LVAstbar_Ca_LVAst = 0.0187
    gCa_HVAbar_Ca_HVA = 0.000555
  }
  geom_nseg()
  area(0.5)
  distance()
  access soma
 
  synlist = new List()
  preconlist = new List()
  stimThreshold =0
  preTrainList = new List()
  preTrainIndexList = new List()
  syngroupIndexList = new List()
  synvarVecList = new List()
  pA = 0.5
}

proc setnetworkparameters(){
  rcpWeightFactor = $1 //how stronger reciprocal connections are on average
  EsynConductance = $2
  IsynConductance = $3
  NsynE = $4
  NsynI = $5
  contactsNumE = $6
  weight_AMPA = $7
  weight_factor_NMDA = $8
  weight_GABA = $9
  gNoiseCoeff = $10
}

proc geom() {
}

proc geom_nseg() {local nSec, L1, L2, D1, D2, nSeg1, nSeg2
  soma area(.5) // make sure diam reflects 3d points
  nSec = 0
  forsec all {
    nseg = 1 + 2*int(L/40)
    nSec = nSec + 1
  }

  nSecAll = 5
  nSecSoma = 1
  nSecApical = 2
  nSecBasal = 1
}

proc connect2target() { //$o1 target point process, $o2 returned NetCon
  soma $o2 = new NetCon(&v(1), $o1)
  $o2.threshold = -30
}

// $s1 section
func getLongestBranch(){local maxL,d localobj distallist,sref
    sprint(tstr,"%s distance()",$s1)
    execute(tstr,this)    
    
		maxL = 0
		d = 0
		distallist = new SectionList()
		forsec $s1 {
			sref = new SectionRef()
			if (sref.nchild==0) distallist.append()
		}
		forsec distallist{
			d = distance(1)
			if(maxL<d) maxL = d
		}
		// for the soma case
		if (maxL == 0) {
      $s1 {
        maxL = L
      }
    }
		return maxL
	}

// $s1 section
// $2 distance x in micrometers
// return list of [1,2] vectors  - of the appropriate section and the location in each vector
obfunc locateSites() {local maxL,site,d0,d1,siteX,i localobj vv,ll
	ll = new List()

  sprint(tstr,"%s distance()",$s1)
  execute(tstr,this)    
    
	maxL = getLongestBranch($s1)
	site = $2
	i = 0
	forsec $s1 {
    if (distance(0) < distance(1)) {
  		d0 = distance(0)
  		d1 = distance(1)
  	} else {
  		d1 = distance(0)
  		d0 = distance(1)
  	}

    if (site <= d1 && site >= d0) {
      siteX = (site-d0)/(d1-d0)
      secNum = i
      vv = new Vector()
      ll.append(vv.append(secNum,siteX))
		}
		i = i+1
	}
  return ll
}


//========================================================================================
//================================= microcircuit related stuff============================
//========================================================================================

// $1 some number that is function of the TTC index
//
// Have each TTC with unique sites, but certain portion of inputs identical to root TTC
proc initRand() {
  rList = new List() //for stochastic synapses

	rd1 = new Random($1) // unique to this TTC
	rd1.uniform(0,1)
}

double siteVec[2]

proc distributeSyn() {local sitenum,i, segInd, compInd localobj sl
	strdef treename,cmd2

        NsynsE = new List()
  	NsynsI = new List()
  	for i = 0, 2 {     
    	  NsynsE.append(new Vector(nsegs))
    	  NsynsI.append(new Vector(nsegs))
  	}

	lengthA = apic[0].L + apic[1].L
	lengthB = dend.L
        pA = lengthA/(lengthA + lengthB)

        for(i=0;i<2*3*nsegs;i+=1) {
          syngroupIndexList.append(new Vector())
        }

	for(i=0;i<(NsynE+NsynI);i+=1){
		if (rd1.repick()<pA){
			treename = "apic"
                        compInd = 1
		} else {
			treename = "dend"
                        compInd = 0
		}

		sl = locateSites(treename,rd1.repick()*getLongestBranch(treename))

  		sitenum = int((sl.count()-1)*rd1.repick())
                compInd = compInd + sl.o[sitenum].x[0] // if we are at apical, and sl.o[sitenum].x[0]=1, then compInd = 2, otherwise 1 at apical, and 0 at basal
                segInd = int(sl.o[sitenum].x[1]*nsegs)             
                if (i<NsynE) {                                                
                  NsynsE.o[compInd].x[segInd] = NsynsE.o[compInd].x[segInd] + 1
  		  syngroupIndexList.o[compInd*nsegs+segInd].append(i)
                } else {                                                       
                  NsynsI.o[compInd].x[segInd] = NsynsI.o[compInd].x[segInd] + 1
  		  syngroupIndexList.o[3*nsegs + compInd*nsegs+segInd].append(i)
                }                                                              
	}
}        


proc distributeSyn2() {local sitenum,syni,preconi,i,i1, segInd, compInd localobj sl,nilstim
	strdef cmd2
        //objref treenameList
        treenameList = new List()

        treenameList.append(new String("dend[0]"))
        treenameList.append(new String("apic[0]"))
        treenameList.append(new String("apic[1]"))

        for(i=0;i<NsynsE.count();i+=1){
            sprint(cmd2,"access %s",treenameList.o[i].s)
            execute(cmd2,this)
            sprint(cmd2,"%s sref = new SectionRef()",treenameList.o[i].s)
            execute(cmd2,this)

            for(iseg=0;iseg<NsynsE.o[i].size();iseg+=1) {
                segx = (0.5+iseg)/NsynsE.o[i].size()
                sref {
                        synlist.append(new ProbAMPANMDA2groupdet(segx))
                        syni = synlist.count()-1 //synapse index
                        rList.append(new Random(int(1000000*rd1.repick())))
                        rList.o[syni].negexp(1)
                        synlist.o[syni].setRNG(rList.o[syni])
                        synlist.o[syni].tau_r_AMPA = 0.3
                        synlist.o[syni].tau_d_AMPA = 3
                        synlist.o[syni].tau_r_NMDA = 2
                        synlist.o[syni].tau_d_NMDA = 65
                        synlist.o[syni].e = 0
                        synlist.o[syni].Dep = 800
                        synlist.o[syni].Fac = 0
                        synlist.o[syni].Use = 0.6
                        synlist.o[syni].u0 = 0
                        synlist.o[syni].gmax = EsynConductance*gNoiseCoeff
                        synlist.o[syni].weight_factor_NMDA = weight_factor_NMDA

                        Nsyns_thissyn = NsynsE.o[i].x[iseg]
                        synvarVecList.append(new Vector(3*Nsyns_thissyn))
                        for i1=0,Nsyns_thissyn-1 {
                          synvarVecList.o[synvarVecList.count()-1].x(i1) = 0
                          synvarVecList.o[synvarVecList.count()-1].x(Nsyns_thissyn+i1) = 1
                          synvarVecList.o[synvarVecList.count()-1].x(2*Nsyns_thissyn+i1) = 0
                          }
                        synlist.o[syni].setVec(synvarVecList.o[synvarVecList.count()-1])
                        preconlist.append(new NetCon(nilstim, synlist.o[syni]))
                        preconi = preconlist.count()-1 //connection index
                        preconlist.o[preconi].weight = weight_AMPA
                        preconlist.o[preconi].delay = 0
                }
            }
        }
        for(i=0;i<NsynsI.count();i+=1){
            sprint(cmd2,"access %s",treenameList.o[i].s)
            execute(cmd2,this)
            sprint(cmd2,"%s sref = new SectionRef()",treenameList.o[i].s)
            execute(cmd2,this)

            for(iseg=0;iseg<NsynsI.o[i].size();iseg+=1) {
                segx = (0.5+iseg)/NsynsI.o[i].size()
                sref {
                        synlist.append(new ProbUDFsyn2groupdet(segx))
                        syni = synlist.count()-1 //synapse index
                        rList.append(new Random(int(1000000*rd1.repick())))
                        rList.o[syni].negexp(1)
                        synlist.o[syni].setRNG(rList.o[syni])
                        synlist.o[syni].tau_r = 1
                        synlist.o[syni].tau_d = 20
                        synlist.o[syni].e = -80
                        synlist.o[syni].Dep = 800
                        synlist.o[syni].Fac = 0
                        synlist.o[syni].Use = 0.25
                        synlist.o[syni].u0 = 0
                        synlist.o[syni].gmax = IsynConductance*gNoiseCoeff

                        Nsyns_thissyn = NsynsI.o[i].x[iseg]
                        synvarVecList.append(new Vector(3*Nsyns_thissyn))
                        for i1=0,Nsyns_thissyn-1 {
                          synvarVecList.o[synvarVecList.count()-1].x(i1) = 0
                          synvarVecList.o[synvarVecList.count()-1].x(Nsyns_thissyn+i1) = 1
                          synvarVecList.o[synvarVecList.count()-1].x(2*Nsyns_thissyn+i1) = 0
                          }
                        synlist.o[syni].setVec(synvarVecList.o[synvarVecList.count()-1])
                        preconlist.append(new NetCon(nilstim, synlist.o[syni]))
                        preconi = preconlist.count()-1 //connection index
                        preconlist.o[preconi].weight = weight_GABA
                        preconlist.o[preconi].delay = 0
                }
            }
        }
}


// adds the microcircuit connections
// $o1 conVec - where 0 (no connection), 1 (one way), rcpWeightFactor (reciprocated)
proc insertMCcons(){local sitenum,syni,ii,jj localobj TconVec,sl
	strdef cmd2,treename
	
	TconVec = $o1

	for(ii=0;ii<TconVec.size();ii+=1){
		if(TconVec.x[ii]!=0){
			for(jj=0;jj<contactsNumE;jj+=1){
				if (rd1.repick()<pA){
					treename = "apic"
				} else {
					treename = "dend"
				}
	
				sl = locateSites(treename,rd1.repick()*getLongestBranch(treename))
	
				sitenum = int((sl.count()-1)*rd1.repick())
				siteVec[0] = sl.o[sitenum].x[0]
				siteVec[1] = sl.o[sitenum].x[1]
	
				sprint(cmd2,"access %s[siteVec[0]]",treename)
				execute(cmd2,this)
		
				sprint(cmd2,"%s[siteVec[0]] sref = new SectionRef()",treename)
				execute(cmd2,this)
	
				sref {
					synlist.append(new ProbAMPANMDA2(siteVec[1]))
					syni = synlist.count()-1 //synapse index
					rList.append(new Random(int(1000000*rd1.repick())))
					rList.o[syni].negexp(1)
					synlist.o[syni].setRNG(rList.o[syni])
					synlist.o[syni].tau_r_AMPA = 0.3
					synlist.o[syni].tau_d_AMPA = 3
					synlist.o[syni].tau_r_NMDA = 2
					synlist.o[syni].tau_d_NMDA = 65
					synlist.o[syni].e = 0
					synlist.o[syni].Dep = 0
					synlist.o[syni].Fac = 0
					synlist.o[syni].Use = 0.25
					synlist.o[syni].u0 = 0
					synlist.o[syni].gmax = TconVec.x[ii] * EsynConductance
				}
			}
		}
	}
}

//$o1 list of event time vectors
proc setpretrains(){local i,j,k,indsum localobj preTrainThis,preTrainIndicesThis,sortedIndicesThis
  for (i=0;i<syngroupIndexList.count();i+=1) { //The two loops can be combined as syngroupIndexList[0-14] only contain exc. and syngroupIndexList[15-29] only contain inh. syngroup indices
    preTrainThis = new Vector()
    preTrainIndicesThis = new Vector()
    for (j=0;j<syngroupIndexList.o[i].size();j+=1) {
      k = syngroupIndexList.o[i].x[j]
      preTrainThis.append($o1.o[k])
      preTrainIndicesThis.append(new Vector($o1.o[k].size(),j))
    }
    sortedIndicesThis = new Vector()
    sortedIndicesThis = preTrainThis.sortindex()
    preTrainList.append(preTrainThis.index(sortedIndicesThis))    
    preTrainIndexList.append(preTrainIndicesThis.index(sortedIndicesThis))    
  }
}

proc queuePreTrains(){
	fih = new FInitializeHandler("initPreSynTrain()",this)
}

// sets presynaptic spike events
proc initPreSynTrain(){local syni,ti
	for(syni=0;syni<preTrainList.count();syni+=1){
		for(ti=0;ti<preTrainList.o[syni].size();ti+=1){
			preconlist.o[syni].event(preTrainList.o[syni].x[ti])
		}
                synlist.o[syni].setVec2(preTrainIndexList.o[syni])
                //synlist.o[syni].printVec2()
	}
}

endtemplate TTC

Loading data, please wait...