Skip to main content

minimizer-stream

CI Coverage Types Mutation Python License

A dependency-free Python library and command-line program that streams canonical minimizer sketches from FASTA and four-line FASTQ. Output includes record, zero-based position, stable 64-bit FNV-1a hash, canonical strand, and canonical k-mer.

Install

python -m pip install minimizer-stream

For development and verification:

python -m pip install -e '.[test]'
ruff check .
pytest --cov=minimizer_stream --cov-branch --cov-fail-under=100

Quickstart

minimizer-stream reads.fasta -k 21 -w 10 > sketch.tsv
minimizer-stream reads.fastq -k 21 -w 10 --format jsonl --deduplicate
cat reads.fasta | minimizer-stream - -k 15 -w 5

TSV has no header and its columns are record, position, hash, strand, kmer. JSONL uses the same field names. The Python API is lazy:

from minimizer_stream import minimizers, naive_minimizers

for item in minimizers("ACGTTGCA", k=3, w=2, deduplicate=True):
    print(item.position, item.hash, item.strand, item.kmer)

assert list(minimizers("ACGTTGCA", 3, 2)) == list(naive_minimizers("ACGTTGCA", 3, 2))

Algorithm

flowchart LR; R[FASTA/FASTQ] --> K[canonical k-mers]; K --> H[FNV-1a 64-bit]; H --> D[monotonic deque, window w]; D --> M[leftmost minimum]; M --> U{deduplicate?}; U --> O[record, position, hash, strand, kmer]

The general iterable path compares each k-mer lexicographically with its reverse complement; the exact-string k=21 path instead maintains equivalent rolling two-bit forward and reverse encodings and materializes strings only for selected minima. Palindromes stay on the forward strand. Canonical values are hashed with deterministic 64-bit FNV-1a, never Python's process-randomized hash. A monotonic deque retains possible minima for each window, removing expired entries from the front and strictly larger hashes from the back. Keeping equal hashes preserves the documented leftmost tie-break.

The general iterable path constructs, reverse-complements, and hashes each canonical k-mer in $O(k)$, for $O(nk)$ total time and $O(w+k)$ working memory. The exact-string k=21 path keeps packed rolling state, so its fixed-width work is $O(n)$ with $O(w)$ per-call memory; the four-base FNV transition table is immutable module state. naive_minimizers remains the executable $O(n(k+w))$ oracle. Non-ACGT characters reset both k-mer construction and the minimizer window, so no output spans an invalid base.

Reproducible capability evidence

PYTHONPATH=src python benchmarks/benchmark.py --json parses 16 deterministic FASTA/FASTQ records totaling 128,000 bases, streams canonical k=21, w=100 minimizers with deduplication, and materializes 2,220 ordered objects. It refuses to time results that differ from naive_minimizers.

On an Apple M3 Max with CPython 3.11.12 on 2026-08-15, 11 samples after two warmups measured frozen baseline 5d37de9d4ff4 at 307.803 ms median and the packed rolling implementation at 143.045 ms, a 2.152x speedup. Both runs produced SHA-256 faaba963089826ffa15afd9f9d9e0d63e3dd5d6de96ea6a3632743fb000fb008. Fixture generation and interpreter startup are excluded; record parsing, minimizer generation, and output materialization are included. These are local in-process timings; rerun with PYTHONPATH pointed at the desired source worktree.

Verification

CI runs Ruff, strict mypy, and the full property-based and deterministic test suites on Linux and macOS with Python 3.11–3.13. Its exact coverage command is:

pytest --cov=minimizer_stream --cov-branch --cov-fail-under=100

Tests include reverse complements, palindromes, ties, invalid-base resets, short and lowercase sequences, FASTA, FASTQ, malformed records, invalid parameters, subprocess execution from a clean temporary directory, TSV, JSONL, standard input, and deduplication.

Mutation testing

From the repository root, reproduce the mutation run with:

source .venv/bin/activate
mutmut run
mutmut results

Mutation testing generated 392 mutants and killed 388 (98.98%). The remaining 4 survivors were reviewed as behavior-equivalent, not missed mutants; the run had zero suspicious mutants and zero timeouts.

Behavior-equivalent rationale Count
ASCII codec alias 1
Initial None versus empty value, compared only to Minimizer instances 2
typing.cast is an identity operation at runtime 1

Limitations

  • FASTQ must use the conventional four-line form; wrapped sequence or quality lines are rejected.
  • FASTA permits wrapped sequence lines but rejects blank lines and empty records.
  • Record names containing control characters or beginning with =, +, -, or @ are rejected so default TSV output keeps five columns and is safe from spreadsheet formula interpretation.
  • Input is decoded as ASCII; compressed files must be decompressed before use.
  • Record sequences are retained one at a time. The parser does not load the full file, but an individual record must fit in memory.
  • w counts consecutive valid k-mers, not bases. A valid window therefore spans k + w - 1 bases.
  • Hash collisions are possible for any 64-bit sketch; the canonical k-mer is emitted so callers can distinguish them when needed.

Metadata

Release files for minimizer-stream 1.0.1

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

Source distribution (sdist)

Source distribution for minimizer-stream 1.0.1
File Size Uploaded
minimizer_stream-1.0.1.tar.gz 15.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for minimizer-stream 1.0.1
File Interpreter ABI Platform
minimizer_stream-1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 26.7 kB

Release files / minimizer_stream-1.0.1.tar.gz

Download URL minimizer_stream-1.0.1.tar.gz
Size 15.1 kB
Tags Source
SHA-256 checksum
How to use checksums
63020be8e59a16fc06f903418fdc12c8c39c0a5921f91e15a9374080e3494349
BLAKE2b-256 checksum
How to use checksums
7ab884166d84292f5f1460d69cdd625f02eb50e733696c1b619d8563b0581819
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Aug 15, 2026.

Transparency log

Release files / minimizer_stream-1.0.1-py3-none-any.whl

Download URL minimizer_stream-1.0.1-py3-none-any.whl
Size 11.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3897917830fb3691abd6ff8015727d8adbb35747de6aa397269f57182b962f0e
BLAKE2b-256 checksum
How to use checksums
f452dcd12391de905aab51e00754cf798410cc3c856dde5b90ab29bde395b947
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Aug 15, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.1 This release

2 release files

1.0.0

2 release files

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