Annotates ChIP-seq peaks to genomic features, nearest genes, ENCODE candidate cis-regulatory elements (cCREs), and regulatory domains. Uses ChIPseeker (R), HOMER annotatePeaks.pl (CLI), pyranges (Python), GREAT/rGREAT (regulatory domain gene-set enrichment), ChIP-Enrich (locus-length-adjusted), ENCODE SCREEN cCRE classification (PLS/pELS/dELS/CA-CTCF/CA-H3K4me3), and ENCODE-rE2G for cell-type-specific enhancer-gene linking. Handles nearest-TSS vs host-gene ambiguity, promoter window definition, and feature priority. Use when assigning genomic context to peaks, linking enhancer peaks to target genes, classifying peaks against ENCODE cCRE registry, or running gene-set enrichment on peak-associated genes.
Annotates ChIP-seq peaks to genomic features, nearest genes, ENCODE candidate cis-regulatory elements (cCREs), and regulatory domains. Uses ChIPseeker (R), HOMER annotatePeaks.pl (CLI), pyranges (Python), GREAT/rGREAT (regulatory domain gene-set enrichment), ChIP-Enrich (locus-length-adjusted), ENCODE SCREEN cCRE classification (PLS/pELS/dELS/CA-CTCF/CA-H3K4me3), and ENCODE-rE2G for cell-type-specific enhancer-gene linking. Handles nearest-TSS vs host-gene ambiguity, promoter window definition, and feature priority. Use when assigning genomic context to peaks, linking enhancer peaks to target genes, classifying peaks against ENCODE cCRE registry, or running gene-set enrichment on peak-associated genes.
ENCODE cCRE registry expanded to 2.37M human and 967k mouse elements (Moore JE et al 2026 Nature). SCREEN web app at screen.encodeproject.org provides browser access; ENCODE provides bed files for batch annotation.
Peak Annotation
"What genes and regulatory elements do my peaks correspond to?" -> Assign each peak to a genomic feature (promoter, exon, intron, intergenic), its target gene (via nearest-TSS or host-gene), and where applicable an ENCODE cCRE class (PLS/pELS/dELS/CA-CTCF/CA-H3K4me3).
R (gene-feature): ChIPseeker::annotatePeak(peaks, TxDb=txdb)
R (cCRE classification): intersect peaks with ENCODE cCRE BED from SCREEN
R (gene-set enrichment): rGREAT::great() or chipenrich::chipenrich()
The single biggest source of misinterpretation is the nearest-TSS vs host-gene distinction (see below). For enhancer-driven biology, ENCODE-rE2G or ABC (in atac-seq/enhancer-gene-linking) is more accurate than nearest-TSS.
Choosing an Annotation Approach
Context
Recommended
Why
Standard genome, pre-built annotations available
ChIPseeker with TxDb package
Simplest; automatic gene symbol mapping via annoDb
Custom or project-specific GTF
ChIPseeker + makeTxDbFromGFF, HOMER -gtf, or pyranges
All three handle custom annotations
HOMER already in pipeline
HOMER annotatePeaks.pl
Reuses tag directory; combined with motif workflow
Fine-grained control
pyranges (Python)
Full control over priority rules, distance calculation
Enhancer peaks (distal regulatory)
GREAT / rGREAT
Regulatory domain assignment (basal + extension), not just nearest
Cell-type-specific enhancer-gene linking
ENCODE-rE2G
Modern (2024); ABC-trained logistic regression with chromatin context
Gene-set enrichment with locus-length adjustment
chipenrich / Broad-Enrich
Corrects for systematic gene-length bias in peak assignment
Compare against ENCODE cCRE atlas
SCREEN cCRE BED intersect
Cross-reference standard regulatory registry
Promoter-coverage decomposition
bedtools intersect with TSS windows
Quick stats per peak set
Critical: Use the same annotation source as the alignment (UCSC knownGene TxDb with GENCODE GTF alignment causes mismatches). When a specific GTF is provided, use it directly via makeTxDbFromGFF rather than a mismatched pre-built TxDb package.
Nearest-TSS vs Host-Gene Convention
Peak annotation involves two decisions that should be coupled but often aren't:
Which gene to assign (target gene)
What feature the peak overlaps (promoter / exon / intron / intergenic)
Example failure: Peak inside gene A's intron, near gene B's TSS. Default tools report nearest_gene=B, feature=intron — but the intron belongs to gene A, not gene B. The annotation is internally inconsistent.
Choosing per Biology
Context
Convention
Rationale
Distal TF binding (enhancers)
Nearest-TSS, but prefer ENCODE-rE2G / ABC
Enhancers can regulate gene A despite sitting in gene B's intron
Histone marks in gene bodies (H3K36me3, H3K27me3)
Host-gene
Mark reflects host transcriptional state
Promoter-associated marks (H3K4me3, H3K27ac at promoters)
Either
Most peaks at promoters where conventions agree
Custom annotation against project GTF
Host-gene
Internal consistency
Reproducing published HOMER results
Nearest-TSS
Matches HOMER default
When a task says "nearest gene," clarify which definition. For most annotation purposes where gene + feature should be consistent, use host-gene; for distal enhancer biology, use a proper enhancer-gene linker (ENCODE-rE2G, ABC).
Coordinate Systems and TSS
BED uses 0-based half-open [start, end). GTF uses 1-based closed [start, end]. Mixing without conversion shifts annotations by one base.
Peak center (BED):(start + end) // 2
TSS from GTF (1-based to 0-based):
Plus-strand: tss_0based = start - 1
Minus-strand: tss_0based = end
Signed distance (negative = upstream of TSS):
Plus-strand: distance = peak_center - tss
Minus-strand: distance = -(peak_center - tss)
ChIPseeker (R)
Goal: Assign each ChIP-seq peak to a gene and a feature category using a transcript database.
Approach: Load the TxDb (pre-built or custom-built from GTF), pass peaks to annotatePeak() with the desired tssRegion window and overlap convention (host-gene vs nearest-TSS), then export the annotated data frame with gene symbols mapped from annoDb or the original GTF.
GENCODE gene IDs have version suffixes (ENSG00000142192.25); strip before joining.
Promoter window:tssRegion = c(-2000, 2000) is common; c(-3000, 3000) is ChIPseeker default. Match to analysis requirements.
Feature priority: Default Promoter > 5'UTR > 3'UTR > Exon > Intron > Downstream > Intergenic. A peak in both a promoter (gene A) and an intron (gene B) receives "Promoter (gene A)" by default.
HOMER's 19-column output: columns 8 (Annotation), 10 (Distance to TSS), 16 (Gene Name) are the primary annotation columns.
HOMER promoter window is fixed at -1kb / +100bp — not configurable via flags. For custom windows, reclassify using the Distance to TSS column post-hoc.
ENCODE cCRE Classification
The ENCODE Registry of candidate cis-Regulatory Elements (cCREs) provides 2.37M human + 967k mouse elements. Registry V4 uses an 8-class scheme (the older V3 "CTCF-only" and "DNase-H3K4me3" were renamed CA-CTCF and CA-H3K4me3):
Class
Definition
Marker pattern
PLS (Promoter-Like Signature)
≤ 200 bp of annotated TSS; high DNase + high H3K4me3
Welch 2014: standard gene-set enrichment on peak-associated genes systematically over-counts long genes. ChIP-Enrich models locus length as a covariate.
library(chipenrich)
res <- chipenrich(peaks ='peaks.bed', genome ='hg38',
genesets ='GOBP', locusdef ='nearest_tss',
out_name ='chipenrich_out', n_cores =4)# Locus definitions: nearest_tss, nearest_gene, exon, intron, 1kb, 5kb, 10kb# method= accepts chipenrich (default) or fet; broadenrich() and polyenrich() are separate functions
For broad marks (H3K27me3, H3K9me3): use the separate broadenrich(peaks = 'peaks.bed', genome = 'hg38', genesets = 'GOBP', locusdef = 'nearest_tss') function, which accounts for region width.
ENCODE-rE2G (Modern Enhancer-Gene Linking)
ENCODE-rE2G (2024) replaces ABC for cell types with ENCODE data. Cell-type-specific logistic-regression weights map distal enhancer peaks to target genes with higher accuracy than nearest-TSS or basal+extension.
See atac-seq/enhancer-gene-linking for full workflow; the same model applies to ChIP-seq enhancer marks (H3K27ac, H3K4me1, H3K4me2).
Per-Tool Failure Modes
ChIPseeker -- TxDb / annoDb genome mismatch
Trigger: Using hg19 TxDb on hg38-aligned BAMs / peaks.
Trigger: Including unfiltered peaks at rRNA / housekeeping / mtDNA in GREAT analysis.
Mechanism: Hyper-ChIPable artifacts are enriched at highly-transcribed loci; GREAT assigns them to associated genes, inflating GO terms for "translation" and "ribosomal" categories.
Symptom: Top enriched GO terms always include "ribosomal", "translation", "mitochondrion" regardless of biology.