uvar — exhaustive precomputed variant annotation¶
uvar ("universal variant") is a per-chromosome Parquet database that
precomputes annotation for essentially every possible single-nucleotide
substitution in GRCh38, plus a large set of enumerated indels in
repeat-rich regions — population frequencies, ClinVar classifications, gene
consequence, and dozens of in-silico pathogenicity/conservation/regulatory
predictors, all joined onto one row per variant. It lives at
/mnt/cephfs/hot_nvme/uvar/ as 24 files (chr1.p … chr22.p, chrX.p,
chrY.p), built with DuckDB (created_by: DuckDB
v1.3.2) and readable by any standard Parquet reader — the .p extension is
just a naming convention, not a distinct format.
This page documents the data itself — model, categories, scale — and shows
how iris reads it, via UvarVariantStore and UvarAnnotator
(src/iris/adapters/driven/stores/uvar.py,
src/iris/adapters/driven/annotators/uvar.py). Every example on this page
ran against the real files.
Scale¶
24 files, one per chromosome, sorted by position, 416 columns wide:
| File | Rows | Row groups | Size |
|---|---|---|---|
| chr1.p | 697,723,257 | 349 | 44.76 GB |
| chr2.p | 728,249,325 | 364 | 46.06 GB |
| chr3.p | 599,657,406 | 300 | 37.36 GB |
| chr4.p | 574,493,843 | 288 | 34.03 GB |
| chr5.p | 548,653,509 | 275 | 33.49 GB |
| chr6.p | 514,950,784 | 258 | 31.96 GB |
| chr7.p | 481,465,078 | 241 | 29.77 GB |
| chr8.p | 438,236,670 | 220 | 27.15 GB |
| chr9.p | 368,668,774 | 185 | 22.91 GB |
| chr10.p | 403,649,527 | 202 | 25.55 GB |
| chr11.p | 407,232,600 | 204 | 25.98 GB |
| chr12.p | 403,205,116 | 202 | 26.01 GB |
| chr13.p | 296,684,670 | 149 | 17.68 GB |
| chr14.p | 274,216,494 | 138 | 17.37 GB |
| chr15.p | 256,275,016 | 129 | 16.41 GB |
| chr16.p | 247,862,947 | 124 | 16.30 GB |
| chr17.p | 251,209,815 | 126 | 16.87 GB |
| chr18.p | 242,369,265 | 122 | 14.17 GB |
| chr19.p | 177,368,363 | 89 | 12.33 GB |
| chr20.p | 193,559,674 | 97 | 12.43 GB |
| chr21.p | 121,352,389 | 61 | 6.98 GB |
| chr22.p | 118,627,486 | 60 | 7.58 GB |
| chrX.p | 467,920,179 | 234 | 21.25 GB |
| chrY.p | 79,283,050 | 40 | 1.93 GB |
| Total | 8,892,915,237 | ~0.55 TB |
Row groups are ~2M rows each and the files are sorted by position, so every
query below relies entirely on Parquet row-group statistics pruning — there is
no secondary index, and none is needed. UvarVariantStore never loads a whole
file; see Access patterns below.
Coverage model: SNVs + repeat-region indels¶
The name "universal SNV database" (from the adapter's own docstring) is a simplification worth correcting here. Most positions carry exactly 3 rows — one for each possible alternate base — which is the exhaustive-SNV core of the database:
But inside tandem-repeat / short-tandem-repeat stretches, uvar also enumerates
plausible indel alleles anchored at that position — real example from
chr21.p around position 6,002,800 (a poly-A/poly-T microsatellite):
position=6002800 ref=A alt=C # SNV
position=6002800 ref=A alt=G # SNV
position=6002800 ref=A alt=T # SNV
position=6002800 ref=ATT alt=A # 2bp deletion
position=6002800 ref=ATTTTATTTTATTTTATTATTTTATT alt=A # 26bp deletion
position=6002800 ref=ATTTTATTTTATTTTATTATTTTATTTTATT alt=A # 32bp deletion
position=6002800 ref=ATTTTATTTTATTTTATTATTTTATTTTATTTTATT alt=A # 37bp deletion
Row counts per position observed on chr21.p range from 3 (plain SNV site) up
to 9 in dense repeat regions. Consumers that assume "3 rows per position" —
e.g. to estimate how many rows a region query will return — should instead
treat 3 as a floor, not a fixed count, in repeat-dense regions (main.gerp,
main.sequence_context and the tandem-repeat annotation itself can be used to
detect these).
Identity & coordinate columns¶
| Column | Type | Meaning |
|---|---|---|
vid |
uint64 |
Deterministic variant ID, packed from chromosome/position/allele where the encoding fits. |
is_hashed |
bool |
True when the allele was too long to pack directly into vid (long indels) — 140,721 such rows on chr21 alone. |
hash30 |
int32 |
Hash of the allele, populated only when is_hashed; vid alone is not sufficient to distinguish these rows. |
chrom_id |
uint8 |
Numeric chromosome ID (matches chromosome). |
chromosome |
int64 |
Chromosome number, no chr prefix (21, not "chr21" or "chr21"). |
position0 |
int32 |
0-based position (position - 1). |
position |
int32 |
1-based position — the one iris uses everywhere (matches GenomicPosition's convention; see Coordinate convention). |
pos_bin_1m |
int32 |
Position integer-divided into 1 Mb bins; used directly by query_region_columns(..., aggregate="pos_bin_1m") for genome-scale summaries without materializing row-level data. |
ref_vcf / alt_vcf |
string |
VCF-style ref/alt (right-trimmed representation). This is what iris matches against Variant.as_key(). |
ref_annovar / alt_annovar |
string |
ANNOVAR-style left-aligned ref/alt — differs from *_vcf for a subset of indels; not used by the iris adapters. |
variant_vcf |
string |
Precomputed display string, "{chromosome}-{position}-{ref}-{alt}", e.g. "21-6116000-G-A". |
Schema by category¶
54 top-level columns, several deeply nested (416 leaf columns total). Grouped by what they annotate:
Gene / transcript consequence — three independent annotation sets¶
gencode, ucsc, and refseq are parallel, independently computed
annotations against three different transcript catalogs — they can and do
disagree on region_type/consequence for the same variant, since they use
different transcript models.
| Struct | Fields |
|---|---|
gencode |
region_type, genes: list<string>, consequence, transcripts: list<{gene, transcript_id, location, hgvsc, hgvsp}> |
ucsc |
region_type, transcripts: list<string>, consequence, exonic_details: list<{transcript_id, location, hgvsc, hgvsp}> |
refseq |
region_type, transcripts: list<string>, consequence, exonic_details: list<{gene, transcript_id, location, hgvsc, hgvsp}> |
region_type observed values (from gencode, full-column scan of
chr21.p, 121M rows):
intergenic, upstream, downstream, upstream;downstream,
intronic, exonic, exonic;splicing, splicing,
UTR3, UTR5, UTR5;UTR3,
ncRNA_exonic, ncRNA_intronic, ncRNA_exonic;splicing, ncRNA_splicing
consequence observed values (ANNOVAR-style exonic function terms):
nonsynonymous SNV, synonymous SNV, stopgain, stoploss, unknown,
frameshift deletion, frameshift insertion, frameshift substitution,
nonframeshift deletion, nonframeshift insertion, nonframeshift substitution
null when the variant is non-exonic.)
Identifiers & clinical databases¶
| Struct | Fields |
|---|---|
dbsnp |
rsid, rsid_all: list<string> |
clinvar |
clnsig: list<string>, clndn: list<string>, clnrevstat, origin: uint16, origin_decoded: list<string>, geneinfo: list<{symbol, id}>, clndisdb, clnsigincl, clndisdbincl, clndnincl, gene |
cosmic |
gene, transcript, cds, aa, hgvsc, hgvsp, hgvsg, sample_count: int32, is_canonical: bool, tier, so_term |
clinvar.clnsig free-text terms (there are more in the raw data than iris
maps — see ClinVar significance mapping
below for the ones UvarAnnotator/UvarVariantStore actually translate to
ClinicalSignificance).
In-silico pathogenicity predictors¶
| Struct | Notable fields |
|---|---|
dbnsfp |
revel, mpc, vest4, mvp, gmvp, phactboost, mutformer, mutscore, varity_r, varity_er, interpro_domain, polyphen2_hdiv, polyphen2_hvar, mutation_taster, mutation_assessor, metasvm_pred, plus {score, pred} pairs for bayesdel, clinpred, esm1b, meta_rnn, meta_lr, m_cap, primate_ai, deogen2, mutpred2, sift4g, provean, list_s2, and aloft: {pred, confidence} — ~29 predictors total, mirroring dbNSFP's own column set |
spliceai |
max_ds, symbol, ds_ag/ds_al/ds_dg/ds_dl (delta scores), dp_ag/dp_al/dp_dg/dp_dl (delta positions) |
alphamissense |
max_pathogenicity, predictions: list<{uniprot_id, transcript_id, protein_variant, pathogenicity, class}> |
mavedb |
gene_name, hgvs_pro, scoresets: list<{score, scoreset_urn}> — experimental deep mutational scanning data |
Top-level scalar scores (not nested under dbnsfp): linsight, fathmm_xf,
gpn_msa_score/gpn_msa_phred, jarvis_score/jarvis_phred,
remm_score/remm_phred, ncer_percentile,
gnomad_constraint_score/gnomad_cst_phred.
main — conservation, sequence context, and regulatory tracks (CADD-style)¶
A single wide struct bundling the annotation categories that CADD itself aggregates from:
| Sub-struct | Fields |
|---|---|
sequence_context |
gc, cpg, gc_phred, cpg_phred |
distance |
min_dist_tss, min_dist_tse |
protein_predictions |
sift_cat, sift_val, polyphen_cat, polyphen_val, grantham |
conservation |
priphcons, mamphcons, verphcons, priphylop, mamphylop, verphylop, bstatistic |
chromhmm |
e1…e25 — 25-state ChromHMM chromatin-state model |
gerp |
rs, rs_pval, n, s |
encode |
{raw, phred} for 13 ENCODE marks: h3k4me1/2/3, h3k9ac, h3k9me3, h3k27ac, h3k27me3, h3k36me3, h3k79me2, h4k20me1, h2afz, dnase, total_rna |
variant_density |
{freq,rare,sngl}_{100,1000,10000}bp — 9 fields, local variant density at 3 window sizes |
remap |
overlap_tf, overlap_cl |
cadd |
raw, phred — this is the cadd_phred score UvarAnnotator extracts as a VariantScore |
Composite / meta pathogenicity scores¶
| Struct | Fields |
|---|---|
apc |
13 "Annotation Principal Component" scores: conservation_v2, epigenetics{,_active,_repressed,_transcription}, local_nucleotide_diversity_v3, mappability, micro_rna, mutation_density, protein_function_v3, proximity_to_coding_v2, proximity_to_tsstes, transcription_factor |
macie |
{raw, phred} for conserved, regulatory, anyclass, plus region |
cv2f |
{raw, phred} for liver, baseline, mpra, lvs, combined |
ncboost |
score, percentile, region, gene |
pgboost |
list<{gene, score, percentile}> |
funseq |
score: uint8, description |
aloft |
score, description (genome-wide non-coding score; distinct from dbnsfp.aloft, which is the protein-coding LoF-tolerance predictor) |
Regulatory elements¶
| Column | Fields |
|---|---|
ccre |
ids, accessions, annotations, count: uint8 — ENCODE candidate cis-regulatory elements |
genehancer |
id, feature_score, targets: list<{gene, score}> |
cage |
cage_enhancer, cage_promoter, cage_tc |
super_enhancer_ids |
list<string> |
Population frequency¶
| Struct | Fields |
|---|---|
gnomad_genome, gnomad_exome |
af, ac, an, nhomalt, filter, grpmax, af_xx/af_xy, ac_xx/an_xx/ac_xy/an_xy, populations: {afr,ami,amr,asj,eas,fin,mid,nfe,sas}: {af, af_xx, af_xy}, faf: {faf95_max, faf95_max_gen_anc, faf99_max, faf99_max_gen_anc}, quality: {qd, inbreeding_coeff, fs, mq, sor}, variant_info: {allele_type, variant_type, n_alt_alleles}, region_flags: {lcr, segdup, non_par}, functional: {revel_max, spliceai_ds_max, pangolin_largest_ds} |
bravo |
bravo_an, bravo_ac, bravo_af, filter_status — TOPMed |
tg |
tg_all, tg_afr, tg_amr, tg_eas, tg_eur, tg_sas — 1000 Genomes |
gnomAD is present at both genome and exome cohort granularity as separate
structs — a variant can have gnomad_genome.af populated,
gnomad_exome.af null, or both.
Genome-wide structural context¶
| Column | Fields |
|---|---|
recombination_rate |
scalar float |
nucdiv |
scalar float — nucleotide diversity |
mutation_rate |
mr, ar, mg, mc, pn, filter |
mappability |
{bismap, umap} at read lengths k24, k36, k50, k100 |
ClinVar significance mapping¶
UvarAnnotator/UvarVariantStore translate clinvar.clnsig free-text terms
into the domain's ClinicalSignificance enum via
src/iris/adapters/driven/stores/uvar_columns.toml:
uvar clnsig term |
ClinicalSignificance |
|---|---|
Pathogenic |
PATHOGENIC |
Pathogenic_low_penetrance |
PATHOGENIC_LOW_PENETRANCE |
Likely_pathogenic, Likely_pathogenic_low_penetrance |
LIKELY_PATHOGENIC |
Uncertain_significance, Uncertain_risk_allele |
UNCERTAIN |
Likely_benign |
LIKELY_BENIGN |
Benign |
BENIGN |
Conflicting_classifications_of_pathogenicity, Conflicting_interpretations_of_pathogenicity |
CONFLICTING |
not_provided, not_classified |
NOT_PROVIDED |
drug_response |
DRUG_RESPONSE |
risk_factor |
RISK_FACTOR |
protective |
PROTECTIVE |
association |
ASSOCIATION |
affects |
AFFECTS |
other |
OTHER |
This is the same ACMG/AMP vocabulary ClinvarAnnotator (the standalone
ClinVar-TSV adapter) maps, kept in a separate TOML table because it parses
uvar's own flattened struct field rather than the ClinVar VCF's CLNSIG INFO
column.
Access patterns from iris¶
UvarVariantStore (stores/uvar.py) and UvarAnnotator
(annotators/uvar.py) never load a whole chromosome file — every method
pushes a predicate down to pyarrow.dataset, relying on row-group statistics
to prune the scan. Column projection works at top-level struct
granularity only: requesting "gnomad_genome" returns the entire nested
struct (all 9 populations, faf, quality, …), not individual leaf fields —
there is no per-leaf-path pushdown in this Parquet layout.
Registering the source¶
# ~/.iris/config.toml
[hosts.local]
kind = "local"
data_dir = "/mnt/cephfs/hot_nvme"
[sources.uvar]
host = "local"
path = "uvar"
from iris.adapters.driven.annotators.uvar import UvarAnnotator
annotator = UvarAnnotator.from_registry() # resolves [sources.uvar]
UvarVariantStore.fetch() — region → VariantAnnotation¶
Full VariantAnnotationStore port conformance, for small (gene-sized)
regions. Uses a fixed default column set
(ref_vcf, alt_vcf, dbsnp, clinvar, gnomad_genome, dbnsfp, main) — never the
full 416-column schema.
from iris.adapters.driven.stores.uvar import UvarVariantStore
from iris.domain.genomics.objects import GenomicPosition
store = UvarVariantStore(data_dir="/mnt/cephfs/hot_nvme/uvar")
region = GenomicPosition(chromosome="21", start=6_116_400, end=6_116_600)
annotations = store.fetch(region)
Live run against chr21.p:
603 VariantAnnotation in 0.854s # 201 positions × 3 SNVs = 603
6116503 C > T ClinicalSignificance.PATHOGENIC (source=uvar_clinvar)
UvarVariantStore.query_region_columns() — bulk path with signal pushdown¶
uvar is exhaustive: a gene-sized region returns hundreds of thousands to
millions of rows, almost all of them theoretical substitutions nobody has
ever observed. require_population_signal=True pushes an "observed gnomAD
frequency OR ClinVar entry" filter down into the same Parquet scan, instead
of materializing every substitution and filtering in Python afterward:
from iris.adapters.driven.stores.uvar import COLUMN_GROUPS
cols = [*COLUMN_GROUPS["population_variation"], *COLUMN_GROUPS["clinical_significance"]]
table = store.query_region_columns(region, columns=cols, require_population_signal=True)
Live run, same 201 bp window: 1 row returned (of 603 theoretical) in 0.479s — the one ClinVar-Pathogenic C>T. (dbSNP membership is deliberately not used as a population signal here — a variant can have an rsID purely from clinical submission without any observed allele count.)
aggregate="pos_bin_1m" collapses a region to per-1Mb-bin variant counts —
for genome/chromosome-scale zoom levels where row-level data would be
impractical:
big_region = GenomicPosition(chromosome="21", start=1, end=46_709_983)
agg = store.query_region_columns(big_region, columns=[], aggregate="pos_bin_1m")
Live run: the full 46.7 Mb chromosome (121M rows) collapses to 42 bins in 1.18s — proving the pushdown prunes row groups rather than materializing everything before aggregating.
UvarVariantStore.query_positions_columns() — scattered point lookups¶
An isin predicate (still row-group-prunable) for arbitrary, non-contiguous
positions — e.g. a variant list, rather than one window. This is what
UvarAnnotator uses internally.
UvarAnnotator — annotate-by-key, merges onto existing VariantAnnotation¶
Unlike fetch(), which reconstructs VariantAnnotation objects from
scratch for whatever falls in a window, UvarAnnotator matches by
Variant.as_key() — the same contract DbNsfpAnnotator, CaddAnnotator,
and every other VariantAnnotator use — and merges uvar's fields onto the
input object via attrs.evolve(). That's what lets uvar run through the
same annotate_vcf use case as any other source, chained or compared
side-by-side:
from iris.applications.genomics.use_cases.annotate_vcf import annotate_vcf
from iris.adapters.driven.annotators.uvar import UvarAnnotator
[result] = annotate_vcf([variant_annotation], [UvarAnnotator(data_dir=UVAR_DIR, workers=8)])
Live run for 21:6116503 C>T (a bare VariantAnnotation with no prior
enrichment, as a VcfReader would produce it):
annotated in 0.455s
scores: (VariantScore(name='cadd_phred', type=PATHOGENICITY, value=22.9),)
classifications: (ClinicalClassification(classification=PATHOGENIC, source='uvar_clinvar'),)
allele_frequencies: () # no gnomAD genome AF for this variant
identity preserved: True # result.variant is the same object passed in
Only cadd_phred and revel are extracted as VariantScores and only
gnomad_genome.af as an AlleleFrequency — see
_extract_uvar_fields() in stores/uvar.py for the full mapping (shared by
fetch() and UvarAnnotator so the column→domain-object mapping is defined
exactly once). The 400+ remaining columns are available via
query_region_columns()/query_positions_columns() for callers that need
more than this fixed default set.
workers partitions by chromosome across a ThreadPoolExecutor, each worker
opening its own UvarVariantStore (and so its own pyarrow.dataset) —
verified to produce identical results to workers=1
(test_annotate_with_workers_matches_sequential).
Dashboard use cases built on COLUMN_GROUPS¶
src/iris/applications/genomics/use_cases/region_features/ (the region
dashboard's backend) reads uvar through the same
query_region_columns(), gated by require_population_signal and choosing
an aggregation level from the region span
(region_features/aggregation.py):
get_population_variation_tracks()— `COLUMN_GROUPS["population_variation"]- ["clinical_significance"]`, combined with MCPS and RGC-ME tracks.
get_insilico_tracks()—COLUMN_GROUPS["insilico"](dbnsfp, main, spliceai, alphamissense) alongsidepopulation_variationcolumns, so the frontend can show only observed/annotated variants (gosling_common._flatten_insilico_recordmirrors the same signal gate).
Benchmarking against dbNSFP¶
projects/benchmarkings/uvar_vs_dbnsfp.py runs UvarAnnotator and
DbNsfpAnnotator over the same variant subset through the same
annotate_vcf use case, and reports coverage, cadd_phred/revel
absolute-value agreement, ClinVar classification agreement, and per-source
throughput — a concrete way to decide which source to trust for a given
field before wiring it into a pipeline:
uv run python projects/benchmarkings/uvar_vs_dbnsfp.py \
--vcf /path/to/valid.vcf.gz \
--sample-size 500 --seed 42 \
--output results/uvar_vs_dbnsfp.tsv
Design notes & caveats¶
- Column projection is top-level only.
columns=["gnomad_genome"]always pulls the whole struct (all 9 populations,faf,quality,region_flags, …); there is no per-leaf-field pushdown in this Parquet layout. Request narrower top-level groups (COLUMN_GROUPS) rather than the full 54-column schema when scanning large regions. - Exhaustive, not observational. Every theoretical SNV has a row whether
or not it has ever been observed in any cohort. Row presence alone is not
evidence of anything — always gate on a population/clinical signal
(
require_population_signal, or checkgnomad_genome.af/clinvar.clnsigdirectly) before treating a match as meaningful. fetch()never requests all 416 columns, by design — it's meant for gene-sized regions with a small fixed column set. Larger regions or different field needs should go throughquery_region_columns()directly with a purpose-specific column list.UvarAnnotatoronly extracts a small slice into domain objects (cadd_phred,revel, one gnomAD-genome frequency, ClinVar classification). It is not a substitute for the rawquery_*_columns()paths when a caller needs, say, SpliceAI or AlphaMissense as first-classVariantScores — that mapping does not exist yet in_extract_uvar_fields().gencode/ucsc/refseqcan disagree — they're independently computed against different transcript catalogs, not cross-validated against each other.- Row count per position is not fixed at 3 in repeat-dense regions — see Coverage model.
Reference¶
iris.adapters.driven.stores.uvar
¶
UvarVariantStore — Parquet-backed adapter for the uvar universal SNV database.
uvar is a per-chromosome Parquet database with exhaustive coverage of
every possible SNV in GRCh38 (3 rows per position, one per alternate allele),
416 columns of precomputed annotation (population frequencies, ClinVar,
in-silico predictors, conservation, regulatory scores, ...). Files are large
(up to ~46 GB per chromosome) and sorted by position, so this adapter relies
entirely on pyarrow.dataset predicate pushdown (row-group statistics
pruning) rather than any manual indexing.
Two access modes, both region-bounded (region.start/region.end must
both be set — there is no "fetch the whole file" mode given the file sizes):
- :meth:
fetch— full port conformance (VariantAnnotationStore), maps a small fixed default column set into :class:VariantAnnotation. Intended for small regions (gene-level); never requests all 416 columns. - :meth:
query_region_columns— low-level bulk path for the region-features use cases. Column projection works at TOP-LEVEL struct/scalar granularity only (e.g. requesting"gnomad_genome"returns the whole nested struct; there is no per-leaf-field pushdown).aggregate="pos_bin_1m"groups by the schema's existing 1 Mb bin column for genome/chromosome-level summaries instead of returning row-level data.
COLUMN_GROUPS
module-attribute
¶
COLUMN_GROUPS = {
name: (load_str_tuple(_TOML, "column_groups", name))
for name in (
"population_variation",
"clinical_significance",
"insilico",
)
}
Maps a dashboard "source" filter name to the top-level uvar columns it needs.
UvarVariantStore
¶
Bases: VariantAnnotationStore
Region-scale variant store backed by per-chromosome uvar Parquet files.
| ATTRIBUTE | DESCRIPTION |
|---|---|
data_dir |
Directory containing
TYPE:
|
file_pattern |
Filename template, formatted with the canonical
chromosome name (e.g.
TYPE:
|
assembly |
Genome assembly label stored in produced GenomicPosition objects.
TYPE:
|
source |
Label stored on produced VariantAnnotation.metadata.
TYPE:
|
query_region_columns
¶
Return uvar rows within region, projected to columns (plus position/chromosome).
| PARAMETER | DESCRIPTION |
|---|---|
region
|
1-based inclusive genomic window. Both start and end must be set — there is no unbounded query mode.
TYPE:
|
columns
|
Top-level uvar column names to project (see COLUMN_GROUPS for the dashboard-source groupings). Struct columns are returned whole (no per-leaf-field projection).
TYPE:
|
aggregate
|
When
TYPE:
|
require_population_signal
|
uvar is exhaustive (every theoretical
SNV, 3 rows/position) — for gene/cytoband-sized regions this
is hundreds of thousands to millions of rows, almost all
never-observed. When True, pushes down a row-group/predicate
filter for an observed gnomAD frequency or a ClinVar
classification (mirrors
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Table
|
A pyarrow.Table. Empty (zero columns) if the chromosome has no |
Table
|
backing file. |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If region.start or region.end is None. |
Source code in src/iris/adapters/driven/stores/uvar.py
query_positions_columns
¶
Point-lookup rows for an explicit, possibly scattered set of positions.
Uses an isin predicate rather than :meth:query_region_columns's
>=/<= range — still row-group-prunable via pyarrow's statistics,
but the right tool when the targets are arbitrary positions from a variant
list (e.g. annotate-by-key) rather than one contiguous window. Used by
UvarAnnotator.
| PARAMETER | DESCRIPTION |
|---|---|
chrom
|
Chromosome, any spelling
TYPE:
|
positions
|
1-based positions to fetch.
TYPE:
|
columns
|
Top-level uvar column names to project.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Table
|
A pyarrow.Table. Empty (zero columns) if the chromosome has no |
Table
|
backing file or positions is empty. |
Source code in src/iris/adapters/driven/stores/uvar.py
fetch
¶
Return VariantAnnotation objects within region, using a fixed default column set.
Intended for small (gene-level) regions — always requests
_DEFAULT_FETCH_COLUMNS, never the full 416-column schema. Larger
regions should use :meth:query_region_columns directly with a
narrower, purpose-specific column set.
| PARAMETER | DESCRIPTION |
|---|---|
region
|
1-based inclusive genomic window.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[VariantAnnotation]
|
Possibly-empty list of VariantAnnotation. |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If region.start or region.end is None. |
Source code in src/iris/adapters/driven/stores/uvar.py
iris.adapters.driven.annotators.uvar
¶
UvarAnnotator — enriches existing VariantAnnotation objects from the uvar Parquet store.
UvarVariantStore.fetch() is region-bounded: it reconstructs VariantAnnotation
objects from scratch for whatever falls inside a window. This annotator instead
matches by Variant.as_key(), the same annotate-by-key contract every other
VariantAnnotator uses (DbNsfpAnnotator, McpsAFAnnotator), merging uvar's
frequencies/classifications/scores onto the input objects via attrs.evolve
rather than replacing them. This is what lets uvar be run through the
annotate_vcf use case and compared against other annotators on equal footing.
UvarAnnotator
¶
Bases: VariantAnnotator
Annotates variants with uvar's population frequency, ClinVar, and in-silico scores.
Point-lookup counterpart to UvarVariantStore: same fixed
_DEFAULT_FETCH_COLUMNS set as fetch() (never the full 416-column
schema), but keyed by variant identity instead of a genomic window.
| ATTRIBUTE | DESCRIPTION |
|---|---|
data_dir |
Directory containing
TYPE:
|
file_pattern |
Filename template, see
TYPE:
|
workers |
Number of chromosome-partitioned parallel queries. Each
worker opens its own
TYPE:
|
from_registry
classmethod
¶
Build a UvarAnnotator resolving source from the iris DataRegistry.
Source code in src/iris/adapters/driven/annotators/uvar.py
annotate
¶
Annotate variants with uvar frequencies, ClinVar classification, and scores.