跳转至

150_Nanopore甲基化检测

一句话概述

Oxford Nanopore测序可以直接从原始电信号中检测DNA甲基化修饰(无需亚硫酸盐转化),通过Dorado basecaller内置的修饰碱基模型生成modBAM/bedMethyl格式数据,再进行差异甲基化区域(DMR)分析。


核心知识点总览

知识点说明
直接甲基化检测原理甲基化修饰改变DNA通过纳米孔时的电信号特征
Dorado basecallerONT官方basecaller,内置修饰碱基检测模型
modBAM格式携带甲基化概率的BAM文件(MM/ML tag)
bedMethyl格式每个CpG位点的甲基化比例统计文件
5mC检测5-甲基胞嘧啶(CpG上下文),最常检测的修饰
5hmC检测5-羟甲基胞嘧啶,与5mC的区分
6mA检测N6-甲基腺嘌呤,原核和真核中的修饰
modkitONT工具,从modBAM提取甲基化统计
DMR分析差异甲基化区域鉴定(DSS/dmrseq)
应用场景全基因组甲基化图谱、印记分析、肿瘤表观基因组

各步骤详解

第一步:理解Nanopore直接甲基化检测原理

白话解释: DNA链穿过纳米孔时会产生电流信号。有甲基化修饰的碱基(比如5mC)和没有修饰的碱基(普通C)通过纳米孔时产生的电流波形不一样。Nanopore的AI模型可以从这些电流差异中直接识别出哪些位置有甲基化——完全不需要像传统方法那样用亚硫酸盐处理DNA。

技术原理: - 纳米孔中的电流由当前位于孔内的约5个碱基(k-mer)决定 - 甲基化碱基改变了k-mer的物理化学性质,导致电流均值和方差发生变化 - Dorado使用深度学习模型(CRF+RNN/Transformer)同时进行basecalling和甲基化检测 - 输出为修饰概率(0-255),存储在BAM文件的MM/ML tag中

支持的修饰类型: | 修饰 | 代码 | 上下文 | 生物学意义 | |------|------|--------|-----------| | 5mC | m | CpG | 基因沉默、发育调控 | | 5hmC | h | CpG | 去甲基化中间体、神经发育 | | 6mA | a | 多种 | 原核限制修饰系统 | | 4mC | - | 多种 | 原核特有 |

代码概念:电流信号与甲基化

# 概念演示:甲基化如何影响电流
# 实际中由Dorado模型自动处理
import numpy as np

# 模拟一个5-mer通过纳米孔的电流
# 未甲基化的 ACGTA
signal_unmethylated = np.array([105.2, 98.7, 112.3, 89.5, 95.1])
# 甲基化的 A(5mC)GTA - CpG位置的C被甲基化
signal_methylated = np.array([105.2, 103.4, 115.8, 89.5, 95.1])
# 甲基化导致电流特征改变,AI模型学习这种差异


第二步:Dorado Basecalling + 修饰碱基检测

白话解释: Dorado是ONT的新一代basecaller(取代Guppy)。在做basecalling的同时就可以检测甲基化——只需在命令中指定使用带修饰碱基检测的模型即可。

技术原理: - Dorado模型命名规则:dna_r10.4.1_e8.2_400bps_hac@v4.3.0 - 芯片类型 (r10.4.1) - 电化学版本 (e8.2) - 速度 (400bps) - 精度级别 (fast/hac/sup) - 版本号 - 甲基化检测通过 --modified-bases 参数指定

代码示例:

# === Dorado basecalling + 5mC检测 ===
# 下载合适的模型
dorado download --model dna_r10.4.1_e8.2_400bps_sup@v4.3.0

# Basecalling + 5mCpG检测 (一步完成)
dorado basecaller \
  dna_r10.4.1_e8.2_400bps_sup@v4.3.0 \
  pod5_dir/ \
  --modified-bases 5mCG \
  --reference hg38.fa \
  --device "cuda:0" \
  > aligned_mod.bam

