1# #START_LICENSE########################################################### 2# 3# 4# This file is part of the Environment for Tree Exploration program 5# (ETE). http://etetoolkit.org 6# 7# ETE is free software: you can redistribute it and/or modify it 8# under the terms of the GNU General Public License as published by 9# the Free Software Foundation, either version 3 of the License, or 10# (at your option) any later version. 11# 12# ETE is distributed in the hope that it will be useful, but WITHOUT 13# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15# License for more details. 16# 17# You should have received a copy of the GNU General Public License 18# along with ETE. If not, see <http://www.gnu.org/licenses/>. 19# 20# 21# ABOUT THE ETE PACKAGE 22# ===================== 23# 24# ETE is distributed under the GPL copyleft license (2008-2015). 25# 26# If you make use of ETE in published work, please cite: 27# 28# Jaime Huerta-Cepas, Joaquin Dopazo and Toni Gabaldon. 29# ETE: a python Environment for Tree Exploration. Jaime BMC 30# Bioinformatics 2010,:24doi:10.1186/1471-2105-11-24 31# 32# Note that extra references to the specific methods implemented in 33# the toolkit may be available in the documentation. 34# 35# More info at http://etetoolkit.org. Contact: huerta@embl.de 36# 37# 38# #END_LICENSE############################################################# 39""" 40This module implements the interoperability between Phylogeny and 41Clade attributes in the phyloXMl schema and the ETE Tree objects. 42 43The PhyloxmlTree class should be use as a substitute for base Clade 44and Phylogeny classes. 45 46""" 47from __future__ import absolute_import 48 49import sys 50from ._phyloxml import Clade, Phylogeny, Confidence, Tag_pattern_ 51from .. import PhyloTree 52 53class PhyloxmlTree(PhyloTree): 54 ''' PhyloTree object supporting phyloXML format. ''' 55 56 def __repr__(self): 57 return "PhyloXML ETE tree <%s>" %hex(hash(self)) 58 59 def _get_dist(self): 60 v = self.phyloxml_clade.get_branch_length_attr() 61 if v is None: 62 v = self.phyloxml_clade.get_branch_length() 63 if v is None: 64 self._set_dist(self._dist) 65 v = self.phyloxml_clade.get_branch_length_attr() 66 return float(v) 67 68 def _set_dist(self, value): 69 try: 70 self.phyloxml_clade.set_branch_length(float(value)) 71 self.phyloxml_clade.set_branch_length_attr(float(value)) 72 except ValueError: 73 raise 74 75 def _get_support(self): 76 if len(self.phyloxml_clade.confidence) == 0: 77 _c = Confidence(valueOf_=1.0, type_="branch_support") 78 self.phyloxml_clade.add_confidence(_c) 79 return float(self.phyloxml_clade.confidence[0].valueOf_) 80 81 def _set_support(self, value): 82 self._get_support() 83 self.phyloxml_clade.confidence[0].valueOf_ = float(value) 84 85 def _get_name(self): 86 return self.phyloxml_clade.get_name() 87 88 def _set_name(self, value): 89 try: 90 self.phyloxml_clade.set_name(value) 91 except ValueError: 92 raise 93 94 def _get_children(self): 95 return self.phyloxml_clade.clade 96 97 dist = property(fget=_get_dist, fset=_set_dist) 98 support = property(fget=_get_support, fset=_set_support) 99 children = property(fget=_get_children) 100 name = property(fget=_get_name, fset=_set_name) 101 102 def __init__(self, phyloxml_clade=None, phyloxml_phylogeny=None, **kargs): 103 if not phyloxml_phylogeny: 104 self.phyloxml_phylogeny = Phylogeny() 105 else: 106 self.phyloxml_phylogeny = phyloxml_phylogeny 107 if not phyloxml_clade: 108 self.phyloxml_clade = Clade() 109 self.phyloxml_clade.set_branch_length(0.0) 110 self.phyloxml_clade.set_name("NoName") 111 #self.__support = Confidence(valueOf_=1.0, type_="branch_support") 112 #self.phyloxml_clade.add_confidence(self.__support) 113 else: 114 self.phyloxml_clade = phyloxml_clade 115 super(PhyloxmlTree, self).__init__(**kargs) 116 117 def build(self, node): 118 nodetype = Tag_pattern_.match(node.tag).groups()[-1] 119 if nodetype == 'phylogeny': 120 self.phyloxml_phylogeny.buildAttributes(node, node.attrib, []) 121 elif nodetype == 'clade': 122 if "branch_length" in node.attrib: 123 node.attrib["branch_length_attr"] = node.attrib["branch_length"] 124 self.phyloxml_clade.buildAttributes(node, node.attrib, []) 125 for child in node: 126 nodeName_ = Tag_pattern_.match(child.tag).groups()[-1] 127 self.buildChildren(child, node, nodeName_, nodetype=nodetype) 128 129 def buildChildren(self, child_, node, nodeName_, fromsubclass=False, nodetype=None): 130 if nodetype == 'phylogeny': 131 baseclass = self.phyloxml_phylogeny 132 if nodeName_ == 'clade': 133 self.build(child_) 134 else: 135 baseclass.buildChildren(child_, node, nodeName_) 136 elif nodetype == 'clade': 137 baseclass = self.phyloxml_clade 138 if nodeName_ == 'clade': 139 new_node = self.add_child() 140 new_node.build(child_) 141 else: 142 baseclass.buildChildren(child_, node, nodeName_) 143 144 def export(self, outfile=sys.stdout, level=0, namespace_='phy:', name_='Phylogeny', namespacedef_=''): 145 if not self.up: 146 self.phyloxml_phylogeny.clade = self.phyloxml_clade 147 self.phyloxml_clade.clade = self.children 148 self.phyloxml_phylogeny.export(outfile=outfile, level=level, name_=name_, namespacedef_=namespacedef_) 149 else: 150 self.phyloxml_clade.clade = self.children 151 self.phyloxml_clade.export(outfile=outfile, level=level, name_=name_, namespacedef_=namespacedef_) 152 153