def tree_test_bifurcation(): root = dendropy.Node() child = dendropy.Node() root.add_child(child) child2 = dendropy.Node() root.add_child(child2) root.deme = Deme(3.0, 0.0, 0.1, 0.0, 5.0) child.deme = Deme(1.0, 0.9, 0.1, 5.0, 6.0) child2.deme = Deme(1.0, 0.9, 0.1, 5.0, 6.0) child.deme.Nsampled = 1000 child2.deme.Nsampled = 1000 tree = dendropy.Tree(seed_node=root) hist = History(tree) lins = hist.simulate(1) assert len(lins) == 1 tree = dendropy.Tree(seed_node=lins[0]) gentree = scaleByGenerations(tree) tree.randomly_assign_taxa() print str(tree) + ';' gentree.randomly_assign_taxa() print str(gentree) + ';'
def test_multiplePrune(self): pruner = TreePruner(re.compile("(.*)"), re.compile("(.*)"), True) pruner.set_taxon_set(["B", "C"]) mrca = self.tree.mrca(taxa=[n.taxon for n in self.tree.leaf_node_iter() if n.taxon.label in ["B", "C"]]) tree_to_prune2 = dendropy.Tree(seed_node=copy.deepcopy(mrca), taxon_namespace=dendropy.TaxonNamespace()) pruner.prune(tree_to_prune2) pruner.set_taxon_set(["A", "A2"]) mrca = self.tree.mrca(taxa=[n.taxon for n in self.tree.leaf_node_iter() if n.taxon.label in ["A", "A2"]]) tree_to_prune = dendropy.Tree(seed_node=copy.deepcopy(mrca), taxon_namespace=dendropy.TaxonNamespace()) pruner.prune(tree_to_prune) self.assertEqual([taxon.label for taxon in tree_to_prune.taxon_namespace], ["A", "A2"]) pruner.set_taxon_set(["B", "C"]) mrca = self.tree.mrca(taxa=[n.taxon for n in self.tree.leaf_node_iter() if n.taxon.label in ["B", "C"]]) tree_to_prune2 = dendropy.Tree(seed_node=copy.deepcopy(mrca), taxon_namespace=dendropy.TaxonNamespace()) pruner.prune(tree_to_prune2) self.assertEqual([taxon.label for taxon in tree_to_prune2.taxon_namespace], ["B", "C"]) self.assertEqual([taxon.label for taxon in self.tree.taxon_namespace], ["A", "B", "A2", "C"])
def lineages_to_SFS(lineages, nsampled=None, normalize=True): alllineages = convert_to_simple_lineage_list(lineages) #check the total num of sampled individuals if not supplied if nsampled == None: nsampled = 0 for lin in alllineages: tree = dendropy.Tree(seed_node=lin) nleaves = len(tree.leaf_nodes()) nsampled += nleaves # main functionality here sfs = [0.0 for i in range(nsampled + 1)] print("lensfs=" + str(len(sfs))) for lineage in alllineages: tree = dendropy.Tree(seed_node=lineage) sfslin = tree_to_SFS(tree, normalize=False) for i in range(len(sfslin)): sfs[i] += sfslin[i] if normalize: total = sum(sfs) sfsout = [freq / total for freq in sfs] return sfsout return sfs
def runTest(self): ref = dendropy.Tree(stream=StringIO("((t5,t6),((t4,(t2,t1)),t3));"), schema="newick") taxon_set = ref.taxon_set encode_splits(ref) o_tree = dendropy.Tree(stream=StringIO("((t1,t2),((t4,(t5,t6)),t3));"), schema="newick", taxon_set=taxon_set) encode_splits(o_tree) self.assertEqual(treecalc.symmetric_difference(o_tree, ref), 2)
def split_randomly_into_two_sets(list_of_child): left_tree = tr.Tree() right_tree = tr.Tree() left_subtree_size = random.choice(range(0,len(list_of_child))) for i in range(0,len(list_of_child)): if i < left_subtree_size: left_tree.seed_node.add_child(list_of_child[i]) else: right_tree.seed_node.add_child(list_of_child[i]) if left_subtree_size == 0: left_tree = None if left_subtree_size == len(list_of_child): right_tree = None return tree_operations.collapse_edges(left_tree),tree_operations.collapse_edges(right_tree)
def createDendroTreeFromConsensus(self, file): ## Creates a dendropy Tree from the consensus file try: with open(file) as f: rows = f.readlines() except IOError: return None tree = dendropy.Tree() tree.is_rooted = True if len(rows) > 0: parent = self._addnodes(tree, tree.seed_node, rows, -1) notin = [] for taxon in self.taxon_namespace: if not tree.taxon_namespace.has_taxon_label(label=str(taxon)): notin.append(taxon) node = tree.seed_node.new_child( taxon=tree.taxon_namespace.require_taxon(label=str(taxon)), edge_length=1) if len(notin) > 0: print notin return tree
def balanced_binary(num_taxa=None, taxa=None, edge_length=1.): if taxa is None: if num_taxa: taxa = TaxaMetadata.default(num_taxa) else: raise TypeError( "Must provide either the number of leaves or a TaxaMetadata") if num_taxa: if num_taxa != len(taxa): raise ValueError( f"The desired number of leaves {num_taxa} must match the number of taxa given {len(taxa)}." ) else: num_taxa = len(taxa) if num_taxa != 2**int(np.log2(num_taxa)): raise ValueError( f"The number of leaves in a balanced binary tree must be a power of 2, not {num_taxa}." ) nodes = taxa.all_leaves(edge_length=edge_length) while len(nodes) > 1: nodes = [ merge_children(nodes[2 * i:2 * i + 2], edge_length=edge_length) for i in range(len(nodes) // 2) ] return dendropy.Tree(taxon_namespace=taxa.taxon_namespace, seed_node=nodes[0], is_rooted=False)
def getTaxa(tree): t = dendropy.Tree() if "=" in tree: tree = tree.split('=')[-1].strip() t.read_from_string(tree, 'newick', preserve_underscores=True) taxa = t.taxon_set.labels() return taxa
def contrasts_tree(self, character_index, annotate_pic_statistics=True, state_values_as_node_labels=False, corrected_edge_lengths=False): """ Returns a Tree object annotated with the following attributes added to each node (as annotations to be serialized if ``annotate_pic_statistics`` is True): - ``pic_state_value`` - ``pic_state_variance`` - ``pic_contrast_raw`` - ``pic_contrast_variance`` - ``pic_contrast_standardized`` - ``pic_edge_length_error`` - ``pic_corrected_edge_length`` """ contrasts = self._get_contrasts(character_index) tree = dendropy.Tree(self._tree) for nd in tree.postorder_node_iter(): nd_results = contrasts[nd._track_id] for k, v in nd_results.items(): setattr(nd, k, v) if annotate_pic_statistics: nd.annotations.add_bound_attribute(k) if corrected_edge_lengths and nd_results['pic_corrected_edge_length'] is not None: nd.edge.length = nd_results['pic_corrected_edge_length'] if state_values_as_node_labels: nd.label = str(nd_results['pic_state_value']) return tree
def join_nodes_in_one_tree(tree1, nodeAinT1, cladeA, tree2, nodeBinT2, cladeB): """Join clade A and clade B in just one tree 1. Re-root tree 1 as (A,X); and extract (A,X); and A 2. Re-root tree 2 as (B,Y); and extract (B,Y); and B 3. Build new tree 2 as (A,(B,Y)); 4. Return tree 1 and tree 2 Parameters ---------- tree1 : dendropy tree object nodeAinT1 : dendropy node object cladeA : list of str taxon labels below node A tree2 : dendropy node object nodeBinT2 : dendropy node object cladeB : list of str taxon labels below node B Returns ------- tree1 : dendropy tree object tree2 : dendropy tree object """ [tree1, nodeAinT1] = extract_nodes_from_split(tree1, nodeAinT1, cladeA) [tree2, nodeBinT2] = extract_nodes_from_split(tree2, nodeBinT2, cladeB) root = dendropy.Node() root.add_child(deepcopy(nodeAinT1)) # TODO: Remove deep copies! root.add_child(tree2.seed_node) tree2 = dendropy.Tree(seed_node=root) tree2.is_rooted = True return [tree1, tree2]
def pure_kingman_tree(taxon_namespace, pop_size=1, rng=None): """ Generates a tree under the unconstrained Kingman's coalescent process. Parameters ---------- taxon_namespace: |TaxonNamespace| instance A pre-populated |TaxonNamespace| where the contained |Taxon| instances represent the genes or individuals sampled from the population. pop_size : numeric The size of the population from the which the coalescent process is sampled. Returns ------- t : |Tree| A tree sampled from the Kingman's neutral coalescent. """ if rng is None: rng = GLOBAL_RNG # use the global rng by default nodes = [dendropy.Node(taxon=t) for t in taxon_namespace] seed_node = coalesce_nodes(nodes=nodes, pop_size=pop_size, period=None, rng=rng, use_expected_tmrca=False)[0] tree = dendropy.Tree(taxon_namespace=taxon_namespace, seed_node=seed_node) return tree
def generate_star_tree2(): num_tips = 10 branch_length = 1 names = [] for i in range(num_tips + 1): names.append("s" + str(i)) taxon_namespace = dendropy.TaxonNamespace(names) tree = dendropy.Tree(taxon_namespace=taxon_namespace) index = 0 for i in range(num_tips + 1): if index == 0: tree.seed_node.taxon = taxon_namespace.get_taxon("s" + str(0)) tree.seed_node.X = 0 tree.seed_node.time = 0 else: node = dendropy.Node(taxon=taxon_namespace.get_taxon("s" + str(index))) node.edge_length = branch_length node.X = random.gauss(0, 1) node.time = branch_length tree.seed_node.add_child(node) return tree
def uniform_pure_birth_tree(taxon_namespace, birth_rate=1.0, rng=None): "Generates a uniform-rate pure-birth process tree. " if rng is None: rng = GLOBAL_RNG # use the global rng by default tree = dendropy.Tree(taxon_namespace=taxon_namespace) tree.seed_node.edge.length = 0.0 leaf_nodes = tree.leaf_nodes() while len(leaf_nodes) < len(taxon_namespace): waiting_time = rng.expovariate(len(leaf_nodes) / birth_rate) for nd in leaf_nodes: nd.edge.length += waiting_time parent_node = rng.choice(leaf_nodes) c1 = parent_node.new_child() c2 = parent_node.new_child() c1.edge.length = 0.0 c2.edge.length = 0.0 leaf_nodes = tree.leaf_nodes() leaf_nodes = tree.leaf_nodes() waiting_time = rng.expovariate(len(leaf_nodes) / birth_rate) for nd in leaf_nodes: nd.edge.length += waiting_time for idx, leaf in enumerate(leaf_nodes): leaf.taxon = taxon_namespace[idx] tree.is_rooted = True return tree
def __merge_subtrees(self, left, right, similarity_matrix, taxa_metadata): # make sure this is necessary left.is_rooted = True right.is_rooted = True # TODO: use truncated svd here # u_12 is matrix S_12 = similarity_matrix[np.ix_(left.mask, right.mask)] [u_12,sigma_12,v_12] = np.linalg.svd(S_12) left.u_12 = u_12 right.u_12 = v_12 left.O = np.outer(u_12[:,0],u_12[:,0]) right.O = np.outer(v_12[0,:],v_12[0,:]) for T1, T2 in [(left, right), (right, left)]: bipartitions1 = T1.bipartition_edge_map.keys() if len(bipartitions1) > 1: min_score = np.inf for bp in bipartitions1: mask1A = taxa_metadata.bipartition2mask(bp) mask1B = (T1.mask ^ mask1A) score = compute_merge_score(mask1A, mask1B, T2.mask, similarity_matrix, T1.u_12[:,0], sigma_12[0], T2.u_12[0,:], T1.O, self.merge_method) if score < min_score: min_score = score bp_min = bp T1.reroot_at_edge(T1.bipartition_edge_map[bp_min]) T = dendropy.Tree(taxon_namespace=taxa_metadata.taxon_namespace) T.seed_node.set_child_nodes([T1.seed_node, T2.seed_node]) return T
def nx_tree_to_dd_tree(T): # build dict from string label to dendropy node T.add_node('my_root') random_node = next(iter(T.nodes())) near = next(iter(T.neighbors(random_node))) T.remove_edge(random_node, near) T.add_edge(random_node, 'my_root') T.add_edge(near, 'my_root') label_node = dict() for v in T.nodes(): dd_node = dd.Node(label=v) label_node[v] = dd_node # root tree at random node # root = next(iter(T.nodes())) dd_tree = dd.Tree() dd_tree.seed_node = label_node['my_root'] # print(root) # add the edges in the tree for v, successors in nx.bfs_successors(T, 'my_root'): dd_node = label_node[v] for s in successors: dd_child = label_node[s] dd_node.add_child(dd_child) # nx.draw(T, with_labels = True) # plt.show() return dd_tree
def scaleByGenerations(tree): gentree = dendropy.Tree(tree) for node in gentree.postorder_node_iter(): if node.edge_length != None: node.edge_length = node.gens return gentree
def from_newick(self, s, taxon_namespace=None, keep_taxon=True): import dendropy if taxon_namespace is None: taxon_namespace = self.infer_namespace(s) tree = dendropy.Tree(taxon_namespace=taxon_namespace) tree = tree.get(data=s, schema="newick") return self.from_dendropy_tree(tree, keep_taxon=keep_taxon)
def lopsided_tree(num_taxa, taxa=None, edge_length=1.): """One node splits off at each step""" if taxa is None: if num_taxa: taxa = TaxaMetadata.default(num_taxa) else: raise TypeError( "Must provide either the number of leaves or a TaxaMetadata") if num_taxa: if num_taxa != len(taxa): raise ValueError( f"The desired number of leaves {num_taxa} must match the number of taxa given {len(taxa)}." ) else: num_taxa = len(taxa) nodes = taxa.all_leaves(edge_length=edge_length) while len(nodes) > 1: # maintain this order, because we want the order of the taxa when we # iterate thru the leaves to be the same as specified in taxa argument b = nodes.pop() a = nodes.pop() nodes.append(merge_children((a, b), edge_length=edge_length)) return dendropy.Tree(taxon_namespace=taxa.taxon_namespace, seed_node=nodes[0], is_rooted=False)
def generate_random_tree_w_adj(m): # generate adjacency matrix A = np.zeros((2*m-2,2*m-2)) active_set = np.arange(m) taxa_metadata = spectraltree.TaxaMetadata.default(m) G = taxa_metadata.all_leaves(edge_length=1) #available_clades = set(range(len(G))) # len(G) == m for i in np.arange(0,m-3): # pick two nodes from active set and merge idx_vec = np.random.choice(active_set,2,replace=False) A[idx_vec[0],m+i]=1 A[m+i,idx_vec[0]]=1 A[idx_vec[1],m+i]=1 A[m+i,idx_vec[1]]=1 # merge two nodes in trees G.append(spectraltree.merge_children((G[idx_vec[0]], G[idx_vec[1]]), edge_length=1)) # update active set active_set = active_set [active_set != idx_vec[0]] active_set = active_set [active_set != idx_vec[1]] active_set = np.append(active_set,m+i) # update adjacency #A[active_set[0],active_set[1]]=1 #A[active_set[1],active_set[0]]=1 A[active_set[0],2*m-3]=1 A[2*m-3,active_set[0]]=1 A[active_set[1],2*m-3]=1 A[2*m-3,active_set[1]]=1 A[active_set[2],2*m-3]=1 A[2*m-3,active_set[2]]=1 return A,dendropy.Tree(taxon_namespace=taxa_metadata.taxon_namespace, seed_node=spectraltree.merge_children(tuple(G[i] for i in active_set)), is_rooted=False), taxa_metadata
def test_suppress_item_comments(self): tree1 = dendropy.Tree() a1 = tree1.seed_node.new_child() a2 = tree1.seed_node.new_child() tree1.comments.append("t1") for nd in tree1: nd.comments.append("n1") nd.edge.comments.append("e1") for suppress_item_comments in (True, False): kwargs = { "suppress_item_comments": suppress_item_comments, } s = self.write_out_validate_equal_and_return( tree1, "nexus", kwargs) tree2 = dendropy.Tree.get_from_string( s, "nexus", extract_comment_metadata=False) if suppress_item_comments: self.assertEqual(tree2.comments, []) for nd in tree2: self.assertEqual(nd.comments, []) self.assertEqual(nd.edge.comments, []) else: self.assertEqual(tree2.comments, ["t1"]) for nd in tree2: self.assertEqual(nd.comments, ["n1", "e1"])
def to_dendropy_tree(self, taxon_namespace=None, weighted=False): tree = dendropy.Tree(taxon_namespace=taxon_namespace) seed_node = self.roots()[0] if weighted: def edge_length(par, child): return np.abs(self.linkage_dist[par] - self.linkage_dist[child]) else: def edge_length(par, child): return 1.0 tree_dict = {seed_node: tree.seed_node} for clus in nx.topological_sort(self): for child in self.successors(clus): tree_dict[child] = tree_dict[clus].new_child( edge_length=edge_length(clus, child)) for clus in self.leaves(): tree_dict[clus].taxon = taxon_namespace.get_taxon(str(clus)) return tree
def bipartitionByEdge(tree, edge): newRoot = edge.head_node tail = edge.tail_node tail.remove_child(newRoot) newTree = dendropy.Tree(seed_node=newRoot, taxon_namespace=tree.taxon_namespace) newTree.childs = edge.childs tree.childs = tree.childs - newTree.childs curNode = tail while curNode is not None: curNode.edge.childs = curNode.edge.childs - edge.childs curNode = curNode.edge.tail_node newTree.collapse_basal_bifurcation() if tail == tree.seed_node: tree.collapse_basal_bifurcation() elif len(tail.child_nodes()) == 1: childs = tail.child_nodes() for child in childs: tail.remove_child(child) tail.parent_node.add_child(child) tail.parent_node.remove_child(tail) return tree, newTree
def pure_kingman_tree_shape(num_leaves, pop_size=1, rng=None): """ Like :func:`dendropy.model.pure_kingman_tree`, but does not assign taxa to tips. Parameters ---------- num_leaves : int Number of individuals/genes sampled. pop_size : numeric The size of the population from the which the coalescent process is sampled. Returns ------- t : |Tree| A tree sampled from the Kingman's neutral coalescent. """ if rng is None: rng = GLOBAL_RNG # use the global rng by default nodes = [dendropy.Node() for t in range(num_leaves)] seed_node = coalesce_nodes(nodes=nodes, pop_size=pop_size, period=None, rng=rng, use_expected_tmrca=False)[0] tree = dendropy.Tree(seed_node=seed_node) return tree
def get_log_likelihood(tree, cm): """ Given a dendropy CharacterMatrix `cm`, and a dendropy Tree `tree`, return the log likelihood. """ with TemporaryDirectory() as tmp_dir: with open(os.path.join(tmp_dir, CHARS_FN), 'w') as f: f.write(cm.as_string(schema='nexus')) with open(os.path.join(tmp_dir, INPUT_TREE_FN), 'w') as f: tree = dendropy.Tree(tree) tree.deroot() # starting trees must be unrooted f.write(tree.as_string(schema='nexus', suppress_taxa_blocks=True)) with open(os.path.join(tmp_dir, BATCH_FILE_FN), 'w') as f: f.write(LL_TEMPLATE % (CHARS_FN, INPUT_TREE_FN)) proc = subprocess.run([CMD, '-n', BATCH_FILE_FN], stderr=subprocess.PIPE, stdout=subprocess.PIPE, cwd=tmp_dir, check=True) _output = proc.stdout.decode() # get the value of the LL matches = re.findall(r'^-ln L +(\S*)\n', _output, flags=re.MULTILINE) if not len(matches) == 1: raise ValueError(_output) nll = float(matches[0].strip()) return -1 * nll
def _network2tree(branches, names): branches.sort(key=lambda x: x[2], reverse=True) branch = [] in_use = {branches[0][0]: 1} while len(branches): remain = [] for br in branches: if br[0] in in_use: branch.append(br) in_use[br[1]] = 1 elif br[1] in in_use: branch.append([br[1], br[0], br[2]]) in_use[br[0]] = 1 else: remain.append(br) branches = remain tre = dp.Tree() node = tre.seed_node node.taxon = tre.taxon_namespace.new_taxon(label=branch[0][0]) for src, tgt, dif in branch: node = tre.find_node_with_taxon_label(src) n = dp.Node(taxon=node.taxon) node.add_child(n) n.edge_length = 0.0 node.__dict__['taxon'] = None n = dp.Node(taxon=tre.taxon_namespace.new_taxon(label=tgt)) node.add_child(n) n.edge_length = dif for taxon in tre.taxon_namespace: taxon.label = names[taxon.label] return tre
def setUp(self): """ Sets up tree: ((((T1, ((T2, T3 )i5, T4 )i4 )i3, (T5, T6, T13 )i6 )i2, ((T7, (T8, T9 )i9 )i8, T10 )i7 )i1, T14, (T11, T12 )i10 )i0; """ self.tree = dendropy.Tree(oid='tree1') self.tree.seed_node.oid = 'i0' node_i1 = self.tree.seed_node.new_child(oid='i1') node_i2 = node_i1.new_child(oid='i2') node_i3 = node_i2.new_child(oid='i3') node_i3.new_child(oid='T1') node_i4 = node_i3.new_child(oid='i4') node_i5 = node_i4.new_child(oid='i5') node_i5.new_child(oid='T2') node_i5.new_child(oid='T3') node_i4.new_child(oid='T4') node_i6 = node_i2.new_child(oid='i6') node_i6.new_child(oid='T5') node_i6.new_child(oid='T6') node_i7 = node_i1.new_child(oid='i7') node_i8 = node_i7.new_child(oid='i8') node_i8.new_child(oid='T7') node_i9 = node_i8.new_child(oid='i9') node_i9.new_child(oid='T8') node_i9.new_child(oid='T9') node_i7.new_child(oid='T10') self.tree.seed_node.new_child(oid='T14') node_i10 = self.tree.seed_node.new_child(oid='i10') node_i10.new_child(oid='T11') node_i10.new_child(oid='T12') node_i6.new_child(oid='T13') self.tree.debug_check_tree(_LOG)
def remove_branch_lengths(str_newick_tree): tree = dendropy.Tree() tree.read_from_string(str_newick_tree, 'newick') for nd in tree: nd.label = None tree = tree.as_newick_string() return tree
def generate_yule_tree(num_tips): lamb = 1 names = [] #lamb = 1 #if there are N tips, there must be 2N-1 nodes for i in range(2 * num_tips - 1): if i < 10: names.append("s000" + str(i)) elif i < 100: names.append("s00" + str(i)) elif i < 1000: names.append("s0" + str(i)) else: names.append("s" + str(i)) taxon_namespace = dendropy.TaxonNamespace(names) tree = dendropy.Tree(taxon_namespace=taxon_namespace) time = 0 name_index = 0 current_nodes = [] tree.seed_node.taxon = taxon_namespace.get_taxon(names[name_index]) name_index = name_index + 1 #tree.seed_node.age=0 current_nodes.append(tree.seed_node) for i in range(num_tips): time_to_split = random.expovariate(lamb * len(current_nodes)) if i == 0: time = 0 else: time = time_to_split + time if i < num_tips - 1: splitting_index = random.randint(0, len(current_nodes) - 1) parent_node = current_nodes[splitting_index] node1 = dendropy.Node( taxon=taxon_namespace.get_taxon(names[name_index])) name_index = name_index + 1 node2 = dendropy.Node( taxon=taxon_namespace.get_taxon(names[name_index])) name_index = name_index + 1 parent_node.set_child_nodes([node1, node2]) parent_node.time = time # node1.edge_length = time-parent_node.age # node2.edge_length = time-parent_node.age current_nodes.pop(splitting_index) current_nodes.append(node1) current_nodes.append(node2) for node in current_nodes: node.time = time for node in tree.preorder_node_iter(): if node.time > 0: node.edge_length = node.time - node.parent_node.time return tree
def uniform_pure_birth_tree(birth_rate, rng=None): "Generates a uniform-rate pure-birth process tree. " if rng is None: rng = GLOBAL_RNG tree = dendropy.Tree() tree.seed_node.edge.length = 0.0 leaf_nodes = tree.leaf_nodes() total_length = 0.0 while total_length < 100.0: waiting_time = rng.expovariate(len(leaf_nodes) * birth_rate) for nd in leaf_nodes: nd.edge.length += waiting_time parent_node = rng.choice(leaf_nodes) c1 = parent_node.new_child() c2 = parent_node.new_child() c1.edge.length = 0.0 c2.edge.length = 0.0 total_length = c1.distance_from_root() leaf_nodes = tree.leaf_nodes() leaf_nodes = tree.leaf_nodes() waiting_time = rng.expovariate(len(leaf_nodes) * birth_rate) for nd in leaf_nodes: nd.edge.length += waiting_time tree.is_rooted = True return tree
def testTreeFromFileKeywordArgsDistinctTaxa(self): tree2 = dendropy.Tree(stream=StringIO(self.tree1_newick_str), schema="newick") self.assertDistinctButEqual(self.tree1, tree2, distinct_taxa=True, equal_oids=False)