Skip to main content

A streaming pipeline library for identifying and classifying pathogenic genetic variants from VCF data

Project description

vartriage

Variant prioritization pipeline for whole-genome sequencing data. Reads a VCF, applies quality filters, annotates functional consequence and population frequency, computes pathogenicity scores, runs ACMG/AMP evidence classification, and writes a ranked candidate list in JSON, CSV, or PDF.

Processes 4M+ variant WGS files under 2GB memory via batched iterators.

Install

pip install vartriage

With faster annotation backends (polars + pyranges):

pip install vartriage[accelerated]

With PDF report support:

pip install vartriage[pdf]

All optional extras:

pip install vartriage[all]

Usage

from pathlib import Path
from vartriage import (
    Pipeline, PipelineConfig, AnnotationConfig,
    PrioritizationConfig, QualityFilterConfig, ReportConfig,
)

config = PipelineConfig(
    vcf_path=Path("sample.vcf.gz"),
    output_path=Path("candidates.json"),
    quality_filter=QualityFilterConfig(min_qual=30.0),
    annotation=AnnotationConfig(
        gene_annotation_path=Path("gencode.v44.gtf"),
        gnomad_path=Path("gnomad.v4.sites.tsv"),
        clinvar_path=Path("clinvar_20240101.tsv"),
    ),
    prioritization=PrioritizationConfig(
        max_allele_frequency=0.01,
        cadd_scores_path=Path("cadd_scores.tsv"),
        revel_scores_path=Path("revel_scores.tsv"),
    ),
    report=ReportConfig(output_format="json"),
)

pipeline = Pipeline(config)
pipeline.run()

Individual stages work on their own:

from vartriage import VCFParser, QualityFilter, QualityFilterConfig

with VCFParser(Path("input.vcf.gz")) as parser:
    qf = QualityFilter(QualityFilterConfig(min_qual=30.0))
    for variant in qf.apply(iter(parser)):
        print(f"{variant.chrom}:{variant.pos} {variant.ref}>{variant.alt}")

Command Line

After installation, the vartriage command is available:

vartriage --vcf sample.vcf.gz --output candidates.json

With annotation and scoring references:

vartriage \
  --vcf sample.vcf.gz \
  --output report.json \
  --output-format json \
  --gene-annotation gencode.v44.gtf \
  --gnomad gnomad.v4.sites.tsv \
  --clinvar clinvar_20240101.tsv \
  --cadd-scores cadd_scores.tsv \
  --revel-scores revel_scores.tsv

Run vartriage --help for all options.

Pipeline stages

VCFParser > QualityFilter > AnnotationEngine > PrioritizationEngine > ACMGClassifier > ReportGenerator

Quality filtering

Drops variants where:

  • FILTER is not PASS or .
  • QUAL is below the threshold (default 20)
  • QUAL field is missing (emits a warning)

Passing variants keep their original order.

Annotation

Adds three annotations to each surviving variant:

Functional consequence: Looked up against gene models (GTF/GFF). Splice_Site applies within 2bp of an exon-intron boundary. When multiple transcripts disagree, the most damaging consequence wins. Severity ranking (highest first): Frameshift, Nonsense, Splice_Site, Missense, In_Frame_Insertion, In_Frame_Deletion, Synonymous, Intergenic.

Population frequency: Matched against gnomAD by (chrom, pos, ref, alt). Variants not found get frequency_unknown=True and a MissingDataWarning.

ClinVar assertion: Pathogenic, Likely_Pathogenic, VUS, Likely_Benign, or Benign when available.

Prioritization

Two phases:

  1. Frequency gate: drops variants with AF above the threshold (default 0.01). Variants marked frequency_unknown always pass.
  2. Composite scoring: normalizes CADD Phred (divide by 99, cap at 1.0) and REVEL (already 0-1), then computes:
composite = (REVEL x 0.6) + (CADD_normalized x 0.4)

Falls back to the single available score when only one source exists. Output sorted descending by composite rank; variants without scores go last.

ACMG classification

Evidence tagging per ACMG/AMP 2015:

Tag Strength Condition
PVS1 Very Strong Nonsense or Frameshift
PM2 Moderate gnomAD AF < 0.0001
PP3 Supporting REVEL > 0.7
PP5 Supporting ClinVar Pathogenic, no conflicting Benign

Tags combine per standard rules into: Pathogenic, Likely_Pathogenic, or VUS. If a data source is unavailable, the corresponding tag is omitted.

Report output

Fields in all formats:

Field Description
chromosome Chromosome name
position 1-based position
ref_allele Reference allele
alt_allele Alternate allele
functional_consequence Most severe consequence
allele_frequency gnomAD AF (null if unknown)
composite_rank Pathogenicity score 0-1
clinvar_assertion ClinVar significance
acmg_classification Final classification
evidence_tags Applied evidence codes

Null values: null in JSON, empty in CSV, N/A in PDF.

Configuration

QualityFilterConfig

