def dot_alignment(sequences, seq_field=None, name_field=None, root=None, root_name=None,<EOL>cluster_threshold=<NUM_LIT>, as_fasta=False, just_alignment=False):
import abstar<EOL>from .cluster import cluster<EOL>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 all([root is None, root_name is None]):<EOL><INDENT>clusters = cluster(sequences, threshold=cluster_threshold, quiet=True)<EOL>clusters = sorted(clusters, key=lambda x: x.size, reverse=True)<EOL>centroid = clusters[<NUM_LIT:0>].centroid<EOL>root = abstar.run(('<STR_LIT>', centroid.sequence))<EOL>root.alignment_id = '<STR_LIT>'<EOL>root.alignment_sequence = root[seq_field]<EOL><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 root_name is not None:<EOL><INDENT>root.alignment_id = root_name<EOL><DEDENT>else:<EOL><INDENT>root_name = root.alignment_id<EOL><DEDENT>seqs = [(root.alignment_id, root.alignment_sequence)]<EOL>seqs += [(s.alignment_id, s.alignment_sequence) for s in sequences]<EOL>aln = muscle(seqs)<EOL>g_aln = [a for a in aln if a.id == root_name][<NUM_LIT:0>]<EOL>dots = [(root_name, str(g_aln.seq)), ]<EOL>for seq in [a for a in aln if a.id != root_name]:<EOL><INDENT>s_aln = '<STR_LIT>'<EOL>for g, q in zip(str(g_aln.seq), str(seq.seq)):<EOL><INDENT>if g == q == '<STR_LIT:->':<EOL><INDENT>s_aln += '<STR_LIT:->'<EOL><DEDENT>elif g == q:<EOL><INDENT>s_aln += '<STR_LIT:.>'<EOL><DEDENT>else:<EOL><INDENT>s_aln += q<EOL><DEDENT><DEDENT>dots.append((seq.id, s_aln))<EOL><DEDENT>if just_alignment:<EOL><INDENT>return [d[<NUM_LIT:1>] for d in dots]<EOL><DEDENT>name_len = max([len(d[<NUM_LIT:0>]) for d in dots]) + <NUM_LIT:2><EOL>dot_aln = []<EOL>for d in dots:<EOL><INDENT>if as_fasta:<EOL><INDENT>dot_aln.append('<STR_LIT>'.format(d[<NUM_LIT:0>], d[<NUM_LIT:1>]))<EOL><DEDENT>else:<EOL><INDENT>spaces = name_len - len(d[<NUM_LIT:0>])<EOL>dot_aln.append(d[<NUM_LIT:0>] + '<STR_LIT:U+0020>' * spaces + d[<NUM_LIT:1>])<EOL><DEDENT><DEDENT>return '<STR_LIT:\n>'.join(dot_aln)<EOL>
Creates a dot alignment (dots indicate identity, mismatches are represented by the mismatched
residue) for a list of sequences.

Args:

    sequence (list(Sequence)): A list of Sequence objects to be aligned.

    seq_field (str): Name of the sequence field key. Default is ``vdj_nt``.

    name_field (str): Name of the name field key. Default is ``seq_id``.

    root (str, Sequence): The sequence used to 'root' the alignment. This sequence will be at the
        top of the alignment and is the sequence against which dots (identity) will be evaluated.
        Can be provided either as a string corresponding to the name of one of the sequences in
        ``sequences`` or as a Sequence object. If not provided, ``sequences`` will be clustered
        at ``cluster_threshold`` and the centroid of the largest cluster will be used.

    root_name (str): Name of the root sequence. If not provided, the existing name of the root
        sequence (``name_field``) will be used. If ``root`` is not provided, the default ``root_name``
        is ``'centroid'``.

    cluster_threshold (float): Threshold with which to cluster sequences if ``root`` is not provided.
        Default is ``0.75``.

    as_fasta (bool): If ``True``, returns the dot alignment as a FASTA-formatted string, rather than
        a string formatted for human readability.

    just_alignment (bool): If ``True``, returns just the dot-aligned sequences as a list.

Returns:

    If ``just_alignment`` is ``True``, a list of dot-aligned sequences (without sequence names) will be returned.
    If ``as_fasta`` is ``True``, a string containing the dot-aligned sequences in FASTA format will be returned.
    Otherwise, a formatted string containing the aligned sequences (with sequence names) will be returned.