Shared Layer Features
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.
All ossify layers (meshes, graphs, skeletons, and point clouds) inherit common functionality through the PointMixin class. This document covers the features that work the same way across all layer types.
Common Properties
Every layer has these basic properties:
# Assuming you have a layer (mesh, graph, skeleton, or point cloud)
layer = cell.skeleton # or cell.mesh, cell.graph, etc.
# Basic properties
print(f"Layer name: {layer.name}")
print(f"Number of vertices: {layer.n_vertices}")
print(f"Bounding box: {layer.bbox}")
print(f"Spatial columns: {layer.spatial_columns}")
print(f"Available features: {layer.feature_names}")
Vertex Data Access
All layers provide consistent access to vertex data:
# Vertex coordinates
vertices_array = layer.vertices # Nx3 numpy array
vertices_df = layer.vertex_df # Pandas DataFrame with index
vertex_indices = layer.vertex_index # Array of vertex indices
vertex_index_map = layer.vertex_index_map # Dict mapping indices to positions
# Complete node data (coordinates + features)
full_data = layer.nodes # DataFrame with all data
features_only = layer.features # DataFrame with just features
Working with features
All layers support adding and accessing vertex features:
# Add features using arrays
quality_values = np.array([0.9, 0.8, 0.7, 0.6])
layer.add_feature(quality_values, name="quality")
# Add multiple features at once
new_features = {
"region": [0, 0, 1, 1],
"processed": [True, True, False, False]
}
layer.add_feature(new_features)
# Access feature data
quality = layer.get_feature("quality")
all_features = layer.features
print(f"Available features: {layer.feature_names}")
Spatial Queries
All layers provide KDTree functionality for spatial searches:
# Get KDTree for spatial queries
kdtree = layer.kdtree
# Find nearest vertices to a point
query_point = [0.5, 0.5, 0.5]
distances, indices = kdtree.query(query_point, k=2) # 2 nearest
# Get vertex indices (not positional indices)
nearest_vertex_ids = layer.vertex_index[indices]
print(f"Nearest vertices: {nearest_vertex_ids}")
print(f"Distances: {distances}")
Copying and Transformations
All layers support copying and spatial transformations:
# Create a deep copy
layer_copy = layer.copy()
# Apply spatial transformation using a function
def scale_and_translate(vertices):
scaled = vertices * 2.0 # Scale by 2
translated = scaled + [10, 0, 0] # Translate
return translated
# Transform (returns new layer)
transformed_layer = layer.transform(scale_and_translate, inplace=False)
# Transform in place
layer.transform(scale_and_translate, inplace=True)
# Transform using a matrix
transform_matrix = np.eye(4)
transform_matrix[:3, 3] = [5, 0, 0] # Translation
layer.transform(transform_matrix, inplace=True)
Masking and Filtering
All layers support masking to create filtered subsets:
# Create boolean mask
mask = layer.get_feature("quality") > 0.7
# Apply mask (creates new layer)
filtered_layer = layer.apply_mask(mask, as_positional=False)
# Use as context manager for temporary filtering
with layer.mask_context(mask) as filtered_layer:
# Work with filtered data
result = some_analysis_function(filtered_layer)
# Original layer unchanged
# Mask using vertex indices instead of boolean
vertex_indices = layer.vertex_index[:10] # First 10 vertices
subset_layer = layer.apply_mask(vertex_indices, as_positional=False)
# Mask using positional indices
positional_mask = np.array([0, 1, 2, 5, 8]) # Specific positions
subset_layer = layer.apply_mask(positional_mask, as_positional=True)
Cross-Layer Mapping
When layers are part of a cell, you can map data between them:
Index Mapping
# Map indices one-to-one between layers
target_indices = layer.map_index_to_layer(
layer="skeleton", # Target layer
source_index=None, # None = all vertices
as_positional=False, # Use vertex indices
validate=False # Check for ambiguous mappings
)
# Map a region to all corresponding vertices
all_target_indices = layer.map_region_to_layer(
layer="mesh",
source_index=layer.vertex_index[:5], # First 5 vertices
as_positional=False
)
# Map each vertex to lists of all corresponding vertices
mapping_dict = layer.map_index_to_layer_region(
layer="graph",
source_index=layer.vertex_index[:3],
as_positional=False
)
print(f"Vertex mappings: {mapping_dict}")
feature Mapping
# Map features from one layer to another
mapped_features = layer.map_features_to_layer(
features="quality", # feature to map
layer="skeleton", # Target layer
agg="mean" # Aggregation method
)
# Map multiple features with different aggregations
mapped_features = layer.map_features_to_layer(
features=["quality", "region"],
layer="mesh",
agg={
"quality": "mean",
"region": "majority" # Custom aggregation function
}
)
# Use the mapping
target_layer = cell.layers["skeleton"]
target_layer.add_feature(mapped_features)
Mask Mapping
# Map a boolean mask to another layer
source_mask = layer.get_feature("processed") == True
target_mask = layer.map_mask_to_layer("mesh", source_mask)
# Apply the mapped mask to target layer
target_layer = cell.layers["mesh"]
filtered_target = target_layer.apply_mask(target_mask, as_positional=True)
Vertex Index vs Positional Index
Understanding the difference between vertex indices and positional indices is crucial:
# Vertex indices: The actual IDs/features of vertices
vertex_ids = layer.vertex_index # e.g., [100, 205, 350, 401]
# Positional indices: Array positions (0, 1, 2, 3...)
# Used for indexing into arrays like layer.vertices
# Convert between them
vertex_index_map = layer.vertex_index_map # Dict: {100: 0, 205: 1, 350: 2, 401: 3}
# Most functions have as_positional parameter
distances = layer.distance_to_root(
vertices=[100, 205], # Vertex indices
as_positional=False # Specify we're using vertex indices
)
distances = layer.distance_to_root(
vertices=[0, 1], # Positional indices
as_positional=True # Specify we're using positions
)
Finding Unmapped Vertices
Find vertices that don't have mappings to other layers:
# Find vertices with no mapping to any other layer
unmapped = layer.get_unmapped_vertices()
# Find vertices with no mapping to specific layers
unmapped_to_mesh = layer.get_unmapped_vertices(target_layers="mesh")
unmapped_to_multiple = layer.get_unmapped_vertices(
target_layers=["mesh", "skeleton"]
)
# Remove unmapped vertices
clean_layer = layer.mask_out_unmapped(target_layers="mesh")
# Remove vertices unmapped to any other layer
fully_clean = layer.mask_out_unmapped() # Checks all other layers
Key Shared Methods Reference
Basic Properties
layer.name- Layer namelayer.n_vertices- Number of verticeslayer.bbox- Bounding boxlayer.spatial_columns- List of coordinate column nameslayer.feature_names- List of available features
Data Access
layer.vertices- Vertex coordinates as numpy arraylayer.vertex_df- Vertices as indexed DataFramelayer.vertex_index- Array of vertex indiceslayer.vertex_index_map- Dict mapping indices to positionslayer.nodes- Complete DataFrame with coordinates and featureslayer.features- DataFrame of all features
features
layer.add_feature(feature, name=None)- Add vertex featureslayer.get_feature(key)- Get feature array
Spatial Operations
layer.kdtree- KDTree for spatial querieslayer.transform(transform, inplace=False)- Apply transformationlayer.copy()- Create deep copy
Masking
layer.apply_mask(mask, as_positional=False, self_only=False)- Create masked subsetlayer.mask_context(mask)- Temporary masking context managerlayer.get_unmapped_vertices(target_layers=None)- Find unmapped verticeslayer.mask_out_unmapped(target_layers=None, self_only=False)- Remove unmapped vertices
Cross-layer Mapping
layer.map_index_to_layer(layer, source_index=None, as_positional=False, validate=False)- Map indices 1:1layer.map_region_to_layer(layer, source_index=None, as_positional=False)- Map region to regionlayer.map_index_to_layer_region(layer, source_index=None, as_positional=False)- Map to listslayer.map_features_to_layer(features, layer, agg="mean")- Map features between layerslayer.map_mask_to_layer(layer, mask)- Map boolean mask