def align_roots(self, gold_tree, matches, DEBUG=False): offset = EuclideanPoint() stack = queue.LifoQueue() swc_test_list = self.get_node_list() for root in gold_tree.root().children: gold_anchor = np.array(root._pos) if root in matches.keys(): test_anchor = np.array(matches[root]._pos) else: nearby_nodes = get_nearby_swc_node_list( gold_node=root, test_swc_list=swc_test_list, threshold=root.radius() / 2) if len(nearby_nodes) == 0: continue test_anchor = nearby_nodes[0]._pos offset._pos = (test_anchor - gold_anchor).tolist() if DEBUG: print("off_set:x = {}, y = {}, z = {}".format( offset._pos[0], offset._pos[1], offset._pos[2])) stack.put(root) while not stack.empty(): node = stack.get() if node.is_virtual(): continue node._pos[0] += offset._pos[0] node._pos[1] += offset._pos[1] node._pos[2] += offset._pos[2] for son in node.children: stack.put(son)
def test_point_to_line(self): p = EuclideanPoint([49.4362, 111.12, 322.687]) l = Line( coords=[[47.9082, 110.024, 323.994], [56.0636, 112.369, 318.703]]) l2 = Line( coords=[[49.4362, 111.12, 322.687], [56.0636, 112.369, 318.703]]) print(p.distance(l)) print(p.distance(l2))
def test_foot_point_right(self): for i in range(5000): p = EuclideanPoint([rand(10), rand(10), rand(10)]) line = Line( coords=[[rand(10), rand(10), rand(10)], [rand(10), rand(10), rand(10)]]) ans1 = p.get_foot_point(line) ans2 = p.get_foot_point(line) for i in range(0, 3): self.assertTrue( math.fabs(ans1._pos[i] - ans2._pos[i]) < 0.0000001)
def test_1(self): line_tuple_a = tuple([ self.test_swc_tree.node_from_id(8), self.test_swc_tree.node_from_id(7) ]) line_tuple_b = tuple([ self.test_swc_tree.node_from_id(7), self.test_swc_tree.node_from_id(6) ]) e_node1 = EuclideanPoint(center=[1.03, -2.1, 6.31]) e_node2 = EuclideanPoint(center=[3.87, 0.98, 1.17])
def calculate_trajectories(swc_root, bin_root, thresholds, z_in_path_dist=True, current_trajectories=0.0, DEBUG=False): stack = queue.LifoQueue() node = bin_root while node.left_son != None and node.right_son == None: node = node.left_son stack.put(node) while not stack.empty(): node = stack.get() if DEBUG: print("[debug: ] calculate trajectories for node {}".format( node.data.get_id())) data = node.data if data.parent_trajectory is None: data.parent_trajectory = EuclideanPoint(center=[0, 0, 0]) if not node.is_root(): data.parent_trajectory.add_coord( find_parent_trajectory(node, thresholds)) else: tmp_pa = BinaryNode(data=swc_root) node.parent = tmp_pa data.parent_trajectory.add_coord( find_parent_trajectory(node, thresholds)) node.parent = None if not node.is_leaf(): if data.left_trajectory is None: data.left_trajectory = EuclideanPoint(center=[0, 0, 0]) if data.right_trajectory is None: data.right_trajectory = EuclideanPoint(center=[0, 0, 0]) data.left_trajectory.add_coord( find_child_trajectory(data, node.left_son, thresholds)) data.right_trajectory.add_coord( find_child_trajectory(data, node.right_son, thresholds)) add_child_bifurcations(stack, node) if DEBUG: print("trajectory:") if data.parent_trajectory is not None: print("pa_tra = {}".format(data.parent_trajectory._pos)) if data.left_trajectory is not None: print("left_tra = {}".format(data.left_trajectory._pos)) if data.right_trajectory is not None: print("right_tra = {}".format(data.right_trajectory._pos))
def load_list(self, lines): self.clear() nodeDict = dict() for line in lines: if not self.is_comment(line): # print line data = list(map(float, line.split())) # print(data) if len(data) == 7: nid = int(data[0]) ntype = int(data[1]) pos = EuclideanPoint(center=data[2:5]) radius = data[5] parentId = data[6] tn = SwcNode(nid=nid, ntype=ntype, radius=radius, center=pos) nodeDict[nid] = (tn, parentId) for _, value in nodeDict.items(): tn = value[0] parentId = value[1] if parentId == -1: tn.parent = self._root tn._depth = 0 else: parentNode = nodeDict.get(parentId) if parentNode: tn.parent = parentNode[0] tn._depth = tn.parent._depth + 1
def test_2(self): self.init() line_tuple_a = tuple([ self.test_swc_tree.node_from_id(4), self.test_swc_tree.node_from_id(3) ]) line_tuple_b = tuple([ self.test_swc_tree.node_from_id(15), self.test_swc_tree.node_from_id(9) ]) e_node1 = EuclideanPoint(center=[-1.89657, 6.51822, -1.40403]) e_node2 = EuclideanPoint(center=[-2.02446, 0.54277, 7.48183]) test_length = get_lca_length(self.test_swc_tree, \ line_tuple_a, \ line_tuple_b, \ Line(e_node_1=e_node1, e_node_2=e_node2)) self.assertEqual(test_length, 34.372721303735716)
def get_nearest_edge(gold_node, test_edge_list, DEBUG=False): dis = DINF match_line = None for test_edge in test_edge_list: test_line = Line(swc_node_1=test_edge[0], swc_node_2=test_edge[1]) eu_node = EuclideanPoint(gold_node._pos) tmp_dis = eu_node.distance(test_line) tmp_line = test_edge if DEBUG: eu_node.to_str() test_line.to_str() print("tmp_dis = {}".format(tmp_dis)) if tmp_dis < dis: dis = tmp_dis match_line = tmp_line return match_line, dis
def test_1(self): self.init() line_tuple_a = tuple([ self.test_swc_tree.node_from_id(8), self.test_swc_tree.node_from_id(7) ]) line_tuple_b = tuple([ self.test_swc_tree.node_from_id(7), self.test_swc_tree.node_from_id(6) ]) e_node1 = EuclideanPoint(center=[1.03, -2.1, 6.31]) e_node2 = EuclideanPoint(center=[3.87, 0.98, 1.17]) test_length = get_lca_length(self.test_swc_tree, \ line_tuple_a, \ line_tuple_b, \ Line(e_node_1=e_node1, e_node_2=e_node2)) self.assertEqual(test_length, 9.589854552695694)
def get_match_edges_e(gold_swc_tree=None, test_swc_tree=None, dis_threshold=0.1, DEBUG=False): match_edge = set() gold_node_list = [node for node in PreOrderIter(gold_swc_tree.root())] test_node_list = [node for node in PreOrderIter(test_swc_tree.root())] test_edge_list = get_test_edge_list(test_node_list) for node in gold_node_list: if node.is_virtual() or node.parent.is_virtual(): continue e_node = EuclideanPoint(node._pos) e_parent = EuclideanPoint(node.parent._pos) line_tuple_a, dis_a = get_nearest_edge(e_node, test_edge_list, DEBUG=False) line_tuple_b, dis_b = get_nearest_edge(e_parent, test_edge_list, DEBUG=False) if dis_a <= dis_threshold and dis_b <= dis_threshold: match_edge.add(tuple([node, node.parent])) if DEBUG: with open('normal.txt', 'a') as f: f.write( "\nnode = {} {}\nnode.parent = {} {}\nnode_line = {},{}\nnode_p_line = {},{}\n" .format( node.get_id(), node._pos, node.parent.get_id(), node.parent._pos, line_tuple_a[0]._pos, line_tuple_a[1]._pos, line_tuple_b[0]._pos, line_tuple_b[1]._pos, )) return match_edge
def convert_to_binarytree(tot_root, swc_root): # swc_tree._print() bintree_root = swctree_to_binarytree(swc_root) # debug # bintree_root.print_tree() re_arrange(bintree_root) calculate_trajectories(swc_root=tot_root, bin_root=bintree_root, thresholds=EuclideanPoint([1.2, 0, 0]), z_in_path_dist=True) bintree_root = remove_continuations(swc_root=tot_root, bin_root=bintree_root, calc_path_dist=True, z_in_path_dist=False) return bintree_root
def calculate_trajectories_xy(origin, first, second, threshold): point = EuclideanPoint(center=[0, 0, 0]) to_first = origin.distance(first, _2D) to_second = origin.distance(second, _2D) proportionAlongLine = (threshold - to_first) / (to_second - to_first) point.set_x(first.get_x() + proportionAlongLine * (second.get_x() - first.get_x())) point.set_y(first.get_y() + proportionAlongLine * (second.get_y() - first.get_y())) return point
def is_sub_continuation(gold_node, ancestor_node, ancestor_match, is_left, gold_path_length, bin_test_list, add_to_list): if ancestor_match is None: return False path_length_map = {} path_length_map[gold_node] = gold_path_length ancestor_tra = EuclideanPoint() if is_left: ancestor_tra = ancestor_node.data.left_trajectory else: ancestor_tra = ancestor_node.data.right_trajectory left_child_match = get_des_in_for_continuation( gold_node.left_son, ancestor_node, ancestor_match, ancestor_tra, path_length_map, bin_test_list) right_child_match = get_des_in_for_continuation( gold_node.right_son, ancestor_node, ancestor_match, ancestor_tra, path_length_map, bin_test_list) if left_child_match is not None and right_child_match is not None: common_ancestor = LCA(left_child_match, right_child_match, ancestor_match) if common_ancestor is not None and is_within_dis_match_threshold( common_ancestor, gold_node): g_matches[gold_node] = common_ancestor g_matches[common_ancestor] = gold_node if add_to_list: g_distance_match.append(gold_node) elif add_to_list: g_continuation.append(gold_node) return True elif left_child_match is not None or right_child_match is not None: if add_to_list: g_continuation.append(gold_node) return True return False
def find_parent_trajectory(node, thereholds, DEBUG=False): done_x = False done_z = False xy_dis = 0.0 z_dis = 0.0 c = node data = node.data c_data = c.data point = EuclideanPoint(center=[0, 0, 0]) while not done_x or not done_z: c = c.parent prev_data = c_data c_data = c.data if not done_x: xy_dis = data.distance(c_data, _2D) if xy_dis > thereholds.get_x(): tmp_point = EuclideanPoint(center=[0, 0, 0]) tmp_point.add_coord( calculate_trajectories_xy(data, prev_data, c_data, thereholds.get_x())) point.set_x(tmp_point.get_x()) point.set_y(tmp_point.get_y()) done_x = True elif c.is_root: point.set_x(c_data.get_x()) point.set_y(c_data.get_y()) done_x = True if not done_z: z_dis = math.fabs(data.get_z() - c_data.get_z()) if z_dis > thereholds.get_z(): point.set_z( calculate_trajectories_z(data, prev_data, c_data, thereholds.get_z())) done_z = True elif c.is_root: point.set_z(c_data.get_z()) done_z = True if DEBUG: print(node.data._id) print("trx = {}, try = {}, trz = {}".format(point.get_x(), point.get_y(), point.get_z())) print( "----------------------------------------------------------------") return point
def find_child_trajectory(data, child, thresholds, DEBUG=False): xy_dis = 0.0 z_dis = 0.0 done_x = False done_z = False prev_data = data point = EuclideanPoint(center=[0, 0, 0]) while not done_x or not done_z: c_data = child.data if not done_x: xy_dis = data.distance(c_data, _2D) if xy_dis > thresholds.get_x(): tmp_point = EuclideanPoint(center=[0, 0, 0]) tmp_point.add_coord( calculate_trajectories_xy(data, prev_data, c_data, thresholds.get_x())) point.set_x(tmp_point.get_x()) point.set_y(tmp_point.get_y()) done_x = True elif child.is_leaf(): point.set_x(c_data.get_x()) point.set_y(c_data.get_y()) done_x = True elif child.right_son != None: point.set_x(TRAJECTORY_NONE) point.set_y(TRAJECTORY_NONE) done_x = True if not done_z: z_dis = math.fabs(data.get_z() - c_data.get_z()) if z_dis > thresholds.get_z(): point.set_z( calculate_trajectories_z(data, prev_data, c_data, thresholds.get_z())) done_z = True elif child.is_leaf(): point.set_z(c_data.get_z()) done_z = True elif child.right_son != None: point.set_z(TRAJECTORY_NONE) done_z = True prev_data = c_data if not child.is_leaf(): child = child.left_son if DEBUG: print(data.id) print("trx = {}, try = {}, trz = {}".format(point.get_x(), point.get_y(), point.get_z())) print( "----------------------------------------------------------------") return point
def Make_Virtual(): return SwcNode(nid=-1, center=EuclideanPoint(center=[0, 0, 0]))
def get_trajectory_for_path(ancestor_node, descendant_node): path_stack = queue.LifoQueue() ancestor_data = ancestor_node.data while descendant_node != ancestor_node: path_stack.put(descendant_node) descendant_node = descendant_node.parent if descendant_node is None: return None trajectory = EuclideanPoint() descendant_node = path_stack.get() down_x = False down_z = False while not path_stack.empty() and (not down_x or not down_z): sec_data = descendant_node.data next_descendant = path_stack.get() if next_descendant.is_left(): if not down_x and sec_data.left_trajectory.get_x( ) != TRAJECTORY_NONE: trajectory.set_x(sec_data.left_trajectory.get_x()) trajectory.set_y(sec_data.left_trajectory.get_y()) down_x = True if not down_z and sec_data.left_trajectory.get_z( ) != TRAJECTORY_NONE: trajectory.set_z(sec_data.left_trajectory.get_z()) down_z = True elif not next_descendant.is_left( ) and sec_data.right_trajectory is not None: if not down_x and sec_data.right_trajectory.get_x( ) != TRAJECTORY_NONE: trajectory.set_x(sec_data.right_trajectory.get_x()) trajectory.set_y(sec_data.right_trajectory.get_y()) down_x = True if not down_z and sec_data.right_trajectory.get_z( ) != TRAJECTORY_NONE: trajectory.set_z(sec_data.right_trajectory.get_z()) down_z = True if not down_x and not is_in_XY_threshold(ancestor_data, next_descendant.data): tmp = calculate_trajectories_xy(ancestor_data, descendant_node.data, next_descendant.data, g_xy_threshold) trajectory.set_x(tmp.get_x()) down_x = True if not down_z and math.fabs(ancestor_data.get_z() - next_descendant.get_z()) > g_z_threshold: trajectory.set_z( calculate_trajectories_z(ancestor_data, descendant_node.data, next_descendant.data, g_z_threshold)) down_z = True descendant_node = next_descendant if not down_x: trajectory.set_x(descendant_node.data.get_x()) trajectory.set_y(descendant_node.data.get_y()) if not down_z: trajectory.set_z(descendant_node.data.get_z()) return trajectory
def get_match_path_length_difference(gold_node, test_node, bin_gold_list, bin_test_list): if test_node.parent is None: return 0 gold_target = gold_node gold_swc_path_length = SwcNode() gold_swc_path_length.add_length(gold_node.data) test_swc_path_length = SwcNode() test_swc_path_length.add_length(test_node.data) test_path_XY_mod = get_end_node_XY_dis_diff( gold_node.data, gold_node.data.parent_trajectory, test_node.data) test_path_Z_mod = get_end_node_Z_dis_diff(gold_node.data, gold_node.data.parent_trajectory, test_node.data) test_swc_path_length.xy_path_length += test_path_XY_mod test_swc_path_length.z_path_length += test_path_Z_mod is_branch_left = gold_node.is_left() gold_node = gold_node.parent test_node = test_node.parent ancestor_trajectory = EuclideanPoint() checked_node = set() no_match = True no_done = True while no_match and no_done: if is_in_threshold(gold_node, test_node): gold_data = gold_node.data if is_branch_left: ancestor_trajectory = gold_data.left_trajectory else: ancestor_trajectory = gold_data.right_trajectory if ancestor_trajectory.get_x() == TRAJECTORY_NONE or \ ancestor_trajectory.get_z() == TRAJECTORY_NONE: tmp_trajectory = get_trajectory_for_path( gold_node, gold_target) if ancestor_trajectory.get_x() == TRAJECTORY_NONE: ancestor_trajectory.set_x(tmp_trajectory.get_x()) ancestor_trajectory.set_y(tmp_trajectory.get_y()) if ancestor_trajectory.get_z() == TRAJECTORY_NONE: ancestor_trajectory.set_z(tmp_trajectory.get_z()) test_XY_path_length = test_swc_path_length.xy_path_length + \ get_end_node_XY_dis_diff(gold_data, ancestor_trajectory, test_node.data) test_Z_path_length = test_swc_path_length.z_path_length + \ get_end_node_Z_dis_diff(gold_data, ancestor_trajectory, test_node.data) percent_error = path_length_matches(gold_swc_path_length, \ test_XY_path_length, \ test_Z_path_length) if percent_error < 1: return percent_error else: return 1 else: if gold_swc_path_length.path_length < test_swc_path_length.path_length: if gold_node.parent is None: no_done = False else: nearby_nodes = get_nearby_node_list( gold_node, bin_test_list, False) for node in nearby_nodes: if node in checked_node: no_done = False break checked_node.add(gold_node) gold_swc_path_length.add_length(gold_node.data) is_branch_left = gold_node.is_left() gold_node = gold_node.parent else: if test_node.parent is None: no_done = False else: nearby_nodes = get_nearby_node_list( test_node, bin_gold_list, False) for node in nearby_nodes: if node in checked_node: no_done = False break checked_node.add(test_node) test_swc_path_length.add_length(test_node.data) test_node = test_node.parent return 1
def test_foot_point2(self): for i in range(5000): p = EuclideanPoint([1, 2, 3]) l = Line(coords=[[2, 3, 4], [5, 6, 7]]) p.get_foot_point(l)