the distance() function

The basics of how to develop, test, and use models.
rlindroos
Posts: 17
Joined: Thu Jan 02, 2014 2:23 pm

the distance() function

Post by rlindroos »

Hi,
I want to create a function for setting channel densities etc based on somatic cable/path distance for an anatomically detailed model (the morphology is imported from a .swc file). I first tried this function:

Code: Select all

    proc alldist() {
      soma distance() // make soma(0) be the reference point for distance measurements
      forall {
        print secname()
        for (x,0) print x, " ", distance(x)
      }
    }
from this tread:

http://www.neuron.yale.edu/phpbb/viewto ... =16&t=1975

that I think calcualtes the distance for each internal node to the center of the soma, right? To get the length from the end of each section I therefore added L/2 to each measurment.
The distances reported from this function was a little shorter than the previously calculated distances (using GENESIS and Matlab) so I desided to calculate the distances manually. This was done by following the example from this thread:

http://www.neuron.yale.edu/phpbb/viewto ... =15&t=2892

i.e. the end of each section the somatic distance were calulated by summing the length of all parent sections higher in the tree. This gave distances that were a little longer but still shorter than the expected ones.

My questions are therfore:
1) what distance does the distance() function calculate?
2) Is it possible to specify metric used in distance(), e.g. dendritic or radial etc?
3) what are the connection between the pt3d from the imported morphology and the distance() function?
4) where do I find the source/hoc code for the distance() function? (I have looked at /usr/local/nrn/share/nrn/lib/hoc/ using grep with no success).


Grateful for any help.
Robert

ps.
I have read about distance() at its reference page:
http://www.neuron.yale.edu/neuron/stati ... l#distance
ted
Site Admin
Posts: 6289
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: the distance() function

Post by ted »

The surest and safest way to proceed is to take advantage of the CellBuilder--see the tutotrial
Specifying parameterized variation of biophysical properties
at
http://www.neuron.yale.edu/neuron/stati ... /main.html

Make a toy model cell (soma, one or two apical dendritic branches, maybe some basilar branches), set up the gradient you want, export a hoc file that instantiates that gradient, and mine it for code that you can reuse with your own model cell.
ted
Site Admin
Posts: 6289
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: the distance() function

Post by ted »

I have read about distance() at its reference page:
http://www.neuron.yale.edu/neuron/stati ... l#distance
The conciseness of the Programmer's Reference is both its strength and its weakness. You will need to read that again, after first

1. reviewing the concepts of range and nseg--see chapters 5 and 6 of the NEURON Book, or read the relevant parts of
Hines, M.L. and Carnevale, N.T. The NEURON simulation environment. Neural Computation 9:1179-1209, 1997.
and
Hines, M.L. and Carnevale, N.T. NEURON: a tool for neuroscientists. The Neuroscientist 7:123-135, 2001.
(both available from links at http://www.neuron.yale.edu/neuron/nrnpubs).

and

2. verifying what you learned by running a few simple tests. Start NEURON and at the oc> prompt enter the following statements, one at a time:
create soma, dend
soma L = 10
dend L = 100
soma distance()
forall for (x) print secname(), " ", x, distance(x)
Did those results make sense?

Now execute
soma distance(0, 0.5)
and then repeat the forall statement (hint: use the keyboard's up arrow key to recall the command). Do the new results make sense?
I think calcualtes the distance for each internal node to the center of the soma
The comment in the code you cited says the reference point for distance measurements is soma(0). Middle of the soma is soma(0.5). This is why I suggested the particular reading material.
To get the length from the end of each section I therefore added L/2 to each measurment.
An ambiguous statement, and an unnecessary action. Each section has two ends. Do you mean the 1 end or the 0 end? For distances from the reference point to the 1 ends
forall print secname(), " ", distance(1)
The distances reported from this function was a little shorter than the previously calculated distances (using GENESIS and Matlab)
Does your new understanding now help you eliminate such discrepancies, and does it answer these questions?
1) what distance does the distance() function calculate?
2) Is it possible to specify metric used in distance(), e.g. dendritic or radial etc?
3) what are the connection between the pt3d from the imported morphology and the distance() function?
4) where do I find the source/hoc code for the distance() function? (I have looked at /usr/local/nrn/share/nrn/lib/hoc/ using grep with no success).
Implemented in C, contained in one of the files in the gzipped tar file of NEURON source code. Reading the C source code is not really the most direct way to understand what distance() does. If you followed the above suggestions, it shouldn't be necessary.
rlindroos
Posts: 17
Joined: Thu Jan 02, 2014 2:23 pm

