Skip to main content

BRANCHSNV — Exact branch-level SNV interrogation from a rooted tree and alignment

CI CodeQL Python 3.10–3.14 Latest release

PyPI Bioconda Conda downloads Documentation status bio.tools DOI

Runtime dependencies: 0 License: MIT Status: beta

Identify nucleotide states that distinguish a clade and substitutions that reconstruct to a selected phylogenetic branch — without conflating the two.

BRANCHSNV is a dependency-free Python command-line tool for interrogating one selected branch of a rooted bacterial phylogeny using a nucleotide NEXUS SNV matrix. It reports strict clade-exclusive nucleotide markers separately from substitutions reconstructed on the focal edge, retains uncertainty across all globally optimal equal-cost parsimony solutions, validates exact taxon and branch membership, and records deterministic SHA-256 provenance.

NEXUS alignment             ─┐
Newick tree + rooting choice ├──> BRANCHSNV ───> results.tsv
exact focal-clade tip list ──┘                  members.txt
                                                report.json

What BRANCHSNV reports

Mode Question answered Reporting rule
fixed-exclusive Which nucleotide states are strict markers of this clade in the supplied dataset? Every descendant has the same unambiguous base; every outside taxon is callable; no outside taxon has that base.
parsimony Which substitutions reconstruct to the selected branch? Parent and child states are evaluated across all globally optimal equal-cost Sankoff reconstructions.
both Which sites meet either definition? Reports the union and records the reason for each row. This is the default.

The definitions are deliberately separate. A strict clade marker can have ambiguous placement on the incoming branch, while a reconstructed branch change can recur elsewhere and therefore not be clade-exclusive.

Installation

BRANCHSNV requires Python 3.10 or later.

Install the stable release from Bioconda:

conda create -n branchsnv branchsnv=0.1.0 \
  --channel conda-forge \
  --channel bioconda \
  --strict-channel-priority
conda activate branchsnv
branchsnv --version

Alternatively, install from PyPI:

python -m pip install branchsnv==0.1.0
branchsnv --version

Or install directly from the tagged source release:

git clone https://github.com/RhysWhite/branchsnv.git
cd branchsnv
git checkout v0.1.0
python -m pip install .
branchsnv --version

For development installation and contribution guidance, see CONTRIBUTING.md.

Quick start

The bundled example contains five taxa, six sites, and a focal branch containing isolates A and B.

branchsnv find \
  --alignment examples/simple/alignment.nex \
  --tree examples/simple/tree.nwk \
  --outgroup Outgroup \
  --clade-tips examples/simple/clade_tips.txt \
  --mode both \
  --output results.tsv \
  --members-output members.txt \
  --report report.json

BRANCHSNV reports:

Selected b_daee1cd25194ae95 (2 descendants); reported 2 of 6 sites.

The full TSV contains the original site identifier, inferred parent and child states, all optimal focal-edge state pairs, call counts, parsimony score, and selection reason. The example reduces to:

Site Reconstructed change Parsimony status Fixed-exclusive Reported because
ref_1 G>A unambiguous_change yes both
ref_6 ambiguous placement_ambiguous yes fixed-exclusive

Committed expected outputs are available in examples/simple/expected/.

Running BRANCHSNV on your data

1. Prepare three inputs

You need:

  1. a nucleotide NEXUS matrix in conventional taxon-by-character or transposed character-by-taxon orientation;
  2. a Newick tree containing exactly the same taxon names; and
  3. the exact tip names descending from the branch of interest.

The NEXUS taxon order does not need to match the visual tip order in the tree. BRANCHSNV matches taxa by exact name.

Example focal-clade file:

isolate_A
isolate_B
isolate_C

2. Validate the alignment, tree, and root

For a single outgroup tip:

branchsnv validate \
  --alignment alignment.nex \
  --tree tree.nwk \
  --outgroup Outgroup_isolate

For an outgroup containing several genomes:

branchsnv validate \
  --alignment alignment.nex \
  --tree tree.nwk \
  --outgroup outgroup_1 outgroup_2 outgroup_3 outgroup_4

A one-name-per-line outgroup file can instead be supplied with --outgroup-file outgroup_tips.txt.

3. Find branch-associated SNVs

