Trimmomatic / cutadapt 裁剪报错:接头文件路径、参数错误、输出丢失

做 RNA-seq 的同行们,十有八九都在裁剪这一步卡过。我当年第一次跑 Trimmomatic,就为了一个路径错误折腾了半小时。说白了,接头裁剪工具的错误 80% 集中在三个地方:文件找不着、参数写错、输出莫名其妙没了。

4.1 接头文件路径——最简单的坑,最气人

4.1.1 路径错误 / 文件名拼错

这个问题在 Linux 服务器上特别常见。你明明看见有个 adapters.fa 文件,Trimmomatic 就是报找不到。为什么会这样?

TrimmomaticPE: ILLUMINACLIP:./adapters.fa:2:30:10
Error: Unable to find adapter file

我检查过的三个最常见原因:

  • 相对路径失效:脚本里用的是 ./adapters.fa,但调度器把工作目录改了。我曾经在 SLURM 集群上遇到过,明明当前目录有文件,但 sbatch 提交后工作目录变成了用户 home。
  • 文件名大小写:Linux 严格区分大小写。Adapter.fa 和 adapters.fa 是两个文件。
  • 文件格式不对:有些接头文件是 fasta 格式,但用户存成了 .txt,内容没问题,但工具不认。

我个人习惯,无论在哪里跑,一律写绝对路径:

ILLUMINACLIP:/home/user/reference/adapters/truseq3.fa:2:30:10

4.1.2 接头文件自身内容问题

文件路径对了,有时候工具还是不干活。我看过最诡异的报错是 Trimmomatic 解析文件时直接崩溃,日志只有一行 Segmentation fault。排查了才发现,接头序列里有个非法字符——文件本来是 Windows 编辑的,末尾多了 ^M 回车符。

快速检查接头文件是否合法:
用 head -3 adapters.fa 看前几行,确认每条序列只有一行,没有多余空格或特殊符号。
file adapters.fa 可以查看文件编码,如果是 ASCII text, with CRLF line terminators,用 dos2unix 转一下。

4.2 参数错误——笔误的代价

4.2.1 Trimmomatic 的参数顺序陷阱

Trimmomatic 有个让人抓狂的设计:参数必须严格按照 ILLUMINACLIP:fa:seedMismatches:palindromeClipThreshold:simpleClipThreshold 的顺序。我见过有人写成 2:10:30:file,或者丢了冒号,工具不会给你明确错误,直接说 Invalid argument。

正确的写法:

ILLUMINACLIP:truseq3.fa:2:30:10

注意:

  • 冒号分隔,不能多不能少
  • 四个参数:接头文件、允许错配数(一般2)、回文匹配阈值(30)、简单匹配阈值(10)
  • 阈值写小了容易误删,写大了去不掉接头

4.2.2 Cutadapt 的参数混淆

Cutadapt 的报错相对友好,但新手经常把 -a、-g、-b 搞混。简单区分:

参数 含义 典型报错
-a 3' 端接头(最常用) Error: adapter sequence not found
-g 5' 端接头 Warning: no reads with adapter(其实是用了错的方向)
-b 自动检测两端 比预估多删了很多碱基,可能是接头方向反了

我建议所有双端测序数据,先搞清楚建库试剂盒用了哪套接头。如果是 TruSeq 单索引,两边接头不同,必须分别指定 -a 和 -A。

4.2.3 其他常见参数乌龙

  • 滑动窗口质量阈值:Trimmomatic 的 SLIDINGWINDOW:4:15 表示窗口4个碱基,平均质量低于15则切除。有人写成 SLIDINGWINDOW:15:4,15bp窗口+4的质量阈值……结果读长全没了。
  • 最小长度:MINLEN:36 写成了 MINLEN:3,输出了一堆短得离谱的序列。
  • Cutadapt 的 -e:允许错误率默认0.1,写 -e 0 会导致严格匹配,实际接头有错配时全部漏掉。
