CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-kimimaro

Skeletonize densely labeled image volumes using TEASAR-derived algorithms for neuroscience and connectomics research.

Pending
Overview
Eval results
Files

point-connection.mddocs/

Point Connection and Targeting

Functions for creating direct connections between specific points and converting synapse locations to skeleton targets. These capabilities are useful for precise path tracing and integrating external annotations into skeletonization workflows.

Capabilities

Direct Point Connection

Creates a skeleton path between two preselected points on a binary image, finding the optimal route through the object geometry.

def connect_points(
    labels,
    start,
    end,
    anisotropy=(1,1,1),
    fill_holes=False,
    in_place=False,
    pdrf_scale=100000,
    pdrf_exponent=4
):
    """
    Draw a centerline between preselected points on a binary image.

    Extract a single centerline skeleton between two preselected points
    from a binary image using a penalty distance field approach.

    Parameters:
    - labels (numpy.ndarray): Binary image (2D or 3D)
    - start (tuple): Starting point coordinates (x, y, z) in voxel space
    - end (tuple): Ending point coordinates (x, y, z) in voxel space
    - anisotropy (tuple): Physical voxel dimensions (default: (1,1,1))
    - fill_holes (bool): Fill holes in shapes before tracing (default: False)
    - in_place (bool): Modify input array in place (default: False)
    - pdrf_scale (float): Penalty field scale factor (default: 100000)
    - pdrf_exponent (int): Penalty field exponent (default: 4)

    Returns:
    Skeleton: Single skeleton tracing the path between start and end points

    Raises:
    ValueError: If start and end points are in disconnected components

    Notes:
    - Input must be binary (True/False values)
    - Coordinates are in voxel space (not physical units)
    - Uses penalty distance field with Dijkstra's algorithm
    - Start and end points must be in the same connected component
    """

Usage Example

import kimimaro
import numpy as np

# Extract single neuron as binary image
neuron_binary = (labels == target_neuron_id)

# Connect soma to axon terminal
soma_center = (125, 200, 45)        # Coordinates in voxels
axon_terminal = (890, 1240, 156)    # Coordinates in voxels

# Trace direct connection
direct_path = kimimaro.connect_points(
    neuron_binary,
    start=soma_center,
    end=axon_terminal,
    anisotropy=(16, 16, 40)  # nm per voxel
)

print(f"Direct path length: {direct_path.cable_length():.1f} nm")
print(f"Path vertices: {len(direct_path.vertices)}")

# Compare with full skeletonization
full_skeleton = kimimaro.skeletonize(
    neuron_binary.astype(np.uint32),
    anisotropy=(16, 16, 40)
)[1]

print(f"Full skeleton length: {full_skeleton.cable_length():.1f} nm")
print(f"Direct path is {direct_path.cable_length()/full_skeleton.cable_length()*100:.1f}% of full skeleton")

Advanced Point Connection

# Connect multiple points in sequence
connection_points = [
    (100, 150, 30),   # Start point
    (200, 250, 45),   # Intermediate point 1
    (350, 400, 60),   # Intermediate point 2
    (500, 550, 75)    # End point
]

# Create sequential connections
path_segments = []
for i in range(len(connection_points) - 1):
    segment = kimimaro.connect_points(
        neuron_binary,
        start=connection_points[i],
        end=connection_points[i + 1],
        anisotropy=(16, 16, 40)
    )
    path_segments.append(segment)

# Combine segments (you would need to implement skeleton merging)
print(f"Created {len(path_segments)} path segments")

Synapse Target Conversion

Converts synapse centroid locations to skeleton target points, enabling enhanced skeletonization around synaptic sites.

def synapses_to_targets(labels, synapses, progress=False):
    """
    Convert synapse centroids to skeleton targets.

    Given synapse centroids (in voxels) and desired SWC integer labels,
    finds the nearest voxel to each centroid for the corresponding label.
    This enables targeted skeletonization that ensures skeleton paths
    pass through or near synaptic sites.

    Parameters:
    - labels (numpy.ndarray): Labeled volume with neuron segments
    - synapses (dict): Mapping of {label_id: [((x,y,z), swc_label), ...]}
        - label_id: Which neuron label the synapse belongs to
        - (x,y,z): Synapse centroid coordinates in voxel space
        - swc_label: SWC node type for this synapse (e.g., 3=dendrite, 4=axon)
    - progress (bool): Show progress bar (default: False)

    Returns:
    dict: Mapping of {(x,y,z): swc_label, ...} for use as extra_targets

    Notes:
    - Coordinates are in voxel space, not physical units
    - SWC labels follow standard: 1=soma, 2=axon, 3=dendrite, 4=apical, etc.
    - Targets can be used with extra_targets_before or extra_targets_after
    """

Usage Example

import kimimaro
import numpy as np

# Define synapse locations for multiple neurons
synapses = {
    # Neuron 1 has 3 synapses
    1: [
        ((120, 200, 30), 3),  # Dendrite synapse
        ((150, 220, 35), 3),  # Another dendrite synapse  
        ((180, 240, 40), 4),  # Apical dendrite synapse
    ],
    # Neuron 5 has 2 synapses
    5: [
        ((80, 180, 25), 2),   # Axon synapse
        ((90, 190, 28), 2),   # Another axon synapse
    ],
    # Neuron 12 has 1 soma synapse
    12: [
        ((300, 400, 60), 1),  # Soma synapse
    ]
}

