Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

align-pair

Pairwise sequence alignment from the command line: global, glocal, overlap and local alignment of DNA, RNA or protein, with the published BLOSUM and PAM matrices, affine gap penalties, and identity and similarity reported with the denominator they were divided by. Pure Python with no third-party dependencies, and a self-contained HTML report that opens from a local disk with no network connection and no JavaScript.

Install

Install the prerelease from PyPI:

python -m pip install --pre norvara-align-pair

The Python package and command keep the shorter project name:

import align_pair
align-pair --version

Quickstart

align-pair align -a examples/hbb_human.fasta -b examples/hbb_mouse.fasta
> NP_000509.1 vs NP_032246.2
  score    638  global  BLOSUM62  gap 10/0.5  protein
  columns  147  identity 118 (80.3%)  similarity 132 (89.8%)  gaps 0 in 0 runs
  aligned  NP_000509.1 1-147 of 147 aa  |  NP_032246.2 1-147 of 147 aa

  NP_000509.1   1 MVHLTPEEKSAVTALWGKVNVDEVGGEALGRLLVVYPWTQRFFESFGDLSTPDAVMGNPK  60
                  |||||..||:||:.||||||.||||||||||||||||||||:|:||||||:..|:|||.|
  NP_032246.2   1 MVHLTDAEKAAVSGLWGKVNADEVGGEALGRLLVVYPWTQRYFDSFGDLSSASAIMGNAK  60

  NP_000509.1  61 VKAHGKKVLGAFSDGLAHLDNLKGTFATLSELHCDKLHVDPENFRLLGNVLVCVLAHHFG 120
                  ||||||||:.||:|||.|||:||||||:|||||||||||||||||||||::|.||.||.|
  NP_032246.2  61 VKAHGKKVITAFNDGLNHLDSLKGTFASLSELHCDKLHVDPENFRLLGNMIVIVLGHHLG 120

  NP_000509.1 121 KEFTPPVQAAYQKVVAGVANALAHKYH 147
                  |:|||..|||:||||||||.|||||||
  NP_032246.2 121 KDFTPAAQAAFQKVVAGVAAALAHKYH 147
  | identical residues, : different residues scoring above zero, . different residues scoring zero or below, space a gap

Human and mouse beta globin are the same length and close enough that no gap pays for itself, so the optimal global alignment is gapless and its identity count can be checked without aligning anything. The marker line distinguishes identical residues from merely similar ones, which is the distinction the matrix exists to make.

The same pair of genes as messenger RNA needs a different mode, because the untranslated ends diverge where the coding sequence does not:

align-pair align -a examples/hbb_human_mrna.fasta -b examples/hbb_mouse_mrna.fasta -m local --no-view
> NM_000518.5 vs NM_008220.5
  score    1,967  local  NUC.4.4  gap 10/0.5  DNA
  columns  644  identity 505 (78.4%)  similarity 505 (78.4%)  gaps 32 in 12 runs
  aligned  NM_000518.5 1-628 of 628 bp  |  NM_008220.5 3-630 of 646 bp
  ! 64 alignments share this score; the one shown is reached by preferring an aligned pair to a gap and continuing a gap to opening another at each step, which makes it deterministic rather than the best of the set by any further measure

The alphabet is read from the sequences, so the protein pair is scored with BLOSUM62 and the nucleotide pair with NUC.4.4 without either being named.

The modes

Mode What it aligns
global both sequences end to end, every gap paid for (Needleman-Wunsch)
glocal the first sequence end to end within the second; the second may overhang at either end for free
overlap either sequence may overhang at either end for free, so a suffix of one aligns to a prefix of the other
local the best-scoring pair of subsequences, beginning and ending with an aligned pair (Smith-Waterman)

An overhang is not part of the alignment: it is neither scored nor shown, and the coordinates beside each row say which residues were aligned.

Options

align
-a, --first PATH         the first input, or '-' for standard input
-b, --second PATH        the second input; without it, the records of the
                         first are aligned against each other
    --input-format       auto | fasta | fastq (default: auto)
    --limit N            read only the first N records of each input
    --pairing            all | positional (default: all)
