转录组计划
转录组计划 —— 自用(不产图)
最终目录 + 统一表头/格式 + 各脚本 I/O 契约 + 通用 ORA 引擎接入规范
按此执行,结果可直接进论文 Source Data,也便于后续把任意基因集合丢进富集模块复用。
0)目标与适用范围
- 核心目标:在不产图的前提下,输出统计口径统一、可追溯、能直接给顶刊补充材料的表格与方法文本。
- 适用范围:
- 标准 RNA-seq:Salmon → tximport → DESeq2 → clusterProfiler
- 任意基因集合的 GO/KEGG 过度表达分析(ORA):PSG、CAFE 扩缩、CNV、甲基化、ATAC、共表达模块等。
- 非目标:不做复杂流程治理/并发/版本化;不做图表;不做 GEO 等公共数据库打包(必要字段在表里体现)。
1)ID 口径“四条铁律”(新增、全流程约束)
一处决定,全链生效
- 是否修剪前/后缀,只在配置
annotations.id_cleanup中定一次。 - 相关脚本(至少 02 / 03 / 07)统一只读这一处开关和规则。
- 若未启用清理,则任何脚本都不得私自修剪 ID。
- 是否修剪前/后缀,只在配置
02 的 header 为唯一真理源(transcript 主键)
02_refprep_salmon_index.py写出的transcripts.fa头部(Name)是全流程唯一 transcript 主键。- 04(Salmon)、05(tximport)、07(emapper 对齐)等所有地方,都必须以此为准。
- 谁改它,谁负责重建索引并重跑 04/05/07。
gene_id 永不动刀(gene 层唯一主键)
- gene 层主键为
gene_id,用于 05/06/07/08/09 全链。 - 不允许:
- 在任意脚本中对
gene_id进行版本号拼接、前后缀添加、别名替换。 - 从 emapper 或其他外部注释中“反写” gene_id。
- 在任意脚本中对
gene_name仅作为别名列(可选第二列),不会作为主键使用。
- gene 层主键为
07 只为对齐而“临时清理”(且默认关闭)
- 07 中的 ID 清理逻辑仅用于:当 emapper 的
query与 03 的transcript_id不一致时,用统一规则做前/后缀修剪做对齐。 - 默认关闭;不开则不做任何修剪。
- 若在开启
id_cleanup后仍无法匹配,必须 硬错误退出,并在日志中提示在配置中明确列出前/后缀原因及修订建议。
- 07 中的 ID 清理逻辑仅用于:当 emapper 的
这四条铁律的目的:消灭 tximport 对不齐 与富集阶段“空气对空气”的隐性丢失,保证 transcript / gene / 注释 三方 ID 体系高度一致且可追溯。
2)最终目录结构(自用·不画图·定稿)
1 | |
3)统一表头与格式约定(定规)
通用规范
- 编码:UTF-8
- 换行:LF
- 分隔:TSV(
\t) - 缺失:
NA - 列名:英文
snake_case - 布尔:
true/false - 多基因列表:用分号
;分隔,按字典序排序。
3.1 data/samples.tsv
1 | |
3.2 data/contrasts.tsv
1 | |
3.3 QC 相关表
results/01_qc/sample_qc.tsv
sample, raw_reads, retained_reads, retention_rate, q30, gc_percent, adapter_percent, dup_percentresults/01_qc/summary.tsv
行 = sample,列同sample_qc.tsvresults/01_qc/outliers.tsv
sample, metric, value, rule, threshold, noteresults/01_qc/rejects.tsv
sample, reason, detail
3.4 表达矩阵
gene_counts.tsv / gene_tpm.tsv- 第一列:
gene_id - 可选第二列:
gene_name - 后续列:每个
sample
- 第一列:
matrix_stats.tsv
n_samples, n_genes, zero_fraction_median, libsize_median, libsize_q1, libsize_q3
3.5 差异表达(每 contrast)
DEG_*.tsv
gene_id, log2fc, lfc_se, stat, p_value, p_adjust, base_meanvarTop100.list
单列gene_idrle_range.tsv
rle_min, rle_max, rle_iqrdesign.txt
纯文本(模型 formula 与 batch 说明)
3.6 注释字典
gene2go.tsv:gene_id, go_idgene2pathway.tsv:gene_id, pathway_idgo/term2name.tsv:go_id, term_namego/obsolete_map.tsv:old_go_id, action, new_go_idkegg/term2gene.tsv:pathway_id, gene_idkegg/term2name.tsv:pathway_id, term_name
3.7 背景(每 contrast 或外部 tag)
<label>.list- 单列
gene_id
- 单列
<label>.meta.tsv
label, n_detectable, n_annot_mapped, universe_size, detectable_rule, samples_used
3.8 富集 by-term(RNA 对比或外部 tag)
GO:
GO_(bp|cc|mf)_by_term_(all|up|down).tsv列:
1
2
3term_id, term_name, test_set, ontology, gene_ids, gene_count,
bg_size, gene_ratio, bg_ratio, p_value, p_adjust,
universe_size, min_gs, max_gsGO 总表:
GO_sig_(all|up|down).tsv- 列同上,多一列
ontology - 内容 = 三本体(BP/CC/MF)纵向合并后按 FDR 过滤。
- 列同上,多一列
KEGG:
KEGG_by_term_(all|up|down).tsv列:
1
2
3pathway_id, term_name, test_set, count_mode, gene_ids, gene_count,
bg_size, gene_ratio, bg_ratio, p_value, p_adjust,
universe_size, min_gs, max_gs
4)各脚本 I/O 契约(逐模块)
4.0 00_make_sample_contrasts.py(可选)
- 输入:
data/samples.tsv,data/contrasts.tsv - 输出:
data/samples.checked.tsv,data/contrasts.checked.tsv - 说明:仅校验表头与取值合法;其余脚本可直接用原表,亦可用 checked 版(等价)。
4.1 01_qc_fastp_cutadapt.py(必须)
输入:
data/samples.tsv(或 checked 版),FASTQ 实体输出:
results/01_qc/sample_qc.tsvresults/01_qc/summary.tsvresults/01_qc/outliers.tsvresults/01_qc/rejects.tsv
约束:
rejects.tsv中样本在后续一律排除。
4.2 02_refprep_salmon_index.py(建议)
输入:
ref/*.fa,ref/*.gff3|gtf输出:
results/02_ref/gentrome_decoy_summary.tsv(构建摘要;同时生成 gentrome / decoys / index 等)ID 铁律关联:
- 该脚本产出的
transcripts.faheader 为全流程 transcript 主键; - 若重新构建索引,须按铁律 2 重跑下游(04/05/07)。
- 该脚本产出的
4.3 03_build_tx2gene_map.py(必须)
输入:
ref/*.gff3|gtf输出:
results/03_maps/tx2gene.clean.tsvresults/03_maps/tx2gene.blacklist.tsv
规则:
- 以
gene_id为主键。 - 一对多映射超过阈值(建议 ≥10)时,记录到
tx2gene.blacklist.tsv。 - 记录未能解析的条目数以便排查。
- 以
ID 铁律关联:
gene_id不允许被换名或拼接;遵守「gene_id 永不动刀」。transcript_id在此处若启用id_cleanup,其逻辑必须与 02 / 07 同源。
4.4 04_salmon_quant.py(建议)
输入:
data/samples.tsv(或 checked 版)results/02_ref中的索引路径(来自 config)
输出:
results/04_quant/<sample>/quant.sf(Salmon 原生结构)- (可选)
results/04_quant/samples.with_libtype.tsv(库型推断结果)
说明:
quant.sf:Name必须与 02 中 transcripts header 一致;后续 05 将以此对齐 tx2gene。
4.5 05_matrix_aggregate.py + 05_tximport_aggregate.R(必须)
输入:
results/04_quant/*/quant.sfresults/03_maps/tx2gene.clean.tsv
输出:
results/05_matrix/counts/gene_counts.tsvresults/05_matrix/tpms/gene_tpm.tsvresults/05_matrix/matrix_stats.tsv- (可保留
expressed_genes.tsv供参考)
行为要求:
- 基于
tx2gene.clean进行基因层聚合。 - 不再使用
tximport.ignoreTxVersion等“忽略版本”选项;ID 对齐统一通过 02/03 的 ID 铁律保证。
- 基于
质量闸口(Fail-Fast 建议):
- 在运行 tximport 前,校验
quant.sf:Name与tx2gene.clean:transcript_id的交集比例; - 若低于阈值(如 <95%),即 Fail-Fast,提示“请统一 02/03 的 ID 口径或检查 id_cleanup 配置”。
- 在运行 tximport 前,校验
4.6 06_deg_module.py + 06_f_deg.R(必须)
输入:
data/contrasts.tsvdata/samples.tsvresults/05_matrix/counts/gene_counts.tsv
输出(每 contrast 独立目录):
results/06_deg/<contrast>/design.txtresults/06_deg/<contrast>/DEG_all.tsvresults/06_deg/<contrast>/DEG_up.tsvresults/06_deg/<contrast>/DEG_down.tsvresults/06_deg/<contrast>/varTop100.listresults/06_deg/<contrast>/rle_range.tsv
阈值:
- 从
config.yaml读取(如|log2FC| ≥ 1,FDR ≤ 0.05;apeglm/independent filtering)。
- 从
4.7 07_prepare_emapper_annotations.py(建议)
输入:
ref/annotations/*(eggnog-mapper 结果 / KO / GO 等)输出:
results/07_annot/gene2go.tsvresults/07_annot/gene2pathway.tsv- 并统计并集覆盖率(用于 08 检查)
ID 铁律关联:
- 若 emapper 的
query与 03 中transcript_id不一致,且配置annotations.id_cleanup开启,则按统一规则清理。 - 默认不开清理;若仍不匹配则硬错误退出,要求用户明确 ID 口径。
- 若 emapper 的
4.8 go_local.R(建议)
- 输入:本地 GO.db / 注释资源
- 输出:
results/07_annot/go/term2name.tsvresults/07_annot/go/obsolete_map.tsv
4.9 kegg_local.sh(建议)
输入:离线 KEGG 映射资源
输出:
results/07_annot/kegg/term2gene.tsvresults/07_annot/kegg/term2name.tsv
开关:
count_mode(by_gene或by_ko),从config.yaml读取,项目内固定一种口径。
4.10 08_enrich_module.py + 08_g_enrich.R(必须)
输入(两种来源可并存):
① RNA-seq 对比
results/06_deg/<contrast>/DEG_all.tsv|DEG_up.tsv|DEG_down.tsvresults/05_matrix/*(用于生成 per-contrast 可检测集合)results/07_annot/gene2go.tsv, gene2pathway.tsv, go/term2name.tsv, go/obsolete_map.tsv, kegg/*results/08_enrich/background/<contrast>.{list,meta.tsv}- 若不存在,则按背景规则自动生成并落盘。
② 外部分析(通用 ORA 引擎)
results/08_enrich/inputs/<tag>/test.list(或up.list/down.list)results/08_enrich/inputs/<tag>/background.list(必需)- 可选:
meta.tsv
输出(到
<contrast>或<tag>目录):- 全部 GO/KEGG by-term 表
GO_sig_all.tsv / GO_sig_up.tsv / GO_sig_down.tsv
列名与统计口径:
- 见“统一表头与格式约定”;
- GO 三本体独立校正;
- KEGG 记
count_mode; - 背景
universe_size,min_gs,max_gs明确写入。
4.11 09_publish_results.py(必须)
输入:
results/05_matrix/results/06_deg/results/08_enrich/results/08_enrich/background/
输出:
results/09_publish/source_data/…目录树results/09_publish/source_data/METHODS_README.txt
可选:
- 若
config.yaml中publish.xlsx: true,同时输出results/09_publish/<contrast>.xlsx- 含 DEG / GO / KEGG / 设计 / 背景 meta / GO 总表 等所有关键表。
- 若
5)通用 ORA(过度表达分析)引擎:外部结果一致接入
输入规范(外部任意分析类型适用)
1 | |
- 基因 ID 必须与
results/07_annot/*使用的gene_id名称空间一致。 - 产物将落到
results/08_enrich/<tag>/,表头与 RNA-seq 一致。 - PSG 用
<tag>=psg_*,CAFE 扩/缩用<tag>=cafe_*(扩=up,缩=down);CNV / 甲基化 / ATAC / 共表达模块等均可类似接入。
6)config.yaml 最小必备口径(供脚本读取)
所有脚本只从本文件读取参数;不在命令行传参。
目录结构与 project/data|ref|results|scripts 完全一致。
1 | |
额外口径说明(不改变文件结构):
- 不再使用
tximport.ignoreTxVersion之类“蒙眼忽略版本”。 - ID 对齐由:
- 02 的 transcripts header
- 03 的 tx2gene 映射
- 07 的统一 ID 清理规则
三者共同保证。
7)METHODS_README.txt(一页骨架)
- Samples & Library:组织、处理条件、文库类型、读长、链特异性。
- Quantification:Salmon 索引构建(decoy-aware)、libType 策略、自举/后验(若未用可注明“未启用”)。
- Aggregation:tximport 聚合策略与 tx2gene 规则(gene_id 优先、blacklist 阈值)。
- Differential expression:设计式生成规则(是否纳入 batch)、apeglm、阈值、independent filtering。
- Enrichment:背景定义(“可检测 ∩ 可注释”)、GO/KEGG 词典来源、minGS/maxGS、FDR 方法、count_mode。
- Key Tables:列出提交到补充材料的表格名与路径(对应 09_publish/source_data 目录)。
8)关键统计口径(顶刊会关心)
ID 体系:
- 全流程以
gene_id为主键;gene_name仅作别名列。 - transcript 层以 02 的 header 为真理源,ID 清理由统一配置控制。
- 全流程以
设计式:
- 优先在模型中显式纳入 batch(若样本允许);
- 若不足以估计,在
design.txt中说明并在 Methods 中解释。
差异阈值(建议默认):
|log2FC| ≥ 1,FDR ≤ 0.05;- 启用 apeglm 与 independent filtering。
背景定义(RNA 对比):
- 背景 = 该对比样本的可检测基因集合 ∩ 可注释宇宙;
- 每对比落一份
<label>.list + <label>.meta.tsv。
富集方法:
- ORA(超几何 + BH);
- GO 的 BP/CC/MF 三本体 分层独立统计与校正;
- KEGG 采用固定
count_mode(建议by_gene)。
GO 大小阈值:
minGS = 10,maxGS = 500;- obsolete term 用
obsolete_map做替换/忽略并留痕。
“GO 总表”:
- 将 BP/CC/MF 三张 by-term 纵向合并后,按全局 FDR 阈值过滤,得到
GO_sig_all/up/down.tsv三张可直接引用的汇总表。
- 将 BP/CC/MF 三张 by-term 纵向合并后,按全局 FDR 阈值过滤,得到
外部基因集(通用 ORA 引擎):
- 任意
<tag>必须自带test.list(或 up/down) + background.list; - 背景 = “该分析真实可评估的基因全集”。
- 任意
9)各模块设计细节(实现思路与边界条件)
A. 参考与注释
GFF3/GTF 口径:
- 以
gene_id为准;非法字符与重复 ID 先处理; gene_name仅保留为别名输出。
- 以
gentrome/decoys 摘要:
- 记录转录本总数、decoy 条目数与过滤条目数,便于解释比对/定量率。
tx2gene.clean:
- 归并同一
gene_id的转录本; - 一对多映射超过阈值(建议 ≥10)进入
tx2gene.blacklist; - 对“未能映射”的转录本计数并提示(避免隐形丢失)。
- 归并同一
GO/KEGG 离线词典:
gene2go / gene2pathway以gene_id记;term2name写英文名;obsolete_map落实替换逻辑(优先replaced_by,其次consider)。
边界 & 坑
- GFF3 的
Parent/ID关系不规范会导致 tx2gene 崩;需在映射统计里明确“未解析条目数”。 - 非模式物种 KEGG 映射若通过 KO,注意
by_gene与by_ko口径不可混用;固定一种并写明。
B. 质控(fastp → 表)
样本级:读数、Q30、GC%、adapter%、dup%、保留率;
跨样本:输出矩阵与离群列表;
Fail-Fast(默认阈值):
- 保留率 <50%
- 原始读数 <5M
- 平均读长 <40 bp
→ 写入rejects.tsv并在下游自动排除。
不作图:
- 所有判断均以表格数值为准,便于后续重跑与审稿人复核。
边界 & 坑
- 少数样本质量极差但数量不足以支撑对比,会在 06 阶段触发“功效不足”提示(不自动改阈值)。
C. 表达矩阵聚合
tximport:
- 基于
tx2gene.clean聚合到基因层; - counts / TPM 双轨输出。
- 基于
矩阵体检:
- 样本数、基因数、零表达比例、库深统计。
全局“可检测基因”:
- 定义为:
TPM>0 或 count>0 任一样本; - 仅作参考,不直接用于富集背景(背景由 per-contrast 规则计算)。
- 定义为:
边界 & 坑
- 异常高的零表达比例可能意味着 tx2gene 问题或样本污染,应在矩阵体检中高亮。
D. 差异分析(DESeq2)
设计式生成:
- 从
samples.tsv + contrasts.tsv自动写出design.txt(包含是否纳入 batch 及原因)。
- 从
统一阈值:
- 按
config.yaml; - 收缩 LFC 与 independent filtering 打开。
- 按
诊断而不作图:
varTop100.list:帮助快速排查批次/离群;rle_range.tsv:RLE 的 min/max/IQR 直观反映标准化效果。
三套 DEG 表:
- All / Up / Down,列名固定,便于与富集/可视化联动。
边界 & 坑
- 组内样本数 <3 时仍可出结果,但
design.txt必须写明功效偏低,并在 Methods 中解释。
E. 富集分析(clusterProfiler · ORA)
背景(RNA 对比):
- 从该对比涉及的样本中计算“可检测集合”(TPM>0 或 count≥1 任一样本);
- 与
gene2go / gene2pathway的并集求交,得到universe_size; - 明确写入
background/<label>.meta.tsv:- 样本清单
samples_used - 判定规则
detectable_rule - 覆盖率与
universe_size。
- 样本清单
统计:
- GO:三本体独立
enricher()+ BH;minGS=10, maxGS=500;obsolete 替换后再统计; - KEGG:
enricher();count_mode固定为by_gene(或by_ko); GO_sig_all/up/down.tsv:BP/CC/MF 纵向合并后按 FDR 过滤;- 所有表写
universe_size / min_gs / max_gs,方便审稿人检查“分母”。
- GO:三本体独立
通用 ORA 引擎(外部
<tag>):- 任意分析只要给
test.list(或 up/down) + background.list,即走相同统计流程并产出同规格结果; - PSG:
test = 通过分支/集合检验的基因,background = 实际参与并得到有效统计的基因全集; - CAFE 扩缩:扩张 = up,收缩 = down;背景 = “进入 CAFE 有效评估的基因全集”。
- 任意分析只要给
边界 & 坑
- 外部
<tag>的 ID 体系必须与gene2go/gene2pathway使用同一gene_id;若不同,先做映射表。 - 背景千万不要偷懒复用 RNA-seq 的默认背景;就地取材是避免虚假富集的关键。
F. Methods 一页骨架
已在第 7 节给出骨架;实现时按项目实际情况填充即可。
10)质量控制与验收逻辑(运行后的“闸口”)
QC 闸口:
rejects.tsv的样本不得进入后续分析。
DEG 闸口:
- 若某对比
DEG_all< 10,日志提示“功效不足或阈值过严”; - 不自动降阈值,由人工判断。
- 若某对比
富集闸口:
- 注释覆盖率(可检测 ∩ 可注释 / 可检测)< 60% 时:
- 生成高亮提示,并建议补注释或调整 count_mode / minGS。
- 注释覆盖率(可检测 ∩ 可注释 / 可检测)< 60% 时:
发布:
source_data/目录完整 +METHODS_README.txt六段齐备;- 如开启 xlsx,合并成便于人工审阅的工作簿。
11)扩展与演进(保持自用的简洁前提下)
GSEA 并行通道(可选):
- 当需要排名列表型分析时,旁路新增一个
ranked.tsv输入的 GSEA 模式(gseGO/gseKEGG); - 不影响 ORA 主通道。
- 当需要排名列表型分析时,旁路新增一个
多注释源融合(可选):
- 在
07_annot引入多源合并(eggnog + 自建 + 物种专属库),通过“优先级 + 去重”生成统一的gene2go/pathway,提升覆盖率。
- 在
术语冗余裁剪(可选):
- GO 结果可加简易冗余移除逻辑(如相似度阈值 + 代表 term 选取),
- 当前版本以“原始 by-term 表 + 总表”为主,最大程度保持可复查性。
12)典型“从零到交付”的一次执行故事线
- 填好
samples.tsv与contrasts.tsv。 - 跑 01,得到 QC 四表,确认是否有样本进入
rejects.tsv。 - 跑 02/03/04/05,拿到
gene_counts/TPM + matrix_stats,且 tx2gene/quant 对齐通过检查。 - 跑 06,得到每个对比的三套 DEG 与诊断。
- 构建每个对比的背景(自动或显式),跑 08,得到 GO/KEGG by-term +
GO_sig_*。 - 若要并行 PSG/CAFE/ATAC 等,向
08_enrich/inputs/<tag>放入test.list + background.list再跑 08。 - 跑 09,生成
source_data/与METHODS_README.txt(可选 xlsx)。
13)典型问题对照(“踩坑 → 解释 → 解决”)
问:富集结果几乎无显著项?
解:背景过大/过宽或注释覆盖率太低。
策:检查<label>.meta.tsv的universe_size / coverage,必要时合并注释源或放宽minGS(须写入方法说明)。问:某对比 Up/Down 数量极不对称?
解:可能由 LFC 收缩或样本不均衡引起。
策:查看design.txt与rle_range.tsv,确认是否有离群与 batch 未纳入。问:外部
<tag>富集偏离常识?
解:最常见是背景错用 RNA-seq 默认背景或 ID 空间不一致。
策:核对background.list来源与gene_id映射,确保遵守“test + background”统一口径。
14)小结
这份 《转录组计划 vNext》:
- 保留了皇上原先的 目录结构、表头约定、脚本 I/O 契约;
- 把 ID 口径四条铁律、背景规则、GO/KEGG 统计、config 关键字段 全部固化写进文档;
- 不改变任何既有路径与文件名,只是补上原来隐含但没写明的规则;
- 运行出来的所有表格,都可以直接进顶刊的 Source Data 与 Methods。