# Convert synapses to target format
targets = kimimaro.synapses_to_targets(
    labels, 
    synapses, 
    progress=True
)

print(f"Generated {len(targets)} target points")
print("Target locations:", list(targets.keys())[:5])

# Use targets in skeletonization to ensure paths hit synapses
skeletons = kimimaro.skeletonize(
    labels,
    anisotropy=(16, 16, 40),
    extra_targets_after=list(targets.keys()),  # Add as extra endpoints
    teasar_params={
        "scale": 1.5,
        "const": 300,
        "soma_detection_threshold": 750,
    },
    progress=True
)

# The resulting skeletons will have paths that pass through synapse locations
for label_id, skeleton in skeletons.items():
    if label_id in synapses:
        n_synapses = len(synapses[label_id])
        print(f"Neuron {label_id}: {n_synapses} synapses, {len(skeleton.vertices)} skeleton vertices")

Integration with Connectomics Annotations

import kimimaro
import pandas as pd
import numpy as np

# Load connectomics annotations
def load_synapse_annotations(annotation_file):
    """Load synapse annotations from CSV or database."""
    # Example format: neuron_id, x, y, z, synapse_type, confidence
    df = pd.read_csv(annotation_file)
    
    synapses = {}
    for _, row in df.iterrows():
        neuron_id = int(row['neuron_id'])
        coords = (int(row['x']), int(row['y']), int(row['z']))
        
        # Map synapse type to SWC label
        swc_type_map = {
            'presynaptic': 2,    # Axon terminal
            'postsynaptic': 3,   # Dendrite
            'soma_synapse': 1,   # Soma
            'apical': 4          # Apical dendrite
        }
        swc_label = swc_type_map.get(row['synapse_type'], 3)
        
        if neuron_id not in synapses:
            synapses[neuron_id] = []
        synapses[neuron_id].append((coords, swc_label))
    
    return synapses

# Load and process annotations
synapses = load_synapse_annotations("connectome_synapses.csv")
targets = kimimaro.synapses_to_targets(labels, synapses, progress=True)

# Skeletonize with synapse targets
skeletons = kimimaro.skeletonize(
    labels,
    anisotropy=(8, 8, 30),  # High-resolution EM data
    extra_targets_after=list(targets.keys()),
    teasar_params={
        "scale": 1.2,          # Tighter invalidation for precise targeting
        "const": 200,          # Smaller minimum radius
        "pdrf_scale": 150000,  # Higher penalty field influence
    },
    parallel=8,
    progress=True
)

print(f"Processed {len(skeletons)} neurons with {len(targets)} synapse targets")

Validation and Quality Control

def validate_synapse_targeting(skeletons, synapses, targets, max_distance=500):
    """Validate that skeletons actually reach synapse targets."""
    
    validation_results = {}
    
    for label_id, skeleton in skeletons.items():
        if label_id not in synapses:
            continue
            
        results = {
            'synapses_targeted': len(synapses[label_id]),
            'distances': [],
            'missed_synapses': []
        }
        
        # Check each synapse
        for (synapse_coords, swc_label) in synapses[label_id]:
            # Find closest skeleton vertex to synapse
            skeleton_coords = skeleton.vertices
            distances = np.sqrt(np.sum((skeleton_coords - np.array(synapse_coords))**2, axis=1))
            min_distance = np.min(distances)
            
            results['distances'].append(min_distance)
            
            if min_distance > max_distance:
                results['missed_synapses'].append({
                    'coords': synapse_coords,
                    'distance': min_distance,
                    'swc_label': swc_label
                })
        
        results['mean_distance'] = np.mean(results['distances'])
        results['max_distance'] = np.max(results['distances'])
        results['success_rate'] = 1 - len(results['missed_synapses']) / len(synapses[label_id])
        
        validation_results[label_id] = results
    
    return validation_results

# Run validation
validation = validate_synapse_targeting(skeletons, synapses, targets)

for label_id, results in validation.items():
    print(f"Neuron {label_id}:")
    print(f"  Success rate: {results['success_rate']*100:.1f}%")
    print(f"  Mean distance to synapses: {results['mean_distance']:.1f} nm")
    if results['missed_synapses']:
        print(f"  Missed {len(results['missed_synapses'])} synapses")

Use Cases and Applications

Axon Tracing

  • Connect soma to axon terminals for long-range projection analysis
  • Validate axonal continuity across image boundaries
  • Measure axon length and branching patterns

Dendritic Analysis

  • Connect soma to dendritic tips for morphological analysis
  • Trace specific dendritic branches identified in functional studies
  • Validate dendritic spine connectivity

Connectomics Integration

  • Incorporate synapse annotations into skeleton generation
  • Ensure skeleton paths pass through confirmed connection sites
  • Generate skeletons optimized for connectivity analysis

Quality Control

  • Verify skeleton completeness by connecting known endpoints
  • Test alternative paths through complex morphologies
  • Validate automated skeletonization results with manual annotations

Cross-scale Analysis

  • Connect structures identified at different resolution scales
  • Bridge between light microscopy and electron microscopy data
  • Integrate multi-modal annotations into unified skeletons

Install with Tessl CLI

npx tessl i tessl/pypi-kimimaro

docs

analysis-utilities.md

cli-interface.md

core-skeletonization.md

index.md

point-connection.md

post-processing.md

tile.json