//genesis //ConstrainUp.g /*Functions used to connect a set of spines that are constrained by *pathlength from soma *sharing a common parent branch, either soma, primary, secondary, or tertiary */ function ConnectWithDelay (totalDelay,meanDelay,othercell,compt,branchoffset,randDelayYesNo,mirrorBranch) str othercell, compt float meanDelay,branchoffset, mirrorBranch float totalDelay int i int randDelayYesNo //echo "minDelay: " {minDelay} " maxDelay: " {maxDelay} " StimDelay: " {StimDelay} addmsg {othercell}/spikegen {compt}/{NMDAname} SPIKE addmsg {othercell}/spikegen {compt}/{AMPAname} SPIKE int msgnum = {getfield {compt}/{NMDAname} nsynapses} - 1 if ({randDelayYesNo}==0) setfield {compt}/{NMDAname} synapse[{msgnum}].weight 1 synapse[{msgnum}].delay {totalDelay+meanDelay+branchoffset} msgnum = {getfield {compt}/{AMPAname} nsynapses} - 1 setfield {compt}/{AMPAname} synapse[{msgnum}].weight 1 synapse[{msgnum}].delay {totalDelay+meanDelay+branchoffset} totalDelay = totalDelay+meanDelay else float randDelay = {{-1.0*{meanDelay}}*{log {rand 0 1}}} // Transform from uniform dist to exp dist: -mean_expdist*ln(uniform(0,1)) float randBound = {10.0*{meanDelay}} if ({randDelay}>{randBound}) randDelay={randBound} end echo "random exponential for ISI= " {randDelay} setfield {compt}/{NMDAname} synapse[{msgnum}].weight 1 synapse[{msgnum}].delay {totalDelay+randDelay+branchoffset} msgnum = {getfield {compt}/{AMPAname} nsynapses} - 1 setfield {compt}/{AMPAname} synapse[{msgnum}].weight 1 synapse[{msgnum}].delay {totalDelay+randDelay+branchoffset} totalDelay = totalDelay+randDelay end return {totalDelay} end // This function loops through all spines, determines if each is valid (e.g. meets parent branch, distance requirements, // and appends valid spine names to a space-separated list (as a single string) which can then be manipulated with arglist, getarg routines function countSpines(startcomp,parenttype,maxpath) int parenttype str startcomp float maxpath str spinelist="",compt,compParent,commonBranch float compPathLen,rannum,minpath int numsp=0 //extract minpath from starting compartment; maxpath is total distance between start comp and most distant spine minpath={getfield {neuronname}/{startcomp} pathlen}-{getfield {neuronname}/{startcomp} len}/2 maxpath={minpath}+{maxpath} //parenttype is either 0:soma, 1:parentprim, 2:parentsec, 3:parenttert if ({parenttype}==0) commonBranch="soma" elif ({parenttype}==1) commonBranch={getfield {neuronname}/{startcomp} parentprim} elif ({parenttype}==2) commonBranch={getfield {neuronname}/{startcomp} parentsec} elif ({parenttype}==3) commonBranch={getfield {neuronname}/{startcomp} parenttert} end foreach compt ({el {neuronname}/##[TYPE=compartment]}) //is this a spine head, if so, determine pathlength if ({strcmp {getpath {compt} -tail} "head"} == 0) compPathLen={getfield {compt} pathlen} //is pathlength within min and max? If so, determine parent branch if ((compPathLen > minpath) && (compPathLen < maxpath)) // echo "within path length" {compt} if ({parenttype} == 1) compParent={getfield {compt} parentprim} elif ({parenttype} == 2) compParent={getfield {compt} parentsec} elif ({parenttype} == 3) compParent={getfield {compt} parenttert} else compParent="soma" end //is parent branch correct? if so count it and append to valid spine list if ({strcmp {compParent} {commonBranch}}==0) //count valid spines echo "valid sp" {compt} {compPathLen} "bt" {minpath} "&" {maxpath} "par:" {compParent} "numsp" {numsp+1} numsp=numsp+1 //append spinecompartment to spinelist followed by a space for a space-separated list spinelist = spinelist @ {compt} @ " " //echo {spinelist} end end end end return {spinelist} end //This function reads in a list of valid spines and the total number to connect, and connects the total number randomly by passing to connect w/delay //Note: this enables user to provide explicit list and option to connect to all in list in order or to use a list of spines generated by countSpines function connectSpines(spinelist,numstim,meanDelay,randDelayYesNo,branchoffset,mirrorBranch) //will need to add delay terms for when passing to connectwdelay str spinelist int numstim, randDelayYesNo, mirrorBranch float meanDelay, branchoffset float totalDelay = 0.0 int numconnected = 0 while (numconnected < numstim) //randomly select spine to connect until desired number (numstim) are connected int listlen= {getarg {arglist {spinelist}} -count} //how many left in list? int prob = {rand 1 {listlen+0.99999999}} //randomly select 1 integer within length of list. Note: 0.99... because int(rand b/t 1,1.999...) returns 1, etc., so i want the last item in list (for example, if listlen = 20, item 20) to have same probablility of being selected. Any rand b/t 20-20.999... returns 20 as int str connectwhich = {getarg {arglist {spinelist}} -arg {prob}} //which spine (based on index from prob)? totalDelay={ConnectWithDelay {totalDelay} {meanDelay} {precell} {connectwhich} {branchoffset} {randDelayYesNo} {mirrorBranch}} if ({mirrorBranch}==1) str mirrorcompt = {strsub {connectwhich} "tertdend1_" "tertdend2_"} ConnectWithDelay {totalDelay} 0.0 {precell} {mirrorcompt} {branchoffset} 0 1 //ConnectwithDelay but don't return new total Delay and pass mean 0, not rando, to match delay on original branch end echo "connect" {connectwhich} " delay" {totalDelay} numconnected = numconnected+1 // Generate new spinelist that takes the last entry and moves it to the entry just selected and reduces list by 1 str newlist = "" int i for (i=1;i<listlen;i=i+1) if (i==prob) str append = {getarg {arglist {spinelist}} -arg {listlen}} else str append = {getarg {arglist {spinelist}} -arg {i}} end newlist = newlist @ append @ " " end //echo {newlist} //echo {listlen} spinelist = newlist end end /* This function loops through all spines to either count the number filling criteria or to connect one of those spines */ function spineLoop(startcomp,parenttype,maxpath,connectProb,maxdelay,mindelay,mirrorbranch,branchoffset) int parenttype,mirrorbranch str startcomp, connectProb float maxpath,maxdelay,mindelay,branchoffset float compPathLen,ConnProb, rannum,StimDelay,meanDelay=0 str compt,compParent,commonBranch int numsp=0,connect=0 //echo "spineLoop function minDelay= " {mindelay} //extract minpath from the starting compartment //maxpath is the total distance between start comp and most distance spine float minpath={getfield {neuronname}/{startcomp} pathlen}-{getfield {neuronname}/{startcomp} len}/2 maxpath={minpath}+{maxpath} //strcmp returns 0 if connectProb = 0, so we do this only if NE 0 if ({strcmp {connectProb} "0"}) connect=1 ConnProb={connectProb} end //parenttype is either 0:soma, 1:parentprim, 2:parentsec, 3:parenttert if ({parenttype}==0) commonBranch="soma" elif ({parenttype}==1) commonBranch={getfield {neuronname}/{startcomp} parentprim} elif ({parenttype}==2) commonBranch={getfield {neuronname}/{startcomp} parentsec} elif ({parenttype}==3) commonBranch={getfield {neuronname}/{startcomp} parenttert} end foreach compt ({el {neuronname}/##[TYPE=compartment]}) //is this a spine head, if so, determine pathlength if ({strcmp {getpath {compt} -tail} "head"} == 0) compPathLen={getfield {compt} pathlen} //is pathlength within min and max? If so, determine parent branch if ((compPathLen > minpath) && (compPathLen < maxpath)) // echo "within path length" {compt} if ({parenttype} == 1) compParent={getfield {compt} parentprim} elif ({parenttype} == 2) compParent={getfield {compt} parentsec} elif ({parenttype} == 3) compParent={getfield {compt} parenttert} else compParent="soma" end //is parent branch correct? if so either count it (first time through loop) or connect with probability if ({strcmp {compParent} {commonBranch}}==0) if (connect) //if parenttert of this compartment is parenttert of start comp then connect for the mirrorbranch case //if ((mirrorbranch) && ({strcmp {getfield {compt} parenttert} {getfield {neuronname}/{startcomp} parentter}}}==0)) rannum={rand 0 1} if ({rannum}<{ConnProb}) StimDelay={ConnectWithDelay {mindelay} {maxdelay} {precell} {compt} {meanDelay} {branchoffset}} //count connected spines numsp=numsp+1 meanDelay=meanDelay+StimDelay echo "connect" {compt} "ranum" {rannum} "stimdelay" {StimDelay} if (mirrorbranch) str mirrorcompt = {strsub {compt} "tertdend1_" "tertdend2_"} StimDelay={ConnectWithDelay {mindelay} {maxdelay} {precell} {mirrorcompt} {meanDelay} {branchoffset}} echo "connect" {compt} "ranum" {rannum} "stimdelay" {StimDelay} numsp=numsp+1 end else echo "no connect" {compt} {rannum} "gt" {ConnProb} end else //count valid spines echo "valid sp" {compt} {compPathLen} "bt" {minpath} "&" {maxpath} "par:" {compParent} "numsp" {numsp+1} numsp=numsp+1 end end end end end if (connect) echo "meanDelay=" {meanDelay/numsp} "num connect=" {numsp} end return {numsp} end function ConstrainUp(numstim,startcomp,parenttype,maxpath,meanDelay,file,mirrorbranch,branchoffset,randDelayYesNo) int numstim,parenttype,mirrorbranch,randDelayYesNo str startcomp,file float maxpath,meanDelay,branchoffset // note: if mirrorbranch=1, the connected spines (location, and relative temporal order) should be equivalent for the case of multiple branches str noConnect="0" int nummsg=0 float initSim=0.1,postSim=0.62 //*********set up presynaptic element for stimulating PreSynStim {precell} //addmsg {precell}/spikegen /output/{Vmfile} SAVE state if ({mirrorbranch==1}) numstim = numstim/2 //Only works for if mirroring on 2 total branches, need to make more extensible in future // meanDelay/2 as well?? end //call spineloop to count number of valid spines str spinelist = {countSpines {startcomp} {parenttype} {maxpath}} //echo {spinelist} connectSpines {spinelist} {numstim} {meanDelay} {randDelayYesNo} {branchoffset} {mirrorbranch} end function connectGABA(totalDelay,compt,othercell,delay,offset) str compt, othercell float delay,offset, totalDelay addmsg {othercell}/spikegen {compt}/{GABAname} SPIKE int msgnum = {getfield {compt}/{GABAname} nsynapses} - 1 setfield {compt}/{GABAname} synapse[{msgnum}].weight 1 synapse[{msgnum}].delay {offset+delay} echo "connecting " {compt} "/" {GABAname} " with delay " {offset + delay} end function runConstrainUp(numstim,startcomp,parenttype,maxpath,meanDelay,file,mirrorbranch,branchoffset,randDelayYesNo) int numstim,parenttype,mirrorbranch,randDelayYesNo str startcomp,file float maxpath,meanDelay,branchoffset int run // Set up Hsolve if Using that Method if (hsolveYesNo==1) call {neuronname}/solve SETUP end reset reset //if ({numsp}<{numstim}) // echo "PROBLEM in SpineLoop:" {numsp} "spines < " {numstim} ": not enough spines fill criteria" // else //calculate connection prob, then call spineloop to connect spines //If mirroring branches, need to divide total spines by number of branches // also, if mirroring, change parent type to p3 HERE (after counting) so that only 1st branch is connected with spineloop // Then, if mirroring, connect with delay will perform the mirrored connection on the 2nd branch //float nstim=numstim //if (mirrorbranch) // nstim = numstim/2 //parenttype = 3 //end //float prob=nstim/numsp //echo "spines" {numsp} "stim" {numstim} "connecting with probability" {prob} //numsp = {spineLoop {startcomp} {parenttype} {maxpath} {prob} {maxdelay} {mindelay} {mirrorbranch} {branchoffset}} //end //**********set the file name and headers. Must be after spines connected spinehead={add_outputMultiSpines {spinefile} {0.1}} str saveComps= "secdend11,tertdend1_1,tertdend1_2,tertdend1_3,tertdend1_4,tertdend1_5,tertdend1_6,tertdend1_7,tertdend1_8,tertdend1_9,tertdend1_10,tertdend1_11,tertdend2_1,tertdend2_2,tertdend2_3,tertdend2_4,tertdend2_5,tertdend2_6,tertdend2_7,tertdend2_8,tertdend3_1,tertdend3_2,tertdend3_3,tertdend3_4,tertdend3_5,tertdend3_6,tertdend3_7,tertdend3_8,tertdend3_9,tertdend3_10,tertdend3_11" // // echo {saveComps} multispinehead={add_outputOneSpinePerComp {multispinefile} {neuronname} {saveComps} {chans}} // to look at spines in non stim compartments str filenam={file}@"p"@{parenttype}@{startcomp}@{maxpath}@"TimeDelay"@{meanDelay}@"Mirror_"@{mirrorbranch}@"BranchOffset_"@{branchoffset} spinehead={add_outputMultiSpines {spinefile} {2} {chans}} setfilename {Vmfile} {filenam} 1 {Vmhead} setfilename {Cafile} {filenam} 1 {Cahead} setfilename {Gkfile} {filenam} 1 {Gkhead} setfilename {spinefile} {filenam} 1 {spinehead} setfilename {Ikfile} {filenam} 1 {Ikhead} setfilename {multispinefile} {filenam} 1 {multispinehead} float initSim=0.1,postSim=.6 // //run the simulation step {initSim} -time setfield {precell} Vm 10 step 1 showfield {precell}/spikegen state lastevent setfield {precell} Vm 0 step {postSim} -time fileFLUSH {Vmfile} fileFLUSH {Cafile} fileFLUSH {Gkfile} fileFLUSH {spinefile} fileFLUSH {Ikfile} fileFLUSH {multispinefile} // //disconnect the spike generator, in preparation for another stimulation paradigm int nummsg={getmsg {precell}/spikegen -out -count} int i for (i=0; i<nummsg; i=i+1) deletemsg {precell}/spikegen 0 -outgoing end end