我以为我尝试使用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
答案 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.id
,SeqRecord.name
和SeqRecord.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')