# 检测5mC和5hmC (双修饰)
dorado basecaller \
  dna_r10.4.1_e8.2_400bps_sup@v4.3.0 \
  pod5_dir/ \
  --modified-bases 5mCG_5hmCG \
  --reference hg38.fa \
  > aligned_mod_5mc_5hmc.bam

# 排序和索引
samtools sort -o sorted_mod.bam aligned_mod.bam
samtools index sorted_mod.bam

# === 检查modBAM的MM/ML tag ===
samtools view sorted_mod.bam | head -1 | tr '\t' '\n' | grep -E "^(MM|ML)"
# MM:Z:C+m,0,1,3;     # 甲基化位置(相对于比对位置)
# ML:B:C,230,15,200    # 甲基化概率(0-255)


第三步:modkit提取甲基化统计

白话解释: Dorado产生的BAM文件里每条read都带有甲基化概率。modkit工具的作用是把这些信息汇总——统计每个CpG位点有多少条read支持甲基化、多少不支持,算出甲基化频率。

技术原理: - modkit从modBAM中解析MM/ML tag - 对每个基因组位点汇总所有覆盖read的甲基化概率 - 输出bedMethyl格式(BED格式扩展) - 支持阈值过滤、链分离、区间统计等

代码示例:

# === 安装modkit ===
# 从GitHub releases下载: https://github.com/nanoporetech/modkit
# 或 conda install -c nanoporetech modkit

# === 基本用法:生成bedMethyl ===
modkit pileup \
  sorted_mod.bam \
  output.bedmethyl \
  --ref hg38.fa \
  --cpg \
  --combine-strands \
  --filter-threshold 0.75 \
  --threads 16

# 参数说明:
# --cpg               : 只输出CpG位点
# --combine-strands   : 合并正负链的CpG信息
# --filter-threshold  : 概率阈值(>=0.75判为甲基化)
# --threads           : 线程数

# === 输出bedMethyl格式说明 ===
# chr  start  end  modified_base  score  strand  ...  N_valid  fraction_modified  N_mod  N_canon  N_other  N_delete  N_fail  N_diff  N_nocall
# chr1 10468  10469  m             953    +      ...  21       0.952              20     1        0       0         0       0       0

# === 按区间统计 ===
# 统计promoter区域的甲基化
modkit pileup \
  sorted_mod.bam \
  promoter_methyl.bedmethyl \
  --ref hg38.fa \
  --cpg \
  --combine-strands \
  --include-bed promoters.bed \
  --threads 16

# === 甲基化摘要统计 ===
modkit summary sorted_mod.bam
# 输出全局甲基化比例、检测到的修饰类型等

# === 提取特定区域 ===
modkit pileup \
  sorted_mod.bam \
  region_methyl.bedmethyl \
  --ref hg38.fa \
  --region chr1:1000000-2000000 \
  --cpg


第四步:可视化甲基化数据

白话解释: 甲基化数据拿到后,需要用各种图表展示。常见的有:全基因组甲基化分布、单基因甲基化热图、CGI(CpG岛)甲基化状态等。

代码示例:

library(ggplot2)
library(GenomicRanges)

# 1. 读取bedMethyl文件
bedmethyl <- read.delim("output.bedmethyl", header = FALSE,
  col.names = c("chr", "start", "end", "mod_base", "score", "strand",
                "start2", "end2", "color", "N_valid", "fraction_mod",
                "N_mod", "N_canon", "N_other", "N_delete", "N_fail",
                "N_diff", "N_nocall"))

# 2. 全基因组甲基化分布
ggplot(bedmethyl, aes(x = fraction_mod)) +
  geom_histogram(bins = 50, fill = "steelblue", alpha = 0.7) +
  labs(x = "Methylation Fraction", y = "Number of CpG sites",
       title = "Genome-wide CpG Methylation Distribution") +
  theme_minimal()

# 3. 染色体水平甲基化
chr_methyl <- aggregate(fraction_mod ~ chr, data = bedmethyl, FUN = mean)
ggplot(chr_methyl, aes(x = chr, y = fraction_mod)) +
  geom_bar(stat = "identity", fill = "coral") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(title = "Average Methylation by Chromosome")

