示例#1
0
def kinkPositions(fully_annotated_mainbranch, scale=(0.22, 0.22, 0.3)):
    """
    Returns the positoins of kinks and outgrowth events along the mainbranch.

    Parameters
    ----------
    fully_annotated_mainbranch : np.ndarray
        Mainbranch with annotated kinks (encoded in the radius) and outgrowth events (encoded with type set to 2).
    scale : tuple of floats
        x, y and z scales of the images underlying the analysis.

    Returns
    -------
    kink_positions : np.ndarray
        Array with distances of kinks from distal end.
    outgrowth_positions : np.ndarray
        Array with distances of outgrowth events form distal end.
    """

    n_kinks = np.sum(fully_annotated_mainbranch[:, 5] > 0.5)
    n_outgrowths = np.sum(fully_annotated_mainbranch[:, 1] == 2)
    kink_positions = np.zeros(n_kinks)
    outgrowth_positions = np.zeros(n_outgrowths)
    #fully_annoated_mainbranch has nodes of raius 0.5, nodes of radius >0.5 are kinks.
    endpoints = utility.findEndpoints(fully_annotated_mainbranch,
                                      return_node=True)
    current_node = endpoints[0]
    next_node = utility.nextNode(current_node, fully_annotated_mainbranch)
    distance = 0
    i = 0
    j = 0

    while isinstance(next_node, np.ndarray):
        distance += utility.dist3D(current_node, next_node, scale=scale)
        if next_node[5] > 0.5:  #if next_node is a kink
            kink_positions[i] = distance
            i += 1
        if next_node[1] == 2:  #if next_node is a branching point
            outgrowth_positions[j] = distance
            j += 1
        current_node = next_node
        next_node = utility.nextNode(current_node, fully_annotated_mainbranch)
    return kink_positions, outgrowth_positions
示例#2
0
def findWindow(node, branch, window_size=4, scale=(0.22, 0.22, 0.3)):
    if isinstance(node, np.ndarray):
        node = node.tolist()
        node[1] = 2
    parent_distance = 0
    child_distance = 0
    parent_nodes = []
    child_nodes = []
    # select nodes in distance window_size/2 around node
    current_parent_node = node
    while parent_distance < window_size / 2:
        parent_nodes.append(current_parent_node)
        next_parent_node = utility.nextNode(current_parent_node,
                                            branch).tolist()
        if not isinstance(next_parent_node, list):
            #print('not enough parent nodes!')
            break
        parent_distance += utility.dist3D(current_parent_node,
                                          next_parent_node,
                                          scale=scale)
        current_parent_node = next_parent_node
    current_child_node = node
    while child_distance < window_size / 2:
        child_nodes.append(current_child_node)
        next_child_node = utility.prevNode(current_child_node, branch).tolist()
        if not next_child_node == []:
            next_child_node = next_child_node[0]
        if not isinstance(next_child_node, list):
            #print('not enough child nodes!')
            break
        child_distance += utility.dist3D(current_child_node,
                                         next_child_node,
                                         scale=scale)
        current_child_node = next_child_node
    child_nodes = child_nodes[1:]
    try:
        window_nodes = np.concatenate(
            (np.array(parent_nodes), np.array(child_nodes)), axis=0)
    except ValueError:
        if parent_nodes == []:
            window_nodes = child_nodes
        elif child_nodes == []:
            window_nodes = parent_nodes
        else:
            raise NameError('NoWindowFound')
    return np.array(window_nodes)
示例#3
0
def traceBranch(endpoint, tree, main_nodes=[], soma_nodes=[], scale=(1, 1, 1)):
    '''Trace from an endpoint to a root node or any other node specified in main_branch soma_nodes and pmv_nodes.'''
    if isinstance(endpoint, (float, int)):
        endpoint_index = endpoint
    else:
        endpoint_index = endpoint[0]
    if isinstance(tree, list):
        tree = np.array(tree)
    if isinstance(main_nodes, np.ndarray):
        main_nodes = main_nodes.tolist()
    if isinstance(soma_nodes, np.ndarray):
        soma_nodes = soma_nodes.tolist()

    #any tracing eventually stops in a root_node
    root_nodes_array = utility.findRoots(tree, return_node=True)
    root_nodes = root_nodes_array.tolist()

    branch = []
    length = 0
    current_node = utility.thisNode(endpoint_index, tree, as_list=False)
    branch.append(current_node)
    count = 0
    while current_node.tolist() not in root_nodes and current_node.tolist(
    ) not in main_nodes and current_node.tolist() not in soma_nodes:
        count += 1
        if count > 10000:
            break

        next_node = utility.nextNode(current_node, tree)
        dist = utility.dist3D(current_node, next_node, scale=scale)
        try:
            length += dist
            current_node = next_node
            branch.append(current_node)
        except TypeError:
            break

    branch_array = np.array(branch)
    return branch_array, length
