【问题标题】:Removing PCR Duplicates From Fastq File Containing Unique Molecular Identifiers从包含唯一分子标识符的 Fastq 文件中删除 PCR 重复
【发布时间】:2015-06-11 04:51:36
【问题描述】:

我正在尝试编辑包含基因组数据和每个序列两侧的唯一分子标识符的 Fastq 文件。

前两个读取的示例如下所示:

1 @HISEQ:230:C6G45ANXX:3:1101:1395:2141 1:N:0:ACAGTGGTTGAACCTT
2 TGACGGCACTTTCTCTTCCCAACCACGTGGCTGCAGACTTCTTGCTCTCAAGTTGTCCTGACATGCTCTGAGAGCACACACAACATACATACAACACCTGGATCTGTGAATTAATTACTGCCTAGG
3 +
4 BB//<<BFBFFF<FFFFBBB<<<F/FBBB<FF/B<FFFFFFFFFFFFFFBFFFBFB/FBFFB//F//B<FFF</</BF<BBBFFFFF//B<FBFF/77F/B/BF7/FF/<BF/7FFFFBBF//B7B
5 @HISEQ:230:C6G45ANXX:3:1101:1498:2162 1:N:0:ACAGTGGTTGAACCTT
6 TGACGGCACTTTCTCTTCCCAACCACGTGGCTGCAGACTTCTTGCTCTCAAGTTGTCCTGACATGCTCTGAGAGCACACACAACATACATACAACACCTGGATCTGTGAATTAATTACTGCCTAGG
7 +
8 BBB<B<F<FFFFFFFBFFFFFFBFFFFBFF/F<FFFFBBFFFFFFFFFFBFB/BFFFFFFFFFFFBFFB/<<<FFFFFFFFFFFFFFBFFFF##################################

这些行解释如下:

1 Information
2 Sequence
3 +
4 Quality Scoring
5 Information
6 Sequence
7 +
8 Quality Scoring

我需要一个输出文件,其中已删除给定序列的所有精确重复(及其相应信息)。也就是说,我需要删除文件中已经出现第二行的 4 行块。

因此,在上面的示例中,由于第 2 行和第 6 行中的序列匹配,输出文件应该包含第 1、2、3 和 4 行,而不是 5、6、7 和 8 行。

生成的输出文件:

1 @HISEQ:230:C6G45ANXX:3:1101:1395:2141 1:N:0:ACAGTGGTTGAACCTT
2 TGACGGCACTTTCTCTTCCCAACCACGTGGCTGCAGACTTCTTGCTCTCAAGTTGTCCTGACATGCTCTGAGAGCACACACAACATACATACAACACCTGGATCTGTGAATTAATTACTGCCTAGG
3 +
4 BB//<<BFBFFF<FFFFBBB<<<F/FBBB<FF/B<FFFFFFFFFFFFFFBFFFBFB/FBFFB//F//B<FFF</</BF<BBBFFFFF//B<FBFF/77F/B/BF7/FF/<BF/7FFFFBBF//B7B

【问题讨论】:

  • 如果它的第三行(带有核苷酸序列的那个)与前一个块的匹配,您想要删除一个四行块,我理解正确吗?垃圾行是否应该是输出的一部分,如果不是,我如何识别哪些行是垃圾?
  • 你是对的。一切都将在这四行块中,如果序列部分匹配,则应删除所有四行。垃圾行不应包含在输出中,并且只会是 Fastq 的前三行,因此四行的起始组从第 4 行开始,然后将在第 6、10、14、18 行找到序列。 ....

标签: python bash awk sed


【解决方案1】:

我认为您在 FASTQ 订单上偏离了一行。在您的示例中:

1 Junk
2 Junk
3 Junk
4 Information        +->
5 Sequence           |     these four lines constitute a single record
6 +                  |
7 Quality Scoring    +->
9 Information
10 Sequence
11 +

所以第 1-3 行(垃圾)实际上是 上一个 记录的前 3 行,而第 9-11 行是 下一个 记录的前 3 行。

无论如何,我建议您使用 BioPython 的 SeqIO 来解析您的 FASTQ 文件并进行重复数据删除。

http://biopython.org/wiki/SeqIO

一种基本的方法是:

