2026年4月16日 研究日志¶

研究内容:阅读了一篇蛋白质组学相关综述和一篇利用iPSC进行多组学研究的论文。这两篇内容太丰富了,总结尚未完成。今天讲一个大家可能经常看到,但又因为现在各种工具的自动处理而忽略的内容。就是fastq文件的base quality行。就是每条记录里最后那条各种符号横飞宛如乱码的那一行,同时也是其之所以与fasta文件不同的那一行。

1. FASTQ 的四行结构¶

FASTQ 是测序数据最常见的格式,每条 read 占四行:

@read_name
ACGTACGTACGT
+
HHGFFEDDDCCB

其中:

  • 第 1 行:read 名称
  • 第 2 行:碱基序列
  • 第 3 行:占位符(通常是 +)
  • 第 4 行:base quality(质量分数),用 ASCII 字符编码

第四行就是今天要聊的内容哦。


📝 附言:为什么测序需要质量分数?(理想 vs 现实)¶

在理想世界里,测序仪读到的每一个碱基都应该是 100% 正确 的:

A 就是 A  
C 就是 C  
G 就是 G  
T 就是 T

但现实世界远没有这么完美。


现实世界的测序会出错¶

测序仪在读取碱基时会受到很多因素影响:

  • 光信号太弱或太强
  • 相邻 cluster 干扰
  • 化学反应效率不稳定
  • 测序 cycles 越往后噪声越大
  • 某些序列(如同聚物)更难读

因此,测序仪对每个碱基都会给出一个 “我有多大把握读对了” 的概率。

这就是 测序错误概率 $P_{\text{error}}$


2. 测序错误概率 $P_{\text{error}}$ 是怎么来的?¶

测序仪内部会对每个碱基的信号进行建模,例如:

  • 光强度
  • 峰形
  • 背景噪声
  • 颜色通道分离度
  • 该 cycle 的整体质量

然后根据这些信号计算:

$$ P_{\text{error}} = \text{该碱基被读错的概率} $$

例如:

  • (P = 0.01) → 1% 的可能性读错
  • (P = 0.001) → 0.1% 的可能性读错 但一大堆的小数不方便机器储存及输出,因此才发明了质量分数Q值。

2. Base Quality(Q 值)是什么?¶

测序仪对每个碱基都会给一个“可信度”,称为 Phred 质量分数(Q)。

它的定义是:

$$ Q = -10 \log_{10}(P_{\text{error}}) $$

其中 $P_{\text{error}}$ 是测序错误的概率。

容易得:

  • Q = 20 → 错误率 1%
  • Q = 30 → 错误率 0.1%
  • Q = 40 → 错误率 0.01%

Q 值越高,碱基越可靠。


3. FASTQ 如何把 Q 值编码成字符?(Phred+33)¶

Illumina 现代测序平台使用 Phred+33 编码:

$$ \text{ASCII code} = Q + 33 $$

也就是说:

  • 字符 '!'(ASCII 33) → Q = 0
  • 字符 'I'(ASCII 73) → Q = 40

你看到的那一串奇怪字符,其实就是质量分数的“压缩版”。


4. 常用 ASCII ↔ Q 值对照表¶

下面是最常见的质量字符(你博客里可以直接贴这张表):

字符 ASCII Q 值 错误率(约)
! 33 0 1(完全不可信)
" 34 1 0.79
# 35 2 0.63
+ 43 10 0.1
5 53 20 0.01
? 63 30 0.001
I 73 40 0.0001
J 74 41 0.000079
K 75 42 0.000063

你会发现:

  • 越靠后的字符 → Q 越高
  • Illumina 常见 Q 值范围是 Q20–Q40

5. 一个简单示例¶

假设 FASTQ 的质量行是:

HHGFFEDDDCCB

我们可以逐个字符转换:

  • H → ASCII 72 → Q = 39
  • G → ASCII 71 → Q = 38
  • F → ASCII 70 → Q = 37
  • E → ASCII 69 → Q = 36
  • D → ASCII 68 → Q = 35
  • C → ASCII 67 → Q = 34
  • B → ASCII 66 → Q = 33

这说明:

  • 这个 read 的质量非常高(Q33–Q39)
  • 错误率大约在 0.05%–0.001% 之间

6. 小结¶

  • FASTQ 的第 4 行是 base quality
  • 使用 Phred+33 编码
  • Q 值越高,碱基越可靠
  • ASCII 字符是为了节省空间,麻烦你自己转化咯
  • 你可以用 ord(char) - 33 得到 Q 值,并根据Q值得到具体的错误概率,如下所示:
In [2]:
import math

def char_to_q(char):
    """
    将 FASTQ 的质量字符转换为 Phred Q 值(Phred+33)
    """
    return ord(char) - 33

def q_to_perror(q):
    """
    根据 Q 值计算测序错误概率 P_error
    Q = -10 * log10(P_error)
    => P_error = 10^(-Q/10)
    """
    return 10 ** (-q / 10)

# 示例:一串质量字符
quality_string = "HHGFFEDDDCCB"

print("质量字符:", quality_string)
print("字符 | Q值 | P_error")
print("--------------------------")

for c in quality_string:
    q = char_to_q(c)
    perror = q_to_perror(q)
    print(f"  {c}   | {q:2d} | {perror:.6f}")
质量字符: HHGFFEDDDCCB
字符 | Q值 | P_error
--------------------------
  H   | 39 | 0.000126
  H   | 39 | 0.000126
  G   | 38 | 0.000158
  F   | 37 | 0.000200
  F   | 37 | 0.000200
  E   | 36 | 0.000251
  D   | 35 | 0.000316
  D   | 35 | 0.000316
  D   | 35 | 0.000316
  C   | 34 | 0.000398
  C   | 34 | 0.000398
  B   | 33 | 0.000501

附注: 完整Q=0–41 的 ASCII ↔ Q 值对照表(illumina设备输出的质量分数行是不会输出Q>41的质量分数,所以以下是你所有可能看到的字符)

Q 值 ASCII 码 字符
0 33 !
1 34 "
2 35 #
3 36 $
4 37 %
5 38 &
6 39 '
7 40 (
8 41 )
9 42 *
10 43 +
11 44 ,
12 45 -
13 46 .
14 47 /
15 48 0
16 49 1
17 50 2
18 51 3
19 52 4
20 53 5
21 54 6
22 55 7
23 56 8
24 57 9
25 58 :
26 59 ;
27 60
28 61 =
29 62 >
30 63 ?
31 64 @
32 65 A
33 66 B
34 67 C
35 68 D
36 69 E
37 70 F
38 71 G
39 72 H
40 73 I
41 74 J

发现规律了吗?因为是根据ASCII码生成的字符,而字符又是按顺序来的,所以符号和数字往往意味着测序结果不够可靠,而字母则相对可靠,尤其是越往后越可靠,要都是J……那应该是用来展示的示例(笑)好了,今天就到这里,下个工作日见!