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
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)
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
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