Re: the distance() function

Post by rlindroos »

First of all, thank you for the fast reply - to have a living forum at disposal is fantastic!
Do the new results make sense?
It make perfect sence, thank you.
An ambiguous statement...
I realise I did not give enought detailes in the introduction of the question. I have not specified nseg so there is only one node per section and I wanted to compare the result gained here with the results from another model where each point is the end point of a compartment. Each dendritic stem is connected to the center of the soma.
Does your new understanding now help you eliminate such discrepancies, and does it answer these questions?
It does answer these questions about distance(). However the discrepancies remains. I think maybe the question should be restated as how the length of each section is calculated from the 3D points in the morphology file. But maybe that question should be stated in a separate thread? And maybe I should recheck the algorithm that calculates the length in GENESIS and Matlab (and perhaps even visit the source of the of the morphology file neuromorpho.org.)
ted
Site Admin
Posts: 6289
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: the distance() function

Post by ted »

rlindroos wrote:First of all, thank you for the fast reply - to have a living forum at disposal is fantastic!
Responsiveness to users is an important part of the NEURON project. Questions, suggestions, requests, and code contributions from users have all been very helpful for ensuring that NEURON continues to be a useful tool.
there is only one node per section and I wanted to compare the result gained here with the results from another model where each point is the end point of a compartment. Each dendritic stem is connected to the center of the soma.
Time to review several key points that follow from NEURON's use of the central difference approximation to the second spatial derivative. You may already know these, but other readers may not, so here goes:

The value accessed by statements of the form
rangevar(x)
will be the value of the range variable "rangevar" at the center of the compartment that contains x. If x is 0 or 1, it will be the value in the center of the first or last compartment along a section, respectively. If x lies on the boundary between two adjacent compartments in a section, the value returned will be governed by roundoff error--might be from the compartment centered at x-1/nseg/2, or the compartment centered at x+1/nseg/2

Since membrane potential has second order accuracy in space, the values calculated by NEURON provide a piecewise linear approximation to the variation of membrane potential with distance. This means that for any point along a section that does not lie at the center of a segment (compartment), a second order accurate value for the membrane potential at that point can be found by linear interpolation between the potentials at the two compartment centers that span x.
Does your new understanding now help you eliminate such discrepancies, and does it answer these questions?
It does answer these questions about distance(). However the discrepancies remains. I think maybe the question should be restated as how the length of each section is calculated from the 3D points in the morphology file.
Time to make a toy model and figure this out for yourself.

Code: Select all

create soma, dend
connect dend(0), soma(1)
soma {
  pt3dclear()
  pt3dadd(0,0,0,1)
  pt3dadd(10,0,0,1)
}
dend {
  pt3dclear()
  pt3dadd(0,0,0,1)
  pt3dadd(50,0,0,1)
  pt3dadd(50,50,0,1)
}
What do you expect distances from soma(0) to be? What does NEURON tell you? What does MatLab tell you?
Now try a cell that has the same neurite geometries, but in which dend is attached to soma(0.5)
Next try a cell in which dend's geometry is

Code: Select all

dend {
  pt3dclear()
  pt3dadd(0,0,0,1)
  pt3dadd(100,100,0,1)
}
Finally, try one that has

Code: Select all

dend {
  pt3dclear()
  pt3dadd(0,0,0,1)
  pt3dadd(50,0,0,1)
  pt3dadd(100,50,0,1)
}
rlindroos
Posts: 17
Joined: Thu Jan 02, 2014 2:23 pm

Re: the distance() function

Post by rlindroos »

Ok I think we are getting somewhere.

In general the distance I would expect for an arbitrary single branch structure in absolute coordinates connected to the mid point of the soma (i.e. we only count the dendritic length) is:

