The Cell Object
AI-Generated Documentation
This documentation was generated with assistance from AI. While we strive for accuracy, errors may be present. If you find issues, unclear explanations, or have suggestions for improvement, please report them on GitHub.
The Cell is the central container in ossify that holds all morphological data for a single cellular structure. It manages different types of data layers and their relationships through a unified interface.
Cell Architecture
A Cell object contains:
- Layers: Primary morphological data (mesh, skeleton, graph, and additional point clouds)
- Annotations: Sparse point data representing specific features
- Metadata: Additional information about the cell
- Links: Mappings that connect data between different layers
Creating a Cell
Basic Creation
import ossify
# Create an empty cell
cell = ossify.Cell(name="my_cell")
# Create with metadata
cell = ossify.Cell(
name="neuron_12345",
meta={"source": "experiment_A", "date": "2024-01-15"}
)
print(cell.name) # "neuron_12345"
print(cell.meta) # {"source": "experiment_A", "date": "2024-01-15"}
Cell Properties
# Basic information
print(f"Cell name: {cell.name}")
print(f"Metadata: {cell.meta}")
# Layer access
print(f"Available layers: {cell.layers.names}")
print(f"Available annotations: {cell.annotations.names}")
# Quick layer access
skeleton = cell.skeleton # or cell.s
mesh = cell.mesh # or cell.m
graph = cell.graph # or cell.g
annotations = cell.annotations # or cell.a
layers = cell.layers # or cell.l
Core Layer Types
The Cell supports three main types of morphological layers:
Skeleton Layer
Tree-structured data representing the branching morphology:
import numpy as np
vertices = np.array([[0,0,0], [1,0,0], [2,0,0]])
edges = np.array([[0,1], [1,2]])
cell.add_skeleton(
vertices=vertices,
edges=edges,
root=0, # Index of root vertex
features={"radius": [0.5, 0.3, 0.2]} # Optional features
)
# Access skeleton properties
print(f"Root location: {cell.skeleton.root_location}")
print(f"End points: {cell.skeleton.end_points}")
print(f"Branch points: {cell.skeleton.branch_points}")
Mesh Layer
Surface mesh data with faces:
mesh_vertices = np.array([[0,0,0], [1,0,0], [0,1,0]])
faces = np.array([[0,1,2]]) # Triangle
cell.add_mesh(vertices=mesh_vertices, faces=faces)
# Access mesh properties
print(f"Surface area: {cell.mesh.surface_area()}")
print(f"Number of faces: {len(cell.mesh.faces)}")
Graph Layer
General graph structure without tree constraints:
graph_vertices = np.random.randn(5, 3)
graph_edges = np.array([[0,1], [1,2], [2,3], [3,4], [4,0]]) # Cycle
cell.add_graph(vertices=graph_vertices, edges=graph_edges)
print(f"Graph vertices: {cell.graph.n_vertices}")
Annotations System
Annotations are sparse point data representing specific features:
# Add synaptic sites
synapse_locations = np.array([[0.5, 0, 0], [1.5, 0, 0]])
cell.add_point_annotations(
name="pre_synapses",
vertices=synapse_locations,
spatial_columns=["x", "y", "z"]
)
# Access annotations
print(f"Number of synapses: {len(cell.annotations.pre_synapses.vertices)}")
print(f"Annotation names: {cell.annotations.names}")
Layer Management
Adding Additional Point Layers
Beyond the three core layer types, you can add additional point cloud layers:
# Add a general point cloud layer (not an annotation)
point_data = np.random.randn(100, 3)
cell.add_point_layer(
name="sampling_points",
vertices=point_data,
spatial_columns=["x", "y", "z"]
)
Removing Layers
# Remove a layer
cell.remove_layer("sampling_points")
# Remove an annotation
cell.remove_annotation("pre_synapses")
Working with features
Both layers and annotations can have associated feature data:
# Add features to skeleton
import pandas as pd
# Using arrays
radius_values = np.array([0.5, 0.3, 0.2])
cell.skeleton.add_feature(radius_values, name="radius")
# Using dictionaries
features_dict = {"compartment": [0, 1, 1]} # 0=dendrite, 1=axon
cell.skeleton.add_feature(features_dict)
# Access features
print(f"Available features: {cell.skeleton.feature_names}")
radius = cell.skeleton.get_feature("radius")
Cell Information and Inspection
Summary View with describe()
The describe() method provides a comprehensive overview of your cell's structure and contents:
# Get a hierarchical summary of the cell
cell.describe()
# Example output:
# Cell: my_cell
# ├── Layers (3)
# │ ├── skeleton: 150 vertices, 149 edges
# │ ├── mesh: 2847 vertices, 5691 faces
# │ └── graph: 45 vertices, 67 edges
# ├── Annotations (2)
# │ ├── synapses: 23 points
# │ └── spines: 47 points
# └── Linkage (3 connections)
# ├── skeleton → mesh: 150 mappings
# ├── synapses → skeleton: 23 mappings
# └── spines → skeleton: 47 mappings
# HTML view in Jupyter notebooks (interactive tree view)
cell.describe(html=True)
# Simple string representation
print(cell) # Shows basic layers and annotations summary
The describe() method is particularly useful for:
- Quick overview of cell contents and structure
- Debugging linkage issues between layers
- Validation that data loaded correctly
- Documentation of cell composition in notebooks
Multi-Level Inspection with describe()
Ossify provides detailed inspection at multiple levels of granularity:
# 1. Cell overview (high-level summary)
cell.describe()
# 2. All morphological layers (detailed)
cell.layers.describe()
# Output:
# Layers (3)
# ├── skeleton (SkeletonLayer)
# │ ├── 150 vertices, 149 edges
# │ ├── features: [radius, branch_type]
# │ └── Links: mesh <-> skeleton, synapses → skeleton
# ├── mesh (MeshLayer)
# │ ├── 2847 vertices, 5691 faces
# │ ├── features: [compartment]
# │ └── Links: skeleton <-> mesh
# └── graph (GraphLayer)
# ├── 45 vertices, 67 edges
# ├── features: []
# └── Links: []
# 3. All annotations (detailed)
cell.annotations.describe()
# Output:
# Annotations (2)
# ├── synapses (PointCloudLayer)
# │ ├── 23 vertices
# │ ├── features: [synapse_type, confidence]
# │ └── Links: skeleton → synapses
# └── spines (PointCloudLayer)
# ├── 47 vertices
# ├── features: [spine_type]
# └── Links: skeleton → spines
# 4. Individual layers (with cell context)
cell.skeleton.describe()
# Output:
# Cell: my_neuron
# Layer: skeleton (SkeletonLayer)
# ├── 150 vertices, 149 edges
# ├── features: [radius, branch_type]
# └── Links: mesh <-> skeleton, synapses → skeleton
cell.annotations.synapses.describe()
# Output:
# Cell: my_neuron
# Layer: synapses (PointCloudLayer)
# ├── 23 vertices
# ├── features: [synapse_type, confidence]
# └── Links: skeleton → synapses
This hierarchical inspection system lets you:
- Start broad with cell.describe() for overall structure
- Focus on groups with cell.layers.describe() or cell.annotations.describe()
- Drill down to individual layers for detailed analysis
- Maintain context with cell name shown in individual layer descriptions
Accessing All features
# Get DataFrame of all features across layers
all_features = cell.features
print(all_features)
# Map features from one layer to another
mapped_features = cell.get_features(
features="radius",
target_layer="mesh",
source_layers="skeleton",
agg="mean" # How to aggregate when mapping
)
Copying and Transforming Cells
Creating Copies
# Deep copy of the cell
cell_copy = cell.copy()
# Copy preserves all data and structure
print(cell_copy.name) # Same name
print(len(cell_copy.skeleton.vertices)) # Same data
Spatial Transformations
# Apply a transformation to all spatial layers
# Using a transformation matrix
transform_matrix = np.eye(4) # Identity matrix
transform_matrix[:3, 3] = [10, 0, 0] # Translation
cell.transform(transform_matrix, inplace=True)
# Using a function
def scale_by_two(vertices):
return vertices * 2
cell.transform(scale_by_two, inplace=False) # Returns new cell
Advanced Features
Layer Aliases
# Short aliases for common access patterns
skel = cell.s # skeleton
mesh = cell.m # mesh
graph = cell.g # graph
annos = cell.a # annotations
layers = cell.l # layers
Context Managers
# Temporarily apply a mask
mask = cell.skeleton.vertex_index < 10
with cell.mask_context("skeleton", mask) as masked_cell:
# Work with filtered data
result = some_analysis_function(masked_cell)
# Original cell unchanged
Key Methods Reference
Cell Creation and Management
ossify.Cell(name, meta=None)- Create new cellcell.copy()- Deep copy of cellcell.describe()- Summary viewcell.transform(transform, inplace=False)- Apply spatial transformation
Adding Layers
cell.add_skeleton(vertices, edges, root=None, features=None)- Add skeletoncell.add_mesh(vertices, faces, features=None)- Add meshcell.add_graph(vertices, edges, features=None)- Add graphcell.add_point_layer(name, vertices, features=None)- Add point cloudcell.add_point_annotations(name, vertices, features=None)- Add annotations
Layer Management
cell.remove_layer(name)- Remove morphological layercell.remove_annotation(name)- Remove annotation layer
Data Access
cell.layers- Access to layer managercell.annotations- Access to annotation managercell.features- DataFrame of all featurescell.get_features(features, target_layer, source_layers=None, agg="median")- Map features between layers
Masking and Filtering
cell.apply_mask(layer, mask, as_positional=False)- Apply mask to create new cellcell.mask_context(layer, mask)- Temporary masking context manager