// to parse the morphology data, then calculate the distance from the soma
// implemented by Kai Du, kai.du@ki.se
function findChildrenElements (parent)
str parent, msgtype , list
int num1,num2, numRaxial,numAxial, i
list = ""
num1 = {getmsg {parent} -out -count} // count the total outcoming msgs numbers
num2 = {getmsg {parent} -in -count} // incoming
// this is the ending compartment,
// so it has NO child comparment and return -1
if ((num1==1) && (num2==1))
return {list}
end
// if it is not the ending compartment
for (i=0;i< num1 ; i=i+1)
msgtype = {getmsg {parent} -out -type {i}} // find the msg-type corresponding to the msg-index number
if ({msgtype} == "AXIAL" ) // we only need the msg sending to its "child" compartments
list = {list}@" "@{getmsg {parent} -out -destination {i}} // note: we need a SPACE !!
end // end of if
end // end of for
return {list}
end
function deleteLastNode(nodelist)
str nodelist, list, node
int num,i
list = ""
num = {getarg {arglist {nodelist}} -count}
if({num == 0})
echo the nodelist is NULL
return
// elif({num} == 1)
// return {list}
else
for (i=1;i<num;i=i+1)
node = {getarg {arglist {nodelist}} -arg {i}}
list = {list}@" "@{node}
end
return {list}
end
end
function findDistance(parent,child)
str parent, child
float len,position1,position2
len = {getfield {child} len}
// echo the len is {len}
position1 = {getfield {parent} position}
position2 = {position1} + {len}
setfield {child} position {position2}
end
// Depth-first searching
function SetPosition(somapath)
str somapath,parent,child, listofBranches,list2, nodes, node1
int num1,num2,num3,i,flag
float position1,len,len2
//float x,y,z
if (!{exists {somapath}})
echo The current input {somapath} does not exist!
return
end
// listofBranches = {findChildrenElements {somapath}}
//foreach compt ({arglist {listofBranches}})
// echo now is {compt} in foreach
nodes ="" // start from the root
flag = 1
num2 = 1 // NUMBER of the nodes
num1 = 1 // NUMBER of the Child-compartment(s)
parent = {somapath} // Parent-compartment
len2 = {getfield {somapath} dia}
setfield {somapath} position {len2} //initialize the soma position
// if there is any node in the list:
int n=1
// while ({n}<=55)
// echo ""
// echo ""
// echo the {n}th loop
// echo the parent compt is {parent} and the number of nodes is {num2}
while ({num2}>0)
// echo ""
// echo the parent compt is {parent} and the number of nodes is {num2}
//we first find what is/are the next child compartment(s)
list2 = {findChildrenElements {parent}}
// echo the child compartment of {parent} is {list2}
// count the total number of child-compartment(s)
num1 = {getarg {arglist {list2}} -count}
// echo num1 is {num1}
/***************************************************/
/***if this is an ending compartment, we do:********/
/***************************************************/
if ({num1} == 0 )
parent = {getarg {arglist {nodes}} -arg {num2}} // switch to the last node in the list
// echo there are {num2} nodes in the list
// echo {child} is an end compartment, so it switches to {parent}
/*****************************************************/
// if this is a single child compartment, we do:
/*****************************************************/
elif ({num1} == 1)
child = {arglist {list2}}
findDistance {parent} {child} // (1) calculation of distance
parent = {child} // (2) update the parent compartment
// echo this is a single compt, so it switches to next one
/********************************************************/
// if this is a bifurcation
/*******************************************************/
elif ({num1} > 1)
i=1
child = {getarg {arglist {list2}} -arg {i}} // we choose the first one
// echo we now work on {child}!!
position1 = {getfield {child} position}
//adding this node into the node-list if the first child-compartment is not visited
if ({position1} ==0)
// echo the {child} has not been visited!
nodes = {nodes}@" "@{parent}
// echo add the parent nodes {parent} into the node-list
findDistance {parent} {child}
parent = {child}
// echo updated parent compartment {parent}
end
// if this compartment has already been visited, then move to the next one
// "position > 0" meaning this one has been visited
while({ position1 > 0}&&({i}<={num1}))
// echo {child} has been visited
// echo i is {i} and num1 is {num1}
if({i<num1})
child = {getarg {arglist {list2}} -arg {i+1}} // moving to the next branch by updating "i"
position1 = {getfield {child} position}
// echo we pick up {child} and its parent is {parent}
if ({position1}==0)
findDistance {parent} {child}
parent = {child}
end
elif({i==num1})
// echo the nodes before deletion are {nodes} and the current visiting compt is {child}
nodes = {deleteLastNode {nodes}} // delete the current node
// echo now the nodes left are {nodes}
num2 = {getarg {arglist {nodes}} -count} // update num2
if({num2}>0)
parent = {getarg {arglist {nodes}} -arg {num2}} // switch to the last node in the list
end
end // end of if
i=i+1
end // end of while
end // end of if
num2 = {getarg {arglist {nodes}} -count}
end // end of while
//n=n+1
//end
// end // end of foreach
end
function checkSet(cellpath)
str cellpath,compt, badCompts
float position1
int i=0
badCompts = ""
foreach compt ({el {cellpath}/##[TYPE=compartment]})
position1 = {getfield {compt} position}
if ({position1}==0)
badCompts = {badCompts}@" "@{compt}
i=i+1
end
end
//return {i}
return {badCompts}
end
//####################################################################################################
function add_exSyns_evenly(cellpath,a,b,number)
// number: num of AMPA/NMDA per compartment
str cellpath,compt,NMDAname,AMPAname
float a,b,position
int number,i
float AMPAcond = 170e-12
float NMDAcond = 470e-12
str buffer1 = "Ca_difshell_1" // name of the calcium pool in the spine
str buffer2 = "Ca_difshell_2"
str buffer3 = "Ca_difshell_3" // only to record NMDA-dependent [Ca]
foreach compt ({el {cellpath}/##[TYPE=compartment]})
position={getfield {compt} position}
if ({position>=a} && {position<b} )
for(i=1;i<=number;i=i+1)
NMDAname = "NMDAghk"@"_"@{i}
AMPAname = "AMPAghk"@"_"@{i}
addAMPAchannelGHKCa {compt} {AMPAname} {buffer1} {AMPAcond}
addNMDAchannelGHKCa {compt} {NMDAname} {buffer1} {NMDAcond}
if({exists /spikes/input_train/spike })
addmsg /spikes/input_train/spike {compt}/{NMDAname} SPIKE
addmsg /spikes/input_train/spike {compt}/{NMDAname} SPIKE
end // end of if ({exists /spikes/input_train/spike })
end // end of for...
end // end of if({position>=a} && {position<b} )
end // end of foreach...
end
//##########################################################################################################
function adjustCellForSpines(cellpath,a,b, F,F2 )
/***** The dendritic length and diameter of compartments are adjust for spines*************
********** L = l* F^(2/3); D = d* F^(1/3)***************************************************
************ the factor "F" is calculated by: F = A_dend+A_spines/A_dend********************
**ref: NMDA/AMPA Ratio Impacts State Transitions and Entrainment to Oscillations in a Computational Model of the Nucleus Accumbens Medium Spiny Projection Neuron. Wolf, et.al.2005
*/
str cellpath, compt
float a,b,position,dia,len,dia2,len2,Rm,Cm,Ra,Rm2,Cm2,Ra2,F,F2, Dsurf
//************************* Begin Warnings *********************************
if (!{exists {cellpath}})
echo the cell path {cellpath} does not exist! Please check it (add_CaShells)
return
end
if (a > b)
echo You set a WRONG boundary of a and b (add_CaShell)
return
end
//************************* End Warnings **********************************
foreach compt ({el {cellpath}/##[TYPE=compartment]})
//************** Begin external if statement*****************************
if (!{{compt} == {{cellpath}@"/axIS"} || {compt} == {{cellpath}@"/ax"}})
dia = {getfield {compt} dia}
position = {getfield {compt} position}
// echo the position of this compt is {position}
len = {getfield {compt} len}
Rm = {getfield {compt} Rm}
Cm = {getfield {compt} Cm}
Ra = {getfield {compt} Ra}
if ({{getpath {compt} -tail} == "soma"})
len = dia
end
//************** Begin internal if statement**************************
//if the compartment is not a spine and its position is between [a,b]
if ({position >= a} && {position < b} )
len2 = len*{pow {F} {2.0/3.0}}
dia2 = dia*{pow {F} {1.0/3.0}}
Rm2 = Rm*(dia*len/(dia2*len2))
// echo the old Rm is {Rm} and the new Rm is {Rm2}
Cm2 = Cm*(dia2*len2/(dia*len))
//Cm2 = Cm*10
// echo the old Cm is {Cm} and the new Cm is {Cm2}
if ({position} >= 30e-6)
Ra2 = Ra*(len2*dia*dia/(len*dia2*dia2))*F2 // "*4" as in Surmeier's paper
else
Ra2 = Ra
end
// echo the old Ra is {Ra} and the new Ra is {Ra2}
setfield {compt} dia {dia2}
setfield {compt} len {len2}
setfield {compt} Rm {Rm2}
setfield {compt} Cm {Cm2}
setfield {compt} Ra {Ra2}
end
end
end // end of foreach...
end
function set_colors(cellpath, compt_list,color_values)
str cellpath, path, compt, compt_list
float color_values
foreach compt ({arglist {compt_list}})
path = {cellpath}@"/"@{compt}
setfield {path} color {color_values}
end
end