SWC_Tree Class Reference
Support for the .swc tree format: a piece-wise segment model of neurons.
More...
#include <swc.h>
Structures
• |
kind
| : SWC_Kind |
• |
x
| : float |
• |
y
| : float |
• |
z
| : float |
• |
r
| : float |
|
|
Enumerated Scalars
|
SWC_Kind
| : { SWC_UNDEFINED, SWC_SOMA, SWC_AXON, SWC_BASAL_DENDRITE, SWC_APICAL_DENDRITE, SWC_FORK_POINT, SWC_END_POINT, SWC_CUSTOM } |
|
|
Routines
SWC_Bundle * |
Read_SWC_File
(SWC_Bundle *forest RM, string file_name) |
boolean |
Write_SWC_File
(string file_name, SWC_Bundle *forest) |
void |
Print_SWC_Tree
(SWC_Tree *tree, FILE *output, int indent, string format) |
SWC_Tree * |
Make_SWC_Tree
(int size_estimate) |
SWC_Node * |
Add_Vertex_As_Root
(SWC_Tree *tree, int kind, double x, double y, double z, double r) |
SWC_Node * |
Add_Vertex_As_First_Child
(SWC_Tree *tree, SWC_Node *v, int kind, double x, double y, double z, double r) |
SWC_Node * |
Add_Vertex_As_Sibling
(SWC_Tree *tree, SWC_Node *v, int kind, double x, double y, double z, double r) |
SWC_Node * |
Add_Vertex_As_Father
(SWC_Tree *tree, SWC_Node *v, int kind, double x, double y, double z, double r) |
SWC_Bundle * |
Clip_SWC_TreeG
(SWC_Bundle *forest RM, SWC_Tree *tree, Double_Vector *beg F, Double_Vector *end F) |
Detailed Description
The .swc-format is a standard in neuroscience (see http://www.neuromorph.org) for encoding
and modeling neurons. While a neuron is a continuous 3D object, the SWC model
approximates the shape as a tree of cylindrical segments where the radius of the
cylinder at each end need not be the same. The standard does not dictate a degree
of precision to which the piecewise linear approximation needs to model the true shape.
An SWC_Tree object is a tree for which each node or vertex has a 3D real-valued
coorindate, a radius, and an optional designation (see SWC_Kind) as to what the node
or its segment represent. The segment of a node is the line segment from its point
to that of the father of the node in the tree (if any). It is unspecified as to how
the radius defines a cylinder about each segment, but the general idea is that the
radius is an estimate of the thickness of the neuron at the point of each node.
An SWC_Node models each node of an SWC_Tree and the class provides primitives
for traversing a tree. Namely, you can get the root of an SWC_Tree with Get_SWC_Root
and you can recursively traverse the tree with Get_SWC_Child, which takes you to the
first child of a node, and Get_SWC_Sibling, which then takes you to the next sibling
of a node. For example, the code snippet below traverses every node in an
SWC_Tree T:
void Traverse_Tree(SWC_Node *v)
{ // Visiting v
for (v = Get_SWC_Child(v); v != NULL; v = Get_SWC_Sibling(v))
Traverse_Tree(v);
}
Traverse_Tree(Get_SWC_Root(T));
There are also routines to get the size of an SWC_Tree, the ith node of a tree,
and the number of children or outdegree of a node, i.e. Get_SWC_Size, Get_SWC_Node,
and Get_SWC_Outdegree. Make_SWC_Tree creates an initially empty tree with an initial memory
allocation large enough to build a tree with a specified number of nodes without additional
memory allocations. One can then add nodes to a tree in a specified position relative to
a specified node already in the tree, with the routines Add_Vertex_As_Root,
Add_Vertex_As_First_Child, Add_Vertex_As_Sibling, and Add_Vertex_As_Father.
The .swc-format specifies not only a model but also is a text-based format for encoding the
model on a file. Read_SWC_File and Write_SWC_File read and write multiple trees to
and from a file in .swc-format. Each line of an .swc-file is either a comment line
that begins with a '#'-sign, or a blank line, or a data line describing a node and its
father (if any). A data line has the format:
<id> <kind> <x> <y> <z> <r> <father>
where the <id>, <kind>, and <father> are non-negative integers, and the <x>, <y>, <z>,
and <r> values are floating point constants, all separated by white space.
Each node must have a unique id.
The structure of the tree is determined from the father links
that must either refer to a node id or -1 if the node is a root of a tree.
As an example, the input below encodes a tree where for illustration purposes the
id's are not consecutive or ordered in any way:
# A comment
1 1 2 51 25 1.4 -1
8 6 196 45 10 1.7 6
2 0 4 67 55 2.2 1
6 5 195 504 19 1.4 5
3 0 5 240 40 1.4 2
5 5 2 185 49 1.4 1
4 6 23 255 0 1.7 3
7 6 346 509 56 1.4 6
Print_SWC_Tree prints a representation of the tree and is principally provided for
debug purposes. For the example above, it might produce the output:
(2.0,51.0,25.0):1.4
|
+->(4.0,67.0,55.0):2.2
| (5.0,240.0,40.0):1.4
| (23.0,255.0,0.0):1.7
|
+->(2.0,185.0,49.0):1.4
(195.0,504.0,19.0):1.4
|
+->(346.0,509.0,56.0):1.4
|
+->(196.0,45.0,10.0):1.7
There are many concievable computations that could be performed on an SWC_Tree. Currently the
library has a routine to clip a tree to a given bounding box (Clip_SWC_Tree),
to determine the 3D real-valued extent of an SWC_Tree (SWC_Tree_Extent), and
to calculate the path length of an SWC_Tree (SWC_Tree_Path_Length).
Structure Documentation
• |
kind | : SWC_Kind |
• |
x | : float |
• |
y | : float |
• |
z | : float |
• |
r | : float |
Individual nodes (vertices) in an SWC tree have a kind, a coordinate in 3D space
(x,y,z) and a radius r.
Holds a collection of num_trees SWC trees given in trees[i] for
i ∈ [0,num_trees-1].
Enumerated Scalars Documentation
SWC_Kind | : { SWC_UNDEFINED, SWC_SOMA, SWC_AXON, SWC_BASAL_DENDRITE, SWC_APICAL_DENDRITE, SWC_FORK_POINT, SWC_END_POINT, SWC_CUSTOM } |
Each segment in an SWC tree can have a kind documenting whether it is soma,
axon, basal or apical dendrite, or it can be left undefined. The segment identified
by a node is the one from its father in the tree to itself (if it exists).
Note that in general, that the kind can be undefined (SWC_UNDEFINED) and so is not critical
to the neuron model per se. The routines in this module do not in any way rely on this
information for their proper function.
The last three kinds: SWC_FORK_POINT, SWC_END_POINT, and SWC_CUSTOM, are non-standard
and apply to a node (as opposed to its segment). They are
used by some tools to indicate the topology of the segment (the first two values) or to
encode customized annotation (any value equal to or greater than SWC_CUSTOM).
Routine Documentation
Return the number of nodes in SWC tree t.
Return a pointer to the ith node of SWC tree t.
Return a pointer to the root node of SWC tree t.
Return a pointer to the father of vertex n, returning NULL
if n is the root of the tree.
Return a pointer to the leftmost child of vertex n, returning NULL
if there is none.
Return a pointer to the sibling immediately to the right of vertex n, returning NULL
if there is none.
Return the number of children of node n.
Reads an .swc-formated file, building an SWC_Tree for each tree there in, and returning this
set of trees by filling out the bundle forest. Each line of the file is either a comment line
that begins with a '#'-sign, or blank, or a data line describing a node and its father (if any).
A data line has the format:
<id> <kind> <x> <y> <z> <r> <father>
where the <id>, <kind>, and <father> are non-negative integers, and the <x>, <y>, <z>,
and <r> values are floating point constants, all separated by white space. Unlike some more
limited readers, the nodes can be defined in any order of their id, and the id's need not
constitute a consecutive interval, but each node must have a unique id.
Moreover, if there can be multiple trees in the file, and their nodes can be interleaved within
the file -- the number of trees and their structure is determined from the father links
that must either refer to a node id or -1 if the node is a root of a tree. The kind encoding
is a non-negative integer, where the codes correspond to their order in the definition
of SWC_Kind, e.g. 2 is SWC_AXON. As an example, the input below encodes two trees where
for illustration purposes the id's are not consecutive or ordered in any way and the nodes of
the two trees are mixed together:
# A comment
4 1 2 51 25 1.4 -1
1 0 4 67 55 2.2 4
3 0 5 240 40 1.4 1
2 5 2 185 49 1.4 4
5 0 100 200 32 1.3 -1
10 6 23 255 0 1.7 3
6 5 195 504 19 1.4 2
9 6 196 45 10 1.7 6
8 6 346 509 56 1.4 6
11 0 222 361 15 1.2 5
The bundle forest should be a semantically valid SWC_Bundle on input, i.e. if
num_trees > 0 then trees should be a vector of at least num_trees pointers to
SWC trees, and exactly the first num_trees of these pointers should be to valid
SWC_Tree objects. The simplist way to establish a semantically valid bundle is to initialize
num_trees to 0 and trees to NULL. This routine will take the bundle and modify it
so that it reflects the number of trees in the file being read and so that trees is a vector
of pointers to each SWC tree read, where any previous SWC trees in the bundle are freed.
The user is responsible for managing the SWC_Tree objects in the bundle
and the vector trees that points at the trees.
boolean |
Write_SWC_File (string file_name, SWC_Bundle *forest) |
Write the collection of SWC trees in the bundle forest to the file file_name in
.swc-format. The id's will be assigned in order from 1, and each tree will be written
in turn (in order to accommodate more restricted readers than our own).
For the sample input given above for Read_SWC_File, the output produced by this
routine would be:
# Tree 0 (8 nodes):
1 1 2 51 25 1.4 -1
2 0 4 67 55 2.2 1
3 0 5 240 40 1.4 2
4 6 23 255 0 1.7 3
5 5 2 185 49 1.4 1
6 5 195 504 19 1.4 5
7 6 346 509 56 1.4 6
8 6 196 45 10 1.7 6
# Tree 1 (2 nodes):
9 0 100 200 32 1.3 -1
10 0 222 361 15 1.2 9
void |
Print_SWC_Tree (SWC_Tree *tree, FILE *output, int indent, string format) |
Print an ASCII representation of the tree tree to the file output indented by
indent spaces, where floating point numbers will be formated according to the string
format. As an example, for the sample input given above for Read_SWC_File, the print
out for the first of the two trees, given indent=4 and format="%.1f", would be:
(2.0,51.0,25.0):1.4
|
+->(4.0,67.0,55.0):2.2
| (5.0,240.0,40.0):1.4
| (23.0,255.0,0.0):1.7
|
+->(2.0,185.0,49.0):1.4
(195.0,504.0,19.0):1.4
|
+->(346.0,509.0,56.0):1.4
|
+->(196.0,45.0,10.0):1.7
SWC_Tree * |
Make_SWC_Tree (int size_estimate) |
Generate an initally empty tree with room for size_estimate nodes before a reallocation of
memory becomes necessary.
SWC_Node * |
Add_Vertex_As_Root (SWC_Tree *tree, int kind, double x, double y, double z, double r) |
SWC_Node * |
Add_Vertex_As_First_Child (SWC_Tree *tree, SWC_Node *v, int kind, double x, double y, double z, double r) |
SWC_Node * |
Add_Vertex_As_Sibling (SWC_Tree *tree, SWC_Node *v, int kind, double x, double y, double z, double r) |
SWC_Node * |
Add_Vertex_As_Father (SWC_Tree *tree, SWC_Node *v, int kind, double x, double y, double z, double r) |
Add_Vertex_As_X adds a new node or vertex to the tree tree of kind kind, with position
(x,y,z) and radius r. The new node is added (a) as the root,
(b) as the first child of v, (c) as the immediately following sibling of v, or (d) as the
father of v for X equal to Root, First_Child, Sibling, and Father, respectively.
Other nodes in the tree adjust accordingly. That is, the first child of v becomes the second
child of v and the immediate sibling of the new node in the case of Add_Vertex_As_First_Child.
For Add_Vertex_As_Father, the new node takes the place of v in its sibling list and v
becomes the sole child of the new node. The current root becomes the only child of the new
node in the case of Add_Vertex_As_Root, and the sibling of v becomes the sibling of the
new node in the case of Add_Vertex_As_Sibling.
Clip the SWC_Tree tree to the rectangle in 3D real space whose minimimum corner is
beg and whose maximum corner is end. This operation can split tree into any number
of pieces (or none at all), so the routine fills in the bundle forest with the resulting
collection of trees.
The bundle forest should be a semantically valid SWC_Bundle on input, i.e. if
num_trees > 0 then trees should be a vector of at least num_trees pointers to
SWC trees, and exactly the first num_trees of these pointers should be to valid
SWC_Tree objects. The simplist way to establish a semantically valid bundle is to initialize
num_trees to 0 and trees to NULL. This routine will take the bundle and modify it
so that it reflects the number of trees in the file being read and so that trees is a vector
of pointers to each SWC tree read, where any previous SWC trees in the bundle are freed.
The user is responsible for managing the SWC_Tree objects in the bundle
and the vector trees that points at the trees.
Compute the smallest bounding rectangle in 3D real space that contains all the vertices
of the tree and return it in the bundle extent.
If the min and max fields of the Extent_Bundle are NULL on input,
then the routine generates 3-element Double_Vectors, otherwise whatever array
they point to is converted to a 3-element Double_Vector if they are not already thus,
and then filled in with the extent values. The caller is responsible for freeing or
killing these vectors.
double |
SWC_Tree_Path_Length (SWC_Tree *tree) |
Returns the path length of tree which is defined as the sum of the lengths of all the
edges in the tree.
|