Home · Pages · Index · Overviews

SWC_Tree Class Reference

Support for the .swc tree format: a piece-wise segment model of neurons. More...

 #include <swc.h>

Structures

  SWC_Node : struct
kind : SWC_Kind
x : float
y : float
z : float
r : float
One of the defined SWC_Kind values below
x, y, z coordinate of vertex
 
 
Radius of neuron at this point

  SWC_Bundle : struct
num_trees : int
trees : SWC_Tree **
Number of trees
trees[0..num_trees-1] point at SWC trees

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

int Get_SWC_Size (SWC_Tree *t)
SWC_Node * Get_SWC_Node (SWC_Tree *t, int i)
SWC_Node * Get_SWC_Root (SWC_Tree *t)
SWC_Node * Get_SWC_Father (SWC_Node *n)
SWC_Node * Get_SWC_Child (SWC_Node *n)
SWC_Node * Get_SWC_Sibling (SWC_Node *n)
int Get_SWC_Outdegree (SWC_Node *n)

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)

Extent_Bundle * SWC_Tree_Extent (Extent_Bundle *extent RM, SWC_Tree *tree)
double SWC_Tree_Path_Length (SWC_Tree *tree)

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

SWC_Node : struct
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.

SWC_Bundle : struct
num_trees: int
trees: SWC_Tree **

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

int Get_SWC_Size (SWC_Tree *t)

Return the number of nodes in SWC tree t.

SWC_Node * Get_SWC_Node (SWC_Tree *t, int i)

Return a pointer to the ith node of SWC tree t.

SWC_Node * Get_SWC_Root (SWC_Tree *t)

Return a pointer to the root node of SWC tree t.

SWC_Node * Get_SWC_Father (SWC_Node *n)

Return a pointer to the father of vertex n, returning NULL if n is the root of the tree.

SWC_Node * Get_SWC_Child (SWC_Node *n)

Return a pointer to the leftmost child of vertex n, returning NULL if there is none.

SWC_Node * Get_SWC_Sibling (SWC_Node *n)

Return a pointer to the sibling immediately to the right of vertex n, returning NULL if there is none.

int Get_SWC_Outdegree (SWC_Node *n)

Return the number of children of node n.

SWC_Bundle * Read_SWC_File (SWC_Bundle *forest RM, string file_name)

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.

SWC_Bundle * Clip_SWC_TreeG (SWC_Bundle *forest RM, SWC_Tree *tree,
                               Double_Vector *beg F, Double_Vector *end F)

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.

Extent_Bundle * SWC_Tree_Extent (Extent_Bundle *extent RM, SWC_Tree *tree)

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.