sum( norm( [x(i), y(i), z(i]) - [x(i-1), y(i-1), z(i-1)])

That is if we have two vectors a and b and want to calculate the distance (d) between them:

d = |a - b| = sqrt( (xa-xb)^2 + (ya-yb)^2 + (za-zb)^2 ).


That said, I followed your advice and build the three test models (I did change the soma and connec statement to more resemble the model I'm working with).

Code: Select all

// MODEL 1
////////////////////////////////////////////////////////////
    create soma, dend
    connect dend(0), soma(0.5)
    soma {
      pt3dclear()
      pt3dadd(-10,0,0,1)
      pt3dadd(0,0,0,1)
      pt3dadd(10,0,0,1)
    }
    dend {
      pt3dclear()
      pt3dadd(0,0,0,1)
      pt3dadd(50,0,0,1)
      pt3dadd(50,50,0,1)
    }
    soma distance(0, 0.5)
    
    forall for (x,0) {
    	print secname(), " ", distance(x) + L/2
    	} 

//MODEL 2
////////////////////////////////////////////////////////////
    create soma, dend
    connect dend(0), soma(0.5)
    soma {
      pt3dclear()
      pt3dadd(-10,0,0,1)
      pt3dadd(0,0,0,1)
      pt3dadd(10,0,0,1)
    }
    dend {
      pt3dclear()
      pt3dadd(0,0,0,1)
      pt3dadd(100,100,0,1)
    }
    soma distance(0, 0.5)
    
    forall for (x,0) {
    	print secname(), " ", distance(x) + L/2
    	} 

// MODEL 3
////////////////////////////////////////////////////////////
    create soma, dend
    connect dend(0), soma(0.5)
    soma {
      pt3dclear()
      pt3dadd(-10,0,0,1)
      pt3dadd(0,0,0,1)
      pt3dadd(10,0,0,1)
    }
    dend {
      pt3dclear()
      pt3dadd(0,0,0,1)
      pt3dadd(50,0,0,1)
      pt3dadd(100,50,0,1)
    }
    soma distance(0, 0.5)
    
    forall for (x,0) {
    	print secname(), " ", distance(x) + L/2
    	} 
Running them one by one I got the following result: 100, 141.4, 120.7

For each of the three test cases I also made one morphology file in the swc format (with a spherical soma).

Code: Select all

# MORPHOLOGY 1
1 1 0 0 0 1 -1     //soma
2 3 50 0 0 1 1
3 3 50 50 0 1 2

# MORPHOLOGY 2
1 1 0 0 0 1 -1     //soma
2 3 100 100 0 1 1

# MORPHOLOGY 3
1 1 0 0 0 1 -1    //soma
2 3 50 0 0 1 1
3 3 100 50 0 1 2
for each of these morphologies I then calcualted the dendritic length (using Matlab and GENESIS) and got the same values as I had obtained using NEURON.

Next insted of just writing hoc code I imported the morphologies using import3d in the same way I had done with the original morphology.

1) launch nrngui
2) click Tools -> Miscellaneous -> Import 3D
3) in the pop up window click choose a file
4) once the file was imported I clicked export -> Cellbuilder
5) In the cellbuilder window I clicked Management -> export -> export to file and save the files without specifying anything else.

After cleaning away some dead code and adding a print statement, the files had the following apperance.

Code: Select all

// model 1
proc celldef() {
  topol()
  subsets()
}

create soma, dend

proc topol() { local i
  connect dend(0), soma(0.5)
  basic_shape()
}
proc shape3d_1() {
  soma {pt3dclear()
	pt3dadd(-1, 0, 0, 2)
	pt3dadd(0, 0, 0, 2)
	pt3dadd(1, 0, 0, 2)
  }
  dend {pt3dclear()
	pt3dstyle(1, 0, 0, 0)
	pt3dadd(50, 0, 0, 2)
	pt3dadd(50, 50, 0, 2)
  }
}
proc basic_shape() {
  shape3d_1()
}

objref all, somatic, basal
proc subsets() { local i
  objref all, somatic, basal
  all = new SectionList()
    soma all.append()
    dend all.append()

  somatic = new SectionList()
    soma somatic.append()

  basal = new SectionList()
    dend basal.append()

}

access soma

celldef()
objref s

soma distance(0, 0.5)
    
    forall for (x,0) {
    	s = new SectionRef()
    	if (s.has_parent) {
    	print secname(), " ", distance(x) + L/2
    	} 
    }

Code: Select all

// model 2
proc celldef() {
  topol()
  subsets()
}

create soma

proc topol() { local i
  basic_shape()
}
proc shape3d_1() {
  soma {pt3dclear()
	pt3dadd(-1, 0, 0, 2)
	pt3dadd(0, 0, 0, 2)
	pt3dadd(1, 0, 0, 2)
  }
}
proc basic_shape() {
  shape3d_1()
}

