Skip to main content

Convert VCF files to MAF format — a Python reimplementation of mskcc/vcf2maf

Project description

vcf2maf-py

A Python reimplementation of mskcc/vcf2maf — convert VCF files to MAF (Mutation Annotation Format).

Attribution

This project is a Python port of the original Perl-based vcf2maf created by Cyriac Kandoth at Memorial Sloan Kettering Cancer Center. The original tool and its conversion logic, effect prioritization, and variant classification mappings are the foundation of this reimplementation.

Cyriac Kandoth. mskcc/vcf2maf: vcf2maf v1.6. (2020). doi:10.5281/zenodo.593251

The original repository is available at https://github.com/mskcc/vcf2maf and is licensed under the Apache 2.0 License.

Features

  • VCF → MAF conversion with support for VEP and SnpEff annotations
  • MAF → VCF conversion (reverse direction)
  • Pure Python — no Perl, no C dependencies; installs with pip
  • Parses VEP CSQ and SnpEff ANN annotation fields automatically
  • Handles multi-allelic sites (splits into separate MAF rows)
  • Extracts genotype depths from 7+ variant caller FORMAT conventions (GATK, FreeBayes, Strelka, VarScan, Delly, and more)
  • Effect prioritization matching the original vcf2maf cascade (biotype → severity → canonical → transcript length)
  • Maps 130+ Sequence Ontology terms to MAF Variant_Classification
  • Supports custom isoform overrides (MSKCC, MANE, or your own)
  • Outputs MAF v2.4 compatible with cBioPortal, maftools, and GDC pipelines
  • VCF inspection command to check annotation status before conversion
  • Reads gzipped VCF/MAF files transparently

Installation

pip install vcf2maf-py

With optional reference FASTA support for MAF → VCF conversion:

pip install 'vcf2maf-py[pysam]'

Quick start

VCF → MAF

# Basic conversion (auto-detects annotations, samples, and genome build)
vcf2maf-py vcf2maf somatic.vcf -o somatic.maf

# With explicit options
vcf2maf-py vcf2maf somatic.vcf.gz \
    -o somatic.maf \
    --tumor-id TUMOR_SAMPLE \
    --normal-id NORMAL_SAMPLE \
    --ncbi-build GRCh38 \
    --center MSKCC

# Output only core 34 MAF columns
vcf2maf-py vcf2maf somatic.vcf -o somatic.maf --output-columns core

# With custom isoform overrides
vcf2maf-py vcf2maf somatic.vcf -o somatic.maf --isoform-overrides overrides.tsv

MAF → VCF

# Basic reverse conversion
vcf2maf-py maf2vcf mutations.maf -o mutations.vcf

# With reference FASTA for correct indel padding (requires pysam)
vcf2maf-py maf2vcf mutations.maf -o mutations.vcf --ref-fasta GRCh38.fa

Inspect a VCF

# Check annotation status, sample names, and variant summary
vcf2maf-py inspect somatic.vcf

Python API

from vcf2maf_py import convert_vcf_to_maf, convert_maf_to_vcf

# VCF → MAF
rows = convert_vcf_to_maf(
    "somatic.vcf",
    output_maf="somatic.maf",
    tumor_id="TUMOR",
    normal_id="NORMAL",
)

# MAF → VCF
convert_maf_to_vcf("mutations.maf", "mutations.vcf")

Annotation support

vcf2maf-py works best with annotated VCF files. It auto-detects:

Annotation tool INFO field Status
Ensembl VEP CSQ Fully supported
SnpEff ANN Fully supported
None Converts coordinates and depths; warns about missing annotations

If your VCF is not annotated, you can annotate it with Ensembl VEP:

vep --input_file input.vcf --output_file annotated.vcf \
    --vcf --offline --cache \
    --symbol --canonical --biotype --sift b --polyphen b \
    --fields "Allele,Consequence,IMPACT,SYMBOL,Gene,Feature_type,Feature,BIOTYPE,EXON,INTRON,HGVSc,HGVSp,cDNA_position,CDS_position,Protein_position,Amino_acids,Codons,Existing_variation,DISTANCE,STRAND,CANONICAL,SIFT,PolyPhen,ALLELE_NUM"

How it works