# 4. 特定基因区域的甲基化
gene_region <- bedmethyl[bedmethyl$chr == "chr17" &
                          bedmethyl$start >= 43044295 &
                          bedmethyl$end <= 43170245, ]  # BRCA1区域
ggplot(gene_region, aes(x = start, y = fraction_mod)) +
  geom_point(alpha = 0.5, size = 1) +
  geom_smooth(method = "loess", span = 0.1) +
  labs(x = "Genomic Position", y = "Methylation",
       title = "BRCA1 Locus Methylation") +
  theme_minimal()

# 5. IGV可视化
# 将modBAM加载到IGV,开启"Color by modification"模式
# 红色=甲基化, 蓝色=未甲基化


第五步:差异甲基化区域(DMR)分析

白话解释: DMR分析是比较两组样本(如肿瘤vs正常)之间哪些区域的甲基化水平有显著差异。这些差异区域往往与基因调控、疾病发生相关。

技术原理: - DMR分析工具:DSS(推荐)、dmrseq、methylKit - DSS使用贝叶斯层次模型,支持小样本和不等覆盖度 - 需要控制假发现率(FDR)和设置甲基化差异阈值

代码示例:

# === 使用DSS进行DMR分析 ===
library(DSS)

# 1. 准备输入数据 (从bedMethyl转换)
# DSS需要: chr, pos, N(总覆盖), X(甲基化reads)
prepare_dss_input <- function(bedmethyl_file) {
  bed <- read.delim(bedmethyl_file, header = FALSE)
  data.frame(
    chr = bed$V1,
    pos = bed$V2,
    N = bed$V10,        # N_valid
    X = bed$V12         # N_mod (甲基化reads数)
  )
}

# 读取tumor和normal样本
tumor1 <- prepare_dss_input("tumor1.bedmethyl")
tumor2 <- prepare_dss_input("tumor2.bedmethyl")
normal1 <- prepare_dss_input("normal1.bedmethyl")
normal2 <- prepare_dss_input("normal2.bedmethyl")

# 2. 创建BSseq对象
bs_obj <- makeBSseqData(
  dat = list(tumor1, tumor2, normal1, normal2),
  sampleNames = c("Tumor1", "Tumor2", "Normal1", "Normal2")
)

# 3. DML检测 (差异甲基化位点)
dml_test <- DMLtest(
  bs_obj,
  group1 = c("Tumor1", "Tumor2"),
  group2 = c("Normal1", "Normal2"),
  smoothing = TRUE       # 平滑化(推荐)
)

# 4. DMR调用
dmrs <- callDMR(
  dml_test,
  delta = 0.2,           # 甲基化差异阈值(20%)
  p.threshold = 0.001,   # P值阈值
  minlen = 50,           # 最小DMR长度
  minCG = 3,             # 最小CpG数
  dis.merge = 50,        # 合并距离
  pct.sig = 0.5          # 区域内显著CpG比例
)

head(dmrs)
# chr  start    end      length  nCG  meanMethy1  meanMethy2  diff.Methy  areaStat

# 5. 注释DMR
library(ChIPseeker)
library(TxDb.Hsapiens.UCSC.hg38.knownGene)
dmr_gr <- GRanges(seqnames = dmrs$chr,
                   ranges = IRanges(start = dmrs$start, end = dmrs$end))
dmr_anno <- annotatePeak(dmr_gr, TxDb = TxDb.Hsapiens.UCSC.hg38.knownGene)
plotAnnoPie(dmr_anno)


第六步:单倍型特异性甲基化分析

白话解释: Nanopore的长读长使得可以将reads按单倍型(父本/母本)分开,分别看甲基化状态。这对研究基因组印记(imprinting)和等位基因特异性甲基化(ASM)非常有价值。

代码示例:

# === 单倍型标记 + 甲基化 ===
# 1. 变异检测 (用于分型)
clair3 --bam_fn sorted_mod.bam \
  --ref_fn hg38.fa \
  --output clair3_output/ \
  --platform ont \
  --model_path ont_model/