branchsnv find \
  --alignment alignment.nex \
  --tree tree.nwk \
  --outgroup-file outgroup_tips.txt \
  --clade-tips clade_tips.txt \
  --mode both \
  --output branch_snvs.tsv \
  --members-output branch_members.txt \
  --report branchsnv_report.json

BRANCHSNV stops if the requested tips do not form exactly one rooted clade, if tree and alignment taxa differ, or if unsupported input is encountered.

Selecting a branch

Method Option Best use Important detail
Exact descendants --clade-tips clade_tips.txt Publication and permanent analyses Recommended. The file must equal the complete descendant set of one branch.
MRCA anchors --mrca isolate_A isolate_B Exploration The selected MRCA may contain additional descendants. Inspect members.txt.
Deterministic branch ID --branch-id b_daee1cd25194ae95 Repeating an inspected selection Generate IDs first with branchsnv inspect. Full IDs or unique prefixes are accepted.

To list every branch and its deterministic identifier:

branchsnv inspect \
  --tree tree.nwk \
  --outgroup-file outgroup_tips.txt \
  --output branches.tsv

A branch ID is derived from the SHA-256 hash of its sorted exact descendant-tip names. It is unaffected by sibling order, branch lengths, or Newick formatting outside taxon labels, but exact taxon-name content is significant. It intentionally changes when rooting or descendant membership changes.

See docs/branch-selection.md for details.

Rooting is explicit

Every command that interprets branches requires one of:

--outgroup TIP [TIP ...]
--outgroup-file outgroup_tips.txt
--accept-existing-root

BRANCHSNV never silently assumes that the encoded Newick root is biologically appropriate. Branch direction and reconstructed parent-to-child changes depend on the chosen root.

Output files

File Purpose
results.tsv Reported sites, ancestral-state results, call counts, parsimony scores, and selection reasons.
members.txt Sorted, one-name-per-line record of every descendant on the selected branch.
report.json Deterministic provenance: versions, input dimensions, rooting and selection methods, parameters, counts, and SHA-256 checksums.

The JSON report omits timestamps and absolute paths so that identical input files and parameters produce identical output bytes in different working directories. Its schema is documented in schemas/branchsnv-report.schema.json.

Parsimony classifications

BRANCHSNV uses unordered equal-cost Sankoff parsimony over A, C, G, and T, retaining the complete set of parent-child state pairs attainable on the focal edge among globally optimal reconstructions.

Status Interpretation
unambiguous_change One parent-child pair is possible and the states differ.
change_state_ambiguous Every optimum changes on the edge, but the exact transition is not unique.
placement_ambiguous Some optima change on the edge and others do not.
no_change No optimum changes on the selected edge.

By default, parsimony mode reports only unambiguous_change. Add --include-ambiguous to include the two ambiguous categories.

Input scope

BRANCHSNV accepts one nucleotide DATA or CHARACTERS NEXUS block in conventional taxon-by-character or transposed character-by-taxon orientation, together with one Newick tree with unique exact tip names. It supports quoted labels, comments, branch lengths, multifurcations, standard IUPAC ambiguity codes, and declared missing and gap symbols.

It deliberately does not support interleaved matrices, multiple data blocks, indel reconstruction, structural variants, fuzzy taxon matching, or general-purpose NEXUS dialects. Unsupported content is rejected rather than guessed.

See docs/input-formats.md for the complete accepted subset.

Interpretation and limitations

Every result is conditional on the supplied alignment, upstream filters, tree topology, root, selected descendants, and state model.

“Branch-associated” does not mean causal, adaptive, free from recombination, or unique under future sampling. BRANCHSNV also does not use branch lengths, unequal substitution rates, or nucleotide frequencies in ancestral reconstruction.

See docs/interpretation.md for reporting language and interpretive cautions.

Validation and reproducibility

Production tests and publication validation are deliberately separated.

The production repository contains the unit, regression, determinism, packaging, and bundled-example checks used during development. The current test suite contains 80 tests and is run across Python 3.10–3.14, with additional macOS and Windows jobs in GitHub Actions.

The independent publication-validation repository is maintained separately at RhysWhite/branchsnv-validation. The stable v0.1.0 validation release is archived at https://doi.org/10.5281/zenodo.21919067. It preserves two version-pinned records:

  • the historical publication snapshot for BRANCHSNV v0.1.0a1; and
  • a separate stable-release validation record for BRANCHSNV v0.1.0 under release_validation/v0.1.0/.

