Migrating from ETE 3 ==================== ETE v4 introduces many changes with respect to v3, including some function names and arguments. General considerations ---------------------- In ETE 3 there are two classes that are identical, ``TreeNode`` and ``Tree`` (since a node is a tree in itself). In ete4 there is only the ``Tree`` class. In ETE 3, a node has necessarily a name, a distance and support (which default to ``''``, 0, and 1 respectively). In ETE 4 they don't have to have them. If you request them (``node.name``, ``node.dist``, ``node.support``) for a node that doesn't have them, ETE 4 returns ``None``. A node contains all its properties in a dictionary called ``props``. In particular, reading special properties like ``name`` (which can be done with ``node.name``) is equivalent to ``node.props.get('name')``. Changes in syntax ----------------- This is a summary of the main changes to consider when adapting a program using ETE 3 to ETE 4: +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ETE 3 | ETE 4 | Notes | +=============================================================================================================+==============================================================================================================================+==================================================================================================================================================================================================+ | ``t & 'A'`` | ``t['A']`` | You can refer to a node by its name, or by a tuple that identifies its position as in ``t[0,1,0]`` for the node that comes from the root's 1st child, then its 2nd child, and then its 1st child | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``t.get_tree_root()`` | ``t.root`` | | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``t.is_root()`` | ``t.is_root`` | | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``t.is_leaf()`` | ``t.is_leaf`` | | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``Tree(filename)`` | ``Tree(open(filename))`` | The ``Tree`` constructor now interprets *strings* as newicks (no double-guessing), and *file objects* as files containing newicks | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``Tree(name='Hi', dist=1, support=1)`` | ``Tree({'name': 'Hi', 'dist': 1, 'support': 1})`` | The constructor now admits arbitrary properties for the node, in the form of a dict | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``Tree(nw, format=1)`` | ``Tree(nw, parser=1)`` | Since ``format`` is a reserved word in Python 3, we use ``parser`` instead to identify which parser to use when reading a newick | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``t.get_leaves()``, ``t.iter_leaves()`` | ``t.leaves()`` | All such functions now return iterators (similar to Python's ``range()``), which can be converted to lists with ``list(...)`` | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``t.get_ancestors()`` | ``t.ancestors()`` | | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``t.get_edges()``, ``t.iter_edges()`` | ``t.edges()`` | | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``t.get_leaf_names()`` | ``t.leaf_names()`` | | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``t.get_descendants()``, ``t.iter_descendants()`` | ``t.descendants()`` | | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``t.get_leaves_by_name()`` | ``t.search_leaves_by_name()`` | | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``t.get_ascii()`` | ``t.to_str()`` | It can now fine-tune the representation with different arguments (and produces a nicer / more modern text output) | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``t.convert_to_ultrametric()`` | ``t.to_ultrametric()`` | Also, new implementation that keeps the relative sizes of branches closer to the original tree | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``topology_only=...`` | ``topological=...`` | Argument used in several functions (``to_ultrametric()``, ``ladderize()``, ``get_distance()``, ``get_farthest_leaf()``, etc., which was inconsistently used in ete3) | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``feature(s)=...``, ``attribute(s)=...``, ``property(ies)=...`` | ``prop(s)=...`` | Arguments used in several functions (they all refer to the same thing, arbitrary properties attached to a node, which are elements of its ``node.props`` dictionary | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``attr=...``, ``target_attr=...`` | ``prop=...`` | Argument used in ``get_topology_id()``, ``is_monophiletic()`` and others | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``popup_prop_keys=...`` | ``show_popup_props=...``, ``hide_popup_props=...`` | Argument in ``explore()`` and others | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``t.get_common_ancestor(n1, n2, n3)`` | ``t.common_ancestor(n1, n2, n3)`` | Shorter name, and can instead accept a list of nodes too | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``A.get_distance(B)`` | ``t.get_distance(A, B)`` | | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``t.swap_children()`` | ``t.reverse_children()``, ``t.swap_children()`` | ``t.swap_children()`` now only works for 2 children, otherwise it is unclear what "swapping" means | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``t.populate(size, names_library, random_branches, dist_range, support_range)`` | ``t.populate(size, names, model, dist_fn, support_fn)`` | The tree can be randomly generated according to different models (yule or uniform), and accept arbitrary functions to randomly generate distances and supports | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``nw = t.write(format=f, dist_formatter="%0.1f", name_formatter="TEST-%s", support_formatter="SUP-%0.1f")`` | ``parser = newick.make_parser(f, dist='%0.1f', name='TEST-%s', support='SUP-%0.1f')``
``nw = t.write(parser=parser)`` | ete4 parsers are more general, and we can create customized simple ones using ``newick.make_parser()`` | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``t.write(props=[], format=1)`` | ``t.write(props=None, parser=1)`` | ``props=None`` (the default) means *write all the extended properties*, otherwise it is a list of the properties to write (so, none if it is an empty list like ``props=[]``) | +-------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ New syntax ---------- New in ETE 4: +--------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------+ | ETE 4 | Notes | +================================+=======================================================================================================================================================+ | ``Tree(nw, parser='support')`` | In addition to numbers, some parsers have easy to remember aliases (in this case, interpret field in internal nodes as support, same as ``parser=0``) | +--------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``node.id`` | Tuple like ``(0, 1, 0)`` | +--------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------+ | ``node.level`` | Number of nodes between node and root | +--------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------+ Changes in the ete4 tool ------------------------ When using ``ete4 explore -t [...]``: - Instead of ``~=`` we use ``=~`` - Instead of ``<-`` we use ``<=``