Skip to content

Morphology

Functions related to analysing or manipulating neuron morphology.

Classify nodes.

PARAMETER DESCRIPTION
node_ids
            Array node IDs.

TYPE: (N, ) array

parent_ids
            Array of parent IDs for each node. Root nodes' parents
            must be -1.

TYPE: (N, ) array

RETURNS DESCRIPTION
node_type

Node types: - 0: root - 1: leaf - 2: branch point - 3: slab (intermediate node)

TYPE: (N, ) integer array

Examples:

>>> import navis_fastcore as fastcore
>>> import numpy as np
>>> node_ids = np.arange(8)
>>> parent_ids = np.array([-1, 0, 1, 2, 1, 4, 5, 5])
>>> fastcore.classify_nodes(node_ids, parent_ids)
array([0, 2, 3, 1, 3, 2, 1, 1], dtype=int32)

Calculate synapse flow centrality for this neuron.

Please note that this implementation currently produces slightly different results than the implementation in navis. I'm not sure why that is but the differences seem to be negligible.

PARAMETER DESCRIPTION
node_ids
     Array of int32 node IDs.

TYPE: (N, ) array

parent_ids
     Array of parent IDs for each node. Root nodes' parents
     must be -1.

TYPE: (N, ) array

presynapses
     Array of number of presynapses associated with each node.

TYPE: (N, ) uint32 array

postsynapses
     Array of number of postsynapses associated with each node.

TYPE: (N, ) uint32 array

mode
     The mode to calculate the flow centrality. "centrifugal" will
     calculate the flow from the root to the leaves, "centripetal"
     will calculate the flow from the leaves to the root, and "sum"
     will calculate the sum of both.

TYPE: "centrifugal" | "centripetal" | "sum" DEFAULT: 'sum'

RETURNS DESCRIPTION
cc

Synapse flow centrality for each node.

TYPE: (N, ) uint32 array

Calculcate Strahler Index.

PARAMETER DESCRIPTION
node_ids
            Array node IDs.

TYPE: (N, ) array

parent_ids
            Array of parent IDs for each node. Root nodes' parents
            must be -1.

TYPE: (N, ) array

method
            Method used to calculate Strahler indices: 'standard'
            will use the method described above; 'greedy' will
            always increase the index at converging branches
            whether these branches have the same index or not.

TYPE: 'standard' | 'greedy' DEFAULT: 'standard'

to_ignore
            List of node IDs to ignore. Must be the FIRST node
            of the branch. Excluded branches will not contribute
            to Strahler index calculations and instead be assigned
            the SI of their parent branch.

TYPE: iterable DEFAULT: None

min_twig_size
            If provided, will ignore twigs with fewer nodes than
            this. Instead, they will be assigned the SI of their
            parent branch.

TYPE: int DEFAULT: None

RETURNS DESCRIPTION
strahler_index

Strahler Index for each node.

TYPE: (N, ) int array

Examples:

>>> import navis_fastcore as fastcore
>>> import numpy as np
>>> node_ids = np.arange(8)
>>> parent_ids = np.array([-1, 0, 1, 2, 1, 4, 5, 5])
>>> fastcore.strahler_index(node_ids, parent_ids)
array([2, 2, 1, 1, 2, 2, 1, 1], dtype=int32)

Calculate the height of the subtree below each node.

A node's height is the geodesic distance from it down to the farthest leaf below it. Leafs therefore have a height of 0, and a root has the length of the longest root-to-leaf path in its component.

PARAMETER DESCRIPTION
node_ids
     Array of node IDs.

TYPE: (N, ) array

parent_ids
     Array of parent IDs for each node. Root nodes' parents
     must be -1.

TYPE: (N, ) array

weights
     Array of distances for each child -> parent connection.
     If ``None`` all node to node distances are set to 1. Weights are
     expected to be non-negative. A root's own entry is never read,
     so the ``NaN`` :func:`parent_dist` leaves there is harmless.

TYPE: (N, ) float32 array DEFAULT: None

RETURNS DESCRIPTION
heights

Height of each node, in the same order as node_ids.

TYPE: float32 (single) array

Examples:

>>> import navis_fastcore as fastcore
>>> import numpy as np
>>> node_ids = np.arange(8)
>>> parent_ids = np.array([-1, 0, 1, 2, 1, 4, 5, 5])
>>> fastcore.subtree_height(node_ids, parent_ids)
array([4., 3., 1., 0., 2., 1., 0., 0.], dtype=float32)
See Also

