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:
- Parse alleles — trim shared prefix/suffix bases, convert VCF-padded indels to MAF coordinate conventions
- Detect annotations — auto-detect VEP CSQ or SnpEff ANN in the VCF header
- Parse all transcript effects — extract every annotated transcript for the variant
- 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
- Map SO terms to MAF classifications (missense_variant → Missense_Mutation, stop_gained → Nonsense_Mutation, etc.)
- Extract genotype depths from FORMAT fields (AD, RO/AO, DP4, Strelka tiers, NR/NV, DV, etc.)
- Write MAF with
#version 2.4header
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 |
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file vcf2maf_py-0.1.1.tar.gz.
File metadata
- Download URL: vcf2maf_py-0.1.1.tar.gz
- Upload date:
- Size: 31.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
26cf7e7be3b83288d6494228113f29acc5b95a8fd6f8dba5895546daf109fb7b
|
|
| MD5 |
1d1627394fad355743893df9a78d90d3
|
|
| BLAKE2b-256 |
8b4f81af12350b9789a4edb7c92245c0770c606591bc5bcc9b59683551842a6a
|
Provenance
The following attestation bundles were made for vcf2maf_py-0.1.1.tar.gz:
Publisher:
ci.yml on viktorlj/vcf2maf-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vcf2maf_py-0.1.1.tar.gz -
Subject digest:
26cf7e7be3b83288d6494228113f29acc5b95a8fd6f8dba5895546daf109fb7b - Sigstore transparency entry: 1165373995
- Sigstore integration time:
-
Permalink:
viktorlj/vcf2maf-py@0afc4f61188469440ad7c178680d70a2c948e500 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/viktorlj
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@0afc4f61188469440ad7c178680d70a2c948e500 -
Trigger Event:
push
-
Statement type:
File details
Details for the file vcf2maf_py-0.1.1-py3-none-any.whl.
File metadata
- Download URL: vcf2maf_py-0.1.1-py3-none-any.whl
- Upload date:
- Size: 29.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
513da7f6027345aa070bfc2bade046bce92c110778dbd588f6eedd518d65da99
|
|
| MD5 |
68026c8e26b9830a52eada3099f26e42
|
|
| BLAKE2b-256 |
2204053d283efef5a1515dc0a6e248c0e79f0e5d03bba11b2b7bb13f7fae9c5e
|
Provenance
The following attestation bundles were made for vcf2maf_py-0.1.1-py3-none-any.whl:
Publisher:
ci.yml on viktorlj/vcf2maf-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vcf2maf_py-0.1.1-py3-none-any.whl -
Subject digest:
513da7f6027345aa070bfc2bade046bce92c110778dbd588f6eedd518d65da99 - Sigstore transparency entry: 1165374043
- Sigstore integration time:
-
Permalink:
viktorlj/vcf2maf-py@0afc4f61188469440ad7c178680d70a2c948e500 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/viktorlj
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@0afc4f61188469440ad7c178680d70a2c948e500 -
Trigger Event:
push
-
Statement type: