Distance-dependent synaptic strength in CA1 pyramidal neurons (Menon et al. 2013)

 Download zip file   Auto-launch 
Help downloading and running models
Accession:222726
Menon et al. (2013) describes the experimentally-observed variation in synaptic AMPA and NMDA conductance as a function of distance from the soma. This model explores the effect of this variation on somatic EPSPs and dendritic spike initiation, as compared to the case of uniform AMPA and NMDA conductance.
Reference:
1 . Menon V, Musial TF, Liu A, Katz Y, Kath WL, Spruston N, Nicholson DA (2013) Balanced synaptic impact via distance-dependent synapse distribution and complementary expression of AMPARs and NMDARs in hippocampal dendrites. Neuron 80:1451-63 [PubMed]
Citations  Citation Browser
Model Information (Click on a link to find other models with that property)
Model Type: Neuron or other electrically excitable cell; Synapse;
Brain Region(s)/Organism: Hippocampus;
Cell Type(s): Hippocampus CA1 pyramidal GLU cell;
Channel(s): I A; I K; I Na, slow inactivation;
Gap Junctions:
Receptor(s): AMPA; NMDA;
Gene(s):
Transmitter(s):
Simulation Environment: NEURON;
Model Concept(s): Synaptic Integration;
Implementer(s): Menon, Vilas [vilasmenon2008 at u dot northwestern dot edu];
Search NeuronDB for information about:  Hippocampus CA1 pyramidal GLU cell; AMPA; NMDA; I A; I K; I Na, slow inactivation;
/
MenonEtAl2013
README.txt
dv.mod
ih_new.mod
kadist.mod *
kaprox.mod *
kdrca1.mod *
leakcond.mod *
nafast2.mod
naslowcond2.mod
nmda.mod
spines.mod *
synampa.mod *
vmax.mod
vmax2.mod
vmaxlast.mod
vms.mod
code_membrane.hoc
code_objects.hoc
code_point_processes.hoc
code_routine_for_runs.hoc
code_run_multiple_spines_on_branch.hoc
code_run_single_spine.hoc
code_synapse_array_setup.hoc
code_synapse_setup.hoc
mosinit.hoc
ri06.nrn *
simulated_axon.nrn *
spinearraygeom.nrn
spinegeom.nrn
                            
// Double-click on this file to run the code

load_file("nrngui.hoc")			// neuron main menu and some key parameter init (must come first)
xopen("ri06.nrn")			// geometry

//Generate 10um segments 
ii = 0
tot_nsegs = 0
forall {
	if (ii != 0) {
		mynseg = int((L/10 + 0.9)/2)*2 + 1	
		if (mynseg == 0) {
			mynseg = 1 }
		nseg = mynseg
	}
	tot_nsegs = tot_nsegs + nseg
	ii = ii + 1
}

//load simulated axon and count segments
xopen("simulated_axon.nrn")			
hill {
	tot_nsegs = tot_nsegs + nseg
}
iseg {
	tot_nsegs = tot_nsegs + nseg
}
for jj = 0,1 node[jj] {
	tot_nsegs = tot_nsegs + nseg
}
for jj = 0,2 inode[jj] {
	tot_nsegs = tot_nsegs + nseg
}


naslopebasal=0				//constant Na conductance along basal dendrites
dslopebasal=0				//constant K conductance along basal disconnect
synwait=1000				//time to wait for membrane voltage to equilibrate				
tstop = 100+synwait			//simulation endtime
init_routine = 1			// 1 for using initialization routine
usecvode = 0				// 1 for using cvode

xopen("code_point_processes.hoc")			// point processes (original)
xopen("code_objects.hoc")			// additional objects (specific to geometry)
xopen("code_membrane.hoc")			// membrane mechanisms (was init)
xopen("code_routine_for_runs.hoc")			// contains regular run procedure


// these next few lines correct for the fact that the soma is elliptical rather than cylindrical
// due to an idiosyncrasy of NEURON, you have to do the area call first
access somaA
area(0.5)
correctsoma()

// This procedure initializes the active properties when called from the init() routine
init_params()
forall {insert dv}
insert_pass()
init_props()

// Create spine array, synapse array, and output files
xopen("spinearraygeom.nrn")
objref ampasyn[20], nmdasyn[20], locsyn
locsyn=new Vector(20)
for i=0,19 {
	ampasyn[i]=new synampa()
	nmdasyn[i]=new synnm()
}
objref scalefile
scalefile=new File()

//set spine neck resistance
for ii=0,19 {
	spineneckarray[ii].sec {Ra=200.00}
	spineneckarray[ii].sec {
		insert h
		insert pas
		insert kdr
		insert kap
		insert kad
		insert nafast2
		insert naslowcond2
	}
	spineheadarray[ii].sec {Ra=200.00}
	spineheadarray[ii].sec {
		insert h
		insert pas
		insert kdr
		insert kap
		insert kad
		insert nafast2
		insert naslowcond2
	}
}	
	
xopen("code_synapse_array_setup.hoc")

numruns=50
objref parvec, voltsvec
parvec=new Vector(4)
voltsvec=new Vector(9*20)
strdef filename

//set up random number generator and pick locations
objref r
r=new Random(2)
r.uniform(0,1)
objref randomvals, randomvals2
randomvals=new Vector(20*numruns*basalno)
randomvals2=new Vector(20*numruns*basalno)
for tt=0,20*numruns*basalno-1 {
	randomvals.x[tt]=r.repick()
	randomvals2.x[tt]=r.repick()
}

func makecluster() {local number, scale, synnumber,runval
	//assign locations and strengths to a cluster of synapses on the same branch
	dendno=$1
	synnumber=$2
	scale=$3
	runval=$4
	randindex=dendno*20*numruns+runval*20+synnumber
	seg=randomvals.x[randindex]
	Aval=NA
	Nval=NN
	syntype=1
	probval=randomvals2.x[randindex]
	if (probval<0.075) {
		Aval=calc_syn_strength(1,50)
		Nval=calc_syn_strength(2,50)
		syntype=-1
	}
	if (scale==1) {
		seg=findpoint(dend[dendno].sec.L,seg)
		soma.sec {distance()}
		dend[dendno].sec {dval=distance(seg)}
		perfprob=0.09
		if (dval<135) {perfprob=(0.03*dval+0.9)/55}
		if (probval<perfprob) {
			Aval=calc_syn_strength(1,dval)
			Nval=calc_syn_strength(2,dval)
			syntype=-1
		}
	}
	print "seg ",seg
	dend[dendno].sec connect spineneckarray[synnumber-1].sec(0), seg
	spineheadarray[synnumber-1].sec {
		insert pas
		g_pas=dend[dendno].sec.g_pas(seg)
		cm=dend[dendno].sec.cm(seg)
		gbar_nafast2=0
		gbar_naslowcond2=0
		gbar_kdr=0
		gbar_kap=0
		gbar_kad=0
		//gbar_nafast2=dend[dendno].sec.gbar_nafast2(seg)
		//gbar_naslowcond2=dend[dendno].sec.gbar_naslowcond2(seg)
		//gbar_kdr=dend[dendno].sec.gbar_kdr(seg)
		//gbar_kap=dend[dendno].sec.gbar_kap(seg)
		//gbar_kad=dend[dendno].sec.gbar_kad(seg)
		gbar_h=0
	}
	spineneckarray[synnumber-1].sec {
		insert pas
		g_pas=dend[dendno].sec.g_pas(seg)
		cm=dend[dendno].sec.cm(seg)
		gbar_nafast2=0
		gbar_naslowcond2=0
		gbar_kdr=0
		gbar_kap=0
		gbar_kad=0
		//gbar_nafast2=dend[dendno].sec.gbar_nafast2(seg)
		//gbar_naslowcond2=dend[dendno].sec.gbar_naslowcond2(seg)
		//gbar_kdr=dend[dendno].sec.gbar_kdr(seg)
		//gbar_kap=dend[dendno].sec.gbar_kap(seg)
		//gbar_kad=dend[dendno].sec.gbar_kad(seg)
		gbar_h=0
	}
	spineheadarray[synnumber-1].sec {print gbar_nafast2, gbar_naslowcond2, gbar_kdr}
	syn_cc_array(dendno,seg,Aval,synnumber-1)
	syn_nmdacc_array(dendno,seg,Nval,synnumber-1)
	//disconnect and zero out the remaining values
	for clustercount=synnumber,20-1 {
		syn_cc_array(dendno,0,0,clustercount)
		syn_nmdacc_array(dendno,0,0,clustercount)
	}
	seg = seg*syntype
	return seg
}


// set up parallel context		
objref pc
pc = new ParallelContext()
print "number of hosts: ", pc.nhost(), "\thost id: ", pc.id() 

//function farmed out to slave nodes
func distspike() {localobj parvec, returnvec
        key_ds = $1
        parvec = $o2
        returnvec = new Vector(9*parvec.x[1])
        returnvec = activate_and_run_synapses(parvec.x[0],parvec.x[1],parvec.x[2],parvec.x[3])

        pc.pack(returnvec)
        pc.post(key_ds)

        return key_ds
}


obfunc max_voltage() {localobj outvec
	// find the location and amplitude of maximum voltage change in a dendrite
	dendval_mv=$1
	outvec=new Vector(7) //entries 0-1 :max voltage, location, entries 2-4: first time, location, entries 5-6 soma dv and maxloc
	outvec.x[0]=0
	outvec.x[1]=0
	outvec.x[2]=tstop
	outvec.x[3]=0
	outvec.x[4]=0
	outvec.x[5]=soma.sec.dvmax_dv(0.5)
	outvec.x[6]=soma.sec.vmaxt_dv(0.5)
	print tstop
	dend[dendval_mv].sec {
		for maxcount=0,nseg+1 {
			testloc=maxcount/(nseg+1)
			if (dvmax_dv(testloc)>outvec.x[0]) {
				outvec.x[0] = dvmax_dv(testloc)
				outvec.x[1] = testloc
			}
			if (vmaxt_dv(testloc) < outvec.x[2]) {
				outvec.x[2] = vmaxt_dv(testloc)
				outvec.x[3] = testloc
				outvec.x[4] = dvmax_dv(testloc)
			}
		}
	}
	return outvec
}

//function to sequentially run different numbers of synapses
obfunc activate_and_run_synapses() {localobj mv, returnvec
	dendval_ar=$1
	maxsyn_ar=$2
	scalefactor_ar=$3
	run_ar=$4
	mv = new Vector(7)
	returnvec = new Vector(maxsyn_ar*9)
	for scount_ar=1,maxsyn_ar {
		seg_ar=makecluster(dendval_ar,scount_ar,scalefactor_ar,run_ar)
		init()
		run()
		mv=max_voltage(dendval_ar)
		for count_ar=0,6 {
			returnvec.x[(scount_ar-1)*9+count_ar]=mv.x[count_ar]
		}
		returnvec.x[(scount_ar-1)*9+7]=abs(seg_ar)
		returnvec.x[(scount_ar-1)*9+8]=seg_ar/abs(seg_ar)
	}
	for tempcount=0,maxsyn_ar-1 {
		spineneckarray[tempcount].sec disconnect()
	}
	return returnvec
}

pc.runworker()

//procedure to run simulations on 5 specific long branches that include proximal, middle, and distal regions
proc calc_spikes() {
	somaA distance()
	for ttt=0,4 {
		if (ttt==0) {m=24}
		if (ttt==1) {m=21}
		if (ttt==2) {m=29}
		if (ttt==3) {m=5}
		if (ttt==4) {m=64}
		dend[m].sec startlen=distance(0)
		if ((startlen>50) && (dend[m].sec.L>100) && (startlen<100)) {
			for soption=0,1 {
				if (soption==0) {
					sprint(filename,"basal_spike_noscaling_branch_%d.dat",m)
				} else {
					sprint(filename,"basal_spike_scaling_branch_%d.dat",m)
				}
                scalefile.wopen(filename)	
				scalefile.printf("Dendrite\tRun\tNum_synapses\tLast_synapse_location\tLast_synapse_distance\tMax_dV\tMax_dV_location\tFirst_peak_time\tFirst_peak_location\tFirst_peak_voltage\tSoma_dV\tSoma_peak_time\n")
				dend[m].sec() {
					for nn=1,200 {
						parvec.x[0]=m
						parvec.x[1]=20
						parvec.x[2]=soption
						parvec.x[3]=nn
						mmtag=10000*nn+100*m+soption
						print "submitting ", mmtag
						pc.submit("distspike",mmtag,parvec)	//send out simulation calculations
					}
						
					//collect error values
					while (pc.working()) {	
						key = pc.retval()	//retrieve the tag
						pc.look_take(key)	//remove the tag/job from the bulletin
						
						voltsvec = pc.upkvec()	//unpack the error value associated with the tag
			
						print "received key ",key
						rno=int(key/10000)
						dno=(key-rno*10000)/100
						for ss=1,20 {
							somaA distance()
							dend[dno].sec ddist=distance(voltsvec.x[(ss-1)*9+7])
							scalefile.printf("%d\t%d\t%d\t%g\t%g\t%d",dno,rno,ss,voltsvec.x[(ss-1)*9+7],ddist,voltsvec.x[(ss-1)*9+8])
							for tt=0,6 {
								scalefile.printf("\t%g",voltsvec.x[(ss-1)*9+tt])
							}	
							scalefile.printf("\n")
						}
						scalefile.flush()
					}
				}	
			}
		}
	}
}

		
calc_spikes()