Field Type Default Range
min_qual float 20.0 0 to 1,000,000

AnnotationConfig

Field Type Default Notes
gene_annotation_path Path required GTF/GFF
gnomad_path Path required TSV (see format below)
clinvar_path Path None TSV (see format below)
batch_size int 10,000 1,000 to 100,000

PrioritizationConfig

Field Type Default Range
max_allele_frequency float 0.01 0.0 to 1.0
cadd_scores_path Path None CADD Phred TSV
revel_scores_path Path None REVEL scores TSV
batch_size int 10,000 1,000 to 100,000

ReportConfig

Field Type Default Options
output_format str "json" "json", "csv", "pdf"

MissingDataConfig

Field Type Default Notes
warning_threshold int 1000 Summary warning when exceeded

Reference file formats

All reference files are tab-separated with a header row.

gnomAD:

chrom	pos	ref	alt	af
chr1	12345	A	G	0.00032

ClinVar:

chrom	pos	ref	alt	clinical_significance
chr1	12345	A	G	Pathogenic

Recognized values: Pathogenic, Likely pathogenic, Uncertain significance, Likely benign, Benign.

CADD / REVEL:

chrom	pos	ref	alt	score
chr1	12345	A	G	28.5

Missing data handling

Variants absent from gnomAD are never dropped. They get frequency_unknown=True and pass the frequency filter. Same for ClinVar: no match means clinvar_unknown=True.

A MissingDataWarning is emitted per lookup miss. Once the total exceeds warning_threshold, a summary fires with the count and contributing sources.

pipeline.run()
acc = pipeline.warning_accumulator
print(f"{acc.total_count} missing data events across {acc.sources}")

Dependencies

Package Required Extra Purpose
pysam yes n/a VCF streaming (htslib)
numpy yes n/a Score normalization
polars no [accelerated] Batch frequency/ClinVar joins
pyranges no [accelerated] Interval overlap queries
reportlab no [pdf] PDF report generation

Without optional extras, the library uses pure-Python fallbacks (dict-based lookups, bisect-based interval tree). Correct output either way; the accelerated path runs faster on large reference files.

Error handling

Invalid configuration raises ValueError or FileNotFoundError at construction time, before any variants are processed.

During processing, missing reference data does not crash. The library assigns null values, sets flags, and continues. After a run, inspect pipeline.warning_accumulator to see how many lookup misses occurred and which sources were affected.

Tests

pytest tests/                        # full suite
pytest tests/ -m "not slow"          # skip performance benchmarks
mypy --strict vartriage/  # type checking

Tests pass. mypy strict, 0 errors.

Project layout

vartriage/
    pipeline.py           # Top-level orchestrator
    protocols.py          # Protocol interfaces for swappable backends
    io/                   # VCF parsing, exceptions
    filter/               # Quality-based exclusion
    annotation/           # Consequence, frequency, ClinVar lookups
    prioritization/       # AF gating + pathogenicity scoring
    classification/       # ACMG evidence tagging + combining
    reporting/            # JSON, CSV, PDF output
    models/               # Dataclasses, enums, configs, warnings
    _internal/            # Batch utils, interval tree, vectorized ops

Requirements

  • Python >= 3.10
  • pysam >= 0.22.0
  • numpy >= 1.24.0

License

MIT

Project details


Download files

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

Source Distribution

vartriage-0.1.0.tar.gz (233.8 kB view details)

Uploaded Source

Built Distribution

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

vartriage-0.1.0-py3-none-any.whl (74.1 kB view details)

Uploaded Python 3

File details

Details for the file vartriage-0.1.0.tar.gz.

File metadata

  • Download URL: vartriage-0.1.0.tar.gz
  • Upload date:
  • Size: 233.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for vartriage-0.1.0.tar.gz
Algorithm Hash digest
SHA256 9fc1b156d3cab56e7190bcbdcc46866706153f85175c630f69ba55bdb7aa3b4c
MD5 28e19bb57c5a96650044bf5bad5b450c
BLAKE2b-256 e5887fc7c094d0314d62a8c30cc40fc7d9e3f1d522431245ae7762acd9a51cf7

See more details on using hashes here.

Provenance

The following attestation bundles were made for vartriage-0.1.0.tar.gz:

Publisher: publish.yml on Behordeun/vartriage

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

File details

Details for the file vartriage-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: vartriage-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 74.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for vartriage-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e9328d985ef99f088cdf9b14c60833b4160f5fe360d8e38f0909781088ae223d
MD5 b9e5492b1d2010addcbfd5e252c84c04
BLAKE2b-256 623d827aa939985fac8d0a3e0b06004726fc081e3e0949bd6399c9a061e6eee0

See more details on using hashes here.

Provenance

The following attestation bundles were made for vartriage-0.1.0-py3-none-any.whl:

Publisher: publish.yml on Behordeun/vartriage

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 Pingdom Monitoring Sentry Error logging StatusPage Status page