def get_response_content(fs): # define the requested physical size of the images (in pixels) physical_size = (640, 480) # get the directed edges and the branch lengths and vertex names R, B, N = FtreeIO.newick_to_RBN(fs.tree_string) # get the requested undirected edge edge = get_edge(R, N, fs.branch_name) # get the undirected tree topology T = Ftree.R_to_T(R) # get the leaves and the vertices of articulation leaves = Ftree.T_to_leaves(T) internal = Ftree.T_to_internal_vertices(T) vertices = leaves + internal nleaves = len(leaves) v_to_index = Ftree.invseq(vertices) # get the requested indices x_index = fs.x_axis - 1 y_index = fs.y_axis - 1 if x_index >= nleaves - 1 or y_index >= nleaves - 1: raise ValueError( 'projection indices must be smaller than the number of leaves') # adjust the branch length initial_length = B[edge] t = sigmoid(fs.frame_progress) B[edge] = (1 - t) * initial_length + t * fs.final_length # get the points w, v = Ftree.TB_to_harmonic_extension(T, B, leaves, internal) X_full = np.dot(v, np.diag(np.reciprocal(np.sqrt(w)))) X = np.vstack([X_full[:, x_index], X_full[:, y_index]]).T # draw the image ext = Form.g_imageformat_to_ext[fs.imageformat] return get_animation_frame(ext, physical_size, fs.scale, v_to_index, T, X, w)
def get_tikz_lines(newick, eigenvector_index, yaw, pitch): """ @param eigenvector_index: 1 is Fiedler """ tree = Newick.parse(newick, SpatialTree.SpatialTree) # change the node names and get the new tree string for node in tree.preorder(): node.name = 'n' + str(id(node)) newick = NewickIO.get_newick_string(tree) # do the layout layout = FastDaylightLayout.StraightBranchLayout() layout.do_layout(tree) tree.fit((g_xy_scale, g_xy_scale)) name_to_location = dict( (x.name, tree._layout_to_display(x.location)) for x in tree.preorder()) T, B, N = FtreeIO.newick_to_TBN(newick) # get some vertices leaves = Ftree.T_to_leaves(T) internal = Ftree.T_to_internal_vertices(T) vertices = leaves + internal # get the locations v_to_location = dict((v, name_to_location[N[v]]) for v in vertices) # get the valuations w, V = Ftree.TB_to_harmonic_extension(T, B, leaves, internal) index_to_val = V[:, eigenvector_index - 1] v_to_val = dict( (vertices[i], g_z_scale * val) for i, val in enumerate(index_to_val)) # get the coordinates v_to_xyz = get_v_to_xyz(yaw, v_to_location, v_to_val) # add intersection vertices add_intersection_vertices(T, B, v_to_xyz) intersection_vertices = sorted(v for v in v_to_xyz if v not in vertices) # get lines of the tikz file return xyz_to_tikz_lines(T, B, pitch, v_to_xyz, leaves, internal, intersection_vertices)
def get_response_content(fs): # read the tree T, B, N = FtreeIO.newick_to_TBN(fs.tree) leaves = Ftree.T_to_leaves(T) internal = Ftree.T_to_internal_vertices(T) # get the valuations with harmonic extensions w, V = Ftree.TB_to_harmonic_extension(T, B, leaves, internal) # get the Fiedler valuations with harmonic extensions h = V[:, 0] # check for vertices with small valuations eps = 1e-8 if any(abs(x) < x for x in h): raise ValueError('the tree has no clear harmonic Fiedler point') # find the edge contining the harmonic Fiedler point v_to_val = dict((v, h[i]) for i, v in enumerate(leaves + internal)) d_edges = [(a, b) for a, b in T if v_to_val[a] * v_to_val[b] < 0] if len(d_edges) != 1: raise ValueError('expected the point to fall clearly on a single edge') d_edge = d_edges[0] a, b = d_edge # find the proportion along the directed edge t = v_to_val[a] / (v_to_val[a] - v_to_val[b]) # find the distance from the new root to each endpoint vertices u_edge = frozenset(d_edge) d = B[u_edge] da = t * d db = (1 - t) * d # create the new tree r = max(Ftree.T_to_order(T)) + 1 N[r] = fs.root_name T.remove(u_edge) del B[u_edge] ea = frozenset((r, a)) eb = frozenset((r, b)) T.add(ea) T.add(eb) B[ea] = da B[eb] = db # add a new leaf with arbitrary branch length leaf = r + 1 N[leaf] = fs.leaf_name u_edge = frozenset((r, leaf)) T.add(u_edge) B[u_edge] = 1.0 # get the best branch length to cause eigenvalue multiplicity blen = scipy.optimize.golden(get_gap, (T, B, u_edge), full_output=False, tol=1e-12) B[u_edge] = blen # return the string representation of the new tree R = Ftree.T_to_R_specific(T, r) return FtreeIO.RBN_to_newick(R, B, N)
def _get_v_to_point(self): # Get the leaf vertices and the internal vertices. leaves = Ftree.T_to_leaves(self.T) internal = Ftree.T_to_internal_vertices(self.T) vertices = leaves + internal # Get the harmonic extensions of eigenvectors of schur complement. w, v = Ftree.TB_to_harmonic_extension(self.T, self.B, leaves, internal) x_values = -v.T[0] y_values = -v.T[1] z_values = v.T[2] points = [np.array(xyz) for xyz in zip(x_values, y_values, z_values)] # get the vertex to point map return dict(zip(vertices, points))
def main(args): # do some validation if args.nframes < 2: raise ValueError('nframes should be at least 2') # define the requested physical size of the images (in pixels) physical_size = (args.physical_width, args.physical_height) # get the directed edges and the branch lengths and vertex names R, B, N = FtreeIO.newick_to_RBN(args.tree) # get the requested undirected edge edge = get_edge(R, N, args.branch_name) initial_length = B[edge] # get the undirected tree topology T = Ftree.R_to_T(R) # get the leaves and the vertices of articulation leaves = Ftree.T_to_leaves(T) internal = Ftree.T_to_internal_vertices(T) vertices = leaves + internal nleaves = len(leaves) v_to_index = Ftree.invseq(vertices) # get the requested indices x_index = args.x_axis - 1 y_index = args.y_axis - 1 if x_index >= nleaves - 1 or y_index >= nleaves - 1: raise ValueError( 'projection indices must be smaller than the number of leaves') X_prev = None # create the animation frames and write them as image files pbar = Progress.Bar(args.nframes) for frame_index in range(args.nframes): linear_progress = frame_index / float(args.nframes - 1) if args.interpolation == 'sigmoid': t = sigmoid(linear_progress) else: t = linear_progress B[edge] = (1 - t) * initial_length + t * args.final_length w, v = Ftree.TB_to_harmonic_extension(T, B, leaves, internal) X_full = np.dot(v, np.diag(np.reciprocal(np.sqrt(w)))) X = np.vstack([X_full[:, x_index], X_full[:, y_index]]).T if X_prev is not None: X = reflect_to_match(X, X_prev) X_prev = X image_string = get_animation_frame(args.image_format, physical_size, args.scale, v_to_index, T, X, w) image_filename = 'frame-%04d.%s' % (frame_index, args.image_format) image_pathname = os.path.join(args.output_directory, image_filename) with open(image_pathname, 'wb') as fout: fout.write(image_string) pbar.update(frame_index + 1) pbar.finish()
def get_response_content(fs): # read the tree T, B, N = FtreeIO.newick_to_TBN(fs.tree) leaves = Ftree.T_to_leaves(T) internal = Ftree.T_to_internal_vertices(T) # get the valuations with harmonic extensions w, V = Ftree.TB_to_harmonic_extension(T, B, leaves, internal) # get the Fiedler valuations with harmonic extensions h = V[:, 0] # check for vertices with small valuations eps = 1e-8 if any(abs(x) < x for x in h): raise ValueError('the tree has no clear harmonic Fiedler point') # find the edge contining the harmonic Fiedler point v_to_val = dict((v, h[i]) for i, v in enumerate(leaves + internal)) d_edges = [(a, b) for a, b in T if v_to_val[a] * v_to_val[b] < 0] if len(d_edges) != 1: raise ValueError('expected the point to fall clearly on a single edge') d_edge = d_edges[0] a, b = d_edge # find the proportion along the directed edge t = v_to_val[a] / (v_to_val[a] - v_to_val[b]) # find the distance from the new root to each endpoint vertices u_edge = frozenset(d_edge) d = B[u_edge] da = t * d db = (1 - t) * d # create the new tree r = max(Ftree.T_to_order(T)) + 1 T.remove(u_edge) del B[u_edge] ea = frozenset((r, a)) eb = frozenset((r, b)) T.add(ea) T.add(eb) B[ea] = da B[eb] = db R = Ftree.T_to_R_specific(T, r) # return the string representation of the new tree return FtreeIO.RBN_to_newick(R, B, N)