示例#4
0
def calculateAnglesWithLinearRegression(node,
                                        branch,
                                        window_size=3.2,
                                        scale=(0.22, 0.22, 0.3),
                                        visualize=True,
                                        fixed_node=False):
    if isinstance(node, np.ndarray):
        node = node.tolist()
    parent_distance = 0
    child_distance = 0
    parent_nodes = []
    child_nodes = []

    #select parent nodes in given window
    current_parent_node = node
    while parent_distance < window_size / 2:
        parent_nodes.append(current_parent_node)
        try:
            next_parent_node = utility.nextNode(current_parent_node,
                                                branch).tolist()
        except:
            return 180
        if not isinstance(next_parent_node, list):
            #print('not enough parent nodes!')
            return 180
        parent_distance += utility.dist3D(current_parent_node,
                                          next_parent_node,
                                          scale=scale)
        current_parent_node = next_parent_node

    #select child nodes in given window
    current_child_node = node
    while child_distance < window_size / 2:
        child_nodes.append(current_child_node)
        next_child_node = utility.prevNode(current_child_node, branch).tolist()
        if not next_child_node == []:
            next_child_node = next_child_node[0]

        if not isinstance(next_child_node, list):
            #print('not enough child nodes!')
            return 180
        try:
            child_distance += utility.dist3D(current_child_node,
                                             next_child_node,
                                             scale=scale)
            current_child_node = next_child_node
        except:
            return 180

    #take the coordinates from the nodes
    parent_nodes = np.array(parent_nodes)
    child_nodes = np.array(child_nodes)
    parent_points = parent_nodes[:, 2:5]
    child_points = child_nodes[:, 2:5]

    #calculate the mean of the points
    parent_mean = parent_points.mean(axis=0)
    child_mean = child_points.mean(axis=0)

    #calculate svd's
    parent_uu, parent_dd, parent_vv = np.linalg.svd(parent_points -
                                                    parent_mean)
    child_uu, child_dd, child_vv = np.linalg.svd(child_points - child_mean)

    parent_uu_fixednode, parent_dd_fixednode, parent_vv_fixednode = np.linalg.svd(
        parent_points - parent_points[0])
    child_uu_fixednode, child_dd_fixednode, child_vv_fixednode = np.linalg.svd(
        child_points - child_points[0])

    #calculate vectors and angle
    parent_vector = parent_vv[0]
    if utility.dist3D(parent_points[0] + parent_vector,
                      parent_points[-1]) > utility.dist3D(
                          parent_points[0] - parent_vector, parent_points[-1]):
        parent_vector *= -1
    child_vector = child_vv[0]
    if utility.dist3D(child_points[0] + child_vector,
                      child_points[-1]) > utility.dist3D(
                          child_points[0] - child_vector, child_points[-1]):
        child_vector *= -1
    angle = utility.vectorAngle3D(parent_vector, child_vector)

    parent_vector_fixednode = parent_vv_fixednode[0]
    if utility.dist3D(parent_points[0] + parent_vector_fixednode,
                      parent_points[-1]) > utility.dist3D(
                          parent_points[0] - parent_vector_fixednode,
                          parent_points[-1]):
        parent_vector_fixednode *= -1
    child_vector_fixednode = child_vv_fixednode[0]
    if utility.dist3D(child_points[0] + child_vector_fixednode,
                      child_points[-1]) > utility.dist3D(
                          child_points[0] - child_vector_fixednode,
                          child_points[-1]):
        child_vector_fixednode *= -1
    angle_fixednode = utility.vectorAngle3D(parent_vector_fixednode,
                                            child_vector_fixednode)

    #visualization
    if visualize:
        linspace = np.reshape(np.linspace(-10, 10, 2), (2, 1))
        parent_line = parent_vector * linspace
        child_line = child_vector * linspace
        parent_line += parent_mean
        child_line += child_mean

        linspace_fixednode = np.reshape(np.linspace(-20, 0, 2), (2, 1))
        parent_line_fixednode = parent_vector_fixednode * linspace_fixednode
        child_line_fixednode = child_vector_fixednode * linspace_fixednode
        parent_line_fixednode += parent_points[0]
        child_line_fixednode += child_points[0]

        import matplotlib.pyplot as plt
        import mpl_toolkits.mplot3d as m3d
        lins = np.reshape(np.linspace(0, 1, 2), (2, 1))
        a = parent_points - parent_mean
        a_line = parent_vv[0] * lins
        b = child_points - child_mean
        b_line = child_vv[0] * lins
        c = parent_points - parent_points[0]
        c_line = parent_vv_fixednode[0] * lins
        d = child_points - child_points[0]
        d_line = child_vv_fixednode[0] * lins

        ax = m3d.Axes3D(plt.figure())
        ax.scatter3D(*parent_points.T, color='red')
        ax.quiver(parent_points[0][0],
                  parent_points[0][1],
                  parent_points[0][2],
                  parent_vector[0],
                  parent_vector[1],
                  parent_vector[2],
                  color='red')
        ax.quiver(parent_points[0][0],
                  parent_points[0][1],
                  parent_points[0][2],
                  parent_vv_fixednode[0][0],
                  parent_vv_fixednode[0][1],
                  parent_vv_fixednode[0][2],
                  color='orangered')
        ax.scatter3D(*child_points.T, color='blue')
        ax.quiver(child_points[0][0],
                  child_points[0][1],
                  child_points[0][2],
                  child_vector[0],
                  child_vector[1],
                  child_vector[2],
                  color='blue')
        ax.quiver(child_points[0][0],
                  child_points[0][1],
                  child_points[0][2],
                  child_vv_fixednode[0][0],
                  child_vv_fixednode[0][1],
                  child_vv_fixednode[0][2],
                  color='cyan')
        string = 'angles: ' + str(angle) + '/' + str(angle_fixednode)
        ax.text(child_points[0][0] + 1,
                child_points[0][1],
                child_points[0][2],
                s=string)
        plt.show()
    if fixed_node:
        return angle_fixednode
    else:
        return angle