objref all, somatic
proc subsets() { local i
  objref all, somatic
  all = new SectionList()
    soma all.append()

  somatic = new SectionList()
    soma somatic.append()

}

access soma

celldef()

objref s

soma distance(0, 0.5)
    
    forall for (x,0) {
    	s = new SectionRef()
    	if (s.has_parent) {
    	print secname(), " ", distance(x) + L/2
    	} 
    }

Code: Select all

// model 3
proc celldef() {
  topol()
  subsets()
  geom()
  biophys()
  geom_nseg()
}

create soma, dend

proc topol() { local i
  connect dend(0), soma(0.5)
  basic_shape()
}
proc shape3d_1() {
  soma {pt3dclear()
	pt3dadd(-1, 0, 0, 2)
	pt3dadd(0, 0, 0, 2)
	pt3dadd(1, 0, 0, 2)
  }
  dend {pt3dclear()
	pt3dstyle(1, 0, 0, 0)
	pt3dadd(50, 0, 0, 2)
	pt3dadd(100, 50, 0, 2)
  }
}
proc basic_shape() {
  shape3d_1()
}

objref all, somatic, basal
proc subsets() { local i
  objref all, somatic, basal
  all = new SectionList()
    soma all.append()
    dend all.append()

  somatic = new SectionList()
    soma somatic.append()

  basal = new SectionList()
    dend basal.append()

}
proc geom() {
}
proc geom_nseg() {
}
proc biophys() {
}
access soma

celldef()

objref s

soma distance(0, 0.5)
    
    forall for (x,0) {
    	s = new SectionRef()
    	if (s.has_parent) {
    	print secname(), " ", distance(x) + L/2
    	} 
    }
Interesingly model 1 and model 3 look pretty similar to the models made using hoc code but model 2 is for some reason not having any dendrites at all.

Following this I calculated the distances returned from these models. Here NEURON returned: 50, -, 70.7


To me this indicates that eighter I have done something wrong in the import or the import3d function is doing something I don't understand to the length of each/some sections (perhaps to the first point of the first section of each dendritic stem?).
ted
Site Admin
Posts: 6289
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: the distance() function

Post by ted »

rlindroos wrote:In general the distance I would expect for an arbitrary single branch structure in absolute coordinates
. . .
if we have two vectors a and b and want to calculate the distance (d) between them
Two items about which confusion may be possible:
1. NEURON's distance() function calculates the path distance from a reference point in a branched structure, not the distance between vectors.
2. The root section is treated as the origin of the cell with respect to 3D position. 3D information for each section is kept in an internal list of (x,y,z,diam) where the first point is the point that is connected to the parent, and the xyz values are automatically translated so that the first point's xyz values are the same as those of the parent node and all the other values are shifted by the same amount.

If you only want the distance of the sections' 1 ends from the reference point, just use
forall print secname(), " ", distance(1)
and be done with it--no need to find the distance to the 0.5 location and then add L/2.
For each of the three test cases I also made one morphology file in the swc format
In debugging, the null hypothesis is that "all user written code is incorrect." This also applies to user written data files. Can you prove that your homebrew swc geometry specifications are correct?
rlindroos
Posts: 17
Joined: Thu Jan 02, 2014 2:23 pm

Re: the distance() function

Post by rlindroos »

If you only want the distance of the sections' 1 ends from the reference point, just use
forall print secname(), " ", distance(1)
and be done with it--no need to find the distance to the 0.5 location and then add L/2.
Agreed, much better.
d = |a - b| = sqrt( (xa-xb)^2 + (ya-yb)^2 + (za-zb)^2 ).
Here I was a unclear again. to get the total distance between to nodes you need to sum all "vector distances" from the first node to the last. I.e.
Dtot = sum ( di ).
This follows from the nature of a morphology file (atleast of the swc and GENESIS format) that each row defines the "name", type, end point coordinates, radius (diameter in GENESIS) and parent. Hence the distances between to points can be treated as a vector. The source I used for this is the following web page:


http://research.mssm.edu/cnic/swc.html


I don't know how trustworthy it is tough.
In debugging, the null hypothesis is that "all user written code is incorrect." This also applies to user written data files.
That sounds like a good strategy. And you are right, there could possibly be a bunch of other (more probable?) reasons for this discrepancies.
Can you prove that your homebrew swc geometry specifications are correct?
Not in any other way than refering to the web page above.

