mascaf.morphology_graph¶
- class mascaf.morphology_graph.MorphologyGraph(*args, **kwargs)[source]¶
Bases:
Graph3DGraph representation of neuronal morphology with radii.
This class subclasses networkx.Graph and can contain cycles. Nodes should be keyed directly by their junction id and store at least the attributes xyz (3-vector) and radius (float). Use to_swc_file() to export to SWC format, which breaks cycles by duplicating nodes.
- __init__(*args, **kwargs)[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.
- Return type:
None
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'}
- position_attr = 'xyz'¶
- classmethod from_swc_file(path)[source]¶
Load a MorphologyGraph from an SWC file, restoring cycles.
Reads an SWC file and creates a MorphologyGraph. If the file contains CYCLE_BREAK annotations in the header (generated by to_swc_file), this method will restore the original cycles by reconnecting duplicate nodes to their originals.
- Parameters:
path (
str) – Path to the SWC file to load.- Returns:
Graph with nodes containing ‘xyz’ and ‘radius’ attributes. If CYCLE_BREAK annotations are present, cycles are restored.
- Return type:
Examples
>>> graph = MorphologyGraph.from_swc_file("output.swc") >>> graph.print_attributes()
- add_junction(j)[source]¶
Add a
Junctionas a graph node.The node key is
j.id; stored attributes arexyzandradius.
- copy()[source]¶
Return a deep copy of the graph with all node arrays copied.
- Returns:
A new graph with the same topology and independent node data.
- Return type:
- to_swc_model()[source]¶
Convert MorphologyGraph to a SWCModel instance.
Creates a SWCModel by adding all nodes with their attributes (x, y, z, r, t) and edges from this graph. Note that SWCModel is also a NetworkX Graph, so this is a conversion between graph types.
- Returns:
A SWCModel instance with the same topology and attributes.
- Return type:
SWCModel
Examples
>>> graph = MorphologyGraph() >>> # ... add nodes and edges ... >>> swc_model = graph.to_swc_model() >>> frusta = FrustaSet.from_swc_model(swc_model)
- compute_volume(account_for_overlaps=False)[source]¶
Compute total volume of the morphology as sum of frustum segments.
Each edge represents a truncated cone (frustum) connecting two nodes. The volume of a frustum is: V = (π*h/3) * (r1² + r1*r2 + r2²) where h is the length and r1, r2 are the radii at the endpoints.
For nodes with degree > 2 (branch points), overlap correction is applied by subtracting half a ball volume per edge beyond 2.
- Parameters:
account_for_overlaps (
bool) – If True, subtract branch-point overlap corrections from the naive frustum sum (half a ball volume per edge beyond two at each junction).- Returns:
Total volume of all segments in the morphology.
- Return type:
Examples
>>> graph = MorphologyGraph() >>> # ... add nodes and edges ... >>> volume = graph.compute_volume()
- compute_surface_area(account_for_overlaps=False)[source]¶
Compute total lateral surface area of the morphology.
Each edge represents a truncated cone (frustum) connecting two nodes. The lateral surface area is: A = π * (r1 + r2) * s where s = sqrt(h² + (r1 - r2)²) is the slant height.
End caps are added for terminal nodes (degree 1). For nodes with degree > 2 (branch points), overlap correction is applied by subtracting quarter of a ball surface area per edge beyond 2.
- Parameters:
account_for_overlaps (
bool) – If True, subtract branch-point overlap corrections from the naive sum (quarter of a ball surface area per edge beyond two at each junction).- Returns:
Total lateral surface area of all segments in the morphology.
- Return type:
Examples
>>> graph = MorphologyGraph() >>> # ... add nodes and edges ... >>> area = graph.compute_surface_area()
- scale_radii_to_match_mesh(mesh, metric='surface_area', account_for_overlaps=False)[source]¶
Scale all radii to match the mesh’s surface area or volume.
This method finds a uniform scaling factor
kfor all radii such that the cable model’s surface area or volume (as defined bycompute_surface_area()/compute_volume()) equals that of the input mesh. Because lateral frustum area and volume do not scale as pure powers ofkwhen edge lengths are fixed,kis computed with a one-dimensional root solve (notsqrt/cbrtof a single ratio).- Parameters:
mesh (
trimesh.TrimeshorMeshManager) – The mesh to match. Can be either a trimesh.Trimesh object or a MeshManager instance.metric (
str) – Which metric to match. Options are: - “surface_area”: Match total surface area - “volume”: Match total volumeaccount_for_overlaps (
bool) – If True, subtract branch-point overlap corrections when computing the morphology’s surface area or volume (same as forcompute_surface_area()/compute_volume()).
- Returns:
The scaling factor applied to all radii.
- Return type:
- Raises:
ValueError – If metric is not “surface_area” or “volume”, or if the mesh has zero area/volume, or if the morphology has zero area/volume.
Examples
>>> from mascaf import MeshManager, MorphologyGraph >>> mesh_mgr = MeshManager(mesh_path="neuron.obj") >>> graph = MorphologyGraph.from_swc_file("output.swc") >>> scale_factor = graph.scale_radii_to_match_mesh(mesh_mgr) >>> print(f"Radii scaled by factor: {scale_factor:.3f}")
- print_attributes(*, node_info=False, edge_info=False)[source]¶
Print graph attributes and optional node/edge details.
- to_swc_file(path=None, *, tag=3, annotate_breaks=True)[source]¶
Export the skeleton to SWC format, breaking cycles by duplicating nodes.
The SWC format is a line-based format with columns
n T x y z R parent, wherenis the node id,Tis the SWC type index,x,y,zare coordinates,Ris radius, andparentis the parent’s id (or -1 for the root).Constructs a spanning forest over the undirected graph; for every non-tree edge that would introduce a cycle it duplicates one endpoint and attaches the duplicate as a child of the other endpoint.
- Parameters:
path (
str|None) – If provided, write the SWC text to this file. IfNone, return the SWC text as a string.tag (
int) – Integer placed in the SWCT(type) column for all nodes.annotate_breaks (
bool) – IfTrue, include header comment lines indicating how to reconnect duplicates to restore each broken cycle.
- Returns:
The SWC text (whether or not it was also written to a file).
- Return type:
- Raises:
KeyError – If any node is missing the
xyzorradiusattribute.
- class mascaf.morphology_graph.Junction(id, xyz, radius)[source]¶
Bases:
objectContainer for a traced skeleton node.
Fields mirror what the tracing pipeline in trace.py constructs for each sample along a polyline. The essential geometry is in xyz (XYZ) and radius; other fields are retained for diagnostics/bookkeeping.