def phylogeny(sequences=None, project_dir=None, name=None, aln_file=None, tree_file=None,<EOL>seq_field=None, name_field=None, aa=False, species='<STR_LIT>', unrooted=False, ladderize=True,<EOL>root=None, root_name=None, show_root_name=False, color_dict=None, color_function=None,<EOL>order_dict=None, order_function=None, color_node_labels=False, label_colors=None,<EOL>scale=None, branch_vert_margin=None, fontsize=<NUM_LIT:12>, show_names=True, show_scale=False,<EOL>mirror=False, min_order_fraction=<NUM_LIT:0.1>, figname_prefix=None, figname_suffix=None,<EOL>compact_alignment=False, scale_factor=<NUM_LIT:1>, rename_function=None, linewidth=<NUM_LIT:1.0>,<EOL>delete_nodes=None, quiet=True):
if project_dir is None:<EOL><INDENT>print('<STR_LIT>')<EOL>sys.exit(<NUM_LIT:1>)<EOL><DEDENT>else:<EOL><INDENT>project_dir = os.path.abspath(project_dir)<EOL><DEDENT>if name is None:<EOL><INDENT>name = '<STR_LIT>'.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(<NUM_LIT:8>))<EOL><DEDENT>if sequences is not None and all([arg is None for arg in [aln_file, tree_file]]):<EOL><INDENT>sequences = deepcopy(sequences)<EOL>root = copy(root)<EOL>if seq_field is not None:<EOL><INDENT>if not all([seq_field in list(s.annotations.keys()) for s in sequences]):<EOL><INDENT>print('<STR_LIT>'.format(seq_field))<EOL>sys.exit(<NUM_LIT:1>)<EOL><DEDENT>for s in sequences:<EOL><INDENT>s.alignment_sequence = s[seq_field]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>for s in sequences:<EOL><INDENT>s.alignment_sequence = s.sequence<EOL><DEDENT><DEDENT>if name_field is not None:<EOL><INDENT>if not all([name_field in list(s.annotations.keys()) for s in sequences]):<EOL><INDENT>print('<STR_LIT>'.format(name_field))<EOL>sys.exit(<NUM_LIT:1>)<EOL><DEDENT>for s in sequences:<EOL><INDENT>s.alignment_id = s[name_field]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>for s in sequences:<EOL><INDENT>s.alignment_id = s.id<EOL><DEDENT><DEDENT>if unrooted:<EOL><INDENT>root = None<EOL>root_name = None<EOL><DEDENT>elif root is None:<EOL><INDENT>if not quiet:<EOL><INDENT>print('<STR_LIT>')<EOL><DEDENT>if not all(['<STR_LIT>' in list(s.annotations.keys()) for s in sequences]):<EOL><INDENT>print('<STR_LIT>')<EOL>sequences = abstar.run(*[(s.id, s.sequence) for s in sequences])<EOL>print('<STR_LIT>')<EOL><DEDENT>if not all(['<STR_LIT>' in list(s['<STR_LIT>'].keys()) for s in sequences]):<EOL><INDENT>print('<STR_LIT>')<EOL>sequences = abstar.run(*[(s.id, s.sequence) for s in sequences])<EOL>print('<STR_LIT>')<EOL><DEDENT>top_vgene = sorted(list(Counter([s['<STR_LIT>']['<STR_LIT>'] for s in sequences]).items()),<EOL>key=lambda x: x[<NUM_LIT:1>],<EOL>reverse=True)[<NUM_LIT:0>][<NUM_LIT:0>]<EOL>vgene = get_imgt_germlines(species, '<STR_LIT>', gene=top_vgene)<EOL>if aa:<EOL><INDENT>root = Sequence(vgene.ungapped_aa_sequence, id=top_vgene)<EOL><DEDENT>else:<EOL><INDENT>root = Sequence(vgene.ungapped_nt_sequence, id=top_vgene)<EOL><DEDENT>root.alignment_id = root.id<EOL>root.alignment_sequence = root.sequence<EOL>if not quiet:<EOL><INDENT>print('<STR_LIT>'.format(root.alignment_id))<EOL>print(root.alignment_sequence)<EOL><DEDENT><DEDENT>elif type(root) in STR_TYPES:<EOL><INDENT>root = [s for s in sequences if s.alignment_id == root][<NUM_LIT:0>]<EOL>if not root:<EOL><INDENT>print('<STR_LIT>'.format(root))<EOL>print('<STR_LIT:\n>')<EOL>sys.exit(<NUM_LIT:1>)<EOL><DEDENT>sequences = [s for s in sequences if s.alignment_id != root.alignment_id]<EOL><DEDENT>elif type(root) == Sequence:<EOL><INDENT>if seq_field is not None:<EOL><INDENT>if seq_field not in list(root.anotations.keys()):<EOL><INDENT>print('<STR_LIT>'.format(seq_field))<EOL>sys.exit(<NUM_LIT:1>)<EOL><DEDENT>root.alignment_sequence = root[seq_field]<EOL><DEDENT>if name_field is not None:<EOL><INDENT>if name_field not in list(root.anotations.keys()):<EOL><INDENT>print('<STR_LIT>'.format(name_field))<EOL>sys.exit(<NUM_LIT:1>)<EOL><DEDENT>root.alignment_id = root[name_field]<EOL><DEDENT>sequences = [s for s in sequences if s.alignment_id != root.alignment_id]<EOL><DEDENT>else:<EOL><INDENT>print('<STR_LIT>')<EOL>print('<STR_LIT:\n>')<EOL>sys.exit(<NUM_LIT:1>)<EOL><DEDENT>if not unrooted:<EOL><INDENT>if root_name is not None:<EOL><INDENT>root.alignment_id = root_name<EOL><DEDENT>else:<EOL><INDENT>root_name = root.alignment_id<EOL><DEDENT>sequences.append(root)<EOL><DEDENT><DEDENT>elif aln_file is not None:<EOL><INDENT>if not unrooted and type(root) not in STR_TYPES:<EOL><INDENT>print('<STR_LIT>')<EOL>print('<STR_LIT:\n>')<EOL>sys.exit(<NUM_LIT:1>)<EOL><DEDENT>_sequences = []<EOL>_root = None<EOL>for rec in AlignIO.read(open(aln_file), '<STR_LIT>'):<EOL><INDENT>s = str(rec.seq).replace('<STR_LIT:->', '<STR_LIT>')<EOL>if rec.id == root:<EOL><INDENT>_root = Sequence(s, rec.id)<EOL>_root.alignment_id = _root.id<EOL><DEDENT>else:<EOL><INDENT>_s = Sequence(s, id=rec.id)<EOL>_s.alignment_id = rec.id<EOL>_sequences.append(_s)<EOL><DEDENT><DEDENT>if sequences is None:<EOL><INDENT>sequences = _sequences<EOL><DEDENT>else:<EOL><INDENT>sequence_ids = [s.id for s in sequences]<EOL>if any([_s.alignment_id not in sequence_ids for _s in _sequences]):<EOL><INDENT>print('<STR_LIT>')<EOL><DEDENT>for s in sequences:<EOL><INDENT>s.alignment_id = s.id<EOL>s.alignment_sequence = s.sequence<EOL><DEDENT><DEDENT>if unrooted:<EOL><INDENT>root = None<EOL>root_name = None<EOL><DEDENT>else:<EOL><INDENT>if _root is None:<EOL><INDENT>print('<STR_LIT>'.format(root))<EOL>print('<STR_LIT:\n>')<EOL>sys.exit(<NUM_LIT:1>)<EOL><DEDENT>root = _root<EOL>if root_name is not None:<EOL><INDENT>root.alignment_id = root_name<EOL><DEDENT>else:<EOL><INDENT>root_name = root.alignment_id<EOL><DEDENT>sequences = [s for s in sequences if all([s.alignment_id != name for name in [root.id, root.alignment_id]])]<EOL>sequences.append(root)<EOL><DEDENT><DEDENT>elif tree_file is not None:<EOL><INDENT>if not unrooted and type(root) not in STR_TYPES:<EOL><INDENT>print('<STR_LIT>')<EOL>print('<STR_LIT:\n>')<EOL>sys.exit(<NUM_LIT:1>)<EOL><DEDENT>_sequences = []<EOL>_root = None<EOL>tree = Phylo.read(open(tree_file), '<STR_LIT>')<EOL>for leaf in tree.get_terminals():<EOL><INDENT>s = '<STR_LIT>'<EOL>if leaf.name == root:<EOL><INDENT>_root = Sequence(s, leaf.name)<EOL>_root.alignment_id = _root.id<EOL><DEDENT>else:<EOL><INDENT>_s = Sequence(s, id=leaf.name)<EOL>_s.alignment_id = leaf.name<EOL>_sequences.append(_s)<EOL><DEDENT><DEDENT>if sequences is None:<EOL><INDENT>sequences = _sequences<EOL><DEDENT>else:<EOL><INDENT>sequence_ids = [s.id for s in sequences]<EOL>if any([_s.alignment_id not in sequence_ids for _s in _sequences]):<EOL><INDENT>print('<STR_LIT>')<EOL><DEDENT>for s in sequences:<EOL><INDENT>s.alignment_id = s.id<EOL>s.alignment_sequence = s.sequence<EOL><DEDENT><DEDENT>if unrooted:<EOL><INDENT>root = None<EOL>root_name = None<EOL><DEDENT>elif _root is None:<EOL><INDENT>print('<STR_LIT>'.format(root))<EOL>print('<STR_LIT:\n>')<EOL>sys.exit(<NUM_LIT:1>)<EOL><DEDENT>else:<EOL><INDENT>root = _root<EOL>if root_name is not None:<EOL><INDENT>root.alignment_id = root_name<EOL><DEDENT>else:<EOL><INDENT>root_name = root.alignment_id<EOL><DEDENT>sequences = [s for s in sequences if all([s.alignment_id != name for name in [root.id, root.alignment_id]])]<EOL>sequences.append(root)<EOL><DEDENT><DEDENT>if order_dict is None:<EOL><INDENT>if order_function is not None:<EOL><INDENT>order_dict = {seq.alignment_id: order_function(seq) for seq in sequences}<EOL><DEDENT><DEDENT>if color_dict is None:<EOL><INDENT>if color_function is not None:<EOL><INDENT>color_dict = {seq.alignment_id: color_function(seq) for seq in sequences}<EOL><DEDENT><DEDENT>if color_dict is None:<EOL><INDENT>color_dict = {}<EOL><DEDENT>if all([aln_file is None, tree_file is None]):<EOL><INDENT>aln_file = os.path.abspath(os.path.join(project_dir, '<STR_LIT>'.format(name)))<EOL>do_print = False if quiet else True<EOL>if do_print:<EOL><INDENT>print('<STR_LIT:\n>')<EOL><DEDENT>seqs = [(s.alignment_id, s.alignment_sequence) for s in sequences]<EOL>mafft(seqs, aln_file, as_file=True, print_stdout=do_print, print_stderr=do_print)<EOL><DEDENT>if tree_file is None:<EOL><INDENT>tree_file = os.path.abspath(os.path.join(project_dir, '<STR_LIT>'.format(name)))<EOL>fasttree(aln_file, tree_file, is_aa=aa, quiet=quiet)<EOL><DEDENT>prefix = '<STR_LIT>' if figname_prefix is None else figname_prefix<EOL>suffix = '<STR_LIT>' if figname_suffix is None else figname_suffix<EOL>fig_file = os.path.join(project_dir, '<STR_LIT>'.format(prefix, name, suffix))<EOL>_make_tree_figure(tree_file,<EOL>fig_file,<EOL>color_dict,<EOL>order_dict,<EOL>None if root is None else root.alignment_id,<EOL>rename_function=rename_function,<EOL>show_names=show_names,<EOL>name_field=name_field,<EOL>branch_vert_margin=branch_vert_margin,<EOL>scale=scale,<EOL>color_node_labels=color_node_labels,<EOL>label_colors=label_colors,<EOL>show_root_name=show_root_name,<EOL>tree_orientation=<NUM_LIT:1> if mirror else <NUM_LIT:0>,<EOL>fontsize=fontsize,<EOL>min_order_fraction=min_order_fraction,<EOL>show_scale=show_scale,<EOL>compact_alignment=compact_alignment,<EOL>scale_factor=scale_factor,<EOL>linewidth=linewidth,<EOL>ladderize=ladderize,<EOL>delete_nodes=delete_nodes)<EOL>
Generates a lineage phylogeny figure.