# 2. 使用WhatsHap进行单倍型分型
whatshap phase \
  clair3_output/merge_output.vcf.gz \
  sorted_mod.bam \
  --reference hg38.fa \
  --output phased.vcf.gz

# 3. 单倍型标记reads
whatshap haplotag \
  phased.vcf.gz \
  sorted_mod.bam \
  --reference hg38.fa \
  --output haplotagged_mod.bam

samtools index haplotagged_mod.bam

# 4. 按单倍型分离甲基化
# Haplotype 1
samtools view -b -d HP:1 haplotagged_mod.bam > hap1_mod.bam
samtools index hap1_mod.bam
modkit pileup hap1_mod.bam hap1.bedmethyl --ref hg38.fa --cpg --combine-strands

# Haplotype 2
samtools view -b -d HP:2 haplotagged_mod.bam > hap2_mod.bam
samtools index hap2_mod.bam
modkit pileup hap2_mod.bam hap2.bedmethyl --ref hg38.fa --cpg --combine-strands

# 5. 或使用modkit的单倍型感知模式
modkit pileup \
  haplotagged_mod.bam \
  haplotype_methyl.bedmethyl \
  --ref hg38.fa \
  --cpg \
  --partition-tag HP \
  --prefix hap
# 输出: hap_1.bedmethyl, hap_2.bedmethyl, hap_ungrouped.bedmethyl


实战命令

# === 完整流程: POD5 → 甲基化分析 ===

# 1. Basecalling + 甲基化检测
dorado basecaller sup pod5_dir/ \
  --modified-bases 5mCG \
  --reference hg38.fa \
  --device "cuda:all" \
  > calls.bam

# 2. 排序索引
samtools sort -@ 16 -o sorted.bam calls.bam
samtools index sorted.bam

# 3. 比对统计
samtools flagstat sorted.bam
mosdepth --threads 4 --no-per-base coverage sorted.bam

# 4. 生成bedMethyl
modkit pileup sorted.bam methylation.bedmethyl \
  --ref hg38.fa \
  --cpg \
  --combine-strands \
  --filter-threshold 0.75 \
  --threads 16

# 5. 甲基化统计摘要
modkit summary sorted.bam

# 6. 质控
modkit sample-probs sorted.bam sample_probs.tsv
# 查看修饰概率分布是否合理

# 7. DMR分析 (在R中)
Rscript run_dmr_analysis.R \
  --tumor tumor.bedmethyl \
  --normal normal.bedmethyl \
  --output dmr_results/ \
  --delta 0.2 \
  --pvalue 0.001

面试常问点

Q1:Nanopore直接甲基化检测相比亚硫酸盐测序(BS-seq)有什么优势?

A: (1) 不需要化学处理(亚硫酸盐会降解90%+ DNA),保留了DNA的完整长度信息;(2) 可以同时检测多种修饰(5mC, 5hmC, 6mA),BS-seq无法区分5mC和5hmC;(3) 长读长可以跨越重复区域,获得传统方法难以覆盖的区域的甲基化信息;(4) 可以直接进行单倍型特异性甲基化分析;(5) 无需PCR扩增,避免了扩增偏差。

Q2:Dorado检测甲基化的准确性如何?

A: 使用SUP模型时,5mCpG检测在单read水平的准确率约95-98%,汇总(pileup)后在覆盖度>10x的位点与WGBS的Pearson相关性达到0.95+。R10.4.1芯片比R9.4.1有显著改善。限制因素包括:低覆盖度位点(<5x)不够可靠;非CpG上下文的5mC检测仍不够准确;5hmC和5mC的区分在低覆盖度时较困难。

Q3:modBAM中的MM和ML tag分别存储什么信息?

A: MM tag存储修饰碱基的类型和位置(相对于序列中的碱基),格式如MM:Z:C+m,0,2,5;表示C上的5mC修饰,后面的数字是跳过的未修饰碱基数。ML tag存储对应位置的修饰概率(0-255, 对应0-100%),格式如ML:B:C,230,15,200。SAM spec v1.6引入了这一标准。

Q4:为什么要设置概率阈值(filter-threshold)?

