How to reconstruct the 3D points of a morphology imported by Import3D

The basics of how to develop, test, and use models.
Post Reply
RobinDS
Posts: 22
Joined: Mon Nov 04, 2019 12:17 pm

How to reconstruct the 3D points of a morphology imported by Import3D

Post by RobinDS »

I'm using the Import3D tool on a .asc file. I'm then using the n3d, x3d, y3d, and z3d functions on a section to iterate over what I presume are the 3D positions of all the segments in that section, but there doesn't seem to be a straightforward list of all the nrn.Segments in a section.

Also, a nrn.Section doesn't seem to contain its own 3D information?

So I'm stuck trying to piece together these bits of information and I feel like something this fundamental for NEURON has to have a better Python interface, so I must be missing something.

During the iterating I can connect each segment to the previous one in that section, but for each section I'm stuck with an initial segment that has no parent: So I thought I'd use the section's parentseg function to retrieve the point that the section is connected to. But from there I cannot find any 3D information.
ted
Site Admin
Posts: 6286
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: How to reconstruct the 3D points of a morphology imported by Import3D

Post by ted »

Your post actually contains signs of multiple problems.
I'm using the Import3D tool on a .asc file. I'm then using the n3d, x3d, y3d, and z3d functions on a section to iterate over what I presume are the 3D positions of all the segments in that section
You realize that
* a section's first and last 3d xyz data will correspond to the 0 end of the section's first segment and the 1 end of the section's last segment, respectively
BUT
* no other 3d xyz datum is guaranteed to correspond to either end of any segment
* any segment may span 0 or more 3d xyz data
there doesn't seem to be a straightforward list of all the nrn.Segments in a section
That's because segments are ephemeral--how many exist depends on the section's nseg parameter, and nseg is likely to change during model develpment and revision as a consequence of tests to discover whether spatial discretization is adequate. You want a list, nothing's stopping you from making a list. But what would be the use of such a list? If you want to iterate over the segments that belong to some section foo, what's wrong with
for seg in foo: statement
?
Also, a nrn.Section doesn't seem to contain its own 3D information?
Maybe the Programmer's Reference documentation of n3d(), x3d(), y3d(), z3d(), diam3d() isn't explicit enough. Have you tried a simple test? Here's one:
axon = h.Section(name='axon')
axon.pt3dclear()
axon.pt3dadd(0,0,0,0)
axon.pt3dadd(100,0,0,0)
for i in range(axon.n3d()): print(i, axon.x3d(i))
During the iterating I can connect each segment to the previous one in that section
Now you've lost me. Why is this necessary? What makes it even possible? If some section foo contains more than one segment, the root segment of foo is the segment at foo's zero end. All other segments in foo are necessarily connected to their parents. And foo's root segment will also have a parent, unless foo is the root section of a model cell, or foo's 0 end is connected to the 0 end of the model cell's root section.
for each section I'm stuck with an initial segment that has no parent
Do you mean that, after importing a particular morphometric data file, you end up with a bunch of sections that have no parents? or that all of the sections are connected to the 0 end of the model cell's root section?
RobinDS
Posts: 22
Joined: Mon Nov 04, 2019 12:17 pm

Re: How to reconstruct the 3D points of a morphology imported by Import3D

Post by RobinDS »

Sorry, by referring to the NEURON concepts and more general abstract concepts with the same words I've created a semantic mess. But the question is moot, I've solved the issue.

One small question: If a section.parentseg().x = 0.5 and parent_section.n3d = 21, does that mean that section is connected to parent_section somewhere around the 10th-11th 3d xyz point?

Pretty picture of the morphology as a network of nodes and edges, with access to which NEURON section they belong to. I find this representation way more user friendly for graph/network algorithms than the sections and segments:

Image

I'll for example create large scale networks of many different morphologies and I can use KDTree or RTree etc to get intersecting edges and create synapses between the right NEURON sections
ted
Site Admin
Posts: 6286
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: How to reconstruct the 3D points of a morphology imported by Import3D

Post by ted »

If a section.parentseg().x = 0.5 and parent_section.n3d = 21, does that mean that section is connected to parent_section somewhere around the 10th-11th 3d xyz point?
No. Reflect on the fact that what governs the placement of xyzdiam measurements along the length of an unbranched neurite are the irregularities of its shape, which are completely accidental, and the judgment of the person (or rules of the algorithm) that made the measurements.
RobinDS
Posts: 22
Joined: Mon Nov 04, 2019 12:17 pm

