Stores & Pipeline¶
Adapters for cohort-scale variant extraction and parallel annotation pipelines.
ZarrVariantStore¶
Cohort store backed by a vcf2zarr Zarr v3 archive.
Implements the VariantAnnotationStore port.
Key design points¶
variant_positionvalues are 1-based (VCF native, as written by vcf2zarr without--zero-based).open()loads the fullvariant_contigarray once and builds per-contig start/end offsets vianumpy.searchsorted, then discards the array.- Per-chromosome position vectors are pre-loaded into
_chrom_pos_cachefor O(1) mask computation insidefetch(). fetch()is thread-safe: it performs only read operations on pre-loaded numpy arrays and issues independent fancy-index reads against the Zarr store (Zarr'sLocalStoresupports concurrent reads).
Usage¶
from iris.adapters.driven.stores import ZarrVariantStore
with ZarrVariantStore(path="/data/wes_cohort.zarr") as store:
variants = store.fetch(region)
Genotype processors¶
ZarrVariantStore accepts an optional processor (a
GenotypeProcessor implementation)
and processor_context dict. When set, the processor is called once per
fetch block per ALT allele with the raw genotype arrays
(n_variants, n_samples, ploidy), and its returned dict is merged into each
VariantAnnotation.metadata.data. Built-in genotype counts (n_hom, n_het,
…) are always computed regardless of whether a processor is supplied. See
Genomic analysis for
concrete implementations (AncestryStratifiedAFProcessor,
PerIndividualAltCountProcessor).
iris.adapters.driven.stores.zarr
¶
ZarrVariantStore — vcf2zarr cohort store adapter.
Supports user-defined GenotypeProcessor callables injected at construction time, enabling cohort-level statistics, stratified allele frequencies, and regression models without subclassing.
ZarrVariantStore
¶
Bases: VariantAnnotationStore
Cohort-scale variant store backed by a vcf2zarr Zarr v3 archive.
Designed for variant_position values that are 1-based (VCF native,
as written by vcf2zarr without the --zero-based flag).
The store must be opened before use — either explicitly via
:meth:open or through the context-manager protocol::
with ZarrVariantStore(path=ZARR_PATH) as store:
variants = store.fetch(region)
After open():
- Contig offsets are built once from the full
variant_contigarray usingnumpy.searchsorted. - Per-chromosome position arrays are pre-loaded and cached for O(1) mask
computation in :meth:
fetch.
:meth:fetch is thread-safe: it performs only read operations on the
pre-loaded numpy arrays and issues independent fancy-index reads against
the underlying Zarr store (Zarr's LocalStore supports concurrent
reads).
| ATTRIBUTE | DESCRIPTION |
|---|---|
path |
Path to the Zarr store directory or
TYPE:
|
assembly |
Genome assembly label stored in created
:class:
TYPE:
|
source |
Population / source label used in the generated
:class:
TYPE:
|
processor
class-attribute
instance-attribute
¶
Optional user-defined processor called for each variant block.
When set, the processor receives the raw genotype arrays
(n_variants, n_samples, ploidy) and returns a dict of computed
values that are merged into VariantAnnotation.metadata.data.
The built-in genotype counts (n_hom, n_het, etc.) are always
computed regardless of whether a processor is supplied.
See :class:~iris.domain.genomics.ports.driven.genotype_processor.GenotypeProcessor.
processor_context
class-attribute
instance-attribute
¶
Arbitrary context dict forwarded to the processor on every call.
Use this to pass sample covariates, phenotypes, or configuration that the processor needs but that are not part of the genotype arrays.
open
¶
Open the Zarr store and build in-memory indices.
Loads the full variant_contig array (~35 MB for a 79k cohort)
once to build per-contig start / end offsets, then pre-loads each
per-chromosome position array into _chrom_pos_cache. The large
variant_contig array is discarded after the index is built.
| RETURNS | DESCRIPTION |
|---|---|
ZarrVariantStore
|
Self, so this can be used fluently: |
| RAISES | DESCRIPTION |
|---|---|
ImportError
|
If |
Source code in src/iris/adapters/driven/stores/zarr.py
close
¶
Release in-memory caches and close the Zarr store handle.
fetch
¶
Return all variants whose positions fall within region.
region.start and region.end must both be non-None and are
interpreted as 1-based inclusive coordinates matching the
variant_position encoding in the store.
The method opens the store lazily if :meth:open has not been called.
It is safe to call concurrently from multiple threads.
| PARAMETER | DESCRIPTION |
|---|---|
region
|
1-based inclusive genomic window.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[VariantAnnotation]
|
Possibly-empty list of |
list[VariantAnnotation]
|
class: |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If |
ImportError
|
If |
Source code in src/iris/adapters/driven/stores/zarr.py
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 | |
VariantExtractionPipeline¶
Orchestrates parallel variant extraction followed by sequential annotation.
Two-phase execution¶
- Extraction — the store's
fetch()is called once per region using aThreadPoolExecutor. Because Zarr stores release the GIL for array reads, multi-threading yields near-linear speedups on I/O-bound workloads. - Annotation — collected
VariantAnnotationobjects are passed sequentially through each annotator. Annotators run in serial to avoid saturating tabix file handles or in-memory lookup tables.
Usage¶
from iris.adapters.driven.pipeline import VariantExtractionPipeline
from iris.adapters.driven.stores import ZarrVariantStore
from iris.adapters.driven.annotators.clinvar import ClinvarAnnotator
annotators = (ClinvarAnnotator(path=CLINVAR_TSV),)
with ZarrVariantStore(path=ZARR_PATH) as store:
pipeline = VariantExtractionPipeline(
store, annotators, workers=28, show_progress=True
)
variants = pipeline.run(regions=regions_from_bed)
iris.adapters.driven.pipeline
¶
VariantExtractionPipeline — parallel extraction and sequential annotation.
VariantExtractionPipeline
¶
Orchestrates parallel variant extraction followed by sequential annotation.
The pipeline executes in two phases:
-
Extraction — :attr:
storeis queried once per region using a :class:~concurrent.futures.ThreadPoolExecutorwith up to :attr:workersthreads. Because Zarr stores release the GIL for array reads, multi-threading yields near-linear speedups. -
Annotation — the collected :class:
~iris.domain.genomics.entities.VariantAnnotationobjects are passed through each annotator in :attr:annotatorssequentially. Annotators run in serial to avoid saturating the I/O devices they read from (tabix files, in-memory lookup tables, etc.).
Example::
annotators = (ClinvarAnnotator(path=CLINVAR_TSV),)
with ZarrVariantStore(path=ZARR_PATH) as store:
pipeline = VariantExtractionPipeline(store, annotators, workers=28)
variants = pipeline.run(regions=regions_from_bed)
| ATTRIBUTE | DESCRIPTION |
|---|---|
store |
Opened
:class:
TYPE:
|
annotators |
Zero or more
:class:
TYPE:
|
workers |
Number of threads for the extraction phase. Use
TYPE:
|
show_progress |
When
TYPE:
|
run
¶
Run the pipeline and return fully annotated variants.
Exactly one of regions or variants must be supplied.
- regions — each region is submitted as one extraction task.
- variants — each variant is converted to a point region
(pos, pos)and then de-duplicated by region to avoid redundant store reads. Variants without a valid position are skipped.
| PARAMETER | DESCRIPTION |
|---|---|
regions
|
Genomic windows to extract variants from.
TYPE:
|
variants
|
Specific variants whose positions define point regions.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[VariantAnnotation]
|
Fully annotated list of |
list[VariantAnnotation]
|
class: |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If both or neither of regions and variants are supplied. |