webknossos.skeleton.skeleton
¶
Skeleton
¶
Bases: Group
A hierarchical representation of skeleton annotations in WEBKNOSSOS.
The Skeleton class serves as the root container for all skeleton annotation data, organizing nodes and edges into a hierarchical structure of groups and trees. It contains dataset metadata and provides methods for loading, saving, and manipulating skeleton annotations.
Attributes:
-
voxel_size
(Vector3
) –3D tuple (x, y, z) specifying the size of voxels in nanometers.
-
dataset_name
(str
) –Name of the dataset this skeleton belongs to.
-
organization_id
(Optional[str]
) –Optional ID of the organization owning this skeleton.
-
description
(Optional[str]
) –Optional description of the skeleton annotation.
-
name
(str
) –Always set to "Root" as this is the root group of the hierarchy.
The skeleton structure follows a hierarchical organization
- Skeleton (root)
- Groups (optional organizational units)
- Trees (collections of connected nodes)
- Nodes (3D points with metadata)
- Edges (connections between nodes)
- Trees (collections of connected nodes)
- Groups (optional organizational units)
Examples:
Create and populate a new skeleton:
# Create skeleton through an annotation
annotation = Annotation(
name="dendrite_trace",
dataset_name="cortex_sample",
voxel_size=(11, 11, 24)
)
skeleton = annotation.skeleton
# Add hierarchical structure
dendrites = skeleton.add_group("dendrites")
basal = dendrites.add_group("basal")
tree = basal.add_tree("dendrite_1")
# Add and connect nodes
soma = tree.add_node(position=(100, 100, 100), comment="soma")
branch = tree.add_node(position=(200, 150, 100), radius=1.5)
tree.add_edge(soma, branch)
Load an existing skeleton:
# Load from NML file
skeleton = Skeleton.load("annotation.nml")
# Access existing structure
for group in skeleton.groups:
for tree in group.trees:
print(f"Tree {tree.name} has {len(tree.nodes)} nodes")
Notes
- The Skeleton class inherits from Group, providing group and tree management methods.
- To upload a skeleton to WEBKNOSSOS, create an Annotation with it.
- For complex examples, see the skeleton synapse candidates example in the documentation.
See Also
- Group: Base class providing group and tree management
- Tree: Class representing connected node structures
- Node: Class representing individual 3D points
- Annotation: Container class for working with WEBKNOSSOS
children
property
¶
children: Iterator[GroupOrTree]
Returns an iterator over all immediate children (groups and trees).
This property provides access to both groups and trees that are direct children of this group, in no particular order. For nested access, use flattened_trees() or flattened_groups().
Returns:
-
Iterator[GroupOrTree]
–Iterator[GroupOrTree]: Iterator yielding all immediate child groups and trees.
Examples:
# Print all immediate children
for child in group.children:
if isinstance(child, Tree):
print(f"Tree: {child.name}")
else:
print(f"Group: {child.name}")
groups
property
¶
groups: Iterator[Group]
Returns all (immediate) group children as an iterator. Use flattened_groups if you need also need groups within subgroups.
name
class-attribute
instance-attribute
¶
name: str = field(default='Root', init=False, eq=False, repr=False)
Should not be used with Skeleton
, this attribute is only useful for sub-groups. Set to Root
.
trees
property
¶
trees: Iterator[Tree]
Returns all (immediate) tree children as an iterator. Use flattened_trees if you also need trees within subgroups.
add_graph
¶
add_graph(name: str, color: Optional[Union[Vector4, Vector3]] = None, _enforced_id: Optional[int] = None) -> Tree
Deprecated, please use add_tree
.
add_group
¶
add_group(name: str, _enforced_id: Optional[int] = None) -> Group
Creates and adds a new subgroup to this group.
Parameters:
-
name
(str
) –Name for the new group.
-
_enforced_id
(Optional[int]
, default:None
) –Optional specific ID for the group (internal use).
Returns:
-
Group
(Group
) –The newly created group.
Examples:
# Create nested group hierarchy
dendrites = neuron.add_group("dendrites")
basal = dendrites.add_group("basal")
apical = dendrites.add_group("apical")
add_nx_graphs
¶
add_nx_graphs(tree_dict: Union[List[Graph], Dict[str, List[Graph]]]) -> None
Import NetworkX graphs as skeleton trees.
Converts NetworkX Graph objects into skeleton trees, preserving node positions and edge connections. The graphs can be provided either as a list or as a dictionary mapping group names to lists of graphs.
Parameters:
-
tree_dict
(Union[List[Graph], Dict[str, List[Graph]]]
) –Either: - A list of NetworkX graphs to be added directly to the skeleton - A dictionary mapping group names to lists of graphs, which will create new groups with the specified names containing the graphs
Raises:
-
ValueError
–If any graph nodes lack required position attributes.
-
TypeError
–If tree_dict is neither a list nor a dictionary.
Examples:
Add graphs directly to skeleton:
import networkx as nx
# Create sample graphs
g1 = nx.Graph()
g1.add_node(1, position=(0, 0, 0))
g1.add_node(2, position=(100, 0, 0))
g1.add_edge(1, 2)
g2 = nx.Graph()
g2.add_node(1, position=(0, 100, 0))
g2.add_node(2, position=(100, 100, 0))
g2.add_edge(1, 2)
# Add graphs directly
skeleton.add_nx_graphs([g1, g2])
# Or organize graphs into groups
graphs_by_group = {
"dendrites": [g1],
"axons": [g2]
}
skeleton.add_nx_graphs(graphs_by_group)
Note
- Each node in the input graphs must have a 'position' attribute containing (x, y, z) coordinates
- Other node attributes (e.g., radius, rotation) will be preserved
- Edge attributes are currently not preserved in the conversion
add_tree
¶
add_tree(name_or_tree: Union[str, Tree], color: Optional[Union[Vector4, Vector3]] = None, _enforced_id: Optional[int] = None) -> Tree
Adds a new tree or copies an existing tree to this group.
This method supports two ways of adding trees: 1. Creating a new tree by providing a name 2. Copying an existing tree from another location
Parameters:
-
name_or_tree
(Union[str, Tree]
) –Either a string name for a new tree or an existing Tree instance to copy.
-
color
(Optional[Union[Vector4, Vector3]]
, default:None
) –Optional RGBA color tuple (r, g, b, a) or RGB tuple (r, g, b). If an RGB tuple is provided, alpha will be set to 1.0.
-
_enforced_id
(Optional[int]
, default:None
) –Optional specific ID for the tree (internal use).
Returns:
-
Tree
(Tree
) –The newly created or copied tree.
Examples:
# Create new tree
tree = group.add_tree("dendrite_1", color=(1, 0, 0, 1))
# Copy existing tree
copy = group.add_tree(existing_tree)
Notes
When copying a tree, a new ID will be generated if the original ID already exists in this group.
as_nml_group
¶
as_nml_group() -> Group
Converts this group to its NML representation.
This method creates a lightweight representation of the group suitable for serialization in the NML format.
Returns:
-
Group
–wknml.Group: NML representation of this group.
Notes
This is primarily used internally for file I/O operations.
flattened_groups
¶
flattened_groups() -> Iterator[Group]
Returns an iterator of all groups within this group (and its subgroups).
flattened_trees
¶
flattened_trees() -> Iterator[Tree]
Returns an iterator of all trees in this group and its subgroups.
This method performs a recursive traversal of the group hierarchy, yielding all trees regardless of their nesting level.
Returns:
-
Iterator[Tree]
–Iterator[Tree]: Iterator yielding all contained trees.
Examples:
# Process all trees regardless of grouping
for tree in group.flattened_trees():
print(f"Tree {tree.name} has {len(tree.nodes)} nodes")
from_path
staticmethod
¶
from_path(file_path: Union[PathLike, str]) -> Skeleton
Deprecated. Use Skeleton.load instead.
get_group_by_id
¶
get_group_by_id(group_id: int) -> Group
Returns the group which has the specified group id.
get_max_node_id
¶
get_max_node_id() -> int
Returns the highest node id of all nodes of all trees within this group (and its subgroups).
get_max_tree_id
¶
get_max_tree_id() -> int
Returns the highest tree id of all trees within this group (and its subgroups).
get_node_by_id
¶
get_node_by_id(node_id: int) -> Node
Retrieves a node by its ID from any tree in this group or its subgroups.
Parameters:
-
node_id
(int
) –The ID of the node to find.
Returns:
-
Node
(Node
) –The node with the specified ID.
Raises:
-
ValueError
–If no node with the given ID exists in any tree.
Examples:
try:
node = group.get_node_by_id(42)
print(f"Found node at position {node.position}")
except ValueError:
print("Node not found")
get_total_node_count
¶
get_total_node_count() -> int
Counts all nodes in all trees within this group and its subgroups.
Returns:
-
int
(int
) –Total number of nodes across all contained trees.
Examples:
# Check total annotation points
count = group.get_total_node_count()
print(f"Total annotation points: {count}")
get_tree_by_id
¶
get_tree_by_id(tree_id: int) -> Tree
Retrieves a tree by its ID from this group or its subgroups.
Parameters:
-
tree_id
(int
) –The ID of the tree to find.
Returns:
-
Tree
(Tree
) –The tree with the specified ID.
Raises:
-
ValueError
–If no tree with the given ID exists.
Examples:
try:
tree = group.get_tree_by_id(42)
print(f"Found tree '{tree.name}'")
except ValueError:
print("Tree not found")
has_tree_id
¶
has_tree_id(tree_id: int) -> bool
Checks if a tree with the given ID exists in this group or its subgroups.
Parameters:
-
tree_id
(int
) –The ID to check for.
Returns:
-
bool
(bool
) –True if a tree with the ID exists, False otherwise.
Examples:
if group.has_tree_id(42):
tree = group.get_tree_by_id(42)
print(f"Tree exists: {tree.name}")
load
staticmethod
¶
load(file_path: Union[PathLike, str]) -> Skeleton
Load a skeleton annotation from a file.
This method can load skeleton annotations from either a .nml file or a .zip file that contains an NML file. The .zip file may also contain volume layers.
Parameters:
-
file_path
(Union[PathLike, str]
) –Path to the .nml or .zip file containing the skeleton annotation.
Returns:
-
Skeleton
(Skeleton
) –A new Skeleton instance containing the loaded annotation data.
Raises:
-
FileNotFoundError
–If the specified file does not exist.
-
ValueError
–If the file format is not supported or the file is corrupted.
Examples:
Load from an NML file:
# Load a simple NML file
skeleton = Skeleton.load("dendrite_trace.nml")
# Load from a ZIP archive containing NML and volume data
skeleton = Skeleton.load("full_annotation.zip")
Note
If you need access to volume layers or other annotation data, use
Annotation.load()
instead, which returns an Annotation object
containing both the skeleton and any additional data.
save
¶
save(out_path: Union[str, PathLike]) -> None
Save the skeleton annotation to a file.
Saves the skeleton data to either a .nml file or a .zip archive. The .zip format is recommended when the annotation includes volume layers or when you want to compress the data.
Parameters:
-
out_path
(Union[str, PathLike]
) –Destination path for the saved file. Must end with either .nml or .zip extension.
Raises:
-
AssertionError
–If the file extension is not .nml or .zip.
-
OSError
–If there are permission issues or insufficient disk space.
Examples:
# Save as NML file
skeleton.save("dendrite_annotation.nml")
# Save as ZIP archive (recommended for complex annotations)
skeleton.save("full_annotation.zip")
Note
- The name of the annotation will be derived from the filename stem
- When saving as .zip, any associated volume layers will be included
- The .nml format is human-readable XML but may be larger in size
- The .zip format provides compression and can store additional data
- Get Help
- Community Forums
- Email Support