API Reference#
Public API#
swctools package scaffolding.
Public API is evolving; currently exposes SWC parsing, models, geometry, and visualization utilities.
- class swctools.SWCRecord(n: int, t: int, x: float, y: float, z: float, r: float, parent: int, line: int)[source]
Bases:
objectOne SWC row.
- n
Node id (unique within file)
- Type:
- t
Tag index
- Type:
- x, y, z
Coordinates (usually micrometers)
- Type:
- r
Radius
- Type:
- parent
Parent id; -1 indicates root
- Type:
- line
1-based line number in the source file/string
- Type:
- n: int
- t: int
- x: float
- y: float
- z: float
- r: float
- parent: int
- line: int
- class swctools.SWCParseResult(records: Dict[int, SWCRecord], reconnections: List[Tuple[int, int]], header: List[str])[source]
Bases:
objectParsed SWC content.
- swctools.parse_swc(source: str | PathLike | Iterable[str] | TextIOBase, *, strict: bool = True, validate_reconnections: bool = True, float_tol: float = 1e-09) SWCParseResult[source]
Parse an SWC file or text stream.
- Parameters:
source – Path to an SWC file, a file-like object, an iterable of lines, or a string containing SWC content.
strict – If True, enforce 7-column rows and validate parent references exist.
validate_reconnections – If True, ensure reconnection node pairs share identical (x, y, z, r).
float_tol – Tolerance used when comparing floating-point coordinates/radii.
- Returns:
Parsed records, reconnection pairs, and header lines.
- Return type:
SWCParseResult
- Raises:
ValueError – If parsing or validation fails.
FileNotFoundError – If a string path is provided that does not exist.
- class swctools.SWCModel(*args, backend=None, **kwargs)[source]
Bases:
DiGraphSWC morphology graph representing a valid directed tree structure.
SWCModel conforms to the SWC format specification, which requires a directed tree structure (no cycles). The underlying storage is a directed nx.DiGraph that preserves the original parent -> child relationships from the SWC format.
Nodes are keyed by SWC id n and store attributes: - t: int (tag) - x, y, z: float (coordinates) - r: float (radius) - line: int (line number in source; informational)
For graphs with cycles (e.g., after applying reconnections), use make_cycle_connections() which returns a standard nx.Graph instead of SWCModel.
Methods like to_swc_file() rely on the tree structure and will only work correctly for valid SWC trees.
- __init__() None[source]
Initialize a graph with edges, name, or graph attributes.
- Parameters:
incoming_graph_data (input graph (optional, default: None)) – Data to initialize graph. If None (default) an empty graph is created. The data can be an edge list, or any NetworkX graph object. If the corresponding optional Python packages are installed the data can also be a 2D NumPy array, a SciPy sparse array, or a PyGraphviz graph.
attr (keyword arguments, optional (default= no attributes)) – Attributes to add to graph as key=value pairs.
See also
convertExamples
>>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc >>> G = nx.Graph(name="my graph") >>> e = [(1, 2), (2, 3), (3, 4)] # list of edges >>> G = nx.Graph(e)
Arbitrary graph attribute pairs (key=value) may be assigned
>>> G = nx.Graph(e, day="Friday") >>> G.graph {'day': 'Friday'}
- classmethod from_parse_result(result: SWCParseResult) SWCModel[source]
Build a model from a parsed SWC result.
- classmethod from_records(records: Mapping[int, SWCRecord] | Iterable[SWCRecord]) SWCModel[source]
Build a model from SWC records.
Accepts either a mapping of id->record or any iterable of SWCRecord.
- classmethod from_swc_file(source: str | PathLike[str] | Iterable[str], *, strict: bool = True, validate_reconnections: bool = True, float_tol: float = 1e-09) SWCModel[source]
Parse an SWC source then build a model.
The source is passed through to parse_swc, which supports a path, a file-like object, a string with the full contents, or an iterable of lines.
- parent_of(n: int) int | None[source]
Return the parent id of node n from the original SWC tree (or None).
- path_to_root(n: int) list[int][source]
Return the path from node n up to its root, inclusive.
Example: For edges 1->2->3, path_to_root(3) returns [3, 2, 1].
- get_node_xyz(node_id: int, as_array: bool = False) tuple[float, float, float] | ndarray[source]
Get xyz coordinates for a node.
- Parameters:
- Returns:
The (x, y, z) coordinates of the node.
- Return type:
- Raises:
KeyError – If node_id is not in the graph.
ValueError – If the node is missing x, y, or z attributes.
- set_node_xyz(node_id: int, x: float | None = None, y: float | None = None, z: float | None = None, *, xyz: tuple[float, float, float] | list[float] | ndarray | None = None) None[source]
Set xyz coordinates for a node.
- Parameters:
node_id (int) – Node ID to update.
x (float | None) – New coordinates as separate arguments.
y (float | None) – New coordinates as separate arguments.
z (float | None) – New coordinates as separate arguments.
xyz (tuple | list | np.ndarray | None) – New coordinates as a sequence (x, y, z). If provided, takes precedence over separate x, y, z arguments.
- Raises:
KeyError – If node_id is not in the graph.
ValueError – If neither (x, y, z) nor xyz is provided, or if xyz has wrong length.
- get_edge_length(u: int, v: int) float[source]
Compute Euclidean distance between two nodes.
- Parameters:
- Returns:
Euclidean distance between the nodes.
- Return type:
- Raises:
KeyError – If either node is not in the graph.
ValueError – If either node is missing coordinate attributes.
- get_subtree(root_id: int) list[int][source]
Return all node IDs in the subtree rooted at root_id.
Uses the original SWC tree parent relationships to traverse descendants.
- iter_edges_with_data()[source]
Iterate edges with node attributes for both endpoints.
- Yields:
tuple[int, int, dict] – For each edge (u, v), yields (u, v, data_dict) where data_dict contains: - ‘u_xyz’: tuple of (x, y, z) for node u - ‘v_xyz’: tuple of (x, y, z) for node v - ‘u_r’: radius of node u - ‘v_r’: radius of node v - ‘u_t’: tag of node u - ‘v_t’: tag of node v - ‘length’: Euclidean distance between u and v
- print_attributes(*, node_info: bool = False, edge_info: bool = False) None[source]
Print graph attributes and optional node/edge details.
- copy() SWCModel[source]
Return a shallow copy of this model (nodes/edges/attributes).
- to_swc_file(path: str | PathLike[str], *, precision: int = 6, header: Iterable[str] | None = None) None[source]
Write the model to an SWC file.
The output uses the standard 7-column SWC format per row: “n T x y z r parent” with floats formatted to the requested precision.
- Parameters:
path (str | os.PathLike[str]) – Destination file path.
precision (int) – Decimal places for floating-point fields (x, y, z, r). Default 6.
header (Iterable[str] | None) – Optional additional header comment lines (without leading ‘#’).
- scale(scalar: float) SWCModel[source]
Return a new model with all node coordinates and radii scaled by scalar.
Multiplies each node’s x, y, z, and r by scalar on a copy.
- set_tag_by_sphere(center: tuple[float, float, float] | list[float], radius: float, new_tag: int, old_tag: int | None = None, include_boundary: bool = True, copy: bool = False) SWCModel[source]
Override node ‘t’ values for points inside a sphere.
Sets the tag ‘t’ for all nodes whose Euclidean distance from center is less than radius (or equal if include_boundary is True).
If old_tag is specified, only nodes with that tag are modified.
- Parameters:
center (tuple[float, float, float] | list[float]) – Sphere center as (x, y, z).
radius (float) – Sphere radius (same units as coordinates).
new_tag (int) – Tag to assign to matching nodes.
old_tag (int | None) – If specified, only nodes with this tag are modified.
include_boundary (bool) – If True, include nodes exactly at distance == radius. Default True.
copy (bool) – If True, operate on and return a copy; otherwise mutate in place and return self.
- add_junction(node_id: int | None = None, *, t: int = 0, x: float = 0.0, y: float = 0.0, z: float = 0.0, r: float = 0.0, parent: int | None = None, **kwargs: Any) int[source]
Add a junction (node) to the model.
- Parameters:
node_id (int | None) – Node ID to use. If None, automatically assigns the next available ID.
t (int) – Node tag. Default 0.
x (float) – Node coordinates. Default 0.0.
y (float) – Node coordinates. Default 0.0.
z (float) – Node coordinates. Default 0.0.
r (float) – Node radius. Default 0.0.
parent (int | None) – Parent node ID. If specified, creates an edge to the parent. Default None (root node).
**kwargs (Any) – Additional node attributes.
- Returns:
The ID of the added node.
- Return type:
- remove_junction(node_id: int, *, reconnect_children: bool = False) None[source]
Remove a junction (node) from the model.
- make_cycle_connections(*, validate_reconnections: bool = True, float_tol: float = 1e-09) Graph[source]
Return an undirected nx.Graph with reconnection pairs merged.
Uses reconnection pairs stored under self.graph[‘reconnections’] if present. Node attributes are merged; provenance kept under merged_ids and lines.
The returned graph may contain cycles and is no longer a valid SWC tree structure, so it returns nx.Graph instead of SWCModel. SWCModel should only represent valid directed tree structures conforming to the SWC format.
- Returns:
Undirected graph with merged nodes and edges. Node attributes include x, y, z, r, t, merged_ids (list of original node IDs), and lines.
- Return type:
nx.Graph
- class swctools.Frustum(a: Tuple[float, float, float], b: Tuple[float, float, float], ra: float, rb: float, tag: int = 0)[source]
Bases:
objectOriented frustum between endpoints a and b.
- a, b
Endpoints in model/world coordinates.
- Type:
Point3
- ra, rb
Radii at a and b.
- Type:
- tag
Optional tag for the frustum.
- Type:
- ra: float
- rb: float
- tag: int = 0
- swctools.frustum_mesh(seg: Frustum, *, sides: int = 16, end_caps: bool = False) Tuple[List[Tuple[float, float, float]], List[Tuple[int, int, int]]][source]
Generate a frustum mesh for a single Frustum.
- Returns:
vertices: List[Point3]
faces: List[Face], each = (i, j, k) indexing into vertices
- Return type:
(vertices, faces)
- swctools.batch_frusta(frusta: Iterable[Frustum], *, sides: int = 16, end_caps: bool = False) Tuple[List[Tuple[float, float, float]], List[Tuple[int, int, int]]][source]
Batch multiple frusta into a single mesh.
Returns a concatenated list of vertices and faces with the proper index offsets.
- class swctools.PointSet(vertices: List[Tuple[float, float, float]], faces: List[Tuple[int, int, int]], points: List[Tuple[float, float, float]], base_radius: float, stacks: int, slices: int)[source]
Bases:
objectA batched mesh of small spheres placed at given 3D points.
- base_radius: float
- stacks: int
- slices: int
- classmethod from_points(points: Sequence[Tuple[float, float, float]], *, base_radius: float = 1.0, stacks: int = 6, slices: int = 12) PointSet[source]
Build a batched low-res spheres mesh from a list of 3D points.
- Parameters:
- classmethod from_txt_file(path: str | PathLike, *, base_radius: float = 1.0, stacks: int = 6, slices: int = 12, comments: str = '#') PointSet[source]
- to_mesh3d_arrays() Tuple[List[float], List[float], List[float], List[int], List[int], List[int]][source]
Return Plotly Mesh3d arrays (x, y, z, i, j, k) for this point set.
- scaled(radius_scale: float) PointSet[source]
Return a new PointSet with all sphere radii scaled by radius_scale.
- scale(scalar: float) PointSet[source]
Return a new PointSet with coordinates and radii scaled by scalar.
- project_onto_frusta(frusta: FrustaSet, include_end_caps: bool | None = None) PointSet[source]
Project each point to the nearest surface of the nearest frustum.
- Parameters:
- Returns:
A new PointSet whose points have been moved onto the closest surface points of the closest frusta; sphere mesh is rebuilt.
- Return type:
PointSet
Notes
For each input point, the algorithm iterates all frusta and evaluates the squared distance to: - The lateral surface: project the point to the frustum axis (clamped
t in [0,1]), interpolate radius r(t), then move along the radial direction to the mantle.
The end caps (optional): orthogonal distance to each cap plane; if the projected point falls outside the disk, distance to the rim is used.
Degenerate frusta (zero length) are treated as a sphere of radius max(ra, rb) centered at the endpoint. Complexity is O(N_points × N_frusta), implemented in pure Python.
- class swctools.FrustaSet(vertices: List[Tuple[float, float, float]], faces: List[Tuple[int, int, int]], sides: int, end_caps: bool, n_frusta: int, frusta: List[Frustum], edge_uvs: List[Tuple[int, int]] | None = None)[source]
Bases:
objectA batched frusta mesh derived from a SWCModel.
- vertices
Concatenated vertices for all frusta.
- Type:
List[Point3]
- faces
Triangular faces indexing into vertices.
- Type:
List[Face]
- sides
Circumferential resolution used per frustum.
- Type:
- end_caps
Whether end caps were included during construction.
- Type:
- n_frusta
Number of frusta used (one per graph edge).
- Type:
- frusta
The frusta used to construct the mesh (stored as axis `Frustum`s).
- Type:
List[Frustum]
- edge_uvs
Optional labels preserving which (u, v) edge generated each frustum, in the same order.
- sides: int
- end_caps: bool
- n_frusta: int
- frusta: List[Frustum]
- classmethod from_swc_file(swc_file: str | PathLike[str], *, sides: int = 16, end_caps: bool = False, flip_tag_assignment: bool = False, **kwargs: Any) FrustaSet[source]
- classmethod from_swc_model(model: SWCModel | Any, *, sides: int = 16, end_caps: bool = False, flip_tag_assignment: bool = False) FrustaSet[source]
Build a FrustaSet by converting each undirected edge into a frustum axis Frustum.
Accepts any NetworkX graph (SWCModel or nx.Graph) with nodes that have spatial coordinates and radii. Validates that all nodes have required attributes: x, y, z, r.
- Parameters:
model (SWCModel | nx.Graph) – Graph with nodes containing x, y, z, r attributes. Can be SWCModel or nx.Graph (e.g., from make_cycle_connections()).
sides (int) – Number of sides per frustum.
end_caps (bool) – Whether to include end caps.
flip_tag_assignment (bool) – If True, assign tags from the child node to the parent node. Otherwise, assign tags from the parent node to the child node.
- Raises:
ValueError – If any node is missing required attributes (x, y, z, r).
- to_mesh3d_arrays() Tuple[List[float], List[float], List[float], List[int], List[int], List[int]][source]
Return Plotly Mesh3d arrays: x, y, z, i, j, k.
- scaled(radius_scale: float) FrustaSet[source]
Return a new FrustaSet with all frustum radii scaled by radius_scale.
This rebuilds vertices/faces from the stored frusta list.
- scale(scalar: float) FrustaSet[source]
Return a new FrustaSet with coordinates and radii scaled by scalar.
- nearest_frustum_index(xyz: Sequence[float]) int[source]
Return the index of the frustum whose axis is closest to xyz.
- frustum_order_map() dict[int, tuple[int, int] | tuple[Tuple[float, float, float], Tuple[float, float, float]]][source]
- swctools.plot_centroid(swc_model: SWCModel, *, marker_size: float = 2.0, line_width: float = 2.0, show_nodes: bool = True, title: str | None = None, width: int = 1200, height: int = 900) Figure[source]
Plot centroid skeleton from an SWCModel.
Edges are drawn as line segments in 3D using Scatter3d.
- swctools.plot_frusta(frusta: FrustaSet, *, color: str = 'lightblue', opacity: float = 0.8, flatshading: bool = True, radius_scale: float = 1.0, tag_colors: dict[int, str] | None = None, title: str | None = None, width: int = 1200, height: int = 900) Figure[source]
Plot a FrustaSet as a Mesh3d figure.
- Parameters:
frusta (FrustaSet) – Batched frusta mesh to render.
color (str) – Mesh color.
opacity (float) – Mesh opacity.
flatshading (bool) – Whether to enable flat shading.
radius_scale (float) – Uniform scale applied to all frustum radii before meshing (1.0 = no change).
tag_colors (dict[int, str] | None) – Optional mapping {tag: color}. If provided, each frustum is colored uniformly according to its tag (fallback to color if a tag is missing).
- swctools.plot_frusta_with_centroid(swc_model: SWCModel, frusta: FrustaSet, *, color: str = 'lightblue', opacity: float = 0.8, flatshading: bool = True, radius_scale: float = 1.0, tag_colors: dict[int, str] | None = None, centroid_color: str = '#1f77b4', centroid_line_width: float = 2.0, show_nodes: bool = False, node_size: float = 2.0, title: str | None = None, width: int = 1200, height: int = 900) Figure[source]
Overlay frusta mesh with centroid skeleton from an SWCModel.
Parameters mirror plot_centroid and plot_frusta with an extra radius_scale.
- swctools.plot_frusta_slider(frusta: FrustaSet, *, color: str = 'lightblue', opacity: float = 0.8, flatshading: bool = True, tag_colors: dict[int, str] | None = None, min_scale: float = 0.0, max_scale: float = 1.0, steps: int = 21, title: str | None = None, width: int = 1200, height: int = 900) Figure[source]
Interactive slider (0..1 default) controlling uniform radius_scale.
Precomputes frames at evenly spaced scales between min_scale and max_scale.
- swctools.animate_frusta_timeseries(frusta: FrustaSet, time_domain: Sequence[float], amplitudes: Sequence[Sequence[float]], *, colorscale: str = 'Viridis', clim: tuple[float, float] | None = None, opacity: float = 0.8, flatshading: bool = True, radius_scale: float = 1.0, fps: int = 30, stride: int = 1, title: str | None = None, output_path: str | None = None, auto_open: bool = False)[source]
Animate per-frustum values over time with interactive 3D controls.
Creates a Plotly animation with play/pause controls, time slider, and full 3D interactivity (rotate, zoom, pan). The animation is saved to an HTML file that can be opened in any web browser.
- Parameters:
frusta (FrustaSet) – Batched frusta mesh representing the neuron compartments.
time_domain (Sequence[float]) – Time values for each frame. Length must match the time axis of amplitudes.
amplitudes (Sequence[Sequence[float]]) – Time series V_i(t) shaped (T, N), where T = len(time_domain) and N = frusta.n_frusta. Each time step provides one scalar per frustum.
colorscale (str) – Plotly colorscale name (default: “Viridis”). Examples: “Viridis”, “Plasma”, “Inferno”, “Jet”, “RdBu”, etc.
clim (tuple[float, float] | None) – Color limits (vmin, vmax). If None, inferred from amplitudes.
opacity (float) – Mesh opacity (default: 0.8).
flatshading (bool) – Enable flat shading on the mesh (default: True).
radius_scale (float) – Uniform radius scaling applied to frusta before meshing (default: 1.0).
fps (int) – Frames per second for animation playback (default: 30).
stride (int) – Temporal downsampling factor - use every stride time steps (default: 1).
title (str | None) – Figure title. If None, defaults to “Frusta Animation”.
output_path (str | None) – Path to save the HTML file. If None, defaults to “frusta_animation.html”.
auto_open (bool) – If True, automatically open the HTML file in the default browser when saving (default: False).
- Returns:
The Plotly figure object with animation frames.
- Return type:
go.Figure
Notes
The resulting HTML file contains a fully interactive 3D visualization with: - Play/Pause buttons for animation control - Time slider to scrub through frames - Full 3D rotation, zoom, and pan controls - Colorbar showing value mapping
The file can be shared and opened on any system with a web browser, making it highly portable and robust across different OS and display configurations.
- swctools.plot_model(*, swc_model: SWCModel | None = None, frusta: FrustaSet | None = None, show_frusta: bool = True, show_centroid: bool = True, title: str | None = None, sides: int = 16, end_caps: bool = False, color: str = 'lightblue', opacity: float = 0.8, flatshading: bool = True, tag_colors: dict[int, str] | None = None, radius_scale: float = 1.0, slider: bool = False, min_scale: float = 0.0, max_scale: float = 1.0, steps: int = 21, centroid_color: str = '#1f77b4', centroid_line_width: float = 2.0, show_nodes: bool = False, node_size: float = 2.0, point_set: PointSet | None = None, point_size: float = 1.0, point_color: str = '#d62728', output_path: str | None = None, auto_open: bool = False, width: int = 1200, height: int = 900) Figure[source]
Master visualization combining centroid, frusta, slider, and overlay points.
If frusta is not provided and gm is, a FrustaSet is built from gm.
If slider=True and show_frusta=True, a Plotly slider controls radius_scale.
points overlays arbitrary xyz positions as small markers.
- swctools.plot_points(point_set: PointSet, *, color: str = '#ff7f0e', opacity: float = 1.0, size_scale: float = 1.0, title: str | None = None, width: int = 1200, height: int = 900) Figure[source]
Plot a PointSet as a collection of small spheres.
- Parameters:
- Returns:
Plotly figure with Mesh3d trace.
- Return type:
go.Figure
- swctools.get_config() VizConfig[source]
Return the current visualization configuration (live object).