dbNSFP — aggregated in-silico predictor scores¶
dbNSFP (database for Non-Synonymous SNPs' Functional Predictions) doesn't
compute its own scores — it aggregates the outputs of dozens of published
predictor tools (SIFT, PolyPhen2, CADD, REVEL, AlphaMissense, MetaRNN, ESM1b,
…) into one row per variant, one column pair (*_score/*_pred) per tool.
iris reads dbNSFP5.0a (released 2025-01-01, GRCh38, built on GENCODE
46/Ensembl 112) as 25 bgzipped, tabix-indexed, per-chromosome TSVs at
/mnt/cephfs/hot_nvme/dbNSFP5/ (34 GB total for the files iris actually
uses) — same per-chromosome layout as MCPS, unlike
dbSNP/CADD's single whole-genome files.
This page documents the file and shows how iris reads it via
DbNsfpAnnotator (src/iris/adapters/driven/annotators/dbnsfp.py). Every
number and example below ran against the real files.
Other files in the same directory — don't read these directly¶
| File(s) | What it is |
|---|---|
dbNSFP5.0a_variant.chr{1..22,X,Y,M}.bgz (+ .tbi) |
What DbNsfpAnnotator reads — 25 files, 34 GB total |
dbNSFP5.0a_variant.chr*.gz |
Plain gzip duplicates of the same 25 files, not bgzip/tabix-indexed |
dbNSFP5.0a_grch38.gz (+ .tbi) |
The same data pre-split, recombined into one 37 GB whole-genome tabix file — not what file_pattern points at, and not needed since the per-chromosome split already gives workers something to parallelize over |
dbNSFP5.0_gene.gz |
Gene-level aggregates (constraint, disease association, expression) — a different table entirely; not read by DbNsfpAnnotator, which is variant-level only |
search_dbNSFP50a.jar, h, hg, tryhg*.in, try.vcf |
dbNSFP's own Java command-line search tool and its example inputs — unrelated to iris |
Scale¶
25 files (22 autosomes + X + Y + M, note: M not MT — see
below).
Real per-file row counts:
| Chromosome | Rows | Fetch time |
|---|---|---|
21 (smallest autosome) |
808,183 | 4.3s |
Y |
166,756 | 0.6s |
M (mitochondrial) |
25,574 | <0.1s |
Unlike CADD (exhaustive, ~3 rows per position genome-wide), dbNSFP only carries rows for variants its constituent predictor tools actually scored — overwhelmingly coding and near-coding SNVs, since most of the aggregated tools (SIFT, PolyPhen2, …) are protein-effect predictors by design. 25,574 rows for a 16.6 kb mitochondrial genome is far denser than any nuclear chromosome — consistent with mitochondrial hypervariability (the same pattern showed up in dbSNP's MT contig).
Schema: 59 of 380 real columns¶
The real files are 380 columns wide; dbnsfp.toml [columns] restricts what
DbNsfpAnnotator actually loads to 59 (4 key columns —
chr/pos(1-based)/ref/alt — plus 55 predictor/metadata columns),
keeping peak memory bounded on files with hundreds of columns per row.
Multi-value columns: "most damaging across transcripts" convention¶
dbNSFP is built per-variant, but many predictors compute per-transcript
— a variant overlapping several transcripts gets multiple ;-separated
values in one cell:
DbNsfpAnnotator collapses each multi-value cell to a single number by
taking the most damaging value — max() for scores where higher means
more deleterious (REVEL, PolyPhen2, gMVP, VEST4, MetaSVM, …), min() for
the few where lower means more deleterious (ESM1b's log-likelihood ratio,
SIFT4G). SIFT_pred is parsed for its prediction category only — dbNSFP
doesn't ship a SIFT_score column in this build's [columns] selection, so
sift in iris is a prediction-only VariantScore with no numeric value.
What iris extracts, by category¶
| Category | Score names (VariantScore.name) |
|---|---|
| Clinical pathogenicity/protein | alphamissense (+pred), revel, cadd_phred, polyphen2_hdiv (+pred), sift (pred only), bayesdel_addaf (+pred), bayesdel_noaf, metarnn (+pred) |
| Conservation | gerp_rs, phylop100way, phastcons100way, gerp91, phylop470, phastcons470, phylop17primate, bstatistic |
| Extended pathogenicity/protein | esm1b (+pred), mutscore, phactboost, gmvp, mpc, primateai (+pred), sift4g (+pred), vest4, clinpred (+pred), dann, metasvm (+pred), mutassessor (+pred), aloft_prob_rec, aloft_prob_dom, aloft_pred |
Metadata (VariantAnnotation.metadata) |
clinvar_id, clinvar_clnsig, clinvar_review — dbNSFP's own embedded ClinVar mirror, same caveat as dbSNP's legacy CLN* block: prefer ClinvarAnnotator for authoritative clinical significance. Also interpro_domain. |
AlleleFrequency |
gnomad4_af, gnomad4_popmax_af, gnomad4_{afr,amr,sas,eas,nfe}_af (gnomAD 4.1 joint), topmed_af (TOPMed freeze 8), alfa_af (ALFA) |
Live run against a real coding variant with several predictors populated
(21:10538724 A>C):
cadd_phred 0.16
phylop100way -2.446
phastcons100way 0.0
phylop470 -15.654
phastcons470 0.0
phylop17primate 0.52
esm1b -7.163 prediction=HIGH
gmvp 0.7128484687973009
vest4 0.16
metadata: {'interpro_domain': '.;.;.;.'}
(No AlleleFrequency for this particular variant — not every dbNSFP row has
gnomAD/TOPMed/ALFA data populated.)
The M/MT filename mismatch: mitochondrial variants used to never be annotated¶
DbNsfpAnnotator used to build its per-chromosome file path from
normalize_chromosome()'s canonical form, which maps "M" and "MT"
both to "MT":
But the real file on disk is named dbNSFP5.0a_variant.chrM.bgz — singular
M, not MT. This broke matching in two independent places, the same
shape as MCPS' chrX bug:
- File lookup:
_load()checkedPath(...).exists()before querying, so the constructed pathdbNSFP5.0a_variant.chrMT.bgznever matched anything (the real file only exists as...chrM.bgz) — the file was never even opened. - Tabix contig: even with the right file open, its internal tabix
contig is
"M", not"MT"—resolve_chromosome()'s bare/chr-toggle logic doesn't bridge that either.
Both are now fixed, verified live against a real chrM row:
The fix: _resolve_chrom_file() tries "MT" first, then falls back to the
alias "M" for the file-lookup step; resolve_file_contig() (shared with
MCPS' fix, src/iris/adapters/driven/_helpers.py) handles the tabix-contig
step the same way MCPS' does — falling back to a file's sole contig when
standard resolution fails, which is safe here because DbNsfpAnnotator
only opens a per-chromosome file after already selecting it for that
exact chromosome. In practice this rarely mattered for germline variant
triage (MT variant calling is usually a separate specialized pipeline), but
any code that assumed DbNsfpAnnotator covered the whole genome should
have known it silently excluded MT before this fix.
Access patterns from iris¶
Registering the source¶
Already registered in this environment's ~/.iris/config.toml:
from iris.adapters.driven.annotators.dbnsfp import DbNsfpAnnotator
annotator = DbNsfpAnnotator.from_registry() # resolves [sources.dbnsfp]
annotator = DbNsfpAnnotator.from_registry(workers=8) # sets the default workers
workers — chromosome-partitioned parallel fetch¶
Same shape as MCPS:
workers controls how many of the (up to 25) per-chromosome files are
opened and queried concurrently, each via its own TabixFile handle —
parallelism across files, not within one. Useful when a single annotate()
call spans many chromosomes (e.g. annotating a whole-genome VCF's rare
variants after an AF pre-filter).
Design notes & caveats¶
- Mitochondrial variants used to be silently unannotated — fixed; see above.
- Only 59 of 380 real columns are loaded — extending coverage means
adding both a
dbnsfp.toml [columns]entry and a_update_entry()/_build_scores()case; the mapping isn't automatic. - Multi-transcript values collapse to "most damaging" — see
above.
This is a deliberate simplification: a variant's dbNSFP score reflects its
worst-case transcript, not a specific one. Cross-reference
VepFlightAnnotator'sTranscriptVariantlist when a specific transcript's consequence matters. clinvar_id/clinvar_clnsig/clinvar_revieware dbNSFP's own embedded ClinVar snapshot, not necessarily current — preferClinvarAnnotatorfor authoritative clinical significance, same reasoning as dbSNP's legacyCLN*block.SIFT_scoreisn't loaded — onlySIFT_pred(category), soiris'siftVariantScoreis prediction-only, no numericvalue.- Don't read the
.gzduplicates ordbNSFP5.0a_grch38.gzdirectly — see the file table above. - Per-chromosome files, unlike dbSNP/CADD —
workersparallelizes across files here, the same shape as MCPS.
Reference¶
iris.adapters.driven.annotators.dbnsfp
¶
dbNSFP in-silico scores and population frequency annotator via tabix.
DbNsfpAnnotator
¶
Bases: TabixVariantAnnotator
Annotates variants with in-silico scores and population data from dbNSFP via tabix.
AlphaMissense, REVEL, CADD, PolyPhen2-HDIV, SIFT, BayesDel (addAF/noAF),
GERP++RS, MetaRNN.
Extended scores: ESM1b, MutScore, PHACTboost, gMVP, MPC, PrimateAI, SIFT4G, VEST4, ClinPred, GERP91, phyloP/phastCons (100way/470way/17way-primate), bStatistic. Metadata: ClinVar (id/clnsig/review), gnomAD4.1 (joint + 5 populations), TOPMed, ALFA, Interpro domain.
Expects bgzipped, tabix-indexed per-chromosome files under data_dir matching
file_pattern ({chrom} substituted with the bare chromosome, e.g. "1").
For multi-transcript rows, the most damaging value is kept per score.
workers
class-attribute
instance-attribute
¶
Default parallel per-chromosome-file workers, used when annotate() omits an override.
from_registry
classmethod
¶
Build a DbNsfpAnnotator resolving source from the iris DataRegistry.
Source code in src/iris/adapters/driven/annotators/dbnsfp.py
annotate
¶
Annotate variants with dbNSFP in-silico scores and allele frequencies.
| PARAMETER | DESCRIPTION |
|---|---|
items
|
Variants to annotate.
TYPE:
|
workers
|
Parallel per-chromosome-file workers for this call;
defaults to
TYPE:
|