160_碱基编辑检测分析¶
一句话概述¶
碱基编辑(Base Editing)通过ABE(腺嘌呤碱基编辑器, A→G)和CBE(胞嘧啶碱基编辑器, C→T)实现精准单碱基替换,利用CRISPResso2和BE-Analyzer等工具从扩增子测序数据中定量编辑效率、编辑窗口和脱靶效应。
核心知识点总览¶
| 知识点 | 说明 |
|---|---|
| ABE | 腺嘌呤碱基编辑器,A·T→G·C转换 |
| CBE | 胞嘧啶碱基编辑器,C·G→T·A转换 |
| 编辑窗口 | PAM上游4-8位(CBE)或4-7位(ABE)为主要编辑位置 |
| CRISPResso2 | 广泛使用的CRISPR编辑结果分析工具 |
| BE-Analyzer | 专门针对碱基编辑的分析工具 |
| 扩增子测序 | PCR扩增靶位点→深度测序→量化编辑 |
| Bystander编辑 | 编辑窗口内非目标碱基的编辑 |
| 脱靶分析 | Cas-OFFinder/GUIDE-seq/CIRCLE-seq预测和验证 |
各步骤详解¶
第一步:碱基编辑原理¶
白话解释: 传统CRISPR像"剪刀",碱基编辑器像"铅笔橡皮"——不切断DNA,只把一个字母改成另一个。CBE把C改成T(就像把"猫"改成"毛"),ABE把A改成G。这对修复点突变疾病(如镰刀细胞病)非常有用。
技术原理: - CBE: nCas9(切口酶) + 胞嘧啶脱氨酶(APOBEC/AID) + UGI(尿嘧啶糖基化酶抑制剂) - C → U(脱氨) → T(复制后) - ABE: nCas9 + 进化的tRNA腺嘌呤脱氨酶(TadA) - A → I(次黄嘌呤, 脱氨) → G(复制后被读作G) - 编辑窗口: 以PAM为参考,protospacer的第4-8位(CBE)或4-7位(ABE)编辑效率最高
实验设计流程:
设计sgRNA(靶向目标碱基在编辑窗口内)
↓
转染碱基编辑器+sgRNA到细胞
↓
培养48-72h
↓
提取基因组DNA
↓
PCR扩增靶位点(~200-300bp)
↓
深度测序(NGS, 通常>10000x)
↓
CRISPResso2/BE-Analyzer分析
↓
编辑效率、纯度、bystander评估
第二步:CRISPResso2分析碱基编辑¶
代码示例:
# === 安装CRISPResso2 ===
pip install CRISPResso2
# 或 conda install -c bioconda crispresso2
# === 基本碱基编辑分析 ===
CRISPResso --fastq_r1 sample_R1.fq.gz \
--fastq_r2 sample_R2.fq.gz \
--amplicon_seq ATCGATCGATCGATCGATCGATCGATCGATCGATCGATCG \
--guide_seq ATCGATCGATCGATCGATCG \
--base_editor_output \
--conversion_nuc_from C \
--conversion_nuc_to T \
--output_folder crispresso_output/ \
--name sample1 \
--min_frequency_alleles_around_cut_to_plot 0.01 \
--plot_window_size 20
# 参数说明:
# --amplicon_seq: 扩增子的参考序列(无PAM)
# --guide_seq: sgRNA序列(不含PAM, 与amplicon_seq方向一致)
# --base_editor_output: 开启碱基编辑模式
# --conversion_nuc_from/to: CBE用C→T, ABE用A→G
# --plot_window_size: 分析窗口大小
# === ABE分析 ===
CRISPResso --fastq_r1 sample_R1.fq.gz \
--fastq_r2 sample_R2.fq.gz \
--amplicon_seq REFERENCE_SEQUENCE \
--guide_seq GUIDE_20NT \
--base_editor_output \
--conversion_nuc_from A \
--conversion_nuc_to G \
--output_folder abe_output/ \
--name abe_sample1
# === 批量分析 ===
CRISPRessoBatch --batch_settings batch.txt \
--output_folder batch_output/ \
--base_editor_output \
--conversion_nuc_from C \
--conversion_nuc_to T
# batch.txt格式:
# name fastq_r1 fastq_r2 amplicon_seq guide_seq
# sample1 s1_R1.fq.gz s1_R2.fq.gz AMPLICON_SEQ GUIDE_SEQ
# sample2 s2_R1.fq.gz s2_R2.fq.gz AMPLICON_SEQ GUIDE_SEQ
第三步:BE-Analyzer专项分析¶
代码示例:
import pandas as pd
import numpy as np
from collections import Counter
from Bio import SeqIO, pairwise2
def analyze_base_editing(fastq_file, reference, guide_seq,
edit_from='C', edit_to='T', window=(4, 8)):
"""碱基编辑效率分析"""
# 确定编辑窗口位置
guide_start = reference.find(guide_seq)
if guide_start == -1:
guide_start = reference.find(str(Seq(guide_seq).reverse_complement()))
edit_positions = list(range(guide_start + window[0] - 1, guide_start + window[1]))
# 统计各位置的编辑
total_reads = 0
edited_reads = 0
position_edits = {pos: 0 for pos in edit_positions}
for record in SeqIO.parse(fastq_file, "fastq"):
seq = str(record.seq)
# 简化: 假设已与reference对齐
alignment = pairwise2.align.globalms(reference, seq, 2, -1, -5, -1,
one_alignment_only=True)
if not alignment:
continue
total_reads += 1
read_edited = False
ref_aligned, query_aligned = alignment[0][0], alignment[0][1]
ref_pos = 0
for i, (r, q) in enumerate(zip(ref_aligned, query_aligned)):
if r != '-':
if ref_pos in edit_positions:
if r == edit_from and q == edit_to:
position_edits[ref_pos] += 1
read_edited = True
ref_pos += 1
if read_edited:
edited_reads += 1
# 计算效率
results = {
'total_reads': total_reads,
'edited_reads': edited_reads,
'overall_efficiency': edited_reads / total_reads if total_reads > 0 else 0,
'position_efficiency': {pos: count/total_reads for pos, count in position_edits.items()}
}
return results
# 使用示例
results = analyze_base_editing(
"sample_merged.fq",
reference="ATCGATCGATCGATCGATCGATCGATCG",
guide_seq="ATCGATCGATCGATCGATCG",
edit_from='C', edit_to='T',
window=(4, 8)
)
print(f"总reads: {results['total_reads']}")
print(f"编辑效率: {results['overall_efficiency']:.1%}")
print("各位置效率:")
for pos, eff in results['position_efficiency'].items():
print(f" Position {pos}: {eff:.1%}")
第四步:编辑产物纯度评估¶
代码示例:
# === 编辑产物分类 ===
# 碱基编辑产物类型:
# 1. 完美编辑(desired edit only)
# 2. Bystander编辑(编辑窗口内其他碱基也被编辑)
# 3. Indel(切口导致的插入缺失,碱基编辑的副作用)
# 4. 未编辑
def classify_editing_outcomes(crispresso_output_dir):
"""分类CRISPResso2输出的编辑结果"""
# 读取CRISPResso2的等位基因频率表
alleles = pd.read_csv(
f"{crispresso_output_dir}/Alleles_frequency_table.zip",
sep='\t', compression='zip'
)
outcomes = {
'perfect_edit': 0,
'bystander_edit': 0,
'indel': 0,
'unedited': 0
}
target_position = 5 # 目标编辑位点(相对于guide起始)
for _, row in alleles.iterrows():
aligned_seq = row['Aligned_Sequence']
ref_seq = row['Reference_Sequence']
freq = row['%Reads'] / 100
has_indel = '-' in aligned_seq or '-' in ref_seq
if has_indel:
outcomes['indel'] += freq
else:
# 检查目标位点和bystander
edits = []
for i, (r, a) in enumerate(zip(ref_seq, aligned_seq)):
if r != a and r != '-' and a != '-':
edits.append(i)
if len(edits) == 0:
outcomes['unedited'] += freq
elif len(edits) == 1 and target_position in edits:
outcomes['perfect_edit'] += freq
else:
outcomes['bystander_edit'] += freq
return outcomes
# 可视化编辑产物
import matplotlib.pyplot as plt
outcomes = classify_editing_outcomes("crispresso_output/")
labels = list(outcomes.keys())
sizes = list(outcomes.values())
fig, ax = plt.subplots(figsize=(8, 6))
colors = ['#2ecc71', '#f39c12', '#e74c3c', '#95a5a6']
ax.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%', startangle=90)
ax.set_title("Base Editing Outcome Classification")
plt.savefig("editing_outcomes.png", dpi=150)
第五步:脱靶分析¶
代码示例:
# === Cas-OFFinder: 预测脱靶位点 ===
# 下载: http://www.rgenome.net/cas-offinder/
# 输入文件格式:
# /path/to/genome_dir
# NNNNNNNNNNNNNNNNNNNNNGG (PAM pattern)
# ATCGATCGATCGATCGATCGNNN 3 (guide + 允许的错配数)
cat > input.txt << 'EOF'
/path/to/hg38/
NNNNNNNNNNNNNNNNNNNNNGG
ATCGATCGATCGATCGATCGNNN 4
EOF
cas-offinder input.txt C output.txt
# 输出: 预测的脱靶位点列表
# === 脱靶位点的深度测序验证 ===
# 对top 10预测脱靶位点设计引物
# PCR扩增 → 深度测序 → CRISPResso2分析
# 批量分析多个脱靶位点
for site in OT1 OT2 OT3 OT4 OT5; do
CRISPResso --fastq_r1 ${site}_R1.fq.gz \
--fastq_r2 ${site}_R2.fq.gz \
--amplicon_seq ${site}_ref \
--guide_seq ${site}_guide \
--base_editor_output \
--conversion_nuc_from C \
--conversion_nuc_to T \
--output_folder offtarget_results/${site}/ \
--name ${site}
done
第六步:结果可视化与报告¶
代码示例:
import matplotlib.pyplot as plt
import numpy as np
# === 编辑窗口热图 ===
# 多个sgRNA在不同位置的编辑效率
guides = ['sgRNA_1', 'sgRNA_2', 'sgRNA_3', 'sgRNA_4']
positions = list(range(1, 21)) # protospacer 20个位置
# 模拟数据(实际从CRISPResso2结果提取)
efficiency_matrix = np.random.rand(len(guides), 20) * 0.5
# 编辑窗口(位置4-8)效率更高
efficiency_matrix[:, 3:8] *= 3
fig, ax = plt.subplots(figsize=(12, 4))
im = ax.imshow(efficiency_matrix, cmap='YlOrRd', aspect='auto', vmin=0, vmax=1)
ax.set_xticks(range(20))
ax.set_xticklabels(positions)
ax.set_yticks(range(len(guides)))
ax.set_yticklabels(guides)
ax.set_xlabel("Position in protospacer")
ax.set_ylabel("sgRNA")
plt.colorbar(im, label="Editing efficiency")
ax.set_title("Base Editing Window Profile")
# 标注编辑窗口
ax.axvline(x=2.5, color='blue', linestyle='--', alpha=0.5)
ax.axvline(x=7.5, color='blue', linestyle='--', alpha=0.5)
ax.text(5, -0.7, 'Editing Window', ha='center', color='blue')
plt.tight_layout()
plt.savefig("editing_window.png", dpi=150)
实战命令¶
# === 完整碱基编辑分析流程 ===
# 1. 质控
fastp -i R1.fq.gz -I R2.fq.gz -o clean_R1.fq.gz -O clean_R2.fq.gz
# 2. CRISPResso2分析
CRISPResso --fastq_r1 clean_R1.fq.gz --fastq_r2 clean_R2.fq.gz \
--amplicon_seq AMPLICON_SEQUENCE \
--guide_seq GUIDE_20NT \
--base_editor_output \
--conversion_nuc_from C --conversion_nuc_to T \
--output_folder results/ --name experiment1 \
--min_average_read_quality 30 \
--min_single_bp_quality 20
# 3. 批量处理
CRISPRessoBatch --batch_settings samples.txt \
--base_editor_output --conversion_nuc_from C --conversion_nuc_to T \
--output_folder batch_results/
# 4. 可视化结果
# CRISPResso2自动生成HTML报告和PNG图片
# 关键图: nucleotide_frequency, base_editor_substitution
面试常问点¶
Q1:ABE和CBE的工作机制有什么不同?¶
A: CBE(胞嘧啶碱基编辑器):nCas9-APOBEC1-UGI融合蛋白,APOBEC将靶链上的C脱氨为U,UGI抑制细胞修复U,复制后U被读为T,实现C·G→T·A。ABE(腺嘌呤碱基编辑器):nCas9-TadA*融合蛋白,进化的TadA将靶链上的A脱氨为肌苷I,I被读为G,复制后实现A·T→G·C。两者的编辑窗口都在PAM上游4-8位附近。
Q2:如何评估碱基编辑的效率和纯度?¶
A: 效率=编辑reads/总reads。纯度需要分类:(1) 完美编辑(只有目标位点被编辑);(2) Bystander编辑(窗口内其他碱基也被编辑);(3) Indel(nick导致的插入缺失,是不良副产物)。用CRISPResso2的base_editor_output模式可以同时得到效率和各产物比例。高纯度=高比例的完美编辑+低bystander+低indel。
Q3:什么是Bystander编辑?如何减少?¶
A: Bystander编辑是编辑窗口内非目标的C(CBE)或A(ABE)也被编辑。例如目标是编辑第5位C,但第4位和第7位C也被编辑了。减少策略:(1) 使用窄窗口变体(如BE4-YE1窗口仅1-2nt);(2) 设计sgRNA使非目标碱基位于窗口外;(3) 使用prime editing代替(编辑精度更高)。
Q4:碱基编辑的扩增子测序需要多少深度?¶
A: 通常需要>10,000x覆盖度,建议50,000-100,000x。原因:(1) 碱基编辑效率可能只有1-5%,需要足够reads检测低频编辑;(2) 区分真实编辑与测序错误(Illumina错误率~0.1%,所以1%以下的编辑需要高深度来区分);(3) 定量bystander产物需要单碱基分辨率。
Q5:如何区分碱基编辑和PCR/测序错误?¶
A: (1) 碱基编辑是方向性的(CBE只有C→T,ABE只有A→G),而测序错误是随机方向的——如果在同一位置看到C→T远多于C→A/G,更可能是真实编辑;(2) 未处理对照(无编辑器转染)应该显示<0.1%的"编辑"率;(3) 编辑集中在编辑窗口内(位置4-8),窗口外的变化更可能是噪声。
易错点¶
1. 扩增子序列方向与guide方向不匹配¶
错误: CRISPResso2的amplicon_seq和guide_seq不在同一条链上。 正确做法: guide_seq必须是扩增子序列中可以找到的子串(即同一链方向)。如果guide靶向反义链,需要将guide反向互补。
2. 编辑窗口位置计算错误¶
错误: 将PAM本身计为位置1。 正确做法: 位置从PAM远端(5'端)开始计数:protospacer第1位是离PAM最远的碱基,第20位紧邻PAM。编辑窗口通常为4-8位(离PAM第13-17位)。
3. 未设置未编辑对照¶
错误: 没有阴性对照就报告编辑效率。 正确做法: 必须包含未转染对照或只转染nCas9(无脱氨酶)对照。背景"编辑率"(来自PCR错误和SNP)需要从实验组中扣除。
4. PCR引物设计在编辑位点附近有SNP¶
错误: 引物区域含有高频SNP或重复序列。 正确做法: 引物距离编辑位点>50bp,避免SNP区域。检查引物特异性(primer-BLAST)。使用高保真聚合酶减少PCR错误。
5. 忽略indel副产物¶
错误: 只关注碱基编辑效率,忽略indel比例。 正确做法: 碱基编辑器因为使用nickase,仍有1-10%的indel产生。CRISPResso2会报告indel比例。对于治疗应用,indel应<5%。
补充知识¶
碱基编辑器发展¶
| 版本 | 特点 | 编辑窗口 |
|---|---|---|
| BE3 | 第一代CBE | ~5nt |
| BE4 | 增加UGI减少副产物 | ~5nt |
| ABE7.10 | 第一代成熟ABE | ~4nt |
| ABE8e | 高效率ABE | ~4-5nt |
| BE4-YE1 | 窄窗口CBE | ~1-2nt |
新一代编辑工具¶
- Prime Editing: 真正的"搜索替换",不受编辑窗口限制
- ADAR editing: RNA水平的碱基编辑
- DdCBE: 线粒体DNA碱基编辑(无需PAM)
- GBE: 鸟嘌呤碱基编辑器(C→G)
分析工具对比¶
| 工具 | 特点 | 适用 |
|---|---|---|
| CRISPResso2 | 全能型,支持所有CRISPR编辑类型 | 通用 |
| BE-Analyzer | 专为碱基编辑设计 | CBE/ABE |
| CRIS.py | Python库,可嵌入pipeline | 编程用户 |
| EditR | 从Sanger测序分析编辑 | 低通量验证 |