Ahmed Doghri Logo Image
Ahmed Doghri

vrsbridge

Two VCF rows can describe one molecular change and still miss each other downstream. vrsbridge normalizes the allele into GA4GH VRS, so four different strings collapse into the two variants they actually are.

vrsbridge genomic variant equivalence workbench
vrsbridge workbench translating four VCF records into two normalized alleles

The String Is Not the Variant

Variant callers keep different amounts of surrounding sequence, so two VCF rows can look different while describing the same molecular edit. That breaks joins across cohorts, annotations, and knowledge bases, quietly.

vrsbridge parses sequence-resolved SNVs and indels, expands multiallelic records, trims redundant prefix and suffix context, and converts one-based VCF positions into inter-residue coordinates.

Bridge VCF to a Shared Model

Each normalized record becomes a GA4GH VRS 1.3 Allele with a SequenceLocation and a LiteralSequenceExpression. A deterministic local digest groups equivalent structures so you can inspect them in the CLI, the JSON API, or the browser workbench.

The Demo

Four VCF records encode two molecular changes. A context-rich substitution, GAT→GCT at 100, and its minimal form, A→C at 101, both become an A-to-C change at inter-residue 100 to 101. Two deletion encodings, AAT→AA and AT→A, both become the T deleted at 201 to 202. Four strings, two computable alleles, and CI asserts exactly that on every push.

The scope is explicit. Minimal normalization removes shared context, but fully justifying an indel across a repeat needs a reference-sequence service. The local digest is an equivalence key, not a GA4GH computed identifier.

Two Bugs, One Silent and One Loud

The parser fell back to splitting on any whitespace whenever a tab-delimited line came up short. That was meant to tolerate space-delimited exports, but it also turned a truncated tab-delimited record, a missing ALT column with a stray internal space, into a different and wrong variant, with no error. For a tool whose whole job is getting coordinates right, that's the worst kind of failure. The whitespace fallback now fires only on lines with no tabs at all, and a short tab-delimited line is rejected as malformed.

The second turned up while auditing this page. The browser workbench lived in a web/ folder outside the Python package, so a regular install, the Docker image included, served a FileNotFoundError instead of the page. The UI now ships inside the package, a test checks that it resolves next to the installed module, and CI builds the image and fetches the page before it goes green. 8 tests pass across Python 3.10 through 3.13.

Standards Basis

Built against the GA4GH VRS 1.3 model and its normalization guidance.

Try It

No dependencies:

git clone https://github.com/ahmeddoghri/vrsbridge && cd vrsbridge
pip install -e .
vrsbridge translate demo/variants.vcf --sequences demo/sequences.json
vrsbridge compare demo/variants.vcf --sequences demo/sequences.json  # 4 strings → 2 alleles
vrsbridge serve                                                      # workbench on :8090

Or docker compose up --build.

Tools Used

Python
GA4GH VRS 1.3
VCF
Genomics
Variant Normalization
Docker
Input Validation
unittest