def add_boolean(self, node, trait, boolean_trait_name, regex): if node.annotations.get_value(trait) is not None: if regex.match(str(node.annotations.get_value(trait))): safeNodeAnnotator.annotate(node, boolean_trait_name, True) else: safeNodeAnnotator.annotate(node, boolean_trait_name, False)
def annotate_tips(self, annotations): for node in self.tree.leaf_node_iter(): for ak, av in annotations.get(node.taxon.label, {}).items(): if av and (type(av) is str and len(av) > 0) or type(av) is not str: safeNodeAnnotator.annotate(node, ak, check_str_for_bool(av))
def reconstruct_ancestors(self, node, parent_states, acctran, name, maxtran_value=None): node_states = node.annotations.get_value(name) if isinstance( node.annotations.get_value(name), list) else [node.annotations.get_value(name)] children_at_maxtran_value = 0 if maxtran_value is not None and node.num_child_nodes() > 2: for child in node.child_node_iter(): if child.annotations.get_value(name) == maxtran_value: children_at_maxtran_value += 1 if node.is_leaf() and len( node_states) == 1 and node_states[0] is not None: assigned_states = node_states elif children_at_maxtran_value > 1: assigned_states = [maxtran_value] else: assigned_states = list( set(node_states).intersection(parent_states) ) if len( set(node_states).intersection(parent_states)) > 0 else list( set(node_states).union(parent_states)) if len(assigned_states) > 1: if acctran: assigned_states = [ state for state in assigned_states if state not in parent_states ] else: # can we delay child_states = [] for child in node.child_node_iter(): child_states += child.annotations.get_value( name) if isinstance( child.annotations.get_value(name), list) else [child.annotations.get_value(name)] assigned_states = [ state for state in assigned_states if state in parent_states and state in child_states ] if len( set(parent_states).intersection(child_states)) > 0 else [ state for state in assigned_states if state in child_states ] safeNodeAnnotator.annotate( node, name, assigned_states[0] if len(assigned_states) == 1 else assigned_states) for child in node.child_node_iter(): self.reconstruct_ancestors(child, assigned_states, acctran, name, maxtran_value)
def action(n): """ partially loading this action with the trait_name and value to add to each node this will be called below on each node if it passes the predicate. :param n: :return: """ if n.is_leaf(): safeNodeAnnotator.annotate(n, trait_name, value)
def phylotype_nodes(self, node, phylotype): safeNodeAnnotator.annotate(node, "phylotype", "\"" + phylotype + "\"") i = 1 for child in node.child_node_iter(): suffix = "" if child.taxon is None: if child.edge.length > self.threshold: suffix = "." + str(i) i += 1 self.phylotype_nodes(child, phylotype + suffix)
def annotate_node(self, tip_label, annotations): node = self.tree.find_node_with_taxon( lambda taxon: True if self.taxon_parser(taxon.label) == tip_label else False) if node is None: warnings.warn("Taxon: %s not found in tree" % tip_label, UserWarning) else: for a in annotations: if annotations[a] and (type(annotations[a]) is str and len(annotations[a]) > 0) or type( annotations[a]) is not str: safeNodeAnnotator.annotate( node, a, check_str_for_bool(annotations[a]))
def annotate_mrca(self, trait_name, value): taxon_set = [ tip.taxon for tip in self.tree.leaf_node_iter( lambda node: node.annotations.get_value(trait_name) == value) ] mrca = self.tree.mrca(taxa=taxon_set) current_annotation = mrca.annotations.get_value("%s-mrca" % trait_name) if current_annotation is not None: print("common mrca concatenating %s and %s" % (current_annotation, value)) safeNodeAnnotator.annotate(mrca, "%s-mrca" % trait_name, current_annotation + "-" + value) else: safeNodeAnnotator.annotate(mrca, "%s-mrca" % trait_name, value) return mrca
def fitch_parsimony(self, node, name, polytomy_behavior=None): if len(node.child_nodes()) == 0: tip_annotation = node.annotations.get_value( name) if node.annotations.get_value(name) is not None else [] return tip_annotation if isinstance(tip_annotation, list) else [tip_annotation] union = set() intersection = set() all_states = [] i = 0 for child in node.child_node_iter(): child_states = self.fitch_parsimony(child, name) union = union.union(child_states) intersection = set( child_states) if i == 0 else intersection.intersection( child_states) all_states.extend(child_states) i += 1 value = list(intersection) if len(intersection) > 0 else list(union) if self.majority_rule and len(intersection) == 0: if node.num_child_nodes() > 2: unique_states = list(union) state_counts = [0 for state in unique_states] for child_state in all_states: state_counts[unique_states.index(child_state)] += 1 cutoff = node.num_child_nodes() / 2 majority = [ state for state in unique_states if state_counts[unique_states.index(state)] > cutoff ] value = majority if len(majority) > 0 else value safeNodeAnnotator.annotate(node, "children_" + name, unique_states) safeNodeAnnotator.annotate(node, "children_" + name + "_counts", state_counts) elif self.polytomy_tie_breaker is not None and len( intersection) == 0 and node.num_child_nodes() > 2: # print("polytomy states :") # print(list(union)) if any( [state in self.polytomy_tie_breaker for state in list(union)]): sorted_states = sorted( list(union), key=lambda state: self.polytomy_tie_breaker.index(state) if state in self.polytomy_tie_breaker else math.inf) # print("sorted States: ") # print(sorted_states) value = [sorted_states[0]] # highest rated state in union safeNodeAnnotator.annotate(node, name, value[0] if len(value) == 1 else value) return value
def annotate_nodes(self, tree, trait_name, trait_value): for node in tree.postorder_node_iter(): safeNodeAnnotator.annotate(node, trait_name, trait_value)