skbio.alignment.multi_align#
- skbio.alignment.multi_align(sequences, /, sub_score=(1.0, -1.0), gap_cost=2.0, free_ends=True, guide_tree=None, ids=None, atol=1e-05, keep_tree=False, keep_distmat=False)[source]#
Perform progressive alignment of multiple sequences.
Added in version 0.7.4.
- Parameters:
- sequencesiterable of sequence-like
Sequences to be aligned. Supports
Sequence, strings, or sequence of strings or numbers. Sequences must be non-empty and ungapped. At least two sequences must be provided.- sub_scoretuple of (float, float), SubstitutionMatrix, or str, optional
Score of a substitution. May be two numbers (match, mismatch), a substitution matrix, or its name. See
pair_alignfor details. Default is (1.0, -1.0).- gap_costfloat or tuple of (float, float), optional
Penalty of a gap. May be one (linear) or two numbers (affine). See
pair_alignfor details. Default is 2.0.- free_endsbool, optional
If True (default), gaps at the sequence terminals are free from penalization.
- guide_treeTreeNode, optional
A guide tree determining the merging order of sequences. Must be strictly bifurcating. Tip names must match sequence IDs. If not provided, the function will align all sequence pairs, calculate score-based distances, and compute a guide tree using UPGMA. A provided guide tree will skip these procedures.
- idsiterable of str, optional
Unique identifiers in input order to match tips in the provided guide tree. tree. If not provided, the function will use sequence metadata
'id'if present in every sequence and unique, or use['0', '1', ...]if none is present.- atolfloat, optional
Absolute tolerance in comparing scores of alternative alignment paths. See
pair_alignfor details. Default is 1e-5.- keep_treebool, optional
If True, include the guide tree in the returned object. Default is False.
- keep_distmatbool, optional
If True, and if the guide tree is not provided, include the constructed distance matrix in the returned object. Default is False.
- Returns:
- pathAlignPath
One alignment path in original input sequence order, starting at position zero and consuming every sequence in full.
- treeTreeNode or None
Constructed or provided guide tree determining the merging order of sequences (if
keep_treeis True).- distmatDistanceMatrix or None
Distance matrix constructed based on pairwise alignment scores and used to compute the guide tree (if
keep_distmatis True).
- Raises:
- ValueError
If inputs are empty or gapped, scores or costs are invalid, identifiers do not match, or a guide tree is not binary with exactly the required tips.
- TypeError
If
free_endsis not Boolean orguide_treeis not a TreeNode.
See also
Notes
This function implements the classic progressive alignment method for multiple sequence alignment, originally introduced in [1], with later improvements described in [2] and [3]. Compared with the historical method, this implementation represents a refined form of progressive alignment commonly described in educational materials. Specifically, the algorithm consists of the following steps, described in reverse order:
An alignment of all sequences is constructed by iteratively merging sub-alignments containing one or more sequences. This function adopts the profile alignment approach [3], which aligns two sub-alignments (“profiles”) using the same dynamic programming (DP) algorithm used for pairwise sequence alignment (see
pair_align). The score \(S\) for two matching columns is calculated as the average substitution score \(s\) across all pairs of characters from the two profiles:\[S = \frac{1}{mn}\sum_{x\in A}\sum_{y\in B}s(x,y)\]where \(x\) and \(y\) are characters in the two columns of profiles \(A\) and \(B\), which contain \(m\) and \(n\) rows (sequences), respectively.
Under the “once a gap, always a gap” rule [1], existing gaps within each profile are treated as neutral characters and assigned a substitution score of 0 with any character. Gap penalties are calculated only for gaps introduced during the DP alignment.
The order of merging is determined by a guide tree. The program traverses the tree in postorder and merges the two child sub-alignments at each internal node. If the guide tree is not explicitly supplied, the program computes one using the UPGMA method (see
upgma) from a distance matrix containing all pairwise sequence distances. Each distance is calculated by aligning the two sequences \(a\) and \(b\) using DP (seepair_align) and normalizing the alignment score \(S_{a,b}\) as follows [1]:\[D = -\ln S_{\mathrm{eff}} = -\ln\left(\frac{S_{a,b} - S_{\mathrm{rand}}} {S_{\mathrm{iden}} - S_{\mathrm{rand}}}\right)\]where \(S_{\mathrm{iden}} = (S_{a,a} + S_{b,b})/2\) is the average score of the two sequences aligned to themselves. \(S_{\mathrm{rand}}\) is the random score, calculated as [2]:
\[S_{\mathrm{rand}} = \frac{1}{L}\sum_{x\in a}\sum_{y\in b}s(x,y)N_a(x)N_b(y) - G\]where \(L\) is the length of the alignment, \(G\) is the total gap penalty, and \(N\) is the number of occurrences of a character in the corresponding source sequence.
There are two notes regarding this calculation. First, a factor of 100 is omitted from the effective score \(S_{\mathrm{eff}}\) compared with the original work. Second, to guard against edge cases that would produce undefined, infinite, or negative distances (e.g., when aligning two homopolymers), \(S_{\mathrm{eff}}\) is clipped to the range [1e-6, 1] in this implementation.
Solution quality
The sum-of-pairs (SP) score is the optimality criterion for multiple sequence alignment. This metric can be calculated by applying the
align_scorefunction to the resulting alignment. It should be noted that progressive alignment is a heuristic algorithm and the resulting alignment is not guaranteed to be optimal.Computational efficiency
The algorithm is dominated by the all-vs-all pairwise alignment step, which takes O(n2 L2) time for n sequences of comparable length L. Peak memory usage is O(n2 + L2) for storing the distance matrix and each DP matrix (the algorithm reuses memory for DP matrices). When a guide tree is supplied, time reduces to O(nL2 + n2 L), and memory to O(L2 + nL).
Terminal gap policy
The function defaults to
free_ends=Truewhich prevents terminal gaps from being penalized. This setting is broadly applicable to homologous sequences with incomplete coverage, different domain boundaries, or terminal extensions. However, it can favor short overlaps between weakly related sequences. When sequences are expected to span the same homologous region with defined boundaries (e.g., the coding sequence of a gene), settingfree_ends=Falseis often preferable.References
[1] (1,2,3)Feng, D. F., & Doolittle, R. F. (1987). Progressive sequence alignment as a prerequisite to correct phylogenetic trees. Journal of Molecular Evolution, 25(4), 351-360.
Examples
>>> from skbio.alignment import multi_align, align_score
Align three DNA sequences using default parameters.
>>> from skbio.sequence import DNA >>> seqs = [DNA('CATTAACGT'), ... DNA('CGTTACGGT'), ... DNA('AGTTAACGG')] >>> path = multi_align(seqs).path >>> path <AlignPath, sequences: 3, positions: 11, segments: 7>
Print the aligned sequences.
>>> for seq in path.to_aligned(seqs): ... print(seq) CA-TTAACGT- -CGTTA-CGGT -AGTTAACGG-
The quality of the alignment can be evaluated using the align_score function, which calculates the sum-of-pairs (SP) score. It has the same default parameter settings as multi_align does.
>>> from skbio.alignment import align_score >>> align_score((path, seqs)) 7.0
Under the hood, the function performs pairwise alignments, calculates a distance matrix, then infers a guide tree which determines the merging order. The tree and distance matrix can be retained for diagnostic and educational purposes.
>>> path, tree, dm = multi_align(seqs, keep_tree=True, keep_distmat=True) >>> print(tree.ascii_art()) /-1 ---------| | /-0 \--------| \-2
>>> print(dm) 3x3 distance matrix IDs: '0', '1', '2' Data: [[ 0. 0.70444674 0.40215932] [ 0.70444674 0. 0.40215932] [ 0.40215932 0.40215932 0. ]]
One can supply a custom guide tree to skip the costly automatic pairwise alignment and tree building process. An accurate tree may improve the alignment quality.
>>> from skbio.tree import TreeNode >>> tree = TreeNode.read(['((1,2),0);']) >>> path = multi_align(seqs, guide_tree=tree).path >>> for seq in path.to_aligned(seqs): ... print(seq) CATTAACGT- CGTTA-CGGT AGTTAACGG-
>>> align_score((path, seqs)) 9.0
By default, sequences match taxa (tip names) of the tree by incremental indices ‘0’, ‘1’, ‘2’… Alternatively, explicit sequence IDs can be defined using the
'id'key of sequence metadata or supplied by theidsparameter of this function.>>> for seq, id_ in zip(seqs, 'abc'): ... seq.metadata['id'] = id_ >>> tree = TreeNode.read(['((b,c),a);']) >>> res = multi_align(seqs, guide_tree=tree)
One can customize the alignment parameters, including substitution scores, gap penalties, and terminal gap policy. Refer to
pair_alignfor details of the parameters.>>> params = dict(sub_score=(2, -3), gap_cost=(2, 5), free_ends=False) >>> path = multi_align(seqs, **params).path >>> for seq in path.to_aligned(seqs): ... print(seq) CATTAACGT CGTTACGGT AGTTAACGG
Supply the same parameters when calculating the alignment score.
>>> align_score((path, seqs), **params) 4.0
The entire process of reading a multi-FASTA file of original sequences, performing multiple sequence alignment, and writing the aligned sequences into a multi-FASTA file is:
>>> from skbio.io import read as sk_read >>> from skbio.alignment import TabularMSA >>> it = sk_read('input.fa', format='fasta', constructor=DNA) >>> seqs = list(it) >>> path = multi_align(seqs, **params).path >>> msa = TabularMSA.from_path_seqs(path, seqs) >>> msa.write('output.fa')