Skip to content

Multiple sequence alignment

MIINT provides capability for multiple sequence alignment.

Table of contents

  • MAFFT - Multiple sequence alignment with MAFFT (PartTree).
  • abPOA - Multiple sequence alignment with abPOA.
  • abPOA Consensus Sequence - Generate consensus sequences using abPOA.

Multiple sequence alignment with MAFFT

Multiple sequence alignment using MAFFT's PartTree algorithm. Reads all sequences from a sequence table/view, aligns them, and returns the aligned sequences with gap characters inserted.

MAFFT is embedded as a statically linked C library (no external binary required). The PartTree algorithm uses O(N log N) guide tree construction with k-tuple distances, making it suitable for large datasets (tested up to 5,000+ sequences).

Parameters: - table_name (VARCHAR): Name of a table or view containing sequences to align. Must have read_id (VARCHAR) and sequence1 (VARCHAR) columns. Minimum 2 sequences, each at least 6 characters. DNA and protein sequences are auto-detected. Paired-end tables (those with a sequence2 column) are rejected at bind. - sample_id (VARCHAR, optional): Name of a column in table_name to partition by. When provided, align_mafft runs one MSA per distinct sample value and prepends the sample column to the output. The per-sample ≥2-sequences and ≥6-char validations apply within each sample; the whole query aborts if any sample violates them. sequence_index is per-sample (0..n-1 within each sample). Join back to the input on (<sample_id>, read_id).

Output schema:

Column Type Description
sequence_index BIGINT 0-based position matching input order
read_id VARCHAR Sequence identifier from the input read_id column
aligned_sequence VARCHAR Aligned sequence with - gap characters
original_length INTEGER Length of the input sequence (no gaps)
aligned_length INTEGER Length of aligned sequences (same for all rows)

Algorithm: Equivalent to mafft --quiet --preservecase --parttree. Original case is preserved (MAFFT internally lowercases DNA; the wrapper restores the original characters after alignment).

Thread safety: Alignment uses a process-wide mutex (one alignment at a time). The function is safe to call from concurrent queries but they will serialize.

Examples:

-- Basic multiple sequence alignment
CREATE TABLE seqs AS SELECT read_id, sequence1 FROM read_fastx('sequences.fasta');
SELECT * FROM align_mafft('seqs');

-- Align, then analyze gap content
CREATE TABLE ref_16s AS SELECT read_id, sequence1 FROM read_fastx('16s_sequences.fasta');
SELECT read_id,
       original_length,
       aligned_length,
       aligned_length - original_length AS gaps_inserted
FROM align_mafft('ref_16s')
ORDER BY gaps_inserted DESC;

-- Filter before alignment — operate entirely in SQL, no temp files
CREATE TABLE filtered AS
  SELECT read_id, sequence1 FROM read_fastx('large_dataset.fasta')
  WHERE length(sequence1) >= 100;
SELECT * FROM align_mafft('filtered');

-- Align per-sample: one MSA per distinct sample value
CREATE VIEW cohort AS
  SELECT 'S1' AS sample, * FROM read_fastx('sample1.fasta')
  UNION ALL
  SELECT 'S2' AS sample, * FROM read_fastx('sample2.fasta');
SELECT * FROM align_mafft('cohort', sample_id := 'sample') ORDER BY sample, sequence_index;

-- Compute pairwise identity from aligned sequences
CREATE TABLE seqs2 AS SELECT read_id, sequence1 FROM read_fastx('seqs.fasta');
WITH aligned AS (
  SELECT read_id, aligned_sequence FROM align_mafft('seqs2')
)
SELECT a.read_id AS seq1, b.read_id AS seq2,
       sum(CASE WHEN a.c = b.c AND a.c != '-' THEN 1 ELSE 0 END)::FLOAT
       / nullif(sum(CASE WHEN a.c != '-' OR b.c != '-' THEN 1 ELSE 0 END), 0) AS identity
FROM aligned a, aligned b,
     unnest(string_split(a.aligned_sequence, '')) WITH ORDINALITY AS a(c, pos),
     unnest(string_split(b.aligned_sequence, '')) WITH ORDINALITY AS b(c, bpos)
WHERE a.read_id < b.read_id AND a.pos = b.bpos
GROUP BY a.read_id, b.read_id;

Performance: ~2x faster than native mafft --parttree for 1,000-5,000 sequences (no shell script overhead or temp file I/O). For 36 sequences, ~15x faster.

Limitations: - All sequences are materialized in memory (required by the MSA algorithm) - Sequences must be at least 6 characters (MAFFT internal requirement) - Single-threaded alignment (process-wide mutex)

Multiple sequence alignment with abPOA

Multiple sequence alignment using abPOA (adaptive banded Partial Order Alignment). Reads all sequences from a sequence table/view, aligns them via a partial order graph, and returns the aligned sequences with gap characters inserted.

abPOA is embedded as a statically linked C library (no external binary required). It supports adaptive banding for 3-10x speedup over full-DP POA, minimizer-based progressive guide tree construction, and convex gap penalties.

Parameters: - table_name (VARCHAR): Name of a table or view containing sequences to align. Must have read_id (VARCHAR) and sequence1 (VARCHAR) columns. Minimum 2 sequences. DNA only. Paired-end tables (those with a sequence2 column) are rejected at bind. - sample_id (VARCHAR, optional): Name of a column in table_name to partition by. When provided, align_abpoa runs one MSA per distinct sample value and prepends the sample column to the output. sequence_index is per-sample (0..n-1 within each sample). Unlike align_mafft, per-sample alignments run in parallel (abPOA is thread-safe). - match (INTEGER, default 2): Match score. - mismatch (INTEGER, default 4): Mismatch penalty. - gap_open1 (INTEGER, default 4): First-layer gap opening penalty (affine/convex). - gap_open2 (INTEGER, default 24): Second-layer gap opening penalty (convex gap mode). - gap_ext1 (INTEGER, default 2): First-layer gap extension penalty. - gap_ext2 (INTEGER, default 1): Second-layer gap extension penalty. - align_mode (VARCHAR, default 'global'): Alignment mode — 'global', 'local', or 'extension'. - progressive (BOOLEAN, default true): Use minimizer-based guide tree for progressive alignment order. Improves quality by aligning most-similar sequences first. - disable_seeding (BOOLEAN, default false): Disable minimizer seeding (forces full-length alignment). - amb_strand (BOOLEAN, default false): Try reverse complement if alignment score is too low. - k (INTEGER, default 19): Minimizer k-mer size. - w (INTEGER, default 10): Minimizer window size. - min_w (INTEGER, default 500): Minimum window size for POA between anchors. - bandwidth (INTEGER, default 10): Adaptive banding base width. - bandwidth_frac (FLOAT, default 0.01): Adaptive banding fraction of query length.

Output schema:

Column Type Description
sequence_index BIGINT 0-based position matching input order
read_id VARCHAR Sequence identifier from the input read_id column
aligned_sequence VARCHAR Aligned sequence with - gap characters
original_length INTEGER Length of the input sequence (no gaps)
aligned_length INTEGER Length of aligned sequences (same for all rows)

Thread safety: Each alignment creates its own abPOA instance. No process-wide mutex — per-sample alignments run in true parallel.

Examples:

-- Basic multiple sequence alignment
CREATE TABLE seqs AS SELECT read_id, sequence1 FROM read_fastx('amplicons.fasta');
SELECT * FROM align_abpoa('seqs');

-- With progressive guide tree (default) and custom scoring
SELECT * FROM align_abpoa('seqs', match := 1, mismatch := 3, progressive := true);

-- Per-sample alignment (parallel across samples)
CREATE VIEW cohort AS
  SELECT 'S1' AS sample, * FROM read_fastx('sample1.fasta')
  UNION ALL
  SELECT 'S2' AS sample, * FROM read_fastx('sample2.fasta');
SELECT * FROM align_abpoa('cohort', sample_id := 'sample') ORDER BY sample, sequence_index;

Limitations: - All sequences are materialized in memory (required by the POA algorithm) - DNA only (nucleotide mode)

Consensus sequence generation with abPOA

Consensus sequence generation using abPOA. Reads all sequences from a sequence table/view, builds a partial order alignment graph, and extracts one or more consensus sequences using heaviest bundling or majority voting.

Particularly useful for amplicon denoising, strain-level variant calling, and long-read error correction where multiple consensus sequences from heterogeneous samples are needed.

Parameters:

Same alignment parameters as align_abpoa, plus: - max_num_cons (INTEGER, default 1): Maximum number of consensus sequences to generate. When > 1, abPOA clusters reads and produces one consensus per cluster (up to max_num_cons). - min_freq (FLOAT, default 0.25): Minimum cluster frequency for multi-consensus mode. Clusters below this threshold are merged. - algorithm (VARCHAR, default 'heaviest_bundling'): Consensus algorithm — 'heaviest_bundling' (highest weight path through the graph) or 'majority_voting' (most frequent base per position).

Output schema:

Column Type Description
consensus_id INTEGER 0-based identifier for each consensus sequence
consensus_sequence VARCHAR The consensus nucleotide sequence
consensus_length INTEGER Length of the consensus sequence
num_reads INTEGER Number of input reads assigned to this consensus cluster

Examples:

-- Single consensus from amplicon reads
CREATE TABLE amplicons AS SELECT read_id, sequence1 FROM read_fastx('amplicons.fasta');
SELECT * FROM consensus_abpoa('amplicons');

-- Multi-consensus for strain detection
SELECT * FROM consensus_abpoa('amplicons', max_num_cons := 3, min_freq := 0.1);

-- Per-sample consensus (parallel)
SELECT * FROM consensus_abpoa('cohort', sample_id := 'sample', max_num_cons := 2)
  ORDER BY sample, consensus_id;

-- Majority voting instead of heaviest bundling
SELECT * FROM consensus_abpoa('amplicons', algorithm := 'majority_voting');