-m, --mode               global | glocal | overlap | local (default: global)
    --matrix NAME        a built-in matrix, 'simple' for match/mismatch, or a
                         path to a matrix file
    --match SCORE        score for identical residues under 'simple'
    --mismatch SCORE     score for differing residues under 'simple'
    --gap-open PENALTY   the first residue of a gap (default: 10)
    --gap-extend PENALTY each further residue of a gap (default: 0.5)
    --alphabet           auto | dna | rna | protein (default: auto)
    --strand             plus | minus | both; nucleic acid only
    --band N             fill only N diagonals either side of the main one,
                         in global mode
    --degap              remove gap characters from the input before aligning
    --max-cells N        refuse a pair needing more cells than this
    --max-memory BYTES   refuse a pair estimated to hold more than this;
                         takes a K, M or G suffix
    --width N            residues per block of the alignment view
    --no-view            keep the metrics, leave out the alignment itself

matrices [NAME]          list the built-in matrices, or print one

Outputs

Flag Output
--format table (default) the readable per-pair summary on stdout
--format tsv one row of metrics per pair, on stdout
--format json | none every metric and both aligned rows as JSON, or nothing
--output PATH | - one row of metrics per pair, as a TSV
--columns PATH every column of every alignment, with its score
--alignment PATH the aligned pairs as FASTA, gap characters included
--report PATH the self-contained HTML report

Any combination may be requested in a single pass. Compressed input is recognised from its magic bytes, so gzip, bzip2 and xz files need no flag and no particular file name.

Every input is opened, and every output destination resolved, checked and opened, before any input is read, so a run that cannot be written does not start and a run that fails leaves no file behind: a destination that cannot be opened - a name too long for the filesystem, a directory with no write permission - is found before anything is written, and any file the attempt created is removed again. An output is refused if it names an input under any name - a hard link and a symlink are the same file, and comparing names alone would let a run truncate what it is reading - and two outputs are refused if they name one file, since the second would silently replace the first. A matrix file counts as an input, because it is read too.

A file written on the minus strand says so in its own header, and the column table carries a strand field, because a data file is read without the qualifications that were printed beside it.

Reading the output

  • A gap of L residues costs open + (L - 1) * extend. The first residue costs the opening penalty and each further one the extension, which is the convention of EMBOSS needle and water; the same matrix and penalties give the same score as those programs. BLAST charges one extension more per gap. A gap in one sequence and a gap in the other are two runs, each paying to open, and the gap counts, the report's running score and the alignment score are the same arithmetic.
  • A score means nothing without its matrix. BLOSUM62 is in half-bit units and BLOSUM45 in third-bit units, so 412 under one is not 412 under the other, and neither is comparable with a count of matches. Every output names the matrix and carries the comment lines of the file it came from.
  • Identity always comes with its denominator, over the alignment's length and over the shorter whole sequence, because the two differ by as much as the figure itself when an alignment is gappy. Identity and similarity are different claims: identity is a property of the letters, similarity of the matrix, and neither contains the other. Leucine against isoleucine is similar and not identical; under NUC.4.4 the code S against itself is identical and not similar, since S stands for C or G and two draws from a pair agree half the time. Where an alignment holds such a column the summary says how many. Case is masking, not identity: a against A is a match to the matrix and to the identity count alike, and the rows keep the case they were given.
  • An optimal alignment is rarely the only one. The number sharing the optimal score is counted and reported whenever it is more than one; past a million million it is written as a bound. The one shown is reached by preferring an aligned pair to a gap and continuing a gap to opening another at each step, which makes it deterministic and tends towards fewer, longer gaps - but that is a preference applied step by step, not a second thing being optimised, so another co-optimal alignment may have fewer gap runs.
  • A banded score is a lower bound. Cells outside the band are never computed, so the optimum may lie outside it. The output says so whenever the band leaves any of the matrix out, and reports how many diagonals of room the path had - a diagnostic, not a proof. Widening the band settles it.
  • A local alignment of nothing is reported as nothing. When no pair of subsequences scores above zero the optimum is the empty alignment, scoring zero; a pair scoring exactly zero is that same alignment written out.
  • The alphabet is read from composition, not from a letter. Every IUPAC nucleotide code is also an amino-acid code or ambiguity code, so no letter settles it; a sequence counts as nucleic acid when at least 90% of its letters are A, C, G, T, U or N. The decision is always reported and --alphabet overrides it. A protein matrix is refused for nucleic acid, and so is a batch whose records are not all one kind of molecule: one matrix scores every pair, so a single long protein among a file of DNA would otherwise carry the DNA pairs into a protein table with nothing failing.
  • A minus-strand row is numbered along its record, descending. The second row shows the reverse complement, and every coordinate beside it - view, summary, column table, JSON - is a position in the record as given.
  • Nothing is quietly corrected. An already-aligned record is refused until --degap; a residue the matrix cannot score is named with its position; a matrix file holding nan or inf is refused with its line, since neither is a score and every comparison against NaN is false; a FASTA header carrying a control character is refused rather than printed, since a summary names its records and an ANSI escape would be interpreted by the terminal showing it; uracil scored against a thymine-indexed matrix is reported as substituted.