A: modkit的概率阈值决定了什么水平的概率才被计为"甲基化"。阈值太低(如0.5)会引入假阳性(模型不确定的位点也被计为甲基化);阈值太高(如0.95)会丢失真阳性(特别是信号较弱的修饰位点)。通常0.75是一个平衡点。可以通过modkit sample-probs查看概率分布来选择合适的阈值。

Q5:如何利用Nanopore长读长进行印记基因分析?

A: 印记基因(imprinted genes)的甲基化是等位基因特异性的——一个等位基因甲基化,另一个不甲基化。Nanopore长读长可以:(1) 通过杂合SNP区分两个等位基因(单倍型分型);(2) 长reads可以跨越印记控制区(ICR)和SNP位点,直接读取单倍型甲基化状态;(3) 不需要bisulfite处理,保持了长读长优势。使用WhatsHap分型后,modkit的--partition-tag HP可以按单倍型输出甲基化。


易错点

1. 使用错误的Dorado模型

错误: 用fast模型做甲基化检测。 正确做法: 甲基化检测必须使用hac或sup模型(建议sup)。fast模型不包含修饰碱基检测能力。检查模型是否支持目标修饰:dorado download --list

2. 未指定正确的修饰类型

错误: 想检测CpG甲基化但用了--modified-bases 5mC(所有C上下文)。 正确做法: 对哺乳动物CpG甲基化使用--modified-bases 5mCG(仅CpG上下文)。5mC会检测所有上下文的5mC(包括CHG、CHH),在哺乳动物中大部分是噪声。

3. 覆盖度不足时做DMR分析

错误: 5x覆盖度的数据做DMR分析。 正确做法: DMR分析建议至少10x覆盖度(最好20x+)。低覆盖度导致每个CpG位点的甲基化估计不准确,DMR检测统计力不足。可以通过增加测序量或使用适应低覆盖度的方法(如DSS的平滑模式)缓解。

4. 忽略链方向的影响

错误: 不合并正负链就做分析,导致相邻的正负链CpG被当作两个独立位点。 正确做法: 对于CpG上下文的5mC,使用modkit的--combine-strands选项将正负链信息合并,因为CpG的正链C和负链G是互补配对的同一位点。

5. POD5和FAST5格式混淆

错误: 新版Dorado用FAST5输入。 正确做法: Dorado v1.0+已完全移除FAST5支持,仅接受POD5格式。旧的FAST5文件必须先转换:pod5 convert fast5 input.fast5 --output output.pod5。如果仍需处理FAST5,需使用Dorado 0.9.6或更早版本。

6. 未做质控就下结论

错误: 直接使用bedMethyl进行下游分析而不检查数据质量。 正确做法: 使用modkit summary检查全局统计;modkit sample-probs检查概率分布(应该呈双峰分布:接近0和接近255);检查覆盖度分布是否均匀。


补充知识

与其他甲基化检测方法对比

方法分辨率覆盖度需求5mC/5hmC区分读长成本
WGBS单碱基30x+不区分短读长
RRBS单碱基(CpG富集)10x+不区分短读长
甲基化芯片探针位点(850K/EPIC)N/A不区分N/A
Nanopore单碱基10-20x可区分超长读中-高
PacBio HiFi单碱基10-20x可区分15-20kb

高级应用

  • 全基因组甲基化单倍型图谱:结合de novo组装,构建完整的单倍型甲基化图谱
  • 实时甲基化检测:利用adaptive sampling根据甲基化状态实时富集或排斥特定reads
  • 超长读甲基化:利用>100kb的ultra-long reads研究大范围染色质结构与甲基化的关系
  • RNA修饰检测:Nanopore也可以检测RNA上的修饰(m6A, pseudouridine等)

计算资源需求

  • Dorado SUP模型 + 甲基化检测:需要GPU (建议NVIDIA A100/V100)
  • 30x人类基因组basecalling:A100约需8-12小时
  • modkit pileup:CPU密集,16线程约需1-2小时(30x人类基因组)
  • 存储:30x人类基因组的modBAM约100-200GB