Both records support the same deterministic analytical headline results:

Validation layer Result
Independent exhaustive oracle 128,881/128,881 exact comparisons across seven topology–edge settings
Deliberately faulted implementations 10/10 fault classes detected across 280,216 fault–challenge comparisons
SNPPar comparison 877/877 BRANCHSNV-unambiguous substitutions matched SNPPar; 66 additional SNPPar events were retained as placement-ambiguous
Published focal branches 46/46 published SNVs reproduced across MRSA AK3, MRSA ST97, and E. coli ST131/OXA-48
Complete-phylogeny empirical analysis 31,644 informative comparisons across five phylogenies; 827 (2.61%) fell outside the fixed-exclusive/unambiguous-substitution intersection
Scalability 39/39 measured end-to-end command-line runs completed

The stable v0.1.0 run was generated against production commit 71b055bdbd8e00ee63afda136b88892aee0062f8 using validation-framework commit cfb07389191540ca57c9e822b254c279ab903f36. It verified the production source identity for all 13 Python source files, the validation-script identity, the Experiments 01–06 pass criteria, and exact reproduction of the deterministic analytical outputs in the canonical scientific snapshot. Experiment 04 performance measurements are retained as environment-specific observations.

At validation-repository commit 35a0794ddd9782355e1e06dd95bd10e1cde4c735, the stable record is checksum-gated and checked in CI. The historical snapshot remains separately verifiable with verify_publication_snapshot.py.

The older validation/ak3/ directory in this repository is retained as a checksum-gated working-data regression recipe. It is not the authoritative independent validation record.

See VALIDATION_REPORT.md and docs/validation.md for details.

Documentation

Hosted documentation is available at branchsnv.readthedocs.io.

BRANCHSNV is indexed in the ELIXIR bio.tools registry as biotools:branchsnv. The archived software release is available from Zenodo, and installable releases are available from Bioconda and PyPI.

Topic Document
Accepted NEXUS and Newick syntax docs/input-formats.md
Exact descendants, MRCA, and branch IDs docs/branch-selection.md
Fixed-exclusive and Sankoff algorithms docs/algorithm.md
Scientific interpretation docs/interpretation.md
Validation design docs/validation.md
Shell and Snakemake integration docs/workflow-integration.md
Annotated source-code walkthrough (v0.1.0a1) docs/code-walkthrough/v0.1.0a1/README.md
Contributing CONTRIBUTING.md
Release history CHANGELOG.md

Funding and affiliation

Genomics Aotearoa        PHF Science

Development of BRANCHSNV was supported by Genomics Aotearoa and undertaken at Public Health and Forensic Science (PHF Science), Aotearoa New Zealand.

BRANCHSNV was developed and is maintained by Rhys White.

Citation

Citation metadata are provided in CITATION.cff.

BRANCHSNV v0.1.0 is permanently archived at https://doi.org/10.5281/zenodo.21919038. The corresponding publication-validation release is archived separately at https://doi.org/10.5281/zenodo.21919067.

Licence

BRANCHSNV is released under the MIT License.

Metadata

Release files for branchsnv 0.2.0

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

Source distribution (sdist)

Source distribution for branchsnv 0.2.0
File Size Uploaded
branchsnv-0.2.0.tar.gz 132.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for branchsnv 0.2.0
File Interpreter ABI Platform
branchsnv-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 164.4 kB

Release files / branchsnv-0.2.0.tar.gz

Download URL branchsnv-0.2.0.tar.gz
Size 132.8 kB
Tags Source
SHA-256 checksum
How to use checksums
2000ae11e634cc2f7dc76936aee7247205c2f4e4f2a5aff2e546ce0996175cbd
BLAKE2b-256 checksum
How to use checksums
224ff888cab2a440d404f6f68cc675fee7b6bccc86574163a9154ae499a411c5
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 Oct 6, 2026.

Transparency log

Release files / branchsnv-0.2.0-py3-none-any.whl

Download URL branchsnv-0.2.0-py3-none-any.whl
Size 31.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c62b81bd6bea76f39a965d954f368ce8ff9018c721c371c9fa492b079bd43683
BLAKE2b-256 checksum
How to use checksums
9a55b3287ead01fc3ae8d7a62facf84b2f92bf3b78f0b2e50d1677e964fb96b3
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 Oct 6, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.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