iris.genomics — CLI + Librería Fase 4¶
Typer · pysam · bcftools 1.23.1 · tabix 1.23.1 · micromamba
genomics-core
1. Dependencias¶
Agregadas como optional group genomics en pyproject.toml:
Binarios externos requeridos (detectados automáticamente via shutil.which()):
# Activar env con bcftools y tabix
micromamba activate genomics-core
which bcftools # /home/fenan/micromamba/envs/genomics-core/bin/bcftools
which tabix # /home/fenan/micromamba/envs/genomics-core/bin/tabix
Entrypoint registrado en pyproject.toml:
2. Estructura¶
src/iris/applications/genomics/
├── __init__.py
├── cli.py # Entrypoint principal Typer
├── commands/
│ ├── __init__.py
│ ├── vcf.py # iris genomics vcf filter / region
│ ├── tabix.py # iris genomics tabix index / query / header
│ ├── bcftools.py # iris genomics bcftools stats / view / norm / sort / concat
│ └── store.py # iris genomics store pull / verify
└── use_cases/
├── __init__.py
├── filter_variants.py # Filtra variantes de un VCF
├── annotate_vcf.py # Anota variantes con cadena de anotadores
├── fetch_region.py # Extrae variantes de una región genómica
└── sync_store.py # Sincroniza store remoto a local
3. Use Cases — funciones puras importables¶
Los use cases no saben que existe un CLI. Son importables directamente desde otras apps.
filter_variants¶
from iris.applications.genomics.use_cases.filter_variants import filter_variants
from iris.adapters.driven.readers.vcf import VcfReader
from iris.domain.genomics.filters import AllOf, MaxPopulationFrequency, HighImpactConsequence
results = filter_variants(
path="sample.vcf.gz",
filter=AllOf(filters=(
MaxPopulationFrequency(max_af=0.01, absent_passes=True),
HighImpactConsequence(),
)),
sample_id="NA12878", # opcional — filtra por genotipo
store_info=False, # opcional — serializa INFO en Metadata
)
# → list[VariantAnnotation]
annotate_vcf¶
from iris.applications.genomics.use_cases.annotate_vcf import annotate_vcf
from iris.adapters.driven.annotators.cadd import CaddAnnotator
from iris.adapters.driven.annotators.dbnsfp import DbNsfpAnnotator
annotated = annotate_vcf(
variants=results,
annotators=[
CaddAnnotator(path="/data/cadd/whole_genome_SNVs.tsv.gz"),
DbNsfpAnnotator(path="/data/dbnsfp/dbNSFP4.7a.gz"),
],
)
# → list[VariantAnnotation]
El orden de los anotadores importa — cada uno ve el resultado del anterior.
fetch_region¶
from iris.applications.genomics.use_cases.fetch_region import fetch_region
from iris.domain.genomics.objects import GenomicPosition
variants = fetch_region(
path="sample.vcf.gz",
region=GenomicPosition(chromosome="chr1", start=1_000_000, end=2_000_000),
sample_id="NA12878", # opcional
)
# → list[VariantAnnotation]
sync_store¶
from iris.applications.genomics.use_cases.sync_store import sync_store
result = sync_store(
remote_url="https://storage.iris-lib.click/org-1/",
local_path=Path("/data/genomics/org-1"),
patterns=["*.vcf.gz", "*.vcf.gz.tbi"],
verify=True,
force=False,
)
# → SyncResult(downloaded, skipped, failed)
print(result.success) # True si no hubo fallos
4. CLI — comandos disponibles¶
Commands:
vcf Operaciones sobre archivos VCF/BCF.
tabix Operaciones tabix sobre archivos bgzipped.
bcftools Operaciones bcftools sobre archivos VCF/BCF.
store Gestión del store de archivos genómicos.
vcf¶
# Filtrar variantes por frecuencia y consecuencia
iris-genomics vcf filter sample.vcf.gz \
--max-af 0.01 \
--high-impact \
--sample NA12878 \
-o filtered.tsv
# Extraer variantes de una región
iris-genomics vcf region sample.vcf.gz \
--chrom chr1 \
--start 1000000 \
--end 2000000 \
-o region.tsv
Salida TSV:
tabix¶
# Indexar un VCF bgzipped
iris-genomics tabix index sample.vcf.gz
iris-genomics tabix index sample.vcf.gz --preset vcf --force
# Consultar una región
iris-genomics tabix query sample.vcf.gz --region chr1:1000000-2000000
iris-genomics tabix query sample.vcf.gz \
--region chr1:1000000-2000000 \
-o region.vcf \
--no-header
# Ver header
iris-genomics tabix header sample.vcf.gz
bcftools¶
# Estadísticas
iris-genomics bcftools stats sample.vcf.gz
iris-genomics bcftools stats sample.vcf.gz -o stats.txt --sample NA12878
# Filtrar/convertir
iris-genomics bcftools view sample.vcf.gz \
--include 'QUAL>30' \
--output-type z \
-o filtered.vcf.gz
# Normalizar
iris-genomics bcftools norm sample.vcf.gz \
--reference hg38.fa \
--multiallelics - \
-o normalized.vcf.gz
# Ordenar
iris-genomics bcftools sort unsorted.vcf.gz -o sorted.vcf.gz
# Concatenar
iris-genomics bcftools concat chr1.vcf.gz chr2.vcf.gz -o merged.vcf.gz
store¶
# Descargar archivos del store remoto
iris-genomics store pull https://storage.iris-lib.click/org-1/ \
--local /data/genomics/org-1 \
--patterns "*.vcf.gz,*.vcf.gz.tbi" \
--force
# Verificar integridad del store local
iris-genomics store verify /data/genomics/org-1
iris-genomics store verify /data/genomics/org-1 --patterns "*.vcf.gz"
5. Diseño — separación commands / use_cases¶
use_cases/ commands/
filter_variants ← vcf filter (llama filter_variants internamente)
fetch_region ← vcf region (llama fetch_region internamente)
annotate_vcf ← (sin command propio — usado por BACKAPP genómica)
sync_store ← store pull (llama sync_store internamente)
Los commands son wrappers delgados — solo parsean argumentos CLI y delegan
a los use_cases. Los use_cases son funciones puras sin dependencia de Typer.
La BACKAPP genómica importa los use_cases directamente:
from iris.applications.genomics.use_cases.filter_variants import filter_variants
from iris.applications.genomics.use_cases.annotate_vcf import annotate_vcf
6. Detección de binarios externos¶
bcftools.py y tabix.py detectan los binarios via shutil.which().
Si no se encuentran en PATH, muestran un mensaje claro:
✗ bcftools no encontrado en PATH.
Instala bcftools o activa el env: micromamba activate genomics-core
Para asegurar que el env correcto esté activo al usar el CLI:
7. Verificación end-to-end¶
Prueba real con VCF de array SNV¶
# Extraer región chr1:1M-2M
uv run iris-genomics vcf region \
/home/fenan/Downloads/209583890164_R01C01.snv.vcf.gz \
--chrom chr1 \
--start 1000000 \
--end 2000000 \
-o /tmp/test_region.tsv
# → ✓ 1325 variantes en la región.
# → ✓ Guardado en /tmp/test_region.tsv
# Estadísticas con bcftools
uv run iris-genomics bcftools stats \
/home/fenan/Downloads/209583890164_R01C01.snv.vcf.gz \
| head -20
# → bcftools stats (1.23.1+htslib-1.23.1) output correcto
8. Notas¶
Coordenadas — VcfReader usa coordenadas 1-based internamente (igual que GenomicPosition).
pysam usa 0-based internamente pero la conversión es transparente en el reader.
Nomenclatura cromosómica — el VCF de prueba usa 1 sin prefijo chr.
TabixAnnotator maneja automáticamente el mismatch chr1 ↔ 1 via _resolve_chrom().
Salida TSV — el formato actual es mínimo (chrom, pos, ref, alt, type). En la BACKAPP genómica se extenderá con campos de anotación (CADD, dbNSFP, frecuencias).
Pipeline completo: