质谱数据处理MaxQuant¶
一句话概述:MaxQuant是蛋白质组学质谱数据处理的"瑞士军刀"——把质谱仪吐出的海量原始数据变成蛋白质鉴定和定量结果,是发表蛋白质组学论文的标配工具。
核心知识点表¶
| 知识点 | 白话解释 | 重要程度 |
|---|---|---|
| MaxQuant | 免费的质谱数据分析软件,马普所开发 | ⭐⭐⭐⭐⭐ |
| RAW文件 | 质谱仪产生的原始数据文件 | ⭐⭐⭐⭐⭐ |
| 蛋白质鉴定 | 从质谱数据中找出样品里有哪些蛋白质 | ⭐⭐⭐⭐⭐ |
| LFQ定量 | 无标记定量,比较不同样品中蛋白质的含量差异 | ⭐⭐⭐⭐⭐ |
| FDR控制 | 假发现率控制,通常设为1% | ⭐⭐⭐⭐ |
| Andromeda | MaxQuant内置的搜库引擎 | ⭐⭐⭐⭐ |
| Perseus | MaxQuant配套的统计分析软件 | ⭐⭐⭐⭐ |
一、质谱蛋白组学原理(白话版)¶
质谱蛋白质组学流程(像破案一样):
样品准备阶段:
蛋白质混合物 → 酶切成肽段 → 就像把一本书撕成碎片
质谱检测阶段:
LC-MS/MS检测:
├── LC(液相色谱)= 把碎片按大小排队
├── MS1(一级质谱)= 称每个碎片的重量
└── MS2(二级质谱)= 把碎片再打碎,看指纹
数据分析阶段(MaxQuant做的事):
├── 1. 读取RAW文件(原始数据)
├── 2. 提取MS2谱图
├── 3. 数据库搜索(把碎片指纹和数据库比对)
├── 4. 肽段鉴定(确认这个碎片来自哪个蛋白质)
├── 5. 蛋白质组装(把碎片拼回完整的蛋白质)
├── 6. 定量分析(比较不同样品中蛋白质多少)
└── 7. FDR控制(排除假阳性)
二、MaxQuant安装与配置¶
2.1 安装¶
# ========== Windows安装(推荐) ==========
# 1. 下载MaxQuant:https://www.maxquant.org/maxquant/
# 2. 解压zip文件到任意目录
# 3. 需要安装 .NET Framework 4.7.2+
# ========== Linux安装(通过Mono运行) ==========
# 安装Mono运行时
sudo apt-get install mono-complete # Ubuntu/Debian系统安装Mono
# 下载MaxQuant
wget https://www.maxquant.org/download_asset/maxquant/latest # 下载最新版
unzip MaxQuant_*.zip -d ~/software/MaxQuant # 解压
# 运行MaxQuant(命令行模式)
mono ~/software/MaxQuant/bin/MaxQuantCmd.exe mqpar.xml # 用Mono运行
# ========== 验证安装 ==========
# Windows: 双击MaxQuant.exe
# Linux: mono MaxQuantCmd.exe --help
2.2 准备蛋白质数据库(FASTA)¶
# 从UniProt下载蛋白质数据库
# 人类蛋白质组(推荐用reviewed的Swiss-Prot)
# 下载人类Swiss-Prot蛋白质组
wget "https://rest.uniprot.org/uniprotkb/stream?format=fasta&query=reviewed:true+AND+organism_id:9606" \
-O human_swissprot.fasta # 下载人类已审核蛋白质序列
# 查看序列数量
grep -c "^>" human_swissprot.fasta # 统计蛋白质数量(约20,000+)
# 同时下载常见污染物数据库
wget https://www.maxquant.org/contaminants # MaxQuant自带污染物数据库
# 或使用CRAPome数据库
三、MaxQuant参数配置¶
3.1 XML参数文件(mqpar.xml)¶
<?xml version="1.0" encoding="utf-8"?>
<!-- MaxQuant参数配置文件 -->
<MaxQuantParams>
<!-- 原始数据文件路径 -->
<filePaths>
<string>D:\data\sample1.raw</string> <!-- 样品1的RAW文件 -->
<string>D:\data\sample2.raw</string> <!-- 样品2的RAW文件 -->
<string>D:\data\sample3.raw</string> <!-- 样品3的RAW文件 -->
</filePaths>
<!-- 实验设计 -->
<experiments>
<string>Control</string> <!-- 对照组 -->
<string>Treatment</string> <!-- 处理组 -->
<string>Treatment</string> <!-- 处理组(重复) -->
</experiments>
<!-- 蛋白质数据库 -->
<fastaFiles>
<string>D:\database\human_swissprot.fasta</string> <!-- FASTA数据库路径 -->
</fastaFiles>
<!-- 搜索参数 -->
<enzymes>
<string>Trypsin/P</string> <!-- 酶切方式:胰蛋白酶 -->
</enzymes>
<maxMissedCleavages>2</maxMissedCleavages> <!-- 最多允许2个漏切 -->
<!-- 质量精度 -->
<mainSearchTol>4.5</mainSearchTol> <!-- MS1质量容差:4.5 ppm -->
<msmsSearchTol>20</msmsSearchTol> <!-- MS2质量容差:20 ppm -->
<!-- 修饰设置 -->
<fixedModifications>
<string>Carbamidomethyl (C)</string> <!-- 固定修饰:半胱氨酸烷基化 -->
</fixedModifications>
<variableModifications>
<string>Oxidation (M)</string> <!-- 可变修饰:甲硫氨酸氧化 -->
<string>Acetyl (Protein N-term)</string> <!-- 可变修饰:蛋白质N端乙酰化 -->
</variableModifications>
<!-- LFQ定量 -->
<lfqMode>1</lfqMode> <!-- 启用LFQ定量(1=开启) -->
<lfqMinRatioCount>2</lfqMinRatioCount> <!-- LFQ最少肽段数 -->
<!-- FDR控制 -->
<peptideFdr>0.01</peptideFdr> <!-- 肽段FDR:1% -->
<proteinFdr>0.01</proteinFdr> <!-- 蛋白质FDR:1% -->
<!-- 线程数 -->
<numThreads>8</numThreads> <!-- 使用8个CPU线程 -->
</MaxQuantParams>
3.2 命令行运行¶
# Windows命令行运行
MaxQuantCmd.exe mqpar.xml # 用配置文件运行MaxQuant
# Linux (Mono)
mono MaxQuantCmd.exe mqpar.xml # 用Mono运行MaxQuant
# 查看进度
tail -f combined/proc/progress.txt # 实时查看进度
四、结果文件解读¶
4.1 关键输出文件¶
# MaxQuant输出目录结构
combined/txt/ # 主要结果文件夹
├── proteinGroups.txt # 蛋白质鉴定和定量结果(最重要!)
├── peptides.txt # 肽段鉴定结果
├── evidence.txt # 每个肽段的详细证据
├── msms.txt # MS/MS谱图匹配结果
├── msmsScans.txt # MS/MS扫描信息
├── modificationSpecificPeptides.txt # 修饰肽段
├── summary.txt # 运行摘要
└── parameters.txt # 使用的参数
# 查看蛋白质鉴定数(不含反库和污染物)
awk -F'\t' 'NR>1 && $0!~/^REV__/ && $0!~/^CON__/' combined/txt/proteinGroups.txt | wc -l
4.2 Python解析结果¶
#!/usr/bin/env python3
"""解析MaxQuant输出结果"""
import pandas as pd # 数据处理
import numpy as np # 数值计算
# ========== 读取proteinGroups.txt ==========
df = pd.read_csv(
"combined/txt/proteinGroups.txt",
sep="\t", # Tab分隔
low_memory=False # 避免内存警告
)
print(f"原始蛋白质组数: {len(df)}") # 打印原始数量
# ========== 数据过滤(关键步骤!) ==========
# 1. 去除反库(Reverse)命中
df = df[df["Reverse"] != "+"] # 排除反库匹配
print(f"去除Reverse后: {len(df)}")
# 2. 去除污染物(Contaminant)
df = df[df["Potential contaminant"] != "+"] # 排除污染物蛋白
print(f"去除污染物后: {len(df)}")
# 3. 去除仅通过修饰位点鉴定的蛋白质
df = df[df["Only identified by site"] != "+"] # 排除仅位点鉴定
print(f"最终蛋白质数: {len(df)}")
# ========== 提取LFQ定量数据 ==========
lfq_cols = [col for col in df.columns if col.startswith("LFQ intensity")] # 找所有LFQ列
lfq_data = df[["Protein IDs", "Gene names", "Protein names"] + lfq_cols].copy() # 提取关键列
# 将0替换为NaN(0表示未检测到)
for col in lfq_cols:
lfq_data[col] = lfq_data[col].replace(0, np.nan) # 0→NaN
# Log2转换(蛋白质组学标准操作)
for col in lfq_cols:
lfq_data[f"log2_{col}"] = np.log2(lfq_data[col]) # 对LFQ值取log2
# ========== 基本统计 ==========
print(f"\n===== 蛋白质组学数据概况 =====")
print(f"鉴定的蛋白质总数: {len(lfq_data)}")
for col in lfq_cols:
valid = lfq_data[col].notna().sum() # 有效值数量
print(f" {col}: {valid} 个蛋白质有定量值 ({valid/len(lfq_data)*100:.1f}%)")
# 保存清理后的数据
lfq_data.to_csv("protein_lfq_cleaned.csv", index=False) # 保存为CSV
print("\n清理后的数据已保存到 protein_lfq_cleaned.csv")
五、Perseus下游分析¶
#!/usr/bin/env python3
"""使用Python实现Perseus风格的蛋白质组学分析"""
import pandas as pd # 数据处理
import numpy as np # 数值计算
from scipy import stats # 统计分析
import matplotlib.pyplot as plt # 绑图
# ========== 读取清理后的数据 ==========
df = pd.read_csv("protein_lfq_cleaned.csv") # 读取数据
# 定义样品分组
control_cols = ["LFQ intensity Control_1", "LFQ intensity Control_2", "LFQ intensity Control_3"] # 对照组
treatment_cols = ["LFQ intensity Treat_1", "LFQ intensity Treat_2", "LFQ intensity Treat_3"] # 处理组
# ========== 缺失值过滤 ==========
# 至少在一个组的所有重复中都有值
def valid_in_group(row, cols, min_valid=2):
"""检查一组样品中有效值数量是否足够"""
return row[cols].notna().sum() >= min_valid # 至少min_valid个有效值
mask = df.apply(lambda r: valid_in_group(r, control_cols) or valid_in_group(r, treatment_cols), axis=1)
df_filtered = df[mask].copy() # 过滤后的数据
print(f"过滤后蛋白质数: {len(df_filtered)}")
# ========== 缺失值填充 ==========
# 用正态分布随机值填充(Perseus默认方法)
all_values = []
for col in control_cols + treatment_cols:
all_values.extend(np.log2(df_filtered[col].dropna()).tolist())
mean_val = np.mean(all_values) # 全局均值
std_val = np.std(all_values) # 全局标准差
# 从低端正态分布采样填充(模拟低丰度蛋白)
fill_mean = mean_val - 1.8 * std_val # 下移1.8个标准差
fill_std = 0.3 * std_val # 宽度为0.3倍标准差
for col in control_cols + treatment_cols:
log2_col = np.log2(df_filtered[col])
missing_mask = log2_col.isna() # 找缺失值
n_missing = missing_mask.sum() # 缺失值数量
df_filtered.loc[missing_mask, f"log2_{col}"] = np.random.normal(fill_mean, fill_std, n_missing) # 随机填充
df_filtered.loc[~missing_mask, f"log2_{col}"] = log2_col[~missing_mask] # 保留原值
# ========== 差异分析(t检验) ==========
log2_ctrl = [f"log2_{c}" for c in control_cols] # Log2对照组列名
log2_treat = [f"log2_{c}" for c in treatment_cols] # Log2处理组列名
results = []
for idx, row in df_filtered.iterrows(): # 遍历每个蛋白质
ctrl_vals = row[log2_ctrl].values.astype(float) # 对照组值
treat_vals = row[log2_treat].values.astype(float) # 处理组值
# t检验
t_stat, p_val = stats.ttest_ind(treat_vals, ctrl_vals) # 双样本t检验
log2fc = np.mean(treat_vals) - np.mean(ctrl_vals) # 计算log2倍数变化
results.append({
"gene": row.get("Gene names", ""), # 基因名
"protein": row.get("Protein IDs", ""), # 蛋白质ID
"log2FC": log2fc, # log2倍数变化
"pvalue": p_val, # p值
"-log10p": -np.log10(p_val) if p_val > 0 else 30 # -log10(p)
})
result_df = pd.DataFrame(results) # 转为DataFrame
# 多重检验校正(BH方法)
from statsmodels.stats.multitest import multipletests # 多重检验校正
_, result_df["padj"], _, _ = multipletests(result_df["pvalue"].fillna(1), method="fdr_bh") # BH校正
# ========== 火山图 ==========
plt.figure(figsize=(10, 8)) # 设置图片大小
# 分类:上调、下调、不显著
sig_up = (result_df["log2FC"] > 1) & (result_df["padj"] < 0.05) # 显著上调
sig_down = (result_df["log2FC"] < -1) & (result_df["padj"] < 0.05) # 显著下调
nonsig = ~(sig_up | sig_down) # 不显著
plt.scatter(result_df.loc[nonsig, "log2FC"], result_df.loc[nonsig, "-log10p"],
c="gray", alpha=0.5, s=10, label=f"Not Sig ({nonsig.sum()})") # 不显著=灰色
plt.scatter(result_df.loc[sig_up, "log2FC"], result_df.loc[sig_up, "-log10p"],
c="red", alpha=0.7, s=15, label=f"Up ({sig_up.sum()})") # 上调=红色
plt.scatter(result_df.loc[sig_down, "log2FC"], result_df.loc[sig_down, "-log10p"],
c="blue", alpha=0.7, s=15, label=f"Down ({sig_down.sum()})") # 下调=蓝色
plt.axhline(-np.log10(0.05), color="gray", linestyle="--", alpha=0.5) # p=0.05参考线
plt.axvline(1, color="gray", linestyle="--", alpha=0.5) # log2FC=1参考线
plt.axvline(-1, color="gray", linestyle="--", alpha=0.5) # log2FC=-1参考线
plt.xlabel("Log2 Fold Change", fontsize=14) # X轴标签
plt.ylabel("-Log10 Adjusted P-value", fontsize=14) # Y轴标签
plt.title("Volcano Plot - Proteomics", fontsize=16) # 标题
plt.legend(fontsize=12) # 图例
plt.tight_layout()
plt.savefig("volcano_proteomics.png", dpi=300, bbox_inches="tight") # 保存图片
plt.close()
print("火山图已保存到 volcano_proteomics.png")
常见报错与解决¶
| 报错信息 | 原因 | 解决方法 |
|---|---|---|
Out of memory | 内存不足 | 增加内存或减少同时处理的文件数 |
FASTA file not found | 数据库路径错误 | 使用绝对路径,检查文件是否存在 |
No peptides identified | 搜索参数不对或数据质量差 | 检查酶切方式、修饰设置、质量容差 |
.NET Framework error | .NET版本太低 | 安装.NET Framework 4.7.2+ |
Mono error on Linux | Mono版本不兼容 | 安装最新版Mono |
LFQ values all zero | LFQ没开启或数据太少 | 检查mqpar.xml中lfqMode=1 |
速查表¶
========================================
质谱数据处理MaxQuant 速查表
========================================
【安装】
Windows → 解压即用,需.NET 4.7.2+
Linux → Mono运行:mono MaxQuantCmd.exe
【关键参数】
酶切方式 → Trypsin/P(最常用)
漏切数 → 2(默认)
MS1容差 → 4.5 ppm(Orbitrap)
MS2容差 → 20 ppm
FDR → 1%(肽段和蛋白质都设1%)
固定修饰 → Carbamidomethyl (C)
可变修饰 → Oxidation (M), Acetyl (Protein N-term)
【核心输出文件】
proteinGroups.txt → 蛋白质鉴定+定量(最重要)
peptides.txt → 肽段鉴定
evidence.txt → 肽段证据详情
summary.txt → 运行摘要
【数据过滤(必做!)】
去反库 → Reverse ≠ "+"
去污染物 → Potential contaminant ≠ "+"
去仅位点鉴定 → Only identified by site ≠ "+"
【定量方法】
LFQ → 无标记定量(免费,最常用)
TMT/iTRAQ → 同位素标记定量
SILAC → 细胞培养同位素标记
【下游分析工具】
Perseus → MaxQuant配套统计分析(GUI)
MSstats → R包,蛋白质组统计分析
limma → R包,差异分析
【面试考点】
Q: MaxQuant的Andromeda引擎是什么?
A: 内置的数据库搜索引擎,用打分算法匹配实验谱图和理论谱图
Q: FDR 1%是怎么控制的?
A: Target-Decoy策略:搜索反向数据库,统计假阳性比例
Q: LFQ定量的原理?
A: 基于同一肽段在不同样品中的色谱峰面积比值进行归一化定量
========================================
参考资料:MaxQuant官方文档 | maxquant.org | Perseus | Cox & Mann, Nature Biotechnology 2008