def findWindow(node, branch, window_size=4, scale=(0.22, 0.22, 0.3)):
    """
    Given a `node` on a `branch`, return a window of size `window_size` [um].

    Parameters
    ----------
    node : np.ndarray
        Node around which to return a window.
    branch : np.ndarray
        Parent branch of `node`.
    window_size : float [um]
        Maximum distance of the returned window along the branch.
    scale : tuple of floats
        x, y and z scales of the images underlying the analysis.

    Returns
    -------
    window_nodes : np.ndarray
        Array of nodes belonging to the window.
    """
    if isinstance(node, np.ndarray):
        node = node.tolist()
        node[1] = 2
    parent_distance = 0
    child_distance = 0
    parent_nodes = []
    child_nodes = []
    # select nodes in distance window_size/2 around node
    current_parent_node = node
    while parent_distance < window_size / 2:
        parent_nodes.append(current_parent_node)
        next_parent_node = utility.nextNode(current_parent_node,
                                            branch).tolist()
        if not isinstance(next_parent_node, list):
            #print('not enough parent nodes!')
            break
        parent_distance += utility.dist3D(current_parent_node,
                                          next_parent_node,
                                          scale=scale)
        current_parent_node = next_parent_node
    current_child_node = node
    while child_distance < window_size / 2:
        child_nodes.append(current_child_node)
        next_child_node = utility.prevNode(current_child_node, branch).tolist()
        if not next_child_node == []:
            next_child_node = next_child_node[0]
        if not isinstance(next_child_node, list):
            #print('not enough child nodes!')
            break
        child_distance += utility.dist3D(current_child_node,
                                         next_child_node,
                                         scale=scale)
        current_child_node = next_child_node
    child_nodes = child_nodes[1:]
    try:
        window_nodes = np.concatenate(
            (np.array(parent_nodes), np.array(child_nodes)), axis=0)
    except ValueError:
        if parent_nodes == []:
            window_nodes = child_nodes
        elif child_nodes == []:
            window_nodes = parent_nodes
        else:
            raise NameError('NoWindowFound')
    return np.array(window_nodes)
def traceBranch(endpoint, tree, main_nodes=None, soma_nodes=None, scale=(1,1,1)):
    """
    Trace from an endpoint to a root node or any other node specified in main_branch  or soma_nodes.

    Parameters
    ----------
    endpoint : int or np.ndarray
        Index of endpoint or endpoint-node of the branch to be traced.
    tree : np.ndarray
        Tree on which to trace a branch.
    main_nodes : list or None
        List of nodes that are classified as mainbranch-nodes.
    soma_nodes : list or None
        List of nodes that are classified as soma-nodes.
    scale : tuple of floats [um]
         x, y and z scales of the images underlying the analysis.

    Returns
    -------
    branch_array : np.ndarray
        Tree containing only the traced branch.
    length : float
        Length of the traced branch.

    """

    if isinstance(endpoint, (float, int)):
        endpoint_index = endpoint
    else:
        endpoint_index = endpoint[0]
    if isinstance(tree, list):
        tree = np.array(tree)
    if isinstance(main_nodes, np.ndarray):
        main_nodes = main_nodes.tolist()
    if isinstance(soma_nodes, np.ndarray):
        soma_nodes = soma_nodes.tolist()

    if not main_nodes:
        main_nodes=[]
    if not soma_nodes:
        soma_nodes=[]
 
    
    #any tracing eventually stops in a root_node
    root_nodes_array = utility.findRoots(tree, return_node=True)
    root_nodes = root_nodes_array.tolist()

    
    branch = []
    length = 0
    current_node = utility.thisNode(endpoint_index, tree, as_list=False)
    branch.append(current_node)
    count = 0
    while current_node.tolist() not in root_nodes and current_node.tolist() not in main_nodes and current_node.tolist() not in soma_nodes:
        count += 1
        if count > 10000:
            break

        next_node = utility.nextNode(current_node, tree)
        dist = utility.dist3D(current_node, next_node, scale=scale)
        try:
            length += dist
            current_node = next_node
            branch.append(current_node)
        except TypeError:
            break
    
    branch_array = np.array(branch)
    return branch_array, length