Anything a reader needs in order to read a number correctly is printed after a !, shown in the report, and carried in the JSON under qualifications, because a program reading the JSON cannot see a note printed beside it.

The HTML report

align-pair align -a examples/aav2_vp1.fasta -b examples/aav9_vp1.fasta --report aav.html -f none

One document, no network, no script: the parameters, the metrics, the running score along the alignment as an SVG, and the alignment itself in blocks with every column coloured by what it is. The marker line is kept beside the colour so the document reads in black and white, and every table in it can be downloaded from the page as the same tab-separated file --output would have written. Output is byte-deterministic for a given input, so two runs of the same command produce the same bytes.

Size and speed

Measured on one core: a 1,000 by 1,000 alignment takes 0.35 s and a 3,000 by 3,000 one 3.8 s, at about 2.5 million cells a second.

Memory has two parts, and only one of them a band reduces. The traceback keeps three bytes per cell, which a band cuts to the width of the band. The dynamic programme's rows hold a score and a path count for each of three layers, in the current row and the previous one, and those twelve arrays span the second sequence whatever the band - about 480 bytes per residue of it, measured across alignments from 3,000 to 160,000 residues. A 40,000-residue pair at band zero is therefore 40,001 cells and about 19 MB, which is why --max-cells bounds the work and --max-memory bounds the memory, and why a narrow band over a long pair is quick and still large.

Both limits are applied per pair, as soon as the records have been read and before any cell is computed. They cannot be applied earlier: how large the work is depends on the lengths of the records, and a file is usually far longer than its longest record, so its size says nothing about whether the run is too big.

Examples

examples/ holds six real NCBI records, downloaded unmodified: the VP1 capsid proteins of adeno-associated virus 2 and 9 (YP_680426.1, AAS99264.1), human and mouse beta globin (NP_000509.1, NP_032246.2), and the two globin mRNAs (NM_000518.5, NM_008220.5). Re-fetch them with python examples/fetch_examples.py.

References

  • Needleman SB, Wunsch CD (1970). A general method applicable to the search for similarities in the amino acid sequence of two proteins. Journal of Molecular Biology 48:443-453.
  • Smith TF, Waterman MS (1981). Identification of common molecular subsequences. Journal of Molecular Biology 147:195-197.
  • Gotoh O (1982). An improved algorithm for matching biological sequences. Journal of Molecular Biology 162:705-708.
  • Henikoff S, Henikoff JG (1992). Amino acid substitution matrices from protein blocks. PNAS 89:10915-10919.
  • Dayhoff MO, Schwartz RM, Orcutt BC (1978). A model of evolutionary change in proteins. In Atlas of Protein Sequence and Structure 5:345-352.

License

PolyForm Noncommercial License 1.0.0. See LICENSE.

Metadata

Release files for norvara-align-pair 1.0.0rc3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for norvara-align-pair 1.0.0rc3
File Size Uploaded Provenance Actions
norvara_align_pair-1.0.0rc3.tar.gz 120.5 kB With provenance Details for norvara_align_pair-1.0.0rc3.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for norvara-align-pair 1.0.0rc3
File Interpreter ABI Platform Actions
norvara_align_pair-1.0.0rc3-py3-none-any.whl Python 3 none any Details for norvara_align_pair-1.0.0rc3-py3-none-any.whl

Total release size: 192.3 kB

Release files / norvara_align_pair-1.0.0rc3.tar.gz

Download URL norvara_align_pair-1.0.0rc3.tar.gz
Size 120.5 kB
Tags Source
SHA-256 checksum
How to use checksums
40b498e83a2a6fdeb77806863c2edee838170ea1dbc088ebcfd147e2f5a01d0a
BLAKE2b-256 checksum
How to use checksums
b6d1e40699fd969e4c289fc4bf735ddd6df803f05f8f4c392f0bfd3798c5a196
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Release files / norvara_align_pair-1.0.0rc3-py3-none-any.whl

Download URL norvara_align_pair-1.0.0rc3-py3-none-any.whl
Size 71.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
13e75ecda3b80ad5d65874a555de1afd272cf76d792627e06c108e83114567c3
BLAKE2b-256 checksum
How to use checksums
c9d5b36d8e2ad7e03c52e738135cd89bc9248b2e9925c34f931bd2261ff42687
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Security for norvara-align-pair 1.0.0rc3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for norvara_align_pair-1.0.0rc3.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page