All swc morphology files mentioned in this thread also contained the following header not shown in the previous post:

Code: Select all

# Original file 050803d_finaltrace.swc edited by Duncan Donohue using StdSwc version 1.31 on 3/4/08.
# Irregularities and fixes documented in 050803d_finaltrace.swc.std.  See StdSwc1.31.doc for more information.
#
# Neurolucida to SWC conversion from L-Measure. R. Scorcioni: rscorcio@gmu.edu
# Original fileName:C:\Users\Duncan\Krasnow\CellProcessing\CCDB Data\asc no spines\050803d_finaltrace.ASC
#
This heather was coppied from the original morphology file. As can be seen it contain no other information except who has done the tracing etc.

I will be away next week so you will get a break from me harassing you about these questions. ;)
All the best,
Robert
ted
Site Admin
Posts: 6289
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: the distance() function

Post by ted »

Your swc data do not declare end points or branch (fork) points. It might be useful to examine a file from a real cell that has known topology and geometry.
ted
Site Admin
Posts: 6289
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: the distance() function

Post by ted »

Further comments on your swc test files:
In each case, NEURON's Import3d tool reported problems, but it did the right thing. Here are the comments that hoc printed to the terminal:
For your first file

Code: Select all

Notice: ./one.swc:
The first two points have different types (1 and 3) but
    a single point root section is not allowed.
    Changing point id 2 so that it is type 1.
    If this is an incorrect repair, then change the file.
For the second one

Code: Select all

Notice: ./two.swc:
The first two points have different types (1 and 3) but
    a single point root section is not allowed.
    Changing point id 2 so that it is type 1.
    If this is an incorrect repair, then change the file.
And for the third

Code: Select all

Notice: ./three.swc:
The first two points have different types (1 and 3) but
    a single point root section is not allowed.
    Changing point id 2 so that it is type 1.
    If this is an incorrect repair, then change the file.
Despite these warnings, each imported morphology turns out to be exactly what is specified by the corresponding swc file:
one.swc becomes a 50 um long soma to which a 50 um long dend is attached
two.swc becomes a 100*sqrt(2) um long soma
three.swc becomes a 50 um long soma to which a 50*sqrt(2) um long dend is attached

hoc files exported from the corresponding cell builders contain the following pt3d specifications:
one.swc -> one.hoc

Code: Select all

  soma {pt3dclear()
        pt3dadd(0, 0, 0, 2)
        pt3dadd(50, 0, 0, 2)
  }
  dend {pt3dclear()
        pt3dadd(50, 0, 0, 2)
        pt3dadd(50, 50, 0, 2)
  }
two.swc -> two.hoc

Code: Select all

  soma {pt3dclear()
        pt3dadd(0, 0, 0, 2)
        pt3dadd(100, 100, 0, 2)
  }
three.swc -> three.hoc

Code: Select all

  soma {pt3dclear()
        pt3dadd(0, 0, 0, 2)
        pt3dadd(50, 0, 0, 2)
  }
  dend {pt3dclear()
        pt3dadd(50, 0, 0, 2)
        pt3dadd(100, 50, 0, 2)
  }
rlindroos
Posts: 17
Joined: Thu Jan 02, 2014 2:23 pm

Re: the distance() function

Post by rlindroos »

Thanks for taking time testing my swc morphologies!
In each case, NEURON's Import3d tool reported problems, but it did the right thing. Here are the comments that hoc printed to the terminal: ...
The comments is not the same as the ones I get when importing. I get the following message:

Code: Select all

Notice: ./model1.swc:
The first two points have different types (1 and 3) but
    a single point NEURON section is not allowed.
    Interpreting the point as the center of a sphere of
    radius 1 at location (0, 0, 0)
    Will represent as 3-point cylinder with L=diam and with all
    children kept at their 1st point positions and connected
    with wire to middle point.
    If this is an incorrect guess, then change the file.
which results in the pt3d code and distances stated above.

My "error message" is similar to the one stated in the following thread (perhaps this discussion should be continued there instead since it is not about the distance function any more?):

http://www.neuron.yale.edu/phpbb/viewt ... 13&t=2161