Re: How to reconstruct the 3D points of a morphology imported by Import3D

Post by RobinDS »

Ok, so I can safely assume that Neuron always connects sections end-to-end? What exactly does that x value represent then?
ted
Site Admin
Posts: 6286
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: How to reconstruct the 3D points of a morphology imported by Import3D

Post by ted »

so I can safely assume that Neuron always connects sections end-to-end?
Please rephrase the question. I don't quite know what you're asking.
What exactly does that x value represent then?
If you are asking about the meaning of the value returned by seg.x in statements of the form
for seg in somesection: print(seg.x)
the answer is: normalized path distance between the center of a segment and the 0 end of the section that contains the segment. A mathematician would call this "normalized arc length." It would probably be useful to read
3.2 Spatial discretization in a biological context: sections and segments
in
Hines, M.L. and Carnevale, N.T.
The NEURON Simulation Environment.
Neural Computation 9:1179-1209, 1997
(preprint available https://neuron.yale.edu/neuron/static/p ... simenv.pdf).
RobinDS
Posts: 22
Joined: Mon Nov 04, 2019 12:17 pm

Re: How to reconstruct the 3D points of a morphology imported by Import3D

Post by RobinDS »

ted wrote: Fri Nov 22, 2019 9:10 pm Please rephrase the question. I don't quite know what you're asking.
Is a child section's 0 end xyz always the same as its parent's 1 end xyz?
ted
Site Admin
Posts: 6286
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Re: How to reconstruct the 3D points of a morphology imported by Import3D

Post by ted »

Is a child section's 0 end xyz always the same as its parent's 1 end xyz?
Good question. Looks like you (and probably a lot of other people) have some reading, or maybe re-reading, to do in the Programmer's Reference.

The answer is no, and for two reasons.

Reason 1.

Read the Programmer's Reference documentation of
connect
to discover that the 0 or 1 end of a child section can be connected to any node of the parent section. "Node" means a location along a section at which membrane potential is computed. A section's nodes are discrete locations at which membrane potential is computed, either by numerical integration of an ODE (the internal nodes i.e. segment centers) or algebraically by resolution of boundary conditions (the nodes at 0 and 1). In most cases it is best to connect the 0 end of a child section to the 1 end of its parent, but there are exceptions. One exception is when the parent section is the root section of a cell (the section that has no parent).

For example, consider a pyramidal cell which has a soma to which the following are attached:
an axon
basilar dendrites
an apical trunk
It would make sense attach the proximal (i.e. 0) end of the axon to the 0 end of the soma, the proximal (i.e. 0) ends of the basilar dendrites to the middle (0.5 node) of the soma, and the proximal (i.e. 0) end of the apical trunk to the 1 end of the soma.

For another example, consider how to represent spines attached along the length of a dendrite. The proximal ends of spine neck sections will be attached to the internal nodes of the section that represents the dendrite.

I have never seen a situation in which it is useful to connect the 1 end of a child section to any node of a parent section.

Reason 2.

The pt3d statements that specify the shape of a section set up a table of xyzdiam data ("pt3d info") that governs the shape of that section and where that section will be rendered in a shape plot. However, that section can be connected to any parent section, regardless of whether any node of the parent and child have the same xyz coordinates. If define_shape() is now called--or if a shape plot is created, which has the side-effect of calling define_shape()--the child's pt3d info will be translated so that its first point is at the same location as the parent. So if you created two sections foo and bah whose pt3d info were
0,0,0,1
10,0,0,1
and
0,0,0,1
0,10,0,1
respectively, and they weren't connected to each other, in a shape plot they would look like an L, or the lower left corner of a square. But if you then did
foo.connect(bah,1)
you'd get something that looks like an upper case gamma, or the upper left corner of a square.

In some cases this translation would make the shape plot of a model cell look different from the biological original. A typical example is branches that are physically attached to various locations at the soma's surface. In terms of electrical signaling, they are attached to the middle or the 0 or 1 ends of the soma, but a rendering of the resulting model would look strange. pt3dstyle() can be used to prevent such translation.


Make sure that you read the Programmer's Reference entries about 3-D specification of geometry, including define_shape() and pt3dstyle().
Post Reply