示例#1
0
def mean_parent_daughter_ratio(data: MorphologyLike,
                               node_types: Optional[List[int]] = None
                               ) -> float:
    """ Calculate the average ratio of parent radii to child radii across a 
    reconstruction.

    Parameters
    ----------
    data : The reconstruction whose mean parent daugther ratio will be computed
    node_types : restrict the calculation to compartments involving these node 
        types

    Notes
    -----
    Note that this function differs from the L-measure parent daughter ratio, 
    which calculates the ratio of the child node size to the parent. Note also 
    that both the parent and child must be in node_types in order for a
    compartment to be included in the calculation

    """

    morphology = get_morphology(data)
    roots = morphology.get_roots()

    counters: Dict[str, int] = defaultdict(lambda *a, **k: 0)
    visitor = partial(parent_daughter_ratio_visitor,
                      morphology=morphology,
                      counters=counters,
                      node_types=node_types)

    for root in roots:
        morphology.breadth_first_traversal(
            visitor, start_id=morphology.node_id_cb(root))

    return counters["ratio_sum"] / counters["ratio_count"]
示例#2
0
def mean_bifurcation_angle_remote(data: MorphologyLike,
                                  node_types: Optional[List[int]] = None
                                  ) -> float:
    """
        Compute the average angle between the next branch point or terminal
        tip of child segments at each bifurcation.
        Trifurcations are ignored. Note: this introduces possible segmentation
        artifacts if trifurcations are due to large segment sizes.

        Parameters
        ----------

        Parameters
        ----------
        data: The reconstruction whose max euclidean distance will be
            calculated
        node_types: restrict consideration to these types


        Returns
        -------

        Scalar value, nan if no nodes

    """
    morphology = get_morphology(data)
    total_angle = 0.0
    n = 0
    nodes = morphology.get_node_by_types(node_types)
    for node in nodes:
        if len(morphology.children_of(node)) == 2:
            node_vec = np.asarray([node['x'], node['y'], node['z']])

            # find the point to measure to, whether it be the next
            #   branch point or tip
            a = morphology.children_of(node)[0]
            while len(morphology.children_of(a)) == 1:
                a = morphology.children_of(a)[0]
            a_vec = np.asarray([a['x'], a['y'], a['z']])

            b = morphology.children_of(node)[1]
            while len(morphology.children_of(b)) == 1:
                b = morphology.children_of(b)[0]
            b_vec = np.asarray([b['x'], b['y'], b['z']])

            total_angle += angle_between(a_vec - node_vec, b_vec - node_vec)
            n += 1

    if n == 0:
        return float('nan')
    return total_angle / n
示例#3
0
def early_branch_path(data: MorphologyLike,
                      node_types: Optional[List[int]] = None,
                      soma: Optional[Dict] = None) -> float:
    """ Returns the ratio of the longest 'short' branch from a bifurcation to 
    the maximum path length of the tree. In other words, for each bifurcation, 
    the maximum path length below that branch is calculated, and the shorter of 
    these values is used. The maximum of these short values is divided by the 
    maximum path length.

    Parameters
    ----------
    data : the input reconstruction
    node_types : if provided, restrict the calculation to nodes of these 
        types
    soma : if provided, use this node as the root, otherwise infer the root 
        from the argued morphology

    Returns
    -------
    ratio of max short branch to max path length

    """

    morphology = get_morphology(data)
    soma = soma or morphology.get_root()

    path_len = _calculate_max_path_distance(morphology, soma, node_types)
    if path_len == 0:
        return 0.0

    nodes = morphology.get_node_by_types(node_types)
    longest_short = 0.0

    for node in nodes:
        if len(morphology.get_children(node, node_types)) < 2:
            continue

        current_short = min(
            _calculate_max_path_distance(morphology, child, node_types)
            for child in morphology.children_of(node))

        longest_short = max(longest_short, current_short)

    return longest_short / path_len
示例#4
0
def mean_diameter(data: MorphologyLike,
                  node_types: Optional[List[int]] = None) -> float:
    """ Calculates the mean diameter of all nodes
    
    Parameters
    ----------
    morphology : The reconstruction whose mean diameter
    node_types : restrict the calculation to compartments involving these node 
        types

    Returns
    -------
    The average diameter across selected nodes

    """

    morphology = get_morphology(data)

    return 2 * mean(node["radius"]
                    for node in morphology.get_node_by_types(node_types))