:func:geodesic_farthest Answers a different question: its directed mode looks towards the root, and its undirected mode can leave the subtree entirely.

Prune twigs shorter than a given threshold.

PARAMETER DESCRIPTION
node_ids
     Array node IDs.

TYPE: (N, ) array

parent_ids
     Array of parent IDs for each node. Root nodes' parents
     must be -1.

TYPE: (N, ) array

threshold
     Twigs shorter than this threshold will be pruned.

TYPE: float

weights
     Array of distances for each child -> parent connection.
     If ``None`` all node-to-node distances are set to 1.

TYPE: (N, ) float32 array DEFAULT: None

mask
     Array of booleans to mask nodes that should not be pruned.
     Importantly, twigs with _any_ masked node will not be pruned.

TYPE: (N, ) bool array DEFAULT: None

RETURNS DESCRIPTION
keep

Node IDs to keep.

TYPE: (M, ) integer array

Examples:

>>> import navis_fastcore as fastcore
>>> import numpy as np
>>> node_ids = np.arange(7)
>>> parent_ids = np.array([-1, 0, 1, 2, 1, 4, 5])
>>> fastcore.prune_twigs(node_ids, parent_ids, 2)
array([0, 1, 4, 5, 6])
>>> mask = np.array([True, True, True, False, True, True, True])
>>> fastcore.prune_twigs(node_ids, parent_ids, 2, mask=mask)
array([0, 1, 2, 3, 4, 5, 6])

Calculate betweenness centrality.

PARAMETER DESCRIPTION
node_ids
     Array of node IDs.

TYPE: (N, ) array

parent_ids
     Array of parent IDs for each node. Root nodes' parents
     must be -1.

TYPE: (N, ) array

directed
     If ``True`` only count paths running towards the root, i.e. from
     a node to one of its ancestors. If ``False`` count every
     unordered pair once.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION
betweenness

Number of shortest paths through each node, aligned with node_ids. Pairs are only counted within a connected component.

TYPE: (N, ) int64 array

Notes

O(N), not Brandes' O(VE): shortest paths in a tree are unique*, so the number passing through a node is a closed form rather than a search. Directed, a node lies on one path per (strict descendant, strict ancestor) pair. Undirected, removing it splits its component into its children's sub-trees plus everything above, and it lies between every pair drawn from two different parts.

Counts are int64 because they grow as the square of the component size - an undirected 100k-node skeleton reaches ~5e9, which overflows int32.

Examples:

>>> import navis_fastcore as fastcore
>>> import numpy as np
>>> node_ids = np.arange(5)
>>> parent_ids = np.array([-1, 0, 1, 2, 3])
>>> fastcore.betweenness(node_ids, parent_ids)
array([0, 3, 4, 3, 0])

Leafs and roots are never between anything.

See Also

navis_fastcore.descendant_counts What you want if you are counting how much hangs below a node rather than how much routes through it.

Count, for each node, how many nodes lie strictly below it.

PARAMETER DESCRIPTION
node_ids
     Array of node IDs.

TYPE: (N, ) array

parent_ids
     Array of parent IDs for each node. Root nodes' parents
     must be -1.

TYPE: (N, ) array

targets
     Restrict the count to these node IDs. If ``None`` every node
     counts.

TYPE: iterable DEFAULT: None

RETURNS DESCRIPTION
counts

Aligned with node_ids. A node is never its own descendant, so a leaf scores 0 even when it is itself a target.

TYPE: (N, ) int64 array

Notes

With targets=None this is each node's sub-tree size minus one.

This is what navis' betweeness_centrality(from_=...) actually computed, under a name that suggested otherwise - see navis_fastcore.betweenness.

Examples:

>>> import navis_fastcore as fastcore
>>> import numpy as np
>>> node_ids = np.arange(5)
>>> parent_ids = np.array([-1, 0, 1, 2, 1])
>>> fastcore.descendant_counts(node_ids, parent_ids)
array([4, 3, 1, 0, 0])

Counting only the leafs below each node:

>>> fastcore.descendant_counts(node_ids, parent_ids, targets=[3, 4])
array([2, 2, 1, 0, 0])