Im using Ubuntu 12.04 and NEURON version nrn 7.3-1 which was installed using the Software Center.
Your swc data do not declare end points or branch (fork) points. It might be useful to examine a file from a real cell that has known topology and geometry.
Ok, so is it neccesary that the branching and/or end points are explicitly specified for NEURON to be able to interpret and import the morphology in a correct way?

I Will try to build some other swc files that define these and some other properties and get back to you when I'm done.
ted
Site Admin
Posts: 6289
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: the distance() function

Post by ted »

rlindroos wrote:Im using Ubuntu 12.04 and NEURON version nrn 7.3-1 which was installed using the Software Center.
(1) Are you sure? I just searched https://apps.ubuntu.com/cat/application ... re-center/ and found nothing called "NEURON".
(2) I don't know what 7.3-1 is. Official distributions of NEURON report a version number and date in the first line that hoc prints to the terminal when NEURON first starts. Example:
7.3 (927:f3dcf53fbe74) 2013-07-27
(3) We have no control over software that is distributed from sites other than neuron.yale.edu. I don't even know who packaged whatever you installed. Are you sure you got it from Ubuntu's Software Center, or did you pick up a .deb file from http://www.neuron.yale.edu/neuron/download ?
is it neccesary that the branching and/or end points are explicitly specified for NEURON to be able to interpret and import the morphology in a correct way?
Apparently not, based on my own tests and examination of swc files that Import3D handles without a problem.
rlindroos
Posts: 17
Joined: Thu Jan 02, 2014 2:23 pm

Re: the distance() function

Post by rlindroos »

I have now modified my first swc morphology so that the end point is defined as an end point istead of a dendrite:

Code: Select all

# Original file 050803d_finaltrace.swc edited by Duncan Donohue using StdSwc version 1.31 on 3/4/08.
# Irregularities and fixes documented in 050803d_finaltrace.swc.std.  See StdSwc1.31.doc for more information.
#
# Neurolucida to SWC conversion from L-Measure. R. Scorcioni: rscorcio@gmu.edu
# Original fileName:C:\Users\Duncan\Krasnow\CellProcessing\CCDB Data\asc no spines\050803d_finaltrace.ASC
#
1 1 0 0 0 5 -1     // soma (1)
2 3 50 0 0 2 1    // dendrite (3)
3 6 50 50 0 1 2  // end point (6)
This results in the following pt3d code:

Code: Select all

// EXPLICIT END POINT
proc shape3d_1() {
  soma {pt3dclear()
	pt3dadd(-5, 0, 0, 10)
	pt3dadd(0, 0, 0, 10)
	pt3dadd(5, 0, 0, 10)
  }
  dend_6 {pt3dclear()
	pt3dadd(50, 0, 0, 4)
	pt3dadd(50, 50, 0, 2)
  }
}
This is almost identical to the resulting pt3d using non defined end points (same as previous reply except with changed diameters):

Code: Select all

// NON EXPLICIT END POINT
proc shape3d_1() {
  soma {pt3dclear()
	pt3dadd(-5, 0, 0, 10)
	pt3dadd(0, 0, 0, 10)
	pt3dadd(5, 0, 0, 10)
  }
  dend {pt3dclear()
	pt3dstyle(1, 0, 0, 0)
	pt3dadd(50, 0, 0, 4)
	pt3dadd(50, 50, 0, 2)
  }
}
Except for the different name of the dendrite (dend vs dend_6) the only difference is the added pt3dstyle in the non explicit case.

This lead me to what I think is the core problem here. In both cases the dendritic section consists of only two points, i.e. a start and an end point. This results in a dendritc length d, equal to:

d = norm(a-b).

If we use the example above the dendritic length is:

d = norm( [50 50 0] - [50 0 0] ) = sqrt( (50 - 50)^2 + (50 - 0)^2 + (0 - 0)^2 ) = sqrt( 0 + 50^2 + 0) = 50.

I.e anatomically the dendrite have a length of 100 but electrically the length is only 50. To me this behaviour is strange (but if this is because of a broken swc file or some unwanted NEURON behaviour is for you to deside).

To test this further I added another compartment to the swc file:

Code: Select all

