or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

analysis-utilities.mdcli-interface.mdcore-skeletonization.mdindex.mdpoint-connection.mdpost-processing.md

point-connection.mddocs/

0

# Point Connection and Targeting

1

2

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.

3

4

## Capabilities

5

6

### Direct Point Connection

7

8

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

9

10

```python { .api }

11

def connect_points(

12

labels,

13

start,

14

end,

15

anisotropy=(1,1,1),

16

fill_holes=False,

17

in_place=False,

18

pdrf_scale=100000,

19

pdrf_exponent=4

20

):

21

"""

22

Draw a centerline between preselected points on a binary image.

23

24

Extract a single centerline skeleton between two preselected points

25

from a binary image using a penalty distance field approach.

26

27

Parameters:

28

- labels (numpy.ndarray): Binary image (2D or 3D)

29

- start (tuple): Starting point coordinates (x, y, z) in voxel space

30

- end (tuple): Ending point coordinates (x, y, z) in voxel space

31

- anisotropy (tuple): Physical voxel dimensions (default: (1,1,1))

32

- fill_holes (bool): Fill holes in shapes before tracing (default: False)

33

- in_place (bool): Modify input array in place (default: False)

34

- pdrf_scale (float): Penalty field scale factor (default: 100000)

35

- pdrf_exponent (int): Penalty field exponent (default: 4)

36

37

Returns:

38

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

39

40

Raises:

41

ValueError: If start and end points are in disconnected components

42

43

Notes:

44

- Input must be binary (True/False values)

45

- Coordinates are in voxel space (not physical units)

46

- Uses penalty distance field with Dijkstra's algorithm

47

- Start and end points must be in the same connected component

48

"""

49

```

50

51

#### Usage Example

52

53

```python

54

import kimimaro

55

import numpy as np

56

57

# Extract single neuron as binary image

58

neuron_binary = (labels == target_neuron_id)

59

60

# Connect soma to axon terminal

61

soma_center = (125, 200, 45) # Coordinates in voxels

62

axon_terminal = (890, 1240, 156) # Coordinates in voxels

63

64

# Trace direct connection

65

direct_path = kimimaro.connect_points(

66

neuron_binary,

67

start=soma_center,

68

end=axon_terminal,

69

anisotropy=(16, 16, 40) # nm per voxel

70

)

71

72

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

73

print(f"Path vertices: {len(direct_path.vertices)}")

74

75

# Compare with full skeletonization

76

full_skeleton = kimimaro.skeletonize(

77

neuron_binary.astype(np.uint32),

78

anisotropy=(16, 16, 40)

79

)[1]

80

81

print(f"Full skeleton length: {full_skeleton.cable_length():.1f} nm")

82

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

83

```

84

85

### Advanced Point Connection

86

87

```python

88

# Connect multiple points in sequence

89

connection_points = [

90

(100, 150, 30), # Start point

91

(200, 250, 45), # Intermediate point 1

92

(350, 400, 60), # Intermediate point 2

93

(500, 550, 75) # End point

94

]

95

96

# Create sequential connections

97

path_segments = []

98

for i in range(len(connection_points) - 1):

99

segment = kimimaro.connect_points(

100

neuron_binary,

101

start=connection_points[i],

102

end=connection_points[i + 1],

103

anisotropy=(16, 16, 40)

104

)

105

path_segments.append(segment)

106

107

# Combine segments (you would need to implement skeleton merging)

108

print(f"Created {len(path_segments)} path segments")

109

```

110

111

### Synapse Target Conversion

112

113

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

114

115

```python { .api }

116

def synapses_to_targets(labels, synapses, progress=False):

117

"""

118

Convert synapse centroids to skeleton targets.

119

120

Given synapse centroids (in voxels) and desired SWC integer labels,

121

finds the nearest voxel to each centroid for the corresponding label.

122

This enables targeted skeletonization that ensures skeleton paths

123

pass through or near synaptic sites.

124

125

Parameters:

126

- labels (numpy.ndarray): Labeled volume with neuron segments

127

- synapses (dict): Mapping of {label_id: [((x,y,z), swc_label), ...]}

128

- label_id: Which neuron label the synapse belongs to

129

- (x,y,z): Synapse centroid coordinates in voxel space

130

- swc_label: SWC node type for this synapse (e.g., 3=dendrite, 4=axon)

131

- progress (bool): Show progress bar (default: False)

132

133

Returns:

134

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

135

136

Notes:

137

- Coordinates are in voxel space, not physical units

138

- SWC labels follow standard: 1=soma, 2=axon, 3=dendrite, 4=apical, etc.

139

- Targets can be used with extra_targets_before or extra_targets_after

140

"""

141

```

142

143

#### Usage Example

144

145

