IGVF export¶
cau igvf-export writes a guide design in the IGVF per-guide metadata
format. It is the fourth step: alignment finds each
guide's site, annotation says what gene it falls in,
element mapping says which element it tests, and this
assembles the result into the table IGVF asks for.
In Claude Code the cau-igvf-export skill teaches Claude to run it and read
the output (Agents and skills).
Quick start¶
cau igvf-export run \
--alignment results/alignments/guide_genome_annotation.tsv \
--mapping results/elements/guide_element_mapping.tsv \
--elements elements.bed \
--store gencode.v43.protein_coding.parquet \
--promoters gencode.v43.protein_coding.TSS1bp.bed6 \
--genes measured_element_gene_pairs.tsv \
--outdir results/
--genes is optional and takes a table of measured element-to-gene pairs:
the first column names the element, and the first column of ENSEMBL ids names
the gene. Without it, a promoter's gene is inferred from the nearest TSS.
The format¶
The table follows
Format_for_Per-Guide_Metadata.pdf, the IGVF document that files with
content_type "guide RNA sequences" must abide by. Its conventions are the
ones the rest of this package already uses — 0-based, half-open, ACTG — and
it pins ENSEMBL ids to GENCODE release 43, so build the annotation store
from v43.
What a guide targets is decided from the genome¶
A design's category for an element is a hypothesis; the annotation is evidence. In order:
- a validated enhancer stays
enhancer; - within 2 kb of a protein-coding TSS,
promoter; - overlapping an exon,
exon; - inside a gene,
intron; - otherwise,
distal element.
The 2 kb is the format's own definition of a distal element ("outside of a gene body, >2 kb from any annotated TSS").
The exception is a validated enhancer: that an element was shown to regulate a particular gene is experimental knowledge no annotation can supply, so that label is trusted and its gene comes from the measured pairs.
This matters in practice. In a real 43,778-guide screen the design labelled
344 elements promoter; 300 of those have a measured gene and the genome
agreed with every one, but of the other 44, 39 contained no transcription
start site of any biotype — checked against all 62,757 genes of v43 — and
one sat 109 kb from the nearest. Derived rather than believed, those 44 came
out as 25 exon, 18 promoter and 1 intron.
type has to agree¶
positive control means a guide expected to produce a known measurable
effect. A row claiming that while its genomic_element is exon
contradicts itself, so a guide is a positive control only when its element is
a validated enhancer, or the design calls it a promoter and the genome
agrees.
One row per guide¶
The format requires guide_id to be unique, so a guide inside two
overlapping elements still gets one row: the element sharing the most bases
with the protospacer, ties broken by element id. Nothing is lost, because
putative_target_genes keeps every gene of every element the guide hit —
which is also how a bidirectional promoter keeps both of its genes.
Outputs¶
--outdir gets three folders and nothing loose:
igvf/ guide_metadata.tsv guide_metadata_columns.yaml
run_metadata/ igvf_export_<UTC timestamp>.json
logs/ igvf_export.log
guide_metadata.tsv¶
One row per guide, which the format requires: a guide_id must name one
guide and one spacer.
| Column | Holds |
|---|---|
guide_id |
The guide's name, from the input table's own name for it. |
spacer |
The targeting sequence, 5' to 3', in DNA bases. |
oligo |
The sequence ordered, without the PAM. |
n_oligos |
Entries sharing this spacer; above one the counts are a sum. |
targeting |
TRUE only when the guide targets a relevant locus. |
type |
targeting, safe-targeting, non-targeting or positive control. |
guide_chr, guide_start, guide_end |
The protospacer, 0-based and half-open, without the PAM. |
strand |
The strand targeted. |
pam |
The PAM as the genome holds it, 5' to 3' on that strand. |
element_location |
genic or intergenic: whether the element overlaps a protein-coding gene. Independent of genomic_element, which tests promoter and enhancer first. |
genomic_element |
promoter, enhancer, distal element, exon or intron. |
intended_target_name |
Names the target; what it holds depends on the element. |
intended_target_chr/start/end |
The element's coordinates. |
putative_target_genes |
Every associated gene, comma-separated. |
reporter, imperfect |
Unused here; the format allows them. |
What intended_target_name holds¶
genomic_element |
holds |
|---|---|
promoter |
the regulated gene's ENSEMBL id |
exon |
the ENSEMBL exon id |
intron |
the intron's coordinates |
enhancer, distal element |
the element's coordinates |
A guide in two elements¶
Elements overlap, so a guide can sit in several, and the format still allows
one row. The element sharing the most bases with the protospacer wins, ties
broken by element id so a rerun gives the same answer. Nothing is lost:
putative_target_genes carries every gene of every element the guide hit.
run_metadata/igvf_export_<timestamp>.json¶
The parameters, the input checksums, the store's provenance and the counts:
guides by type, elements by genomic_element, and how many guides are
missing a PAM, which should be zero for anything that maps.
Feeding the CRISPR pipeline¶
The IGVF CRISPR Perturb-seq pipeline takes a guide_metadata.tsv with a
subset of these columns — everything except genomic_element,
putative_target_genes, reporter and imperfect — so this table can be
passed to it as it is.
intended_target_name is what joins the guide table to the pipeline's
pairs-to-test file, so the two have to name elements the same way.
genomic_element does not say genic¶
genomic_element is decided by precedence -- promoter, then exon, then
intron, then distal element -- so promoter and enhancer win before the gene
body is tested and the class cannot say whether the element sits in a gene.
element_location does, computed from the same overlap. On the hiPSC-to-EC
library 499 promoter and 110 enhancer guides are intergenic, while every exon
and intron guide is genic.