# Original file 050803d_finaltrace.swc edited by Duncan Donohue using StdSwc version 1.31 on 3/4/08.
# Irregularities and fixes documented in 050803d_finaltrace.swc.std.  See StdSwc1.31.doc for more information.
#
# Neurolucida to SWC conversion from L-Measure. R. Scorcioni: rscorcio@gmu.edu
# Original fileName:C:\Users\Duncan\Krasnow\CellProcessing\CCDB Data\asc no spines\050803d_finaltrace.ASC
#
1 1 0 0 0 5 -1   
2 3 50 0 0 2 1
3 3 50 50 0 1 2
4 3 50 50 50 1 3
this resulted in the following pt3d structure:

Code: Select all

proc shape3d_1() {
  soma {pt3dclear()
	pt3dadd(-5, 0, 0, 10)
	pt3dadd(0, 0, 0, 10)
	pt3dadd(5, 0, 0, 10)
  }
  dend {pt3dclear()
	pt3dstyle(1, 0, 0, 0)
	pt3dadd(50, 0, 0, 4)
	pt3dadd(50, 50, 0, 2)
	pt3dadd(50, 50, 50, 2)
  }
}
Calculating the distance:

Code: Select all

objref s

soma distance(0, 0.5)
    
    forall	 {
    	s = new SectionRef()
    	if (s.has_parent) {
    	print secname(), " ", distance(1)
    	} 
    }
results in a distance of 100 micro meter. The behavior of ignoring the length between the soma and the first dendritic point is therefore still intact.

further I changed the soma from one to three points to test if the single point soma was the reason for the behaviour:

Code: Select all

# Original file 050803d_finaltrace.swc edited by Duncan Donohue using StdSwc version 1.31 on 3/4/08.
# Irregularities and fixes documented in 050803d_finaltrace.swc.std.  See StdSwc1.31.doc for more information.
#
# Neurolucida to SWC conversion from L-Measure. R. Scorcioni: rscorcio@gmu.edu
# Original fileName:C:\Users\Duncan\Krasnow\CellProcessing\CCDB Data\asc no spines\050803d_finaltrace.ASC
#
1 1 -5 0 0 5 -1  
2 1 0 0 0 5 1 
3 1 5 0 0 5 2  
4 3 50 0 0 2 3
5 3 50 50 0 1 4
6 3 50 50 50 1 5
This resulted in the following connect and pt3d statements:

Code: Select all

proc topol() { local i
  connect dend(0), soma(0.5)
  basic_shape()
}
proc shape3d_1() {
  soma {pt3dclear()
	pt3dadd(-5, 0, 0, 10)
	pt3dadd(0, 0, 0, 10)
	pt3dadd(5, 0, 0, 10)
  }
  dend {pt3dclear()
	pt3dstyle(1, 5, 0, 0)
	pt3dadd(50, 0, 0, 4)
	pt3dadd(50, 50, 0, 2)
	pt3dadd(50, 50, 50, 2)
  }
}
From the connect statement can be seen that electrically the dendrite is connected to the center of the soma while it anatomically is connected to the first end (as can be seen by the pt3dstyle statement).

calculating the length of the dendrite for this model gave the same result as in the single point soma, 100 micro meter.

One solution to this problem is to manually add the somatic connection point to each stem of the dendritic tree. In our example the pt3d statement would have to be changed in the following way:

Code: Select all

}
proc shape3d_1() {
  soma {pt3dclear()
	pt3dadd(-5, 0, 0, 10)
	pt3dadd(0, 0, 0, 10)
	pt3dadd(5, 0, 0, 10)
  }
  dend {pt3dclear()
	// pt3dstyle(1, 5, 0, 0) - change this line to following
        pt3dadd(0, 0, 0, 4)  // this line changes the electrical starting point of the dendrite to start at the soma
	pt3dadd(50, 0, 0, 4)
	pt3dadd(50, 50, 0, 2)
	pt3dadd(50, 50, 50, 2)
  }
}
Recalculating the distance for this model in the same way as above results in the expected result 150 micro meter.
rlindroos
Posts: 17
Joined: Thu Jan 02, 2014 2:23 pm

Re: the distance() function

Post by rlindroos »

Are you sure you got it from Ubuntu's Software Center, or did you pick up a .deb file from http://www.neuron.yale.edu/neuron/download ?
I'm not sure - I might have picked up a .deb file. I sure started at your official page anyhow.

This is the information text about NEURON in software center:

iclass, idemo, idraw, memacs, modlunit, neurondemo, nrngui, nrniv, nrnivmodl