```python

146

import kimimaro

147

import numpy as np

148

149

# Define synapse locations for multiple neurons

150

synapses = {

151

# Neuron 1 has 3 synapses

152

1: [

153

((120, 200, 30), 3), # Dendrite synapse

154

((150, 220, 35), 3), # Another dendrite synapse

155

((180, 240, 40), 4), # Apical dendrite synapse

156

],

157

# Neuron 5 has 2 synapses

158

5: [

159

((80, 180, 25), 2), # Axon synapse

160

((90, 190, 28), 2), # Another axon synapse

161

],

162

# Neuron 12 has 1 soma synapse

163

12: [

164

((300, 400, 60), 1), # Soma synapse

165

]

166

}

167

168

# Convert synapses to target format

169

targets = kimimaro.synapses_to_targets(

170

labels,

171

synapses,

172

progress=True

173

)

174

175

print(f"Generated {len(targets)} target points")

176

print("Target locations:", list(targets.keys())[:5])

177

178

# Use targets in skeletonization to ensure paths hit synapses

179

skeletons = kimimaro.skeletonize(

180

labels,

181

anisotropy=(16, 16, 40),

182

extra_targets_after=list(targets.keys()), # Add as extra endpoints

183

teasar_params={

184

"scale": 1.5,

185

"const": 300,

186

"soma_detection_threshold": 750,

187

},

188

progress=True

189

)

190

191

# The resulting skeletons will have paths that pass through synapse locations

192

for label_id, skeleton in skeletons.items():

193

if label_id in synapses:

194

n_synapses = len(synapses[label_id])

195

print(f"Neuron {label_id}: {n_synapses} synapses, {len(skeleton.vertices)} skeleton vertices")

196

```

197

198

### Integration with Connectomics Annotations

199

200

```python

201

import kimimaro

202

import pandas as pd

203

import numpy as np

204

205

# Load connectomics annotations

206

def load_synapse_annotations(annotation_file):

207

"""Load synapse annotations from CSV or database."""

208

# Example format: neuron_id, x, y, z, synapse_type, confidence

209

df = pd.read_csv(annotation_file)

210

211

synapses = {}

212

for _, row in df.iterrows():

213

neuron_id = int(row['neuron_id'])

214

coords = (int(row['x']), int(row['y']), int(row['z']))

215

216

# Map synapse type to SWC label

217

swc_type_map = {

218

'presynaptic': 2, # Axon terminal

219

'postsynaptic': 3, # Dendrite

220

'soma_synapse': 1, # Soma

221

'apical': 4 # Apical dendrite

222

}

223

swc_label = swc_type_map.get(row['synapse_type'], 3)

224

225

if neuron_id not in synapses:

226

synapses[neuron_id] = []

227

synapses[neuron_id].append((coords, swc_label))

228

229

return synapses

230

231

# Load and process annotations

232

synapses = load_synapse_annotations("connectome_synapses.csv")

233

targets = kimimaro.synapses_to_targets(labels, synapses, progress=True)

234

235

# Skeletonize with synapse targets

236

skeletons = kimimaro.skeletonize(

237

labels,

238

anisotropy=(8, 8, 30), # High-resolution EM data

239

extra_targets_after=list(targets.keys()),

240

teasar_params={

241

"scale": 1.2, # Tighter invalidation for precise targeting

242

"const": 200, # Smaller minimum radius

243

"pdrf_scale": 150000, # Higher penalty field influence

244

},

245

parallel=8,

246

progress=True

247

)

248

249

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

250

```

251

252

### Validation and Quality Control

253

254

```python

255

def validate_synapse_targeting(skeletons, synapses, targets, max_distance=500):

256

"""Validate that skeletons actually reach synapse targets."""

257

258

validation_results = {}

259

260

for label_id, skeleton in skeletons.items():

261

if label_id not in synapses:

262

continue

263

264

results = {

265

'synapses_targeted': len(synapses[label_id]),

266

'distances': [],

267

'missed_synapses': []

268

}

269

270

# Check each synapse

271

for (synapse_coords, swc_label) in synapses[label_id]:

272

# Find closest skeleton vertex to synapse

273

skeleton_coords = skeleton.vertices

274

distances = np.sqrt(np.sum((skeleton_coords - np.array(synapse_coords))**2, axis=1))

275

min_distance = np.min(distances)

276

277

results['distances'].append(min_distance)

278

279

if min_distance > max_distance:

280

results['missed_synapses'].append({

281

'coords': synapse_coords,

282

'distance': min_distance,

283

'swc_label': swc_label

284

})

285

286

results['mean_distance'] = np.mean(results['distances'])

287

results['max_distance'] = np.max(results['distances'])

288

results['success_rate'] = 1 - len(results['missed_synapses']) / len(synapses[label_id])

289

290

validation_results[label_id] = results

291

292

return validation_results

293

294

# Run validation

295

validation = validate_synapse_targeting(skeletons, synapses, targets)

296

297

for label_id, results in validation.items():

298

print(f"Neuron {label_id}:")

299

print(f" Success rate: {results['success_rate']*100:.1f}%")

300

print(f" Mean distance to synapses: {results['mean_distance']:.1f} nm")

301

if results['missed_synapses']:

302

print(f" Missed {len(results['missed_synapses'])} synapses")

303

```

304

305

## Use Cases and Applications

306

307

### Axon Tracing

308

- Connect soma to axon terminals for long-range projection analysis

309

- Validate axonal continuity across image boundaries

310

- Measure axon length and branching patterns

311

312

### Dendritic Analysis

313

- Connect soma to dendritic tips for morphological analysis

314

- Trace specific dendritic branches identified in functional studies

315

- Validate dendritic spine connectivity

316

317

### Connectomics Integration

318

- Incorporate synapse annotations into skeleton generation

319

- Ensure skeleton paths pass through confirmed connection sites

320

- Generate skeletons optimized for connectivity analysis

321

322

### Quality Control

323

- Verify skeleton completeness by connecting known endpoints

324

- Test alternative paths through complex morphologies

325

- Validate automated skeletonization results with manual annotations

326

327

### Cross-scale Analysis

328

- Connect structures identified at different resolution scales

329

- Bridge between light microscopy and electron microscopy data

330

- Integrate multi-modal annotations into unified skeletons