Skip to main content

phred-consensus

CI Coverage Types Mutation Python License

A dependency-free Python library and CLI for Phred-aware Bayesian consensus calling from aligned, same-length reads. It combines observations in log space, reports posterior-derived consensus qualities, and offers an explicit unweighted majority baseline.

Install

Python 3.11 or newer is required.

python -m pip install phred-consensus

For development and verification:

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

Quickstart

FASTQ records are grouped by the portion of each record ID before --delimiter (default /). Groups must be contiguous and all reads within a group must be aligned and the same length.

phred-consensus reads.fastq --output-format jsonl
phred-consensus reads.fastq --delimiter ':' --min-posterior 0.99 -o consensus.fastq

The TSV format is headerless: group, sequence, and Phred+33 quality string.

family1	ACGT	IIII
family1	ACGA	III$
phred-consensus reads.tsv --input-format tsv --output-format fastq

Use a nonuniform prior with all four positive weights:

phred-consensus reads.tsv --input-format tsv --prior A=2,C=1,G=1,T=2

Library use:

from phred_consensus import call_consensus

result = call_consensus(
    ["ACGT", "ACGA"],
    [[40, 40, 40, 40], [40, 40, 40, 3]],
    min_posterior=0.95,
)
print(result.sequence, result.qualities, result.posteriors)

Algorithm

flowchart LR; F[FASTQ/TSV reads] --> G[group by ID prefix]; G --> L[per-position log-likelihoods<br/>e = 10^-Q/10]; P[prior, log-sum-exp] --> L; L --> W[posterior per base]; W --> O[consensus + Phred qualities]

For an observed base $b$ with Phred score $Q$, the error probability is $e=10^{-Q/10}$. The likelihood is $1-e$ when a candidate equals $b$, and $e/3$ for each of the other three bases. For candidate $x$ at a position, the implementation computes

$$ \log P(x \mid \text{reads}) = C + \log P(x) + \sum_i \log P(b_i \mid x,Q_i) $$

and normalizes the four candidate scores with a log-sum-exp calculation. Ties resolve deterministically in A,C,G,T order. The winning posterior $p$ becomes consensus quality $\min(60,\operatorname{round}(-10\log_{10}(1-p)))$. If $p$ is below --min-posterior, the emitted base is N, while the posterior-derived quality is retained.

Reproducible capability evidence

The repository includes a deterministic synthetic benchmark with 2,000 truth bases and five reads per base: three low-quality Q3 reads and two high-quality Q30 reads. Errors are sampled according to the same Phred model, with incorrect bases chosen uniformly. On seed 2026, the Bayesian caller has 1 mismatch (0.05%), while unweighted majority vote has 128 mismatches (6.4%).

Reproduce the exact result:

phred-consensus --benchmark --seed 2026 --bases 2000

The benchmark test asserts determinism and that the Bayesian mismatch count is lower; it does not treat this synthetic scenario as a claim about every biological dataset.

Input validation

The caller rejects empty groups, unequal sequence/quality lengths, unequal aligned-read lengths, symbols outside A/C/G/T, quality values outside 0–93, malformed FASTQ structure, non-Phred+33 text, blank or malformed TSV rows, invalid priors, invalid posterior thresholds, and noncontiguous repeated groups. Errors are reported on stderr with a nonzero status.

Verification

Mutation testing

The deterministic suite generated 764 mutants and killed 729 (95.42%). The 35 survivors were individually reviewed and are behavior-equivalent under the validated public contract, not missed mutants; there were zero suspicious results and zero timeouts. Mutation testing also exposed duplicate prior keys being silently overwritten; the parser now rejects them.

Reviewed equivalent rationale Count
Validated equal-length inputs make strict/non-strict zip behavior identical 15
Parser delimiter, maxsplit, separator, and sentinel identities 12
Additive log-prior normalization constants cancel from posterior ratios 3
The posterior-quality floor is hidden by integer rounding and the quality-60 cap 1
The infinity guard differs only for unreachable validated states 1
UTF-8/type-only/default identities and benchmark PRNG equality 3
Total reviewed equivalents 35

Reproduce the campaign from the repository root:

source .venv/bin/activate
mutmut run
mutmut results

Limitations

  • Reads must already be aligned, ungapped, and equal length within a group.
  • Only canonical A/C/G/T observations are accepted; ambiguity symbols and gaps are deliberately rejected.
  • FASTQ qualities use Sanger Phred+33 and are limited to the representable range 0–93.
  • Under the stated substitution model, Q0 means P(correct)=0: the observed symbol is anti-evidence rather than an uninformative observation. Datasets that use Q0 as a missing-quality sentinel must filter or recode those observations before calling consensus.
  • The model assumes conditionally independent read errors and uniform substitution among the three incorrect bases; it does not model indels, strand bias, context effects, correlated PCR errors, or platform-specific confusion matrices.
  • Input is processed without network access. Completed groups are yielded incrementally; memory is bounded by the largest group plus the set of prior group names used to reject noncontiguous repeats.
  • The 60 cap prevents misleadingly extreme output qualities and means very strong posterior distinctions are intentionally compressed.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

phred_consensus-1.0.0.tar.gz (17.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

phred_consensus-1.0.0-py3-none-any.whl (13.0 kB view details)

Uploaded Python 3

File details

Details for the file phred_consensus-1.0.0.tar.gz.

File metadata

  • Download URL: phred_consensus-1.0.0.tar.gz
  • Upload date:
  • Size: 17.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for phred_consensus-1.0.0.tar.gz
Algorithm Hash digest
SHA256 84d0bc80af6ec099861b8cd1cc73e4a32fea9335dbfff2e6a59f23718ffda741
MD5 516f66beea418a658800fb98e8b349f1
BLAKE2b-256 59822c9f5fc27db1e970420c78bd0bb3e834dd7151b823ceb281da52e53b8eba

See more details on using hashes here.

Provenance

The following attestation bundles were made for phred_consensus-1.0.0.tar.gz:

Publisher: publish.yml on bmouler/phred-consensus

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file phred_consensus-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: phred_consensus-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 13.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for phred_consensus-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7c1cd8ddbd1fa05c6cc309fac8344e741fe16819964f1dc171c402f6891d0566
MD5 9d5c6a3a4aff4f81eeaee2ba2a5c38db
BLAKE2b-256 b188171279cf647b18c46d6f72dbe028b059a1d6a80f93914f6e5cb5bd48888a

See more details on using hashes here.

Provenance

The following attestation bundles were made for phred_consensus-1.0.0-py3-none-any.whl:

Publisher: publish.yml on bmouler/phred-consensus

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page