A Goblin Reactor product

Sequence alignment

stride-align documentation

Smith-Waterman (local) and Needleman-Wunsch (global) dynamic-programming alignment with substitution matrices, linear or affine gaps, traceback to alignment path / CIGAR, and a Farrar-vectorised score-only fast path.

Suitable for bioinformatics, fuzzy matching with custom character-similarity, and any workload that needs the actual alignment rather than just the score.

Output-processing variants

The alignment surface has its own variant family because the outputs are richer than a single distance. <algo> below is smith_waterman or needleman_wunsch.

Suffix Signature Return type Use when
<algo>_score(query, target, …) one-to-one score int you only need the alignment score
<algo>_normalized_score(query, target, …) one-to-one normalised float in [0, 1] length-normalised score
<algo>_scores(query, targets, …) one-to-many ndarray[int64] score against every target
<algo>_normalized_scores(query, targets, …) one-to-many normalised ndarray[float64] normalised scores against every target
<algo>_path(query, target, …) traceback path AlignmentPath you need the path coordinates
<algo>_path_info(query, target, …) path + score AlignmentResult path plus pre-computed score
<algo>_cigar(query, target, …) CIGAR string str SAM/BAM-style CIGAR output
<algo>_trace_cigar(query, target, …) extended CIGAR str =/X distinguished from M
<algo>_trade_cigar(query, target, …) extended CIGAR + score (str, int) CIGAR plus the score that produced it

Smith-Waterman additionally exposes a top-k helper:

sa.smith_waterman_top_k(query, targets, k=5, …)
# -> list[tuple[target, score, target_index]]

There's also a Farrar score-only fast path:

sa.smith_waterman_farrar_score(query, target, …)
sa.smith_waterman_farrar_normalized_score(query, target, …)
sa.smith_waterman_farrar_scores(query, targets, …)
sa.smith_waterman_farrar_normalized_scores(query, targets, …)

The Farrar layout interleaves DP cells across SIMD lanes; it's the fastest path when you only need the score and have a small short-string query against many targets. For traceback or CIGAR output, use the non-Farrar entry points.

Scoring parameters

Every alignment entry point accepts the same scoring kwargs:

Keyword Default Meaning
match_score 2 bonus per matching position
mismatch_score -1 penalty per mismatched position
matrix None SubstitutionMatrix overriding match/mismatch — see matrices
gap_score -1 linear gap penalty (per gap character)
gap_open_score None when set together with gap_extend_score, switches to affine: cost is gap_open + k * gap_extend for a gap of length k
gap_extend_score None per-character cost inside an open gap
width None force a specific SIMD lane width (0 = scalar, 8 / 16 / 32 / 64 bits). None = auto

If matrix= is set, match_score / mismatch_score are ignored; the matrix is the source of truth for per-pair substitution scores. Built-in BLOSUM and PAM tables and a NCBI-text loader are in matrices.

Examples

import stride_align as sa
from stride_align.matrices import BLOSUM62

# Local alignment with affine gaps and BLOSUM62
sa.smith_waterman_score(
    "MQNS", "RMQDL",
    matrix=BLOSUM62,
    gap_open_score=-10,
    gap_extend_score=-1,
)

# Top-5 hits across a target list with custom match/mismatch
sa.smith_waterman_top_k(
    "kitten", ["sitting", "sitten", "smitten", "bitten", "kitty", "kit"],
    k=5, match_score=3, mismatch_score=-2, gap_score=-1,
)

# CIGAR with score for use in downstream SAM tooling
cigar, score = sa.smith_waterman_trade_cigar("ACGTAC", "ACGTAG")

AlignmentResult / AlignmentPath

AlignmentResult is returned by _path_info and carries score, query_begin, query_end, target_begin, target_end, and a nested AlignmentPath with the cell-by-cell traceback. Both are nanobind-bound C++ types but are pure value objects from Python's perspective.

SIMD dispatch

Alignment runs on the same per-CPU backend the rest of the library uses. The internal selector picks a fixed-width kernel based on input size and the width= hint (defaulting to the narrowest width that won't overflow). See edit-distance#simd-dispatch.