Element mapping¶
cau element-mapping says which element of a screen each guide tests. It is
the third step: alignment finds where a guide is,
annotation says what gene it falls in, and this maps it
to the regions the experiment targets.
In Claude Code the cau-element-mapping skill teaches Claude to run it and
read the output (Agents and skills).
Quick start¶
cau element-mapping run \
--alignment results/alignments/guide_genome_annotation.tsv \
--annotation results/annotations/guide_gene_annotation.tsv \
--elements elements.bed \
--outdir results/
--genes is optional and fills putative_target_genes from the same pairs
table cau igvf-export takes, so the two tables name the same genes.
--annotation is optional and fills distance_to_tss; the classes do not
depend on it. Nothing is written outside --outdir.
The three classes¶
Decided per site, not per guide, so a guide whose sites disagree reports each of them.
| Class | Means |
|---|---|
targeting |
The protospacer overlaps this element |
safe_targeting |
The guide maps, but the site overlaps no element |
non_targeting |
The guide matches nowhere in the genome |
There is deliberately no fourth class and no distance threshold. An earlier
draft called a guide safe only beyond 1 Mb from any protein-coding TSS, which
put most of a real library's safe-targeting controls somewhere else: that
design had measured safety against the screen's own readout genes, not every
promoter. Both definitions are defensible, which is the point — the tool
reports distance_to_tss and lets the analysis choose.
Outputs¶
--outdir gets three folders and nothing loose:
elements/ guide_element_mapping.tsv qc.tsv
guide_element_mapping_columns.yaml
run_metadata/ element_mapping_<UTC timestamp>.json
logs/ element_mapping.log
guide_element_mapping.tsv¶
One row per site per element it overlaps. A site inside two overlapping elements gets two rows. A guide that matches nowhere gets one row with no site and no element.
| Column | Holds |
|---|---|
guide_id |
The aligned sequence. With the four site columns, the key back to guide_genome_annotation.tsv. |
chr, start, end, strand |
The protospacer, 0-based and half-open. Empty when the guide matches nowhere. |
element_id |
The element this site overlaps. Empty unless targeting. |
element_category |
The elements BED's fifth column, when it has one. |
target_class |
targeting, safe_targeting or non_targeting. |
distance_to_tss |
Signed bases from the target site to the nearest protein-coding TSS, carried from the annotation. |
putative_target_genes |
Semicolon-separated ENSEMBL ids measured against the element, from --genes. The same genes the IGVF export carries. |
The classes are per site¶
A guide with two sites whose classes differ reports both rows, because the two sites really do different things:
guide_id chr start element_id target_class
G...NGG chr10 86958386 chr10:86958280-86958780 targeting
G...NGG chr17 79714569 safe_targeting
safe_targeting is not a promise¶
It says only that the site maps and overlaps none of the elements given. How
far from a gene a guide has to be before it is safe depends on what the
screen reads out, so that is left to distance_to_tss rather than fixed by a
threshold here. Threshold it yourself, and say which threshold you used.
It follows that an incomplete element list inflates safe_targeting: every
guide for a missing element lands there. Check the count against the library
design before believing it.
qc.tsv¶
Three columns, section, name, value: how the library covers the
elements, which is the question the mapping table cannot answer by itself.
| Section | Says |
|---|---|
classes |
How many guides, and how many sites in each class |
elements |
Total, how many have a guide, how many have none, and how many are below half the median density |
guides_per_element |
Median, min, max, and the median per 100 bases |
category |
The same per element category, so a thinly covered kind of element stands out |
untiled_elements |
How far the elements with no guide are from the nearest mapped one |
Two of these earn their place:
- Density, not count. A wide element collects more guides without being
better covered, so
median_per_100bpandbelow_half_median_densityare what find the elements that are actually thin. - Distance for the untiled ones. An element a few hundred bases from the nearest guide was missed at its boundary; one tens of kilobases away was never targeted at all. Only the second is a hole in the design.
element_id¶
Taken from the BED's fourth column when it has one, so an id used elsewhere
keeps its spelling. Otherwise built as chr:start-end with a 1-based start,
which is how a locus is read aloud and how most element tables write it.
Use it to check the design¶
A library's own labels are a hypothesis. Mapping a real 43,778-guide library against its element list disagreed with the shipped annotation in two ways, in opposite directions:
- 18 guides labelled non-targeting cut inside a targeted element. All 18 are exact 20-nt protospacers with a real NGG, read straight back out of the reference. The aligner the old pipeline used had missed them, so genuine cutters were used as controls.
- 45 guides assigned to an element do not reach it. That pipeline stripped a 5' G before aligning and so searched a 19-mer, which matches places the real 20-mer does not.
Both contaminate a downstream test, in opposite directions, and neither is visible without redoing the mapping from the sequences.