Biopython SeqIO:如何编写修改后的SeqRecord标头

时间:2015-01-14 14:42:07

标签: python bioinformatics biopython fastq

我以为我尝试使用Biopython来挽救协作者提供的一些简单的损坏的fastq文件。我只需要修改包含某个子字符串的标题行(以@开头)。但是,由以下代码创建的新fastq文件未更改。毫无疑问,我错过了一些明显的东西。

编写修改后的fastq SeqRecord的正确方法是什么?

import os, sys
from Bio import SeqIO

path_to_reads = sys.argv[1]
if not os.path.exists(path_to_reads + '/fixed'):
    os.mkdir(path_to_reads + '/fixed')

fwd_fastqs = [fn for fn in os.listdir(path_to_reads) if fn.endswith('_F.fastq')]
rev_fastqs = [fn for fn in os.listdir(path_to_reads) if fn.endswith('_R.fastq')]
fastq_pairs = zip(fwd_fastqs, rev_fastqs)

for fastq_pair in fastq_pairs:
    with open(path_to_reads + '/' +  fastq_pair[0], 'rU') as fwd_fastq:
        with open(path_to_reads + '/fixed/' +  fastq_pair[0], 'w') as fixed_fwd_fastq:
            fixed_fwd_records = []
            for fwd_record in SeqIO.parse(fwd_fastq, 'fastq'):
                fwd_record.name = fwd_record.name.replace('/2','/1')
                fixed_fwd_records.append(fwd_record)
            SeqIO.write(fixed_fwd_records, fixed_fwd_fastq, 'fastq')
    # ...

输入数据(两条记录,标题行以@开头):

@MISEQ01:115:000000000-A8FBM:1:1112:18038:15085/1
GATCGGAAGAGCACACGTCTGAACTCCAGTCACTGCCAATCATCTCGTATGCCGTCTTCTGCTTG
+
AAAAAAAAAF4CGGGGGAGGGFGHBHGHC5AGEGFFHGA3F355FGG223FFAEE0GCGA55BAB
@MISEQ01:115:000000000-A8FBM:1:1101:20590:9966/2
GATCACTCCCCTGTGAGGAACTACTGTCTTCACGCAGAAAGCGTCTAGCCATGGCGTTAGTATGA
+
1>A111DFBA1CFA1FFG1BFGB1D1DGFGH3GECA0ABFFG?E///DDGFBB0FEAEEFBDAB2

2 个答案:

答案 0 :(得分:2)

我不是蟒蛇人,但我做生物信息学,所以我理解文件格式。我可以解释发生了什么以及为什么:

查看BioPython Bio.SeqIO.QualityIO fastq writer code BioPython的SeqRecord对象的工作方式是它有2个字段来存储部分defline。一个name和一个description。通常人们会认为它会像FASTA文件一样工作,并在白色空间上拆分defline,名称为左侧拆分,描述是右侧拆分中的可选注释。然而,BioPython解析器将defline的副本作为描述。我的猜测是这是一个黑客(以及我在下面解释的编写器代码)来绕过CASAVA 1.8读取,其中包含空格。

当作者写出记录时,它会检查名称和描述是否匹配,如果它们不匹配,那么它会写出假定为CASAVA 1.8读取的description行。 ..

由于您只更改了name部分,因此匹配测试失败,因此使用了未更改的描述。当您清空description时,作者正确使用了name字段。

答案 1 :(得分:0)

我找到了一个解决方案,而且我认为它并不是很明显。可以通过SeqRecord.idSeqRecord.nameSeqRecord.description中的任意一种访问标题行。

毫无疑问,它们之间存在微妙的差异,但我已经略过了SeqIO文档,并且没有明确提及它们。如果我添加fwd_record.description = '',我的脚本会按预期将/1的发生率替换为/2

所以,工作代码:

for fastq_pair in fastq_pairs:
    with open(path_to_reads + '/' +  fastq_pair[0], 'rU') as fwd_fastq:
        with open(path_to_reads + '/fixed/' +  fastq_pair[0], 'w') as fixed_fwd_fastq:
            fixed_fwd_records = []
            for fwd_record in SeqIO.parse(fwd_fastq, 'fastq'):
                fwd_record.name = fwd_record.name.replace('/2','/1')
                fwd_record.description = ''
                fixed_fwd_records.append(fwd_record)
            SeqIO.write(fixed_fwd_records, fixed_fwd_fastq, 'fastq')