示例#5
0
def mean_bifurcation_angle_local(data: MorphologyLike,
                                 node_types: Optional[List[int]] = None
                                 ) -> float:
    """
        Compute the average angle between child segments at
        bifurcations throughout the morphology.
        Trifurcations are ignored. Note: this introduces possible segmentation
        artifacts if trifurcations are due to large segment sizes.

        Parameters
        ----------
        data: The reconstruction whose max euclidean distance will be
            calculated
        node_types: restrict consideration to these types

        Returns
        -------

        Scalar value

    """
    morphology = get_morphology(data)
    total_angle = 0.0
    n = 0
    nodes = morphology.get_node_by_types(node_types)
    for node in nodes:
        if len(morphology.children_of(node)) == 2:
            node_vec = np.asarray([node['x'], node['y'], node['z']])

            a = morphology.children_of(node)[0]
            a_vec = np.asarray([a['x'], a['y'], a['z']])

            b = morphology.children_of(node)[1]
            b_vec = np.asarray([b['x'], b['y'], b['z']])

            total_angle += angle_between(a_vec - node_vec, b_vec - node_vec)
            n += 1

    if n == 0:
        return float('nan')
    return total_angle / n
示例#6
0
def max_path_distance(data: MorphologyLike,
                      node_types: Optional[List[int]] = None) -> float:
    """ Calculate the distance, following the path of adjacent neurites, from 
    the soma to the furthest compartment. This is equivalent to the distance 
    to the furthest SWC node.

    Parameters
    ----------
    data : the input reconstruction
    node_types : if provided, restrict the calculation to nodes of these 
        types

    Returns
    -------
    The along-path distance from the soma to the farthest (in the along-path 
    sense) node.

    """

    morphology = get_morphology(data)
    return calculate_max_path_distance(morphology, morphology.get_root(),
                                       node_types)
示例#7
0
def mean_contraction(data: MorphologyLike,
                     node_types: Optional[List[int]] = None) -> float:
    """ Calculate the average contraction of all sections. In other words,
    calculate the average ratio of euclidean distance to path distance
    between all bifurcations in the morphology. Trifurcations are treated
    as bifurcations.

    Parameters
    ----------
    data : the input reconstruction
    node_types : if provided, restrict the calculation to nodes of these 
        types

    Returns
    -------
    The average contraction across all sections in this reconstruction

    """

    morphology = get_morphology(data)
    return calculate_mean_contraction(morphology, morphology.get_root(),
                                      node_types)
示例#8
0
def total_length(data: MorphologyLike,
                 node_types: Optional[List[int]] = None) -> float:
    """ Calculate the total length across all compartments in a reconstruction

    Parameters
    ----------
    data : the input reconstruction
    node_types : if provided, restrict the calculation to compartments 
        involving these types

    Returns
    -------
    The sum of segment lengths across all segments in the reconstruction

    Notes
    -----
    Excludes compartments where the parent is:
        1. the soma
        2. a root of the reconstruction
    The logic here is that the soma root is likely to substantially overlap any 
    of its compartments, while non-root soma nodes will be closer to the soma 
    surface.

    """

    morphology = get_morphology(data)

    nodes = morphology.get_node_by_types(node_types)
    compartment_list = morphology.get_compartments(nodes, node_types)

    total = 0.0
    for compartment in compartment_list:
        first_node_in_compartment = compartment[0]
        if first_node_in_compartment['type'] is SOMA \
            and not morphology.parent_of(first_node_in_compartment):
            continue
        total += morphology.get_compartment_length(compartment)

    return total
示例#9
0
def total_volume(data: MorphologyLike,
                 node_types: Optional[List[int]] = None) -> float:
    """ Calculates the sum of volumes across all comparments (linked pairs of 
    nodes) in a reconstruction. This approximates the total volume of the 
    reconstruction. See Morphology.get_compartment_volume for details.

    Parameters
    ----------
    data : The reconstruction whose volume will be computed
    node_types : restrict the calculation to compartments involving these node 
        types

    Returns
    -------
    The sum of compartment volumes across this reconstruction

    """

    morphology = get_morphology(data)
    nodes = morphology.get_node_by_types(node_types)
    compartments = morphology.get_compartments(nodes, node_types)

    return sum(map(morphology.get_compartment_volume, compartments))
示例#10
0
def max_euclidean_distance(data: MorphologyLike,
                           node_types: Optional[List[int]] = None) -> float:
    """Calculate the furthest distance, in 3-space, of a compartment's end from 
    the soma. This is equivalent to the distance to the furthest SWC node.

    Parameters
    ----------
    data: The reconstruction whose max euclidean distance will be 
        calculated
    node_types: restrict consideration to these types

    Returns
    -------
    The distance between the soma and the farthest-from-soma node in this 
    morphology.

    """

    morphology = get_morphology(data)
    soma = morphology.get_root()

    return max(
        morphology.euclidean_distance(soma, node)
        for node in morphology.get_node_by_types(node_types))
示例#11
0
    def test_get_morphology(self):
        aa = get_morphology(Data(self.morphology))
        bb = get_morphology(self.morphology)

        self.assertEqual(aa.__class__.__name__, "Morphology")
        self.assertEqual(bb.__class__.__name__, "Morphology")