Repository navigation
Releases: FOI-Bioinformatics/tessera
Release list
v1.2.0
What's Changed
- Test the CLI and binary preflight; ship a container with the aligners pinned by @druvus in #54
- Say plainly that distribution is GitHub-only by @druvus in #55
- Cache remote BLAST results, so a re-run does not repeat the slow part by @druvus in #56
- Scan dependencies for vulnerabilities, and pin the actions to commit SHAs by @druvus in #57
- Report similarity as similarity on near-identical panels by @druvus in #68
- Close the input and cache defects found by a second review by @druvus in #71
- Release 1.2.0 by @druvus in #70
Full Changelog: v1.1.0...v1.2.0
v1.1.0
What's Changed
- Stop reporting recombination the data does not support by @druvus in #44
- Measure the false-positive rate, not just a verdict (specificity harness) by @druvus in #46
- Do not gate on caller agreement by default: it costs real detections by @druvus in #47
- Derive window spacing from the median gap, not the first one by @druvus in #48
- Reassortment: cap candidates by ANI window, not by rank alone by @druvus in #49
- Benchmark the region callers, and document the upper divergence bound by @druvus in #50
- Close the audit's silent-wrong-answer and robustness findings by @druvus in #51
- Bound the unbounded computations; make the package installable, typed and citable by @druvus in #52
- Release 1.1.0 by @druvus in #53
Full Changelog: v1.0.0...v1.1.0
Tessera 1.0.0
Initial release of Tessera -- viral recombination detection. Full notes below.
The initial tessera release: the rebuild of the recomfi prototype as the tessera package --
package and CLI renamed from recomfi to tessera (tessera entry point, src/tessera/
layout). recomfi was never released, so the first public version is 1.0.0 (a stable first
release), not a continuation of a prior series.
Added
Core engine. Rebuilt as a dependency-free Python package with a Typer CLI, an entry-point
aligner registry, and a native numpy sliding-window similarity engine (no external recan
dependency). Builds a reference-anchored pseudo-MSA from XMFA / MAF / HAL, excludes ambiguous
bases (N / IUPAC) from comparability, and reports uninformative windows as NA.
Commands.
detect-- one-shot, zero-config entry point: taxon detection, diverse panel recruitment,
alignment, and recombination calling, with a plain-language confidence verdict and a run log.build-panel,recomb,msa-- panel building, detection, and alignment as separate steps
(re-run detection with different settings without re-fetching or re-aligning).find-references,fill-references-- BLAST-based reference discovery and the iterative
build-scan-BLAST-download gap-filling loop (fill_summary.tsvper round).curate-panel-- skani sibling-drop (backbone-relative, no per-organism cutoff) plus skDER
dereplication; also available asfill-references --curate.type-lineages-- assign a lineage to every genome in a collection via a ladder
(header / metadata designation, nearest Nextclade-dataset tip by skani ANI, de-novo ANI
clustering); writes alineages.tsvsidecar the other commands read.reassort-- per-segment reassortment detection for segmented viruses (see Reassortment).
Detection methods. A default four-caller ensemble (HMM segmentation, 3SEQ, MaxChi,
Bootscan) with a lineage-aware consensus merge; each caller is also selectable via --method.
- HMM segmentation (jpHMM-style) with a discordant-site sign test at
--alpha, support scores,
Benjamini-Hochberg q-values, and breakpoint-uncertainty intervals. - 3SEQ maximum-drawdown triplet test, MaxChi chi-square triplet test, and Bootscan
bootstrap-support caller. - Opt-in GENECONV-style clean-fragment caller (
--method geneconv, Sawyer 1989): the longest
uninterrupted run of donor-matches over the triplet discriminating sites, with a permutation
p-value and Benjamini-Hochberg across donors. Not in the default ensemble. - Parent-free PHI (Pairwise Homoplasy Index) and Hudson-Kaplan Rmin diagnostics that
fire even when the true donor is absent from the panel (recombination_profile.tsv). - Opt-in clade-barcode (lineage-marker) caller for typed panels.
- Informative-site windowing for low-divergence panels (auto-enabled below ~8% between-reference
divergence), so windows span polymorphic columns rather than base pairs. - Site callers draw candidate donors from all references (not only window winners) and gate on the
Benjamini-Hochberg q-value, so short sub-window tracts are recovered while the false-call rate
does not scale with the number of candidates scanned.
Reference panels.
- Seed sources: BLAST (
--seed-mode whole|windowed|parents), a finite local pool (skDER
dereplication + skani region matching), NCBI Virus (taxon-scopeddatasetsdownload, cached),
and Nextclade (reference-tree tips reconstructed and clade-labelled, dataset auto-detected or
pinned). Auto-diversify and negative-lineage BLAST recruit divergent parents when a lineage
saturates NCBI nt. - Sibling exclusion and lineage-cluster competition in the caller so near-identical relatives
cannot mask an event. - Lineage-aware panel selection; typed lineage names in the report; query self-typing; a
SARS-CoV-2 Pango recombinant cross-check;--deep-typing(full typing ladder on the recruited
panel);--reattribute-donors(opt-in post-hoc donor re-labelling);--pool-consensus
(one denoised consensus genome per clade).
Aligner backends. mafft (base-level, --addfragments for fragmented queries), minimap2,
SibeliaZ (default), progressiveMauve, and cactus, via a pluggable entry-point registry.
Output. A self-contained HTML report (query-mosaic track, called-regions table, window-winner
chart, per-dataset stats, embedded similarity plot, methods glossary); recombination_regions.tsv
(query + MSA coordinates, support, p / q-values, breakpoint interval, calling methods),
recombination_methods.tsv, recombination_profile.tsv, coverage_gaps.tsv,
panel_lineages.tsv, and a persisted run log.
Reassortment. For segmented viruses (influenza, bunyaviruses, reoviruses); a whole-segment swap
between parents cannot be represented by the single-backbone intragenic scan.
reassorttypes each segment of a multi-FASTA query against its own Nextclade dataset and calls
reassortment when the segments trace to different parents; writesreassortment.tsvand
constellation.tsvand prints a genotype mosaic plus aclonal/reassortant/undetermined
verdict. The verdict is a pairwise, coverage-aware comparison (concordant / discordant /
uninformative over an ANI margin,--margin), so a clonal isolate whose parent strain is not
cross-typed in every segment's tree is not miscalled a reassortant as the segment count grows;
segments are grouped into parent constellations (ranking uses skani ANI and alignment fraction).reassort --scan-segmentsaligns each assigned segment to its own per-clade-consensus panel and
runs the ordinary recombination scan (run_recomb), writing the full per-segment output to
out/<segment>/and a rollup toout/segment_scan.tsv(needs an aligner,--alignerdefault
mafft; a per-segment scan failure is non-fatal).
Validation harnesses (opt-in, not part of CI). Harnesses that score detection on real and
simulated recombination against a documented expectation, recording measured results.
validation/run_reassort_scan.py-- builds a real-tip insert-shaped recombinant plus a clonal
control and checks thatreassort --scan-segmentslocalizes the intragenic recombination
(localization-gated; attribution and specificity reported).validation/run_method_comparison.py-- runs Tessera's callers beside OpenRDP (the maintained
RDP5 reimplementation) on the same published-recombinant alignments, in one combined table;
validation/run_method_comparison_hybrids.pymeasures short-tract sensitivity against ground
truth, including an adversarial sub-window-tract tier.- Benchmark scoring against published datasets: real published recombinants
(validation/run_validation.py,datasets.json, including the HCV 2k/1b inter-genotype
recombinant -- a Flaviviridae case with a precise ~nt 3187 breakpoint -- and a real clonal-negative
control scored by amax_regionskey); reassortment precision / recall / F1
(validation/run_reassort_benchmark.py); and simulated benchmarks -- SANTA-SIM power/specificity
(Jaya 2023,run_benchmark.py), a coalescent design (Posada & Crandall 2001,
run_coalescent_benchmark.py, msprime), and breakpoint noise-robustness (RecombinHunt 2024,
run_recombinhunt_benchmark.py). The pure scorers are unit-tested. - Synthetic-hybrid harness (
validation/run_hybrids.py): a broadened specificity panel of nine
non-recombinantneg_purecontrols across the divergence and panel-size axes, plus two
neg_withinintra-clade-splice controls (the panel keeps both same-clade sources so the splice
is credited intra-clade).neg_hiv1is reported as an investigatedKNOWN-LIMIT(not gating): a
pure HIV subtype genome is statistically indistinguishable from a real recombinant against a
source-removed subtype panel, so it cannot be suppressed without breaking genuine detection.
Datasets with no Nextclade clade attribute are typed de-novo by ANI-clustering their reconstructed
tips, making five of six previously-skipped datasets runnable.
Changed
- CI installs an aligner (mafft) and runs the
requires_binarytests, so the MSA-build and
end-to-end recombination paths are exercised in CI rather than only locally.
Fixed
- MAF reverse-strand projection scrambled SibeliaZ / cactus coordinates (~43% of blocks place the
reference on the-strand); blocks are now placed at their true forward-reference coordinate. find-referencesreturned the query's own record as a self-hit; near-identical near-full-length
hits are auto-skipped (--keep-self-hitsto override,--excludeto drop accessions).- HMM emission produced degenerate likelihoods on some near-identical panels (the CRF01_AE
env-region case). - The Nextclade examples fetch was fatal when a dataset had no examples or the network failed; it
is now non-fatal, and clade labelling prefersLANL_subtypewhere present. - A coverage gap overlapping a low-donor-similarity region is now flagged as donor-undercovered
rather than reported as a confident call. - NCBI Virus full-download for mega-taxa (HIV cold-start): a spurious
--limit, anARG_MAX
overflow from inline skDER paths, and skDER representative symlinks resolved after their temp
directory was removed. build_pool(per_clade_consensus=True)crashed on within-clade indels: the per-clade consensus
reconstructed tips with deletion gaps stripped, so unequal-length tips reached
consensus_sequenceand raised. It now reconstructs in gapped reference coordinates first, which
also repairsdetect's consensus-pool mode on datasets with indels (e.g. influenza).- Nextclade example sequences were written with a mined clade prefix that could masquerade as a real
clade; they now carry anexamplemarker and are treated as untyped by the pool consumers. reassortrejects duplicate segment names up front, rather than silently dropping a colliding
segment (w...