For each variant in the VCF:

  1. Parse alleles — trim shared prefix/suffix bases, convert VCF-padded indels to MAF coordinate conventions
  2. Detect annotations — auto-detect VEP CSQ or SnpEff ANN in the VCF header
  3. Parse all transcript effects — extract every annotated transcript for the variant
  4. Select the best effect using a priority cascade:
    • Biotype priority (protein_coding > IG/TR genes > ncRNA > pseudogene)
    • Effect severity (~130 SO terms ranked from transcript_ablation to intergenic_variant)
    • Canonical transcript preference
    • Custom isoform overrides
  5. Map SO terms to MAF classifications (missense_variant → Missense_Mutation, stop_gained → Nonsense_Mutation, etc.)
  6. Extract genotype depths from FORMAT fields (AD, RO/AO, DP4, Strelka tiers, NR/NV, DV, etc.)
  7. Write MAF with #version 2.4 header

Differences from the original Perl version

Feature Original (Perl) This version (Python)
Language Perl 5 Python 3.9+
VEP dependency Runs VEP as part of conversion Expects pre-annotated VCF (warns if not)
Installation Manual / Docker pip install vcf2maf-py
SnpEff support VEP field mapping only Native ANN field parsing
Reference validation Via samtools faidx Optional (via pysam)
liftOver Built-in Not yet (planned)
Python API None Full programmatic access

Known output differences

Validated against the Perl vcf2maf on ~94,000 variants across 6 VCF files (GRCh37 and GRCh38). Row counts match exactly and 82/109 shared columns are identical. The remaining differences are:

Difference Impact Details
flanking_bps empty Low Perl uses samtools faidx to fetch trinucleotide context from a reference FASTA. Not yet implemented.
Entrez_Gene_Id always 0 Low Perl has an internal gene-name-to-Entrez lookup table. Not yet implemented.
FILTER no common_variant Low Perl appends ;common_variant to the FILTER field for variants in common databases. Not implemented.
HGVSp_Short splice sites Low Perl generates synthetic p.X{position}_splice for splice donor/acceptor variants. Not implemented (2 of 103 variants in test set).
Population AF 0 vs empty Cosmetic Python preserves VEP's 0 for absent population frequencies; Perl leaves the field empty.
t_depth edge case Rare For ~5% of indels, the Perl tool computes t_depth as t_ref_count + t_alt_count while Python uses the VCF DP field. Both are valid approaches.

Development

git clone https://github.com/viktorlj/vcf2maf-py
cd vcf2maf-py
uv venv && source .venv/bin/activate
uv pip install -e '.[dev]'
pytest

License

Apache 2.0 — same as the original vcf2maf.

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

vcf2maf_py-0.1.3.tar.gz (38.2 kB view details)

Uploaded Source

Built Distribution

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

vcf2maf_py-0.1.3-py3-none-any.whl (30.5 kB view details)

Uploaded Python 3

File details

Details for the file vcf2maf_py-0.1.3.tar.gz.

File metadata

  • Download URL: vcf2maf_py-0.1.3.tar.gz
  • Upload date:
  • Size: 38.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for vcf2maf_py-0.1.3.tar.gz
Algorithm Hash digest
SHA256 58eefb3e65f0782d12874521fee05ef1d060814b98c1f1ab339e6ace254116ff
MD5 ab6ed03b6fe27ec7f78edf5c24a696bd
BLAKE2b-256 b5b61b8ab358e57c8b6132756c736b8dc05df35cc8ad8c31460fee45b1983d2e

See more details on using hashes here.

Provenance

The following attestation bundles were made for vcf2maf_py-0.1.3.tar.gz:

Publisher: ci.yml on viktorlj/vcf2maf-py

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

File details

Details for the file vcf2maf_py-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: vcf2maf_py-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 30.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for vcf2maf_py-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 3ee329be642df0a174bf1a1ba153da809f14eee4f240b35651d7365306a79d4d
MD5 8fa242972742b7eae32af02a760b51af
BLAKE2b-256 e71bf83726fe0b37e4225ab53f6d4d36f67180287155f62afa0618e33790b57a

See more details on using hashes here.

Provenance

The following attestation bundles were made for vcf2maf_py-0.1.3-py3-none-any.whl:

Publisher: ci.yml on viktorlj/vcf2maf-py

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