记住这个检查清单:
✓ 参数和它的值是否顺序反了?
✓ 阈值单位是否正确?(质量分数 vs 比例)
✓ 双端输入时,_R1 和 _R2 是否用了对应的参数?

4.3 输出丢失——最隐蔽的失败

工具跑了,日志也没报错,但输出目录空空如也。这种问题比直接报错更难找。

4.3.1 输出目录不存在 / 权限不足

Trimmomatic 不会自动创建输出目录。如果你指定了 ./trimmed/out_R1.fastq,但 trimmed 目录不存在,工具会静默失败吗?不会,它会报 Error: can't open output file。但有些 Shell 脚本把输出重定向到文件,目录不存在时只会在 stderr 里留下一行信息,很容易被忽略。

我有个血泪教训:在集群上用 --output 指定了 results/sample_trimmed.fq.gz,脚本里忘记 mkdir -p results,运行出错但没细看 stderr,以为成功了。第二天发现全是空文件。

4.3.2 输出前缀与后缀混淆

Trimmomatic 输出命名规则是 输出前缀_1P.fastq(PE模式下,paired surviving reads)。如果你只给了 outprefix,忘了加路径,输出就会散落在当前目录。更常见的是有人指定了 --outprefix /full/path/out,但忘了写 .fastq 后缀——不,它不需要后缀,工具自己加,但你习惯性以为需要,结果又去检查不存在的文件。

通常检查输出文件清单:

  • outprefix_1P.fastq / outprefix_2P.fastq(双端均保留)
  • outprefix_1U.fastq / outprefix_2U.fastq(仅一端保留)
  • 如果只需要成对的数据,记得指定 TOPHRED33 或 TOPHRED64 并确保输出目录可写

4.3.3 裁剪后文件为空——参数太激进

有时候输出文件确实生成了,但大小为 0。这通常是因为参数太暴力,所有读长都被切光了。比如:

  • MINLEN:150,但原始读长只有 100bp
  • HEADCROP:50 把头切太多
  • CROP:80 截断后短于最小长度

遇到空输出,先看日志里 Input Read Pairs 和 Both Surviving 的数字。如果后者为 0,就是参数问题了。

4.4 核心排查流程

我把这三类问题的排查路线画了一张图,方便你对照:

Trimmomatic / Cutadapt 报错排查流程 裁剪报错/输出异常 检查接头文件路径 / 文件真实性 / 格式 参数顺序 / 阈值 / 接头方向 / 遗漏 输出目录权限 / 前缀命名 / 空文件 对应修改后重新运行 验证日志中 Both Surviving 数量 > 0 排查口诀 文件 → 参数 → 输出,逐层检查 日志第一行先看路径,最后一行看统计

这张图我贴在自己工位屏风上,每次遇到裁剪报错就按这个顺序查,基本十分钟内定位问题。

4.5 避坑指南——我的实战清单

最后分享几个让我记忆犹新的坑:

  1. 剪完了才发现接头文件版本不对。我曾经用 TruSeq3 的接头去剪 Nextera 的数据,结果日志显示“0 reads with adapter”。白白跑了一天,后来换了正确的 NexteraPE-PE.fa 才解决。
  2. Cutadapt 多线程参数导致 OOM。-j 0 自动检测 CPU,但集群上每个节点的内存有限。我那次 100 个样本同时跑,每个都开 32 线程,直接踩爆资源限制。
  3. 输出文件名冲突。并行跑多个样本时,如果没有用样本名作为前缀,后跑的疯狂覆盖先跑的结果。我建议输出命名强制用 {sample}_R1_trimmed.fastq.gz 格式。
调试小技巧: 在正式跑全数据集前,先拿一条读长测试。
zcat input_R1.fastq.gz | head -4000 | gzip > test_R1.fastq.gz
用这个小文件验证参数和输出路径,确认无误再批量提交。每次我都这么干,至少省掉一半 debug 时间。