def do_layout(self, tree): """ Interleave the processes of breaking the tree and daylight equalization. @param tree: something like a SpatialTree """ # reroot to a node with more than two neighbors if get_neighbor_count(tree.root) < 3: suitable_roots = [ x for x in tree.preorder() if get_neighbor_count(x) > 2 ] if suitable_roots: tree.reroot(suitable_roots[0]) # create the initial layout EqualArcLayout.do_layout(tree) # determine the maximum allowed branch length total_branch_length = tree.get_total_length() max_branch_length = total_branch_length / float(self.min_segment_count) # any branch longer than the max branch length will be broken in half iteration = 0 while True: print 'progressive iteration', iteration + 1 # write the extension tree dtree = day.Day() _build_dtree(dtree, tree.root, 0) # equalize the layout for node in tree.breadth_first(): if get_neighbor_count(node) > 1: dtree.select_node(node.dtree_id) dtree.reroot() try: dtree.equalize() except RuntimeError as e: raise LayoutError(e) # read the extension tree for node in tree.preorder(): dtree.select_node(node.dtree_id) x = dtree.get_x() y = dtree.get_y() node.location = (x, y) # break the branches old_nodes = list(tree.preorder()) for node in old_nodes: if node is tree.root: if node.blen is not None: raise HandlingError( 'the root node should not have a branch length') elif node.blen is None: raise HandlingError( 'each non-root node should have a branch length') elif node.blen > max_branch_length: # create a new node and set its attributes new = self.node_factory() new.name = node.name # insert the new node tree.insert_node(new, node.parent, node, .5) # if no node was added then break out of the loop if len(old_nodes) == len(list(tree.preorder())): break else: iteration += 1
def main(): import EqualArcLayout import Newick import SpatialTree # make a spatial tree tree = Newick.parse(Newick.daylight_example_tree, SpatialTree.SpatialTree) EqualArcLayout.do_layout(tree) max_size = (640, 480) image_formats = ('png', 'pdf', 'ps', 'svg') for image_format in image_formats: # get the image string image_string = get_tree_image(tree, max_size, image_format) # write the image file image_filename = 'test.%s' % image_format with open(image_filename, 'wb') as fout: fout.write(image_string) print 'created', image_filename # write an html file html_filename = 'test.html' with open(html_filename, 'w') as fout: print >> fout, '<html><body>' for image_format in image_formats: image_filename = 'test.%s' % image_format print >> fout, '<a href="%s">%s</a><br/>' % (image_filename, image_filename) print >> fout, '</body></html>' print 'created', html_filename
def do_layout(self, tree): """ @param tree: something like a SpatialTree """ # create the initial layout EqualArcLayout.do_layout(tree) # use sax-like events to create a parallel tree in the C extension dtree = day.Day() count = _build_dtree(dtree, tree.root, 0) # repeatedly reroot and equalize for iteration in range(self.iteration_count): for node in tree.breadth_first(): neighbor_count = len(node.children) if node.parent: neighbor_count += 1 if neighbor_count > 2: dtree.select_node(node.dtree_id) dtree.reroot() try: dtree.equalize() except RuntimeError as e: raise LayoutError(e) # extract the x and y coordinates from the parallel tree for node in tree.preorder(): dtree.select_node(node.dtree_id) x = dtree.get_x() y = dtree.get_y() node.location = (x, y) # take off the silly dtree_id members for node in tree.preorder(): del node.dtree_id
def get_response_content(fs): # get a properly formatted newick tree with branch lengths tree = Newick.parse(fs.tree, SpatialTree.SpatialTree) tree.assert_valid() if tree.has_negative_branch_lengths(): msg = 'drawing a tree with negative branch lengths is not implemented' raise HandlingError(msg) tree.add_branch_lengths() # do the layout if fs.daylight: try: layout = FastDaylightLayout.StraightBranchLayout() layout.do_layout(tree) except RuntimeError as e: pass elif fs.curved: try: layout = FastDaylightLayout.CurvedBranchLayout() layout.set_min_segment_count(400) layout.do_layout(tree) except RuntimeError as e: pass elif fs.arc: EqualArcLayout.do_layout(tree) # draw the image try: ext = Form.g_imageformat_to_ext[fs.imageformat] return DrawTreeImage.get_tree_image(tree, (640, 480), ext) except CairoUtil.CairoUtilError as e: raise HandlingError(e)
def main(): import EqualArcLayout import Newick import SpatialTree # make a spatial tree tree = Newick.parse(Newick.daylight_example_tree, SpatialTree.SpatialTree) EqualArcLayout.do_layout(tree) max_size = (640, 480) image_formats = ('png', 'pdf', 'ps', 'svg') for image_format in image_formats: # get the image string image_string = get_tree_image(tree, max_size, image_format) # write the image file image_filename = 'test.%s' % image_format with open(image_filename, 'wb') as fout: fout.write(image_string) print 'created', image_filename # write an html file html_filename = 'test.html' with open(html_filename, 'w') as fout: print >> fout, '<html><body>' for image_format in image_formats: image_filename = 'test.%s' % image_format print >> fout, '<a href="%s">%s</a><br/>' % ( image_filename, image_filename) print >> fout, '</body></html>' print 'created', html_filename
def do_layout(self, tree): """ Interleave the processes of breaking the tree and daylight equalization. @param tree: something like a SpatialTree """ # reroot to a node with more than two neighbors if get_neighbor_count(tree.root) < 3: suitable_roots = [ x for x in tree.preorder() if get_neighbor_count(x) > 2] if suitable_roots: tree.reroot(suitable_roots[0]) # create the initial layout EqualArcLayout.do_layout(tree) # determine the maximum allowed branch length total_branch_length = tree.get_total_length() max_branch_length = total_branch_length / float(self.min_segment_count) # any branch longer than the max branch length will be broken in half iteration = 0 while True: print 'progressive iteration', iteration+1 # write the extension tree dtree = day.Day() _build_dtree(dtree, tree.root, 0) # equalize the layout for node in tree.breadth_first(): if get_neighbor_count(node) > 1: dtree.select_node(node.dtree_id) dtree.reroot() try: dtree.equalize() except RuntimeError as e: raise LayoutError(e) # read the extension tree for node in tree.preorder(): dtree.select_node(node.dtree_id) x = dtree.get_x() y = dtree.get_y() node.location = (x, y) # break the branches old_nodes = list(tree.preorder()) for node in old_nodes: if node is tree.root: if node.blen is not None: raise HandlingError( 'the root node should not have a branch length') elif node.blen is None: raise HandlingError( 'each non-root node should have a branch length') elif node.blen > max_branch_length: # create a new node and set its attributes new = self.node_factory() new.name = node.name # insert the new node tree.insert_node(new, node.parent, node, .5) # if no node was added then break out of the loop if len(old_nodes) == len(list(tree.preorder())): break else: iteration += 1
def get_response_content(fs): # get a properly formatted newick tree with branch lengths tree = Newick.parse(fs.tree, SpatialTree.SpatialTree) tree.assert_valid() if tree.has_negative_branch_lengths(): msg = 'drawing a tree with negative branch lengths is not implemented' raise HandlingError(msg) tree.add_branch_lengths() # get the dictionary mapping the branch name to the nucleotide name_to_nucleotide = {} # parse the column string for line in iterutils.stripped_lines(fs.column.splitlines()): name_string, nucleotide_string = SnippetUtil.get_state_value_pair(line) if nucleotide_string not in list('acgtACGT'): msg = '"%s" is not a valid nucleotide' % nucleotide_string raise HandlingError(msg) nucleotide_string = nucleotide_string.upper() if name_string in name_to_nucleotide: raise HandlingError('the name "%s" was duplicated' % name_string) name_to_nucleotide[name_string] = nucleotide_string # augment the tips with the nucleotide letters for name, nucleotide in name_to_nucleotide.items(): try: node = tree.get_unique_node(name) except Newick.NewickSearchError as e: raise HandlingError(e) if node.children: msg = 'constraints on internal nodes are not implemented' raise HandlingError(msg) node.state = nucleotide # get the Jukes-Cantor rate matrix object dictionary_rate_matrix = RateMatrix.get_jukes_cantor_rate_matrix() ordered_states = list('ACGT') row_major_rate_matrix = MatrixUtil.dict_to_row_major( dictionary_rate_matrix, ordered_states, ordered_states) rate_matrix_object = RateMatrix.RateMatrix(row_major_rate_matrix, ordered_states) # simulate the ancestral nucleotides rate_matrix_object.simulate_ancestral_states(tree) # simulate a path on each branch # this breaks up the branch into a linear sequence of nodes and adds color for node in tree.gen_non_root_nodes(): simulate_branch_path(tree, node) # do the layout EqualArcLayout.do_layout(tree) # draw the image try: ext = Form.g_imageformat_to_ext[fs.imageformat] return DrawTreeImage.get_tree_image(tree, (640, 480), ext) except CairoUtil.CairoUtilError as e: raise HandlingError(e)
def get_response_content(fs): # get a properly formatted newick tree with branch lengths tree = Newick.parse(fs.tree, SpatialTree.SpatialTree) tree.assert_valid() if tree.has_negative_branch_lengths(): msg = 'drawing a tree with negative branch lengths is not implemented' raise HandlingError(msg) tree.add_branch_lengths() # get the dictionary mapping the branch name to the nucleotide name_to_nucleotide = {} # parse the column string for line in iterutils.stripped_lines(fs.column.splitlines()): name_string, nucleotide_string = SnippetUtil.get_state_value_pair(line) if nucleotide_string not in list('acgtACGT'): msg = '"%s" is not a valid nucleotide' % nucleotide_string raise HandlingError(msg) nucleotide_string = nucleotide_string.upper() if name_string in name_to_nucleotide: raise HandlingError('the name "%s" was duplicated' % name_string) name_to_nucleotide[name_string] = nucleotide_string # augment the tips with the nucleotide letters for name, nucleotide in name_to_nucleotide.items(): try: node = tree.get_unique_node(name) except Newick.NewickSearchError as e: raise HandlingError(e) if node.children: msg = 'constraints on internal nodes are not implemented' raise HandlingError(msg) node.state = nucleotide # get the Jukes-Cantor rate matrix object dictionary_rate_matrix = RateMatrix.get_jukes_cantor_rate_matrix() ordered_states = list('ACGT') row_major_rate_matrix = MatrixUtil.dict_to_row_major( dictionary_rate_matrix, ordered_states, ordered_states) rate_matrix_object = RateMatrix.RateMatrix( row_major_rate_matrix, ordered_states) # simulate the ancestral nucleotides rate_matrix_object.simulate_ancestral_states(tree) # simulate a path on each branch # this breaks up the branch into a linear sequence of nodes and adds color for node in tree.gen_non_root_nodes(): simulate_branch_path(tree, node) # do the layout EqualArcLayout.do_layout(tree) # draw the image try: ext = Form.g_imageformat_to_ext[fs.imageformat] return DrawTreeImage.get_tree_image(tree, (640, 480), ext) except CairoUtil.CairoUtilError as e: raise HandlingError(e)
def get_response_content(fs): # get a properly formatted newick tree with branch lengths tree = Newick.parse(fs.tree, SpatialTree.SpatialTree) tree.assert_valid() if tree.has_negative_branch_lengths(): msg = 'drawing a tree with negative branch lengths is not implemented' raise HandlingError(msg) tree.add_branch_lengths() # get the dictionary mapping the branch name to the nucleotide name_to_nt = {} lines = Util.get_stripped_lines(fs.column.splitlines()) if lines: name_to_nt = SnippetUtil.get_generic_dictionary(lines, 'name', 'nucleotide', list('acgtACGT')) # augment the tips with the nucleotide letters for name, nt in name_to_nt.items(): try: node = tree.get_unique_node(name) except Newick.NewickSearchError as e: raise HandlingError(e) if node.children: msg = 'constraints on internal nodes are not implemented' raise HandlingError(msg) node.state = nt.upper() # read the rate matrix R = fs.matrix # convert the rate matrix to a rate matrix object states = list('ACGT') rate_matrix_object = RateMatrix.RateMatrix(R.tolist(), states) # simulate the ancestral nucleotides rate_matrix_object.simulate_ancestral_states(tree) # simulate a path on each branch # this breaks up the branch into a linear sequence of nodes and adds color for node in tree.gen_non_root_nodes(): simulate_branch_path(tree, node, rate_matrix_object) # do the layout EqualArcLayout.do_layout(tree) # draw the image try: ext = Form.g_imageformat_to_ext[fs.imageformat] return DrawTreeImage.get_tree_image(tree, (640, 480), ext) except CairoUtil.CairoUtilError as e: raise HandlingError(e)
def get_tikz_lines(newick): tree = Newick.parse(newick, SpatialTree.SpatialTree) # layout = FastDaylightLayout.StraightBranchLayout() # layout.set_iteration_count(20) # layout.do_layout(tree) EqualArcLayout.do_layout(tree) tree.fit((2.0, 2.0)) 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) node_lines = [] for v, depth in Ftree.T_to_v_to_centrality(T).items(): x, y = name_to_location[N[v]] line = get_vertex_line(v, depth, x, y) node_lines.append(line) edge_lines = [] for va, vb in T: line = get_edge_line(va, vb) edge_lines.append(line) return node_lines + edge_lines
def get_tikz_lines(newick): tree = Newick.parse(newick, SpatialTree.SpatialTree) #layout = FastDaylightLayout.StraightBranchLayout() #layout.set_iteration_count(20) #layout.do_layout(tree) EqualArcLayout.do_layout(tree) tree.fit((2.0, 2.0)) 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) node_lines = [] for v, depth in Ftree.T_to_v_to_centrality(T).items(): x, y = name_to_location[N[v]] line = get_vertex_line(v, depth, x, y) node_lines.append(line) edge_lines = [] for va, vb in T: line = get_edge_line(va, vb) edge_lines.append(line) return node_lines + edge_lines
def do_layout(self, tree): """ @param tree: something like a SpatialTree """ original_root = tree.root if self.force_straight_branches: min_adjacent_nodes = 3 else: min_adjacent_nodes = 2 EqualArcLayout.do_layout(tree) for i in range(self.iterations): internal_nodes = list(tree.breadth_first()) #random.shuffle(internal_nodes) for node in internal_nodes: adjacent_node_count = 0 if node.parent: adjacent_node_count += 1 adjacent_node_count += len(node.children) if adjacent_node_count >= min_adjacent_nodes: tree.reroot(node) _equal_daylight(tree) tree.reroot(original_root)
def demo(): import EqualArcLayout import DrawTreeImage # read a tree tree_string = Newick.daylight_example_tree tree = Newick.parse(tree_string, SpatialTree) # do the layout EqualArcLayout.do_layout(tree) # show some debugging information max_size = (640, 480) tree.fit(max_size) extents = tree.get_extents() print 'extents:', extents branches = list(tree.gen_branches()) print 'branches:' for branch in branches: print branch.src_location, branch.dst_location # draw the image image_format = 'png' image_string = DrawTreeImage.get_tree_image(tree, max_size, image_format) # write the image file with open('test.%s' % image_format, 'wb') as fout: fout.write(image_string)
def demo(): import EqualArcLayout import DrawTreeImage # read a tree tree_string = Newick.daylight_example_tree tree = Newick.parse(tree_string, SpatialTree) # do the layout EqualArcLayout.do_layout(tree) # show some debugging information max_size = (640, 480) tree.fit(max_size) extents = tree.get_extents() print "extents:", extents branches = list(tree.gen_branches()) print "branches:" for branch in branches: print branch.src_location, branch.dst_location # draw the image image_format = "png" image_string = DrawTreeImage.get_tree_image(tree, max_size, image_format) # write the image file with open("test.%s" % image_format, "wb") as fout: fout.write(image_string)