Args:

    sequences (list(Sequence)): A list of ``Sequence`` objects from which a phylogeny
        will be calculated. Strictly speaking, they do not need to be ``Sequence`` objects,
        rather, any object that contains the sequence name as the ``id`` attribute (or
        by dictionary-style lookup using the provided ``name_field``) and contains the
        sequence as the ``sequence`` attribute (or by dictionary-stype lookup using the
        provided ``seq_field``).

    project_dir (str): directory into which all phylogeny files will be deposited,
        including alignment, tree and figure files.

    name (str): Name to be used for naming alignment, tree, and phylogeny files. If not
        provided, a random name will be generated.

    aln_file (str): if a multiple sequence alignment has already been calculated,
        passing the path to the alignment file (in FASTA format) will force Lineage.phylogeny()
        to use the supplied msa instead of computing a new one.

    tree_file (str): if a tree file has already been calculated, passing the path
        to the pre-computed tree file will force ``phylogeny()`` to use
        the supplied tree file instead of computing a new one. It is important to note that
        only sequence names will be parsed from the tree_file, so if ``order_function`` or
        ``color_function`` is also provided, ensure that these functions only require the
        sequence ID rather than the entire sequence.

    aa (bool): if True, use amino acid sequences to compute the phylogeny.
        Default is False.

    root (Sequence, str: The root can be provided either as a ``Sequence`` object (if ``sequences``
        are being provided) or as the name of a sequence that can be found either in
        ``sequences`` or in the provided ``aln_file`` or ``tree_file``. Note that if
        either ``aln_file`` or ``tree_file`` are provided, the root must be provided
        as the sequence name, not as a ``Sequence`` object (as the root sequence must
        already be included in either ``aln_file`` or ``tree_file``. If the root is not
        provided, the germline V-gene sequence of the

    color_dict (dict): Dictionary with sequence IDs as keys and colors (hex format) as values. If any
        sequence IDs are not found in the dict, they will be colored black. If neither ``color_dict`` nor
        ``color_function`` is provided, all leaves will be colored black.

    color_function (func): Function that that accepts a ``Sequence`` object and returns the color
        (as a hex code). If ``color_dict`` is also provided, ``color_function`` is ignored. Additionally,
        ``color_function`` will only be used if ``sequences`` are provided. If ``sequences`` are not provided
        (instead using ``aln_file` or ``tree_file``), ``color_dict`` must be used instead of ``color_function``.

    orders: a dictionary with sequence IDs as keys and orders (integers) as values.
        If not provided, only the leaf branches will be colored (if <colors> or
        <color_function> is provided).

    chain: build a phylogeny using the given chain ('heavy' or 'light').
        Default is 'heavy'.

    filter_function: function used to filter sequences (identity-based clustering, for
        example). The function should accept a list of Sequence objects and return
        a list of Sequence objects.

    just_pairs: if True, compute the phylogeny using only paired sequences.
        Default (False) will use all sequences of the appropriate chain, paired or not.

    scale (float): passed to ete3.TreeStyle() to set the scale of the tree figure. Increased
        scale results in a wider tree.

    branch_vert_margin (int): passed to ete3.TreeStyle() to set the branch_vertical_margin of
        the tree figure. Increased branch_vert_margin results in a taller tree.

    fontsize: size of the leaf labels. Default is 12.

    show_names: show names of leaf nodes. Options are True (show labels for all leaf nodes),
        False (don't show labels for any leaf nodes) or a list of sequence IDs for which
        labels should be shown. Default is True.

    mirror: flip the orientation of the tree. Default is to draw the tree from left to right.
        Setting mirror to True results in the tree being drawn from right to left.

    min_order_fraction: minimum fraction of downstream leaves requried to color a branch.
        When coloring non-leaf nodes, the earliest 'order' with at least <min_order_fraction>
        leaf nodes is used. Default is 0.1 (which corresponds to 10%).

    figname_prefix: by default, figures will be named <lineage_id>.pdf. If prefix='prefix_' and
        the lineage ID is 'ABC123', the figure file will be named 'prefix_ABC123.pdf'.

    figname_suffix: by default, figures will be named <lineage_id>.pdf. If suffix='_suffix' and
        the lineage ID is 'ABC123', the figure file will be named 'ABC123_suffix.pdf'.