Anatomical Seeding

Goal

Provide initial attachment points for the Purkinje network that respect anatomy, so that growth starts in physiologically meaningful locations and covers the intended chambers.

Interfaces

  • Parameters.init_node_id – index of the first mesh node (root).

  • Parameters.second_node_id – optional helper to define an initial direction.

  • Parameters.fascicles_angles / Parameters.fascicles_length – optional hints for adding early fascicles with specified angles/lengths (if used in your workflow).

Common strategies

  1. Label-driven If the endocardial mesh has region labels (e.g., LV septum, anterior/posterior fascicles, RV septum), pick the nearest mesh node to each target label centroid.

  2. Geometric rules Without labels, derive landmarks from geometry: - septal band: nodes with minimal distance to the interventricular plane, - apex base axis: principal component direction to distinguish basal/apical halves, - anterior/posterior split: plane orthogonal to the apex-base axis.

  3. Manual seed For controlled experiments, choose seed indices by inspecting the mesh in ParaView and reading the point ids under the cursor.

Mapping to parameters

  • Set init_node_id to the chosen root node id.

  • If you have a second node id along the initial direction, set second_node_id. Otherwise, the initial direction is inferred from local surface geometry.

  • Optionally, add fascicle entries to fascicles_angles and fascicles_length if your protocol initializes multiple early branches.

Example

import numpy as np
from purkinje_uv import Parameters, Mesh, FractalTree

mesh = Mesh.from_file("endocardium.vtu")
mesh.detect_boundary()

# Example: pick the mesh node closest to a user-provided landmark (x0)
x0 = np.array([10.2, -3.7, 22.1])  # mm, example landmark in world coordinates
root_id = int(mesh.tree.query(x0)[1])  # nearest vertex id using the KD-tree

p = Parameters()
p.init_node_id = root_id
# Optional: define second node to bias the first direction
# p.second_node_id = ...

ft = FractalTree(mesh=mesh, params=p, mesh_uv=mesh)
ft.grow_tree()

Validation checklist

  • The root node lies on the intended endocardial chamber.

  • The initial direction points into the chamber (not out of it).

  • After the first few generations, endpoints distribute across the intended regions.