A flexible and powerful simulator of neurons and networks NEURON is a simulation environment for developing and exercising models of neurons and networks of neurons. It is particularly well-suited to problems where cable properties of cells play an important role, possibly including extracellular potential close to the membrane), and where cell membrane properties are complex, involving many ion-specific channels, ion accumulation, and second messengers. It evolved from a long collaboration between Michael Hines and John W. Moore at the Department of Neurobiology, Duke University. Their express goal was to create a tool designed specifically for solving the equations that describe nerve cells.

NEURON has benefited from judicious revision and selective enhancement, guided and assisted by the growing number of neuroscientists who have incorporated empirically-based modeling into their research strategies. Their feedback and collaboration have led to many improvements.

(Converted from a rpm package by alien version 8.85.)
Is this an offical version or should I try to reinstall?
ted
Site Admin
Posts: 6289
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: the distance() function

Post by ted »

Puzzled by differences between what you're getting and what I was seeing, I reviewed the mercurial repository's changesets and found
changeset 939:f7e36e023a73 Release 7.3

Import3d allows single point root for SWC files and interprets it as a sphere with x,y,z location and radius given by the point. When exported to a CellBuild or instantiated, this sphere is represented as a 3-point cylinder with L=diam, with all children kept at their 1st point positions and connected with a wire to the middle point.
After installing the latest development version of NEURON from source code (7.3 (999:cdec6759122c) 2014-01-10) I now get the same numerical results as you do with your latest "swc test files."

That said, I see there are some points of misunderstanding. Import3D interprets this

Code: Select all

1 1 0 0 0 5 -1
2 3 50 0 0 2 1
3 6 50 50 0 1 2
as a cell with a 5 um radius spherical soma, with a 50 um long dendrite whose proximal end is located 50 um from the soma center but is electrically connected to the soma center as if by a wire with 0 resistance. One wouldn't expect to find a cell whose parts are separated from each other by 45 um, but the swc data assert that these measurements are from the same cell . . .

Cells typically have somas that are electrically compact, so the proximal ends of all neurites that arise from the soma are at the same potential. However, the most proximal 3d measurement (x,y,z, and diameter, or in the case of swc files, x,y,z, and radius) on any such neurite will be made at some nonzero distance from the soma's center, and should be drawn at the proper location in any graphical rendering of the cell's structure. This is the reason for the notion of "logical connections" (read more about it in the Programmer's Reference).

So Import3D treats the first line in your swc file as a definition of the soma, and subsequent lines as specifying the geometries of neurites that are attached to it.
anatomically the dendrite have a length of 100 but electrically the length is only 50.
No, anatomically its length is 50 um, period. The first line in the file is interpreted as defining the soma's geometry, and has nothing to do with the geometry of the dendrite.
I changed the soma from one to three points to test if the single point soma was the reason for the behaviour:

Code: Select all

1 1 -5 0 0 5 -1  
2 1 0 0 0 5 1 
3 1 5 0 0 5 2  
4 3 50 0 0 2 3
5 3 50 50 0 1 4
6 3 50 50 50 1 5
Again, the lines that define the soma specify the soma's geometry and have nothing to do with the dendrite's geometry.
This resulted in the following connect and pt3d statements:

Code: Select all

proc topol() { local i
  connect dend(0), soma(0.5)
  basic_shape()
}
From the connect statement can be seen that electrically the dendrite is connected to the center of the soma
True.
while it anatomically is connected to the first end (as can be seen by the pt3dstyle statement).
It would be more correct to say that "the pt3dstyle statement tells NEURON something about how to draw the shape of the cell." For this particular data set, the xyz values are not what one would get from a body that is spatially continuous (the proximal end of dend would be at a point on the surface of the spherical soma, not 45 um away from it), so the resulting picture shows two disjoint structures.
One solution to this problem is to manually add the somatic connection point to each stem of the dendritic tree.
There I must differ with you. The "problem" exists only for an swc file that contains "physically unrealizable" xyz values--unrealizable because the soma and dendrite must be contiguous if they are to be recognized as parts of the same cell. Try these data:

Code: Select all

1 1 -5 0 0 5 -1  
2 1 0 0 0 5 1 
3 1 5 0 0 5 2  
4 3 5 0 0 2 3
5 3 55 50 0 1 4
6 3 55 50 50 1 5

I'm still puzzled about what it was you got from Ubuntu's Software Center; will look into this.
Post Reply