Core Classes
The core classes provide the foundational architecture for neuromorphological data management in ossify.
Cell
Cell
Cell(name: Optional[Union[int, str]] = None, morphsync: Optional[MorphSync] = None, meta: Optional[dict] = None, annotation_layers: Optional[list] = None)
Methods:
-
add_layer–Add a initialized layer to the MorphSync.
-
add_mesh–Add a mesh layer to the MorphSync.
-
add_skeleton–Add a skeleton layer to the MorphSync.
-
add_graph–Add the core graph layer to a MeshWork object.
-
add_point_annotations–Add point annotations to the MeshWork object. This is intended for annotations which are typically sparse and represent specific features, unlike general point clouds that represent the morphology of the cell.
-
add_point_layer–Add point layer to the MeshWork object. This is intended for general point clouds that represent the morphology of the cell, unlike annotations which are typically sparse and represent specific features.
-
apply_mask–Create a new Cell with vertices masked out.
-
copy–Create a deep copy of the Cell.
-
transform–Apply a spatial transformation to all spatial layers in the Cell.
-
get_features–Map feature columns from various sources to a target layer.
-
mask_context–Create a masked version of the MeshWork object in a context state.
-
remove_layer–Remove a morphological layer from the Cell.
-
remove_annotation–Remove an annotation layer from the Cell.
-
describe–Generate a hierarchical summary description of the cell and its layers.
Attributes:
-
name(str) –Get the name of the cell (typically a segment id)
-
meta(dict) –Get the metadata associated with the cell.
-
layers(LayerManager) –Get the non-annotation layers of the cell.
-
skeleton(Optional[SkeletonLayer]) –Skeleton layer for the cell, if present. Otherwise, None.
-
graph(Optional[GraphLayer]) –Graph layer for the cell, if present. Otherwise, None.
-
mesh(Optional[MeshLayer]) –Mesh layer for the cell, if present. Otherwise, None.
-
annotations(LayerManager) –Annotation Manager for the cell, holding all annotation layers.
-
s(Optional[SkeletonLayer]) –Alias for skeleton.
-
g(Optional[GraphLayer]) –Alias for graph.
-
m(Optional[MeshLayer]) –Alias for mesh.
-
a(LayerManager) –Alias for annotations.
-
l(LayerManager) –Alias for layers.
-
features(DataFrame) –Return a DataFrame listing all feature columns across all layers. Each feature is a row, with the layer name and feature name as columns.
skeleton
property
skeleton: Optional[SkeletonLayer]
Skeleton layer for the cell, if present. Otherwise, None.
annotations
property
annotations: LayerManager
Annotation Manager for the cell, holding all annotation layers.
features
property
features: DataFrame
Return a DataFrame listing all feature columns across all layers. Each feature is a row, with the layer name and feature name as columns.
add_layer
add_layer(layer: Union[PointCloudLayer, GraphLayer, SkeletonLayer, MeshLayer]) -> Self
Add a initialized layer to the MorphSync.
Parameters:
-
layer(Union[PointCloudLayer, GraphLayer, SkeletonLayer, MeshLayer]) –The layer to add.
Raises:
-
ValueError–If the layer already exists or if the layer type is incorrect.
add_mesh
add_mesh(vertices: Union[ndarray, DataFrame, MeshLayer], faces: Optional[Union[ndarray, DataFrame]] = None, features: Optional[Union[dict, DataFrame]] = None, *, vertex_index: Optional[Union[str, ndarray]] = None, linkage: Optional[Link] = None, spatial_columns: Optional[list] = None) -> Self
Add a mesh layer to the MorphSync.
Parameters:
-
vertices(Union[ndarray, DataFrame, MeshLayer]) –The vertices of the mesh, or a MeshLayer object.
-
faces(Union[ndarray, DataFrame], default:None) –The faces of the mesh. If faces are provided as a dataframe, faces should be in dataframe indices.
-
features(Optional[Union[dict, DataFrame]], default:None) –Additional features for the mesh. If passed as dictionary, the key is the feature name and the values are an array of feature values.
-
vertex_index(Optional[Union[str, ndarray]], default:None) –The column to use as a vertex index for the mesh, if vertices are a dataframe.
-
linkage(Optional[Link], default:None) –The linkage information for the mesh.
-
spatial_columns(Optional[list], default:None) –The spatial columns for the mesh, if vertices are a dataframe.
Returns:
-
Self–
add_skeleton
add_skeleton(vertices: Union[ndarray, DataFrame, SkeletonLayer], edges: Optional[Union[ndarray, DataFrame]] = None, features: Optional[Union[dict, DataFrame]] = None, root: Optional[int] = None, *, vertex_index: Optional[Union[str, ndarray]] = None, linkage: Optional[Link] = None, spatial_columns: Optional[list] = None, inherited_properties: Optional[dict] = None) -> Self
Add a skeleton layer to the MorphSync.
Parameters:
-
vertices(Union[ndarray, DataFrame, SkeletonLayer]) –The vertices of the skeleton, or a SkeletonLayer object.
-
edges(Union[ndarray, DataFrame], default:None) –The edges of the skeleton.
-
features(Optional[Union[dict, DataFrame]], default:None) –The features for the skeleton.
-
root(Optional[int], default:None) –The root vertex for the skeleton, required of the edges are not already consistent with a single root.
-
vertex_index(Optional[Union[str, ndarray]], default:None) –The vertex index for the skeleton.
-
linkage(Optional[Link], default:None) –The linkage information for the skeleton. Typically, you will define the source vertices for the skeleton if using a graph-to-skeleton mapping.
-
spatial_columns(Optional[list], default:None) –The spatial columns for the skeleton, if vertices are a dataframe.
Returns:
-
Self–
add_graph
add_graph(vertices: Union[ndarray, DataFrame, SkeletonLayer], edges: Optional[Union[ndarray, DataFrame]] = None, features: Optional[Union[dict, DataFrame]] = None, *, vertex_index: Optional[Union[str, ndarray]] = None, spatial_columns: Optional[list] = None, linkage: Optional[Link] = None) -> Self
Add the core graph layer to a MeshWork object. Additional graph layers can be used, but they must be added separately and with unique names.
Parameters:
-
vertices(Union[ndarray, DataFrame, SkeletonLayer]) –The vertices of the graph.
-
edges(Union[ndarray, DataFrame], default:None) –The edges of the graph.
-
features(Optional[Union[dict, DataFrame]], default:None) –The features for the graph.
-
vertex_index(Optional[Union[str, ndarray]], default:None) –The vertex index for the graph.
-
spatial_columns(Optional[list], default:None) –The spatial columns for the graph, if vertices are a dataframe.
Returns:
-
Self–
add_point_annotations
add_point_annotations(name: str, vertices: Optional[Union[ndarray, DataFrame]] = None, spatial_columns: Optional[list] = None, *, vertex_index: Optional[Union[str, ndarray]] = None, features: Optional[Union[dict, DataFrame]] = None, linkage: Optional[Link] = None, vertices_from_linkage: bool = False) -> Self
Add point annotations to the MeshWork object. This is intended for annotations which are typically sparse and represent specific features, unlike general point clouds that represent the morphology of the cell.
Parameters:
-
name(str) –The name of the annotation layer.
-
vertices(Union[ndarray, DataFrame], default:None) –The vertices of the annotation layer.
-
spatial_columns(Optional[list], default:None) –The spatial columns for the annotation layer.
-
vertex_index(Optional[Union[str, ndarray]], default:None) –The vertex index for the annotation layer.
-
features(Optional[Union[dict, DataFrame]], default:None) –The features for the annotation layer.
-
linkage(Optional[Link], default:None) –The linkage information for the annotation layer. Typically, you will define the target vertices for annotations.
-
vertices_from_linkage(bool, default:False) –If True, the vertices will be inferred from the linkage mapping rather than the provided vertices. This is useful if you want to create an annotation layer that directly maps to another layer without providing separate vertex coordinates.
Returns:
-
Self–
add_point_layer
add_point_layer(name: str, vertices: Union[ndarray, DataFrame], spatial_columns: Optional[list] = None, *, vertex_index: Optional[Union[str, ndarray]] = None, features: Optional[Union[dict, DataFrame]] = None, linkage: Optional[Link] = None) -> Self
Add point layer to the MeshWork object. This is intended for general point clouds that represent the morphology of the cell, unlike annotations which are typically sparse and represent specific features.
Parameters:
-
name(str) –The name of the point layer.
-
vertices(Union[ndarray, DataFrame]) –The vertices of the point layer.
-
spatial_columns(Optional[list], default:None) –The spatial columns for the point layer.
-
vertex_index(Optional[Union[str, ndarray]], default:None) –The vertex index for the annotation layer.
-
features(Optional[Union[dict, DataFrame]], default:None) –The features for the annotation layer.
-
linkage(Optional[Link], default:None) –The linkage information for the annotation layer. Typically, you will define the target vertices for annotations.
Returns:
-
Self–
apply_mask
Create a new Cell with vertices masked out.
Parameters:
-
layer(str) –The layer name that the mask is based on.
-
mask(ndarray) –The mask to apply. Values that are True are preserved, while values that are False are discarded. Can be a boolean array or an array of vertices.
-
as_positional(bool, default:False) –If mask is an array of vertices, this sets whether indices are in dataframe indices or as_positional indices.
Returns:
-
Self–
transform
Apply a spatial transformation to all spatial layers in the Cell.
Parameters:
-
transform(Union[ndarray, callable]) –If an array, must be the same shape as the vertices of the layer(s). If a callable, must take in a (N, 3) array and return a (N, 3) array.
-
inplace(bool, default:False) –If True, modify the current Cell. If False, return a new Cell.
Returns:
-
Self–The transformed Cell.
get_features
get_features(features: Union[str, list], target_layer: str, source_layers: Optional[Union[str, list]] = None, agg: Union[str, dict] = 'median') -> DataFrame
Map feature columns from various sources to a target layer.
Parameters:
-
features(Union[str, list]) –The features to map from the source layer.
-
target_layer(str) –The target layer to map all features to.
-
source_layers(Optional[Union[str, list]], default:None) –The source layers to map the features from. Unnecessary if features are unique.
-
agg(Union[str, dict], default:'median') –The aggregation method to use when mapping the features. Anything pandas
groupby.aggtakes, as well as "majority" which will is a majority vote across the mapped indices via the stats.mode function.
Returns:
-
DataFrame–The mapped features for the target layer.
mask_context
Create a masked version of the MeshWork object in a context state.
Parameters:
-
layer(str) –The name of the layer to which the mask applies.
-
mask(array or None) –A boolean array with the same number of elements as mesh vertices. True elements are kept, False are masked out.
Example
with mesh.mask_context("layer_name", mask) as masked_mesh: result = my_favorite_function(masked_mesh)
remove_layer
Remove a morphological layer from the Cell.
Parameters:
-
name(str) –The name of the layer to remove
Returns:
-
Self–The Cell object for method chaining
Raises:
-
ValueError–If the layer does not exist or is a core layer that cannot be removed
remove_annotation
Remove an annotation layer from the Cell.
Parameters:
-
name(str) –The name of the annotation to remove
Returns:
-
Self–The Cell object for method chaining
Raises:
-
ValueError–If the annotation does not exist
describe
describe(html: bool = False) -> None
Generate a hierarchical summary description of the cell and its layers.
Provides a tree-like overview including: - Cell name and basic info - Layers section with expandable details - Annotations section with expandable details
Parameters:
-
html(bool, default:False) –If True, create expandable HTML widgets in Jupyter. If False, print formatted string (default).
Returns:
-
None–Always returns None (prints text or displays HTML widgets)
Examples:
Link
Link
dataclass
Link(mapping: Union[list[int], str], source: Optional[str] = None, target: Optional[str] = None, map_value_is_index: bool = True)
Represents the linkage mapping information.
Parameters:
-
mapping(Union[list[int], str]) –The mapping information between the source and target layers. The mapping will have the same length as the source vertices and the values will be the corresponding target vertex indices. If map_value_is_index is True, the mapping values should the dataframe index for target vertices (i.e. df.index), if False they are the positional indices (0-N). If a string, the mapping is the column name in the target's vertex dataframe.
-
source(Optional[str], default:None) –The name of the source layer, typically the one with more vertices than the target. E.g. a graph or mesh to a skeleton, or a graph or skeleton to point annotations. If not provided, will be set to the layer name of the object this is being added to. Either source or target can be undefined, but not both.
-
target(Optional[str], default:None) –The name of the target layer, typically the one with fewer vertices. E.g. a skeleton from a graph or mesh, or point annotations from a skeleton. If not provided, will be set to the layer name of the object this is being added to. Either source or target can be undefined, but not both.
-
map_value_is_index(bool, default:True) –If True, assumes the values in the list or the mapping are a non-positional dataframe index.
Methods:
-
mapping_to_index–Map positional values to index values
Manager Classes
These classes are used internally by Cell to organize and access different types of data layers.
Users should not need to interact with these directly.
LayerManager
LayerManager
LayerManager(managed_layers: Optional[dict] = None, validation: Union[str, Callable] = 'any', context: str = 'layer', initial_layers: Optional[list] = None)
Unified manager for both morphological layers and annotations with flexible validation.
Initialize the unified layer manager.
Parameters:
-
managed_layers(dict, default:None) –Dictionary to store layers in. If None, creates new dict.
-
validation(str or callable, default:'any') –Type validation mode: - 'any': Accept any layer type - 'point_cloud_only': Only accept PointCloudLayer - callable: Custom validation function
-
context(str, default:'layer') –Context name for error messages ('layer', 'annotation', etc.)
-
initial_layers(list, default:None) –Initial layers to add (with validation)
Methods:
-
get–Get a layer by name with optional default.
-
describe–Generate a detailed description of all managed layers.
Attributes:
AnnotationManager
AnnotationManager
module-attribute
AnnotationManager = partial(LayerManager, validation='point_cloud_only', context='annotation')
Usage Examples
Creating and Working with Cells
import ossify
import numpy as np
# Create an empty cell
cell = ossify.Cell(name="example_neuron")
# Add a skeleton layer
vertices = np.random.rand(100, 3) * 1000 # Random 3D points
edges = np.column_stack([np.arange(99), np.arange(1, 100)]) # Linear chain
cell.add_skeleton(vertices=vertices, edges=edges, root=0)
# Add a mesh layer
mesh_vertices = np.random.rand(200, 3) * 1000
faces = np.random.randint(0, 200, (150, 3)) # Random triangular faces
cell.add_mesh(vertices=mesh_vertices, faces=faces)
# Add point annotations
annotation_points = np.random.rand(50, 3) * 1000
cell.add_point_annotations(
name="synapses",
vertices=annotation_points
)
Layer Access and Management
# Access layers by name
skeleton = cell.layers["skeleton"]
mesh = cell.layers["mesh"]
# Access via properties
skeleton = cell.skeleton
mesh = cell.mesh
# Access annotations
synapses = cell.annotations["synapses"]
synapse_locations = cell.annotations.synapses # Alternative syntax
# List all available layers
print("Morphological layers:", cell.layers.names)
print("Annotation layers:", cell.annotations.names)
print("All features across layers:")
print(cell.features)
Data Linking and Mapping
# Create a link between skeleton and annotations
from ossify import Link
# Map synapses to nearest skeleton vertices
link = Link(
mapping=skeleton_vertex_ids, # Array mapping synapses to skeleton vertices
source="synapses",
target="skeleton"
)
cell.add_point_annotations(
name="linked_synapses",
vertices=annotation_points,
linkage=link
)
# Map features between layers
compartment_features = cell.get_features(
features=["compartment"],
target_layer="skeleton",
source_layers=["mesh"],
agg="majority" # Use majority vote for mapping
)
Masking and Filtering
# Apply a mask to create a subset
axon_mask = skeleton.get_feature("is_axon") == True
axon_cell = cell.apply_mask("skeleton", axon_mask)
# Temporary masking with context manager
with cell.mask_context("skeleton", axon_mask) as masked_cell:
# Work with axon-only data
axon_length = masked_cell.skeleton.cable_length()
print(f"Axon length: {axon_length:.2f}")
# The original cell is unchanged after exiting context
Spatial Transformations
# Apply a transformation matrix
transform_matrix = np.array([
[1, 0, 0], # Scale x by 1
[0, 1, 0], # Scale y by 1
[0, 0, 2] # Scale z by 2
])
# Transform all spatial layers
transformed_cell = cell.transform(transform_matrix)
# Or apply in-place
cell.transform(transform_matrix, inplace=True)
# Apply custom transformation function
def rotate_90_degrees(vertices):
\"\"\"Rotate 90 degrees around z-axis\"\"\"
rotation = np.array([
[0, -1, 0],
[1, 0, 0],
[0, 0, 1]
])
return vertices @ rotation.T
rotated_cell = cell.transform(rotate_90_degrees)
Key Design Principles
Consistent Interface: All layer types share common methods for transformations, masking, and feature management.
Method Chaining: Most methods return self to enable fluent interfaces: cell.add_skeleton(...).add_mesh(...)
Non-destructive Operations: Operations like apply_mask() return new objects, preserving the original data.
Flexible Indexing: Support both DataFrame indices (arbitrary integers) and positional indices (0-based arrays).
Performance Tips
- Use
mask_context()for temporary operations to avoid copying data - Leverage the
LinkageSystemfor efficient cross-layer operations - Cache expensive computations using layer properties like
csgraph