理解ChIP-Seq
到了目前這個水平,我學習新的高通量數據分析流程時已經不再考慮代碼應該如何寫的問題了。我更多要去考慮一個技術的目的和意義。
轉錄組主要研究的問題是基因在不同情況下的差異表達以及RNA結構變化等,而表觀組研究的問題是在基因序列不變的情況下,基因的表達、調控和性狀發生了可遺傳變化的分子機制。也就是相同的DNA, RNA,蛋白質經過一定的修飾后會使得生物性狀發生了改變。
Jimmy在生信技能樹的論壇上發了一個帖子我對表觀的18個疑問, 目前他提出了22個問題,還沒有改標題。里面提到的就是ChIP-Seq僅僅是第一個表觀遺傳學領域比較成熟的技術而已,目前還有很多其他的技術,比如說
- DNA修飾: DNA甲基化免疫共沉淀技術(MeDIP), 目標區域甲基化,全基因組甲基化(WGBS),氧化-重亞硫酸鹽測序(oxBS-Seq), TET輔助重亞硫酸鹽測序(TAB-Seq)
- RNA修飾: RNA甲基化免疫共沉淀技術(MeRIP)
- 蛋白質與核酸相互作用: RIP-Seq, ChIP-Seq, CLIP-Seq
- 還有最近比較火的ATAC-Seq ATAC-seq能干啥?
2013年PNAS上面有一篇文章叫做 Epigenetics: Core misconcept 講了幾點關于表觀遺傳學,大家的理解錯誤的地方。
本次主要是分析ChIP-Seq的高通量測序結果,因此,先介紹什么是ChIP-Seq.
所謂的ChIP-Seq其實就是把ChIP實驗做完得到的DNA不僅僅用來跑膠,還送去高通量測序了。重點在于ChIP,也就是染色體免疫共沉淀(Chromatin Immunoprecipitation)是用來解決什么科學問題的。畢竟數據分析不是目的,它只是解決問題的一種手段。
ChIP被用來研究細胞內DNA與蛋白質相互作用,具體來說就是確定特定蛋白(如轉錄因子)是否結合特定基因組區域(如啟動子或其它DNA結合位點)——可能定義順反組。ChIP還被用來確定基因組上與組蛋白修飾相關的特定位點(即組蛋白修飾酶類的靶標) - 來自維基百科。
ChIP的實驗我從來沒有做過,所以只能從網上找來大致的流程,簡單分為
第一步: 將蛋白交聯到DNA上。 也就是保證蛋白和DNA能夠結合,找到互作位點。
第二步: 通過超聲波剪切DNA鏈。
第三步: 加上附上抗體的磁珠用于免疫沉淀靶蛋白。抗體很重要
第四步: 接觸蛋白交聯;純化DNA
如果送去測序就是ChIP-Seq, 后續就是對應分析流程,分析分為4步:
- 質量控制, 用到的是FastQC
- 序列比對,Bowtie2或這BWA
- peak calling, 建議用MACS
- peak注釋, 推薦Y叔的ChIPseeker
文章中ChIP-Seq解決的問題
這部分看看這篇文章想解決什么問題,以及ChIP-Seq解決了什么問題。工具一定要為目的服務。
PS: 可以先去把數據下載了,再看這個部分
文章的研究內容:
PRC1(Polycomb repressive complex 1)與干細胞命運決定有關。PRC1的組成非常的復雜,原文這樣寫道:
The protein families that constitute the core of PRC1 contain several members: Cbx (Cbx2, Cbx4, Cbx6, Cbx7, or Cbx8); Ring1A or Ring1B; PHC (PHC1, PHC2, or PHC3); PCGF (PCGF1, PCGF2, PCGF3, PCGF4, PCGF5, or PCGF6); and RYBP or YAF2. Each combination establishes the subtype of PRC1 complexes
文章想解決的問題是:
- PRC1復合體兩類亞型的全基因組定位
- 兩類復合體調節的基因表達是否有差異
- Cbx7,RYBP是否有共同或獨特的生物學功能
- Cbx7,RYBP在染色質的定位是否是相互依賴
得到的部分答案是:小鼠中有兩個互斥的PRC1復合體的變異體,Cbx7和RYBP。Cbx7和RYBP的在基因組上的結合在同一個位置,但是同樣互斥,不能共存。 Cbx7用于招募Ring1B結合到染色質,RYBP增加PRC1酶活性。 RYBP所結合的基因,有著較低水平Ring1B和H2AK119ub的水平,表達量高于Cbx7結合態。RYBP和Cbx7的在基因位點的結合情況還與代謝調節,細胞周期過程有關。
ChIP的用途:
為了解決PRC1亞型的定位問題, 作者對PRC1復合體的組成Cbx7, Ring1B, RYBP, 以及PRC2的Suz12f分別做了ChIP-Seq. 然后就是畫了很多韋恩圖看不同蛋白的靶基因的相互關系。還看了不同蛋白在基因的上的位置。
一般而言,ChIP-Seq基本就是得到上面這些圖,根據疑問再找到某一些基因看調控蛋白的結合和定位。本次實戰也就是嘗試做出這些圖。
根據原文,ChIP-Seq的流程如下:
- 先用Bowtie(0.12.7)把RYBP, Cbx7, Ring1B, Suz12,和H2AK11Ub的ChIP-Seq產生短讀(reads) 比對到小鼠的參考基因組上(NCBIM37),參數允許seed聯配時有2個錯配。
- 使用MACS(1.4.1)尋找可能的結合位點,也就是基因組中大量短讀片段富集的區域。MACS比較這些區域在對照組和實驗組的差異,選擇p值等于10e-5作為閾值。 之后PDR低于5%的Cbx7, Ring1B, Suz12和H2AK119ub的peak和PDR低于1%的RYBP的peak結合用于進一步分析
這一步看起來就很復雜,之后會重點進行學習
- 在基因內部或距離TSS 2.5kb的 peak 被認為是靶基因。 每個TSS附近5Kb區域,并且與一個或多個ChIP-Seq(RYBP,Ring1B, Cbx7, Suz12, H2AK119ub)結果關聯,用于計算ChIP-Seq表達譜和全ChIP-Seq覆蓋度。
- 使用BEDtools 計算TSS附近ChIP-Seq表達譜
ChIP-Seq數據分析的流程難點在于找到peak,所以peak calling這一階段的軟件選擇比較重要,目前常用的是MACS2, 實際分析建議多用幾個軟件。目前常用的是MACS2, 實際分析建議多用幾個軟件。
數據下載和質量控制
這部分下載ChIP-Seq數據,以及小鼠的參考基因組,注釋。
- 下載測序數據,并用sratoolkit解壓縮
文章提供的GEO是GSE42466,可以在https://www.ncbi.nlm.nih.gov/geo/ 檢索到對應的數據集
# 我習慣將數據保存到項目文件夾下的data中
mkdir -p GSE42466/data/chip-seq
cd GSE42466/data/chip-seq
for ((i=204;i<=209;i++));
do
wget -4 -q ftp://ftp-trace.ncbi.nlm.nih.gov/sra/sra-instant/reads/ByStudy/sra/SRP/SRP017/SRP017311/SRR620$i/SRR620$i.sra;
~/miniconda/envs/biostar/bin/fastq-dump –split-3 SRR620$i.sra;
done &
- 下載小鼠參考基因組的索引和注釋文件, 這里用常用的mm10
# 索引大小為3.2GB, 不建議自己下載基因組構建
mkdir referece && cd reference
wget -4 -q ftp://ftp.ccb.jhu.edu/pub/data/bowtie2_indexes/mm10.zip
unzip mm10.zip
注釋文件到https://genome.ucsc.edu/cgi-bin/hgTables 選取保存。
或者用curl進行下載。
curl 'https://genome.ucsc.edu/cgi-bin/hgTables?hgsid=603641571_MKLxB78UAcjaI3oj5YiFCA0Ms86o&boolshad.hgta_printCustomTrackHeaders=0&hgta_ctName=tb_refGene&hgta_ctDesc=table+browser+query+on+refGene&hgta_ctVis=pack&hgta_ctUrl=&fbQual=whole&fbUpBases=200&fbExonBases=0&fbIntronBases=0&fbDownBases=200&hgta_doGetBed=get+BED' > mm10_refSeq.bed
得到的fastq文件,一般而言都是上機得到的原始數據,也有可能是經過質量控制的結果,但是無論如何都得自己去檢查一下。
## 需要安裝fastqc 和 multiqc
# 先獲取QC結果
ls *gz | while read id; do fastqc -t 4 $id; done
# multiqc
multiqc *fastqc.zip --pdf
根據質控結果,發現序列的前后幾個堿基質量不好,因此在比對的時候會主動忽略。
今后,可能會去下載其他實驗的數據,還要進行質量控制,所以就寫一個Python腳本進行流程化操作。腳本命名為sra2qc.py
,保存在我的GitHub上
序列比對
這一步非常簡單, 就是將得到fastq文件用bowtie2比對小鼠參考基因組上,
bowtie2 -p 6 -3 5 --local -x reference/mm10 -U ChIP-Seq/SRR620204.fastq | ~/miniconda3/bin/samtools sort -O bam -o ../analysis/alignment/ring1B.bam
bowtie2 -p 6 -3 5 --local -x reference/mm10 -U ChIP-Seq/SRR620205.fastq | ~/miniconda3/bin/samtools sort -O bam -o ../analysis/alignment/cbx7.bam
bowtie2 -p 6 -3 5 --local -x reference/mm10 -U ChIP-Seq/SRR620206.fastq | ~/miniconda3/bin/samtools sort -O bam -o ../analysis/alignment/suz12.bam
bowtie2 -p 6 -3 5 --local -x reference/mm10 -U ChIP-Seq/SRR620207.fastq | ~/miniconda3/bin/samtools sort -O bam -o ../analysis/alignment/RYBP.bam
bowtie2 -p 6 -3 5 --local -x reference/mm10 -U ChIP-Seq/SRR620208.fastq | ~/miniconda3/bin/samtools sort -O bam -o ../analysis/alignment/IgGold.bam
bowtie2 -p 6 -3 5 --local -x reference/mm10 -U ChIP-Seq/SRR620209.fastq | ~/miniconda3/bin/samtools sort -O bam -o ../analysis/alignment/IgG.bam
我對比對結果進行了簡單的統計,發現比對率其實不太高. 雖然在RNA-Seq是要求80~90%的比對率,但是在ChIP-Seq上,我沒有具體了解過。
樣品 | 比對到單個區域 | 比對到多個區域 |
---|---|---|
ring1B | 43.76% | 15.81% |
cbx7 | 39.39% | 17.49% |
suz12 | 48.88% | 17.17% |
RYBP | 58.76% | 28.12% |
IgGold | 54.54% | 27.21% |
IgG | 57.83% | 25.45% |
比對的結果,可以打開IGV查看,和RNA-Seq最大的區別在于你能看到明顯的峰,這就是peak。這類peak在全基因組上特別的多,我們無法用肉眼直接選擇,因此就需要借助專門的工具查找。
一般ChIP-Seq都需要提供一個對照組,也就是圖中IgG。很明顯的發現其他實驗組有峰的區域在對照組中是沒有的。而實驗組沒有峰的區域,對照組也沒有,這樣子就能提出背景噪聲。
peak calling
peak calling要用到MACS, 建議用ananconda安裝, 因為可以選擇合適的Python環境。
conda create -n macs python=2
source activate macs
pip install MACS2
macs2包含一系列的子命令,其中最主要的就是callpeak
, 官方提供了使用實例
macs2 callpeak -t ChIP.bam -c Control.bam -f BAM -g hs -n test -B -q 0.01
一般而言,我們照葫蘆畫瓢,按照這個實例替換對應部分就行了,介紹一下各個參數的意義
- -t: 實驗組的輸出結果
- -c: 對照組的輸出結果
- -f: -t和-c提供文件的格式,可以是"ELAND", "BED", "ELANDMULTI", "ELANDEXPORT", "ELANDMULTIPET" (for pair-end tags), "SAM", "BAM", "BOWTIE", "BAMPE" "BEDPE" 任意一個。如果不提供這項,就是自動檢測選擇。
- -g: 基因組大小, 默認提供了hs, mm, ce, dm選項, 不在其中的話,比如說擬南芥,就需要自己提供了。
- -n: 輸出文件的前綴名
- -B: 會保存更多的信息在bedGraph文件中,如fragment pileup, control lambda, -log10pvalue and -log10qvalue scores
- -q: q值,也就是最小的PDR閾值, 默認是0.05。q值是根據p值利用BH計算,也就是多重試驗矯正后的結果。
- -p: 這個是p值,指定p值后MACS2就不會用q值了。
- -m: 和MFOLD有關,而MFOLD和MACS預構建模型有關,默認是5:50,MACS會先尋找100多個peak區構建模型,一般不用改,因為你不懂。
原文寫到:MACS estimated the FDR by comparing the peaks obtained from the samples with those from the control samples, using the same p value cutoff (10e-5). 估計就是指文章用了q=0.05或0.01
macs2 callpeak -c IgGold.bam -t suz12.bam -q 0.05 -f BAM -g mm -n suz12 2> suz12.macs2.log &
macs2 callpeak -c IgGold.bam -t ring1B.bam -q 0.05 -f BAM -g mm -n ring1B 2> ring1B.macs2.log &
macs2 callpeak -c IgG.bam -t cbx7.bam -q 0.05 -f BAM -g mm -n cbx7 2> cbx7.macs2.log &
macs2 callpeak -c IgG.bam -t RYBP.bam -q 0.01 -f BAM -g mm -n RYBP 2>RYBP.macs2.log &
可以看下找到了多個peak,
wc -l *bed
2384 cbx7_summits.bed
8342 ring1B_summits.bed
0 RYBP_summits.bed
7619 suz12_summits.bed
結果顯示RYBP無peak,估計是數據上傳錯誤,我們可以下載作者上傳的peak數據。此外ring1B我找了8000多個,但是原文是7000個,或許要修改閾值。
wget ftp://ftp.ncbi.nlm.nih.gov/geo/series/GSE42nnn/GSE42466/suppl/GSE42466_Suz12_peaks_10.txt.gz
gzip -d GSE42466_Suz12_peaks_10.txt.gz
mv GSE42466_RYBP_peaks_5.txt RYBP2_summits.bed
結果文件不只是上述提到的一類,還有如下格式:
- NAME_peaks.xls: 以表格形式存放peak信息,雖然后綴是xls,但其實能用文本編輯器打開,和bed格式類似,但是以1為基,而bed文件是以0為基.也就是說xls的坐標都要減一才是bed文件的坐標
- NAME_peaks.narrowPeak NAME_peaks.broadPeak 類似。后面4列表示為, integer score for display, fold-change,-log10pvalue,-log10qvalue,relative summit position to peak start。內容和NAME_peaks.xls基本一致,適合用于導入R進行分析。
- NAME_summits.bed:記錄每個peak的peak summits,話句話說就是記錄極值點的位置。MACS建議用該文件尋找結合位點的motif。
- NAME_model.r,能通過
$ Rscript NAME_model.r
作圖,得到是基于你提供數據的peak模型。
這一部分的工作主要是學習MACS2軟件使用方法和參數的含義,難度不大。目標是找到候選靶基因。
結果注釋和可視化
當我們得到上一步的輸出文件后,下一步就是得到文章的結果。用的是Y叔的ChIPseeker,一個充滿故事的R包,搜索一下就能看到Y叔的往事。
ChIPseeker的功能分為三類:
- 注釋:提取peak附近最近的基因, 注釋peak所在區域
- 比較:估計ChIP peak數據集中重疊部分的顯著性;整合GEO數據集,以便于將當前結果和已知結果比較
- 可視化: peak的覆蓋情況;TSS區域結合的peak的平均表達譜和熱圖;基因組注釋;TSS距離;peak和基因的重疊
完全符合我們的需要,都不需要用到bedtools
和deeptools
。
在正式的工作開始之前,我們需要加載ChIPseeker
, 基因組注釋包和bed數據
# biocLite("ChIPseeker")
# biocLite("org.Mm.eg.db")
# biocLite("TxDb.Mmusculus.UCSC.mm10.knownGene")
library("ChIPseeker")
# 根據自己存放文章具體地址修改,保證導入的數據是BED格式
ring1B <- readPeakFile("F:/Data/ChIP/ring1B_peaks.narrowPeak")
cbx7 <- readPeakFile("F:/Data/ChIP/cbx7_peaks.narrowPeak")
RYBP <- readPeakFile("F:/Data/ChIP/RYBP2_summits.bed")
suz12 <- readPeakFile("f:/Data/ChIP/suz12_peaks.narrowPeak")
得到最基本的peak數據后,我們要做以下事情
- 大量的韋恩圖,描述不同蛋白結合基因的關系
- 不同蛋白在染色體結合位點與TSS的距離
為了完成上面說的兩件事情,我們需要注釋peak,準備TSS所在位置然后把peak比對到這些區域.
注: 原文提供不同蛋白的交集的基因TSS區域,所以要先做注釋。
關于peak注釋一定要多說幾句:
- 啟動子區域目前沒有明確定義,一般認為基因起始轉錄位點的上下游區域是啟動子區域,文章認為是TSS2.5 kb 以內都是靶基因
- 注釋有兩類,genomic annotation和nearest gene annotation. 前者是研究直接調控對象,后者是做基因表達調控
- 還有一類注釋就是簡單看peak上下游的范圍的基因
根據文章得知需要距離TSS一定距離的注釋,以及peak上下5 Kb 的注釋
Genes with a peak within the gene body, or within 2.5 kb from the TSS, were considered to be target genes. An area of 5 kb surrounding each TSS that was associated to one or more ChIP-seq (RYBP, Ring1B, Cbx7, Suz12, or H2AK119ub) was used to calculate the ChIP-seq profile and the whole ChIP-seq coverage.
ChIPseeker
負責注釋的就是annotatePeak,提供了3類注釋方式,符合文章的要求
# 對于非向量的循環,推薦構建list,然后用lapply
peaks <- list(ring1B, cbx7, RYBP, suz12)
# 注釋
peakAnnoList <- lapply(peaks, annotatePeak, tssRegion=c(-2500,2500), TxDb=txdb,
addFlankGeneInfo=TRUE, flankDistance=5000)
結果可以用as.GRanges或者as.data.frame查看。
as.GRanges(peakAnnoList[[1]])
as.data.frame(peakAnnoList[[1]])
得到的結果會在原先的bed文件中增加額外的注釋信息,你可以和之前導入的數據進行比較,比如說geneId, transcriptId,distanceToTSS,flank_txIds
等。這些都保存后續作圖所需要的信息。我們可以先看不同蛋白的靶位點的注釋情況,
plotDistToTSS(peakAnnoList)
原文大量的是不同蛋白結合基因的韋恩圖,我們可以用更有趣的UpSet
的點圖
genes= lapply(peakAnnoList, function(i) as.data.frame(i)$geneId)
library(UpSetR)
upset(fromList(genes))
UpSet技術適用于多于5個集合表示情況,對于兩個蛋白的靶基因的比較,大家更加喜歡韋恩圖的。
vennplot(genes[1:2])
感覺沒有原文那么高大上,主要原因就是沒有上色,可以自行搜索找合適的軟件作圖。關于不同蛋白靶基因的集合關系圖基本上就是這樣子。
下面是根據靶基因間的交集,繪制TSS距離圖,比如說四個蛋白的重疊基因。
# 準備TSS區域,然后將peak映射到這些區域,得到tagMatrix
fourgenes <- intersect(genes[[1]],intersect(genes[[2]],intersect(genes[[3]],genes[[4]])))
target <- select(txdb, keys=fourgenes, columns=c("TXID","GENEID"), keytype = "GENEID")
promoter <- promoters(txdb, upstream = 2500, downstream = 2500)
target_promoter <- promoter[promoter$tx_id %in% target$TXID]
tagMatrixList <- lapply(peaks, getTagMatrix, window=target_promoter)
plotAvgProf(tagMatrixList , xlim = c(-3000,2999))
感覺和原圖有那么一點像,還可以畫個熱圖
tagHeatmap(tagMatrixList, xlim=c(-2999, 3000), color=NULL)
基本上原文的圖,我都能畫出來,至于想不想就不管了。