from Bio import SeqIO
from Bio.SeqUtils.CheckSum import seguid
detected = []
unique = []
for rec in SeqIO.parse(open('inputfile.fastq', 'rU'), 'fastq'):
   cksum = seguid(rec.seq)
   if cksum not in detected:
       unique.append(rec)
       detected.append(cksum)
SeqIO.write(unique, open('deduplicated.fastq','w'), 'fastq')

这会读取每条记录并计算序列的校验和以存储在列表中。每个后续记录仅在其序列没有遇到校验和时才添加到输出列表(“唯一”)。

【讨论】:

  • 哦,那好多了。我必须记住这一点,以此为所有来这里使用 sed 和 awk 处理 fastq 文件的生物学家指明方向。
  • 感谢您在我的线路识别中发现错误,这让我免于日后的头疼。我更新了问题以反映这一点。这段代码看起来不错,但我有一个问题,这种重复数据删除是否以类似于 Picard 的方式进行。因为问题是在基因组中从同一位置开始的序列被标记为重复。但就我而言,我所有的序列都从基因组的完全相同的位置开始。
  • 这个例子非常基本——它不关心任何序列来自基因组的哪个位置,也不关心任何标识符是什么,或其他任何事情。它所做的只是直接比较基本序列(或者更确切地说,它们的校验和)。您甚至可以跳过校验和,只比较序列本身。 [为清楚起见进行了编辑]
【解决方案2】:

这似乎是我们循环遍历文件两次的完美案例:首先计算重复项,然后打印适当的行:

awk 'FNR==NR {
          if (FNR%4==2) {
              a[$2]++
              if (a[$2]>1) b[int(FNR/4)]=1
             }
          next}
      b[int(FNR/4)]==0' file file

这里的关键是播放文件中的 4K+2 行,并跟踪到目前为止出现了哪些行。如果是这样,我们存储K(来自4K+2),以便在文件的下一个循环中避免这些行出现在4K+0/1/2/3 形式上。

为了清楚起见,我假设第一列中的行不存在(我不知道它们是为了澄清还是真的存在)。删除它们应该是微不足道的。

测试

$ awk 'FNR==NR {if (FNR%4==2) {a[$2]++; if (a[$2]>1) b[int(FNR/4)]=1} next} b[int(FNR/4)]==0' a a
@HISEQ:230:C6G45ANXX:3:1101:1395:2141 1:N:0:ACAGTGGTTGAACCTT
TGACGGCACTTTCTCTTCCCAACCACGTGGCTGCAGACTTCTTGCTCTCAAGTTGTCCTGACATGCTCTGAGAGCACACACAACATACATACAACACCTGGATCTGTGAATTAATTACTGCCTAGG
+
BBB<B<F<FFFFFFFBFFFFFFBFFFFBFF/F<FFFFBBFFFFFFFFFFBFB/BFFFFFFFFFFFBFFB/<<<FFFFFFFFFFFFFFBFFFF##################################

【讨论】:

  • 这看起来像我想要做的,虽然我不明白文件的写入,似乎无法让它工作。我需要你的最后一行是这样的: b[int(FNR/4)]==0' inputfile > outputfile
  • 不!重定向是在awk 表达式之外完成的,你说awk '...' file file &gt; new_file(不,这不是一个错误,我们写了两次file,因为我们读了两次)。有关 FNR/NR 和两次读取文件的说明,请参阅 backreference.org/2010/02/10/idiomatic-awk
  • 好吧,这看起来很棒而且效果很好我确实将 (FNR%4==2) 更改为 (FNR%4==1)。我认为你拥有它的方式,代码正在检查第 3 行而不是第 2 行的重复项。但无论如何这很有帮助,我不知道你可以用 awk 做到这一点。像往常一样 fedorqui 你真的很有帮助。
  • 很高兴读到 :) 2%4==2,所以检查第二行应该是 NR%4==2... 顺便说一句,我认为(尚未测试)b[int(FNR/4)]==0 可以写成int(FNR/4) not in b
  • 奇怪,当我使用 FNR%4==2 时,我只得到一组四行输出。但是当我使用 FNR%4==1 时,我得到了数百个。这就是我在脑海中想到的方式:0/4 = R0,1/4 = R1,2/4 = R2,3/4 = R3,4/4 = R0。没有?
猜你喜欢
  • 2015-01-02
  • 2020-05-16